]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
bash-4.1 remove leftover and stray files
authorChet Ramey <chet.ramey@case.edu>
Fri, 9 Dec 2011 01:23:56 +0000 (20:23 -0500)
committerChet Ramey <chet.ramey@case.edu>
Fri, 9 Dec 2011 01:23:56 +0000 (20:23 -0500)
160 files changed:
034-glob-globstar~ [deleted file]
CHANGES-4.1~ [deleted file]
CHANGES~ [deleted file]
COMPAT~ [deleted file]
CWRU/CWRU.chlog~ [deleted file]
CWRU/POSIX.NOTES.old [deleted file]
CWRU/old/set.def.save [deleted file]
CWRU/save/unwind_prot.h.save [deleted file]
MANIFEST~ [deleted file]
Makefile.in~ [deleted file]
NEWS-4.1~ [deleted file]
NEWS~ [deleted file]
README~ [deleted file]
aclocal.m4~ [deleted file]
alias.c~ [deleted file]
array.c~ [deleted file]
array.h~ [deleted file]
arrayfunc.c.save [deleted file]
arrayfunc.c~ [deleted file]
assoc.c~ [deleted file]
bashhist.c~ [deleted file]
bashline.c~ [deleted file]
bashtypes.h~ [deleted file]
braces.c~ [deleted file]
builtins/Makefile.in~ [deleted file]
builtins/alias.def~ [deleted file]
builtins/bind.def~ [deleted file]
builtins/common.c~ [deleted file]
builtins/common.h~ [deleted file]
builtins/declare.def~ [deleted file]
builtins/evalfile.c~ [deleted file]
builtins/evalstring.c~ [deleted file]
builtins/exit.def~ [deleted file]
builtins/fc.def.save [deleted file]
builtins/fc.def~ [deleted file]
builtins/help.def~ [deleted file]
builtins/kill.def~ [deleted file]
builtins/mapfile.def~ [deleted file]
builtins/printf.def~ [deleted file]
builtins/shopt.def~ [deleted file]
command.h~ [deleted file]
config-bot.h~ [deleted file]
config-top.h~ [deleted file]
config.h.in~ [deleted file]
configure.in~ [deleted file]
cross-build/cygwin32.cache.old [deleted file]
ddd1~ [deleted file]
doc/FAQ-4.1~ [deleted file]
doc/FAQ.orig [deleted file]
doc/bash.1~ [deleted file]
doc/bashref.texi~ [deleted file]
doc/version.texi~ [deleted file]
error.c~ [deleted file]
examples/loadables/Makefile.in.save [deleted file]
examples/scripts/adventure.sh.save1 [deleted file]
execute_cmd.c~ [deleted file]
expr.c~ [deleted file]
externs.h~ [deleted file]
findcmd.c~ [deleted file]
general.c~ [deleted file]
general.h~ [deleted file]
include/memalloc.h.save [deleted file]
include/posixselect.h~ [deleted file]
jobs.c~ [deleted file]
jobs.h~ [deleted file]
lib/glob/glob.c.orig [deleted file]
lib/glob/glob.c.save1 [deleted file]
lib/glob/glob.c~ [deleted file]
lib/readline/COPYING.old [deleted file]
lib/readline/bind.c~ [deleted file]
lib/readline/complete.c.save1 [deleted file]
lib/readline/complete.c~ [deleted file]
lib/readline/display.c.save [deleted file]
lib/readline/display.c~ [deleted file]
lib/readline/doc/Makefile.old [deleted file]
lib/readline/doc/readline.3~ [deleted file]
lib/readline/doc/rltech.texi~ [deleted file]
lib/readline/doc/rluser.texi~ [deleted file]
lib/readline/doc/version.texi~ [deleted file]
lib/readline/funmap.c~ [deleted file]
lib/readline/input.c~ [deleted file]
lib/readline/keymaps.c~ [deleted file]
lib/readline/mbutil.c~ [deleted file]
lib/readline/parens.c~ [deleted file]
lib/readline/readline.c~ [deleted file]
lib/readline/readline.h~ [deleted file]
lib/readline/rlprivate.h~ [deleted file]
lib/readline/signals.c.save [deleted file]
lib/readline/signals.c~ [deleted file]
lib/readline/text.c~ [deleted file]
lib/readline/undo.c~ [deleted file]
lib/readline/util.c~ [deleted file]
lib/readline/vi_mode.c~ [deleted file]
lib/sh/Makefile.in~ [deleted file]
lib/sh/casemod.c~ [deleted file]
lib/sh/fnxform.c~ [deleted file]
lib/sh/fpurge.c.old [deleted file]
lib/sh/fpurge.c~ [deleted file]
lib/sh/input_avail.c~ [deleted file]
lib/sh/mbscasecmp.c~ [deleted file]
lib/sh/mbschr.c~ [deleted file]
lib/sh/mbscmp.c~ [deleted file]
lib/sh/snprintf.c~ [deleted file]
lib/sh/strcasestr.c~ [deleted file]
lib/sh/strtoimax.c~ [deleted file]
lib/sh/strtoumax.c~ [deleted file]
lib/sh/uconvert.c~ [deleted file]
lib/sh/winsize.c~ [deleted file]
lib/sh/xstrchr.c~ [deleted file]
make_cmd.c~ [deleted file]
make_cmd.h~ [deleted file]
parse.y.diff [deleted file]
parse.y.new [deleted file]
parse.y.save [deleted file]
parse.y.save1 [deleted file]
parse.y~ [deleted file]
parser.h~ [deleted file]
patchlevel.h~ [deleted file]
pathexp.c~ [deleted file]
pcomplete.c~ [deleted file]
po/LINGUAS~ [deleted file]
po/POTFILES.in~ [deleted file]
print_cmd.c~ [deleted file]
redir.c~ [deleted file]
shell.c~ [deleted file]
shell.h~ [deleted file]
sig.c~ [deleted file]
siglist.c~ [deleted file]
subst.c.orig [deleted file]
subst.c.save [deleted file]
subst.c.save1 [deleted file]
subst.c~ [deleted file]
subst.h~ [deleted file]
support/bashbug.sh~ [deleted file]
support/config.sub~ [deleted file]
test.c~ [deleted file]
test.h~ [deleted file]
tests/RUN-ONE-TEST~ [deleted file]
tests/comsub.tests~ [deleted file]
tests/comsub1.sub~ [deleted file]
tests/dollar-at-star~ [deleted file]
tests/dollar.right~ [deleted file]
tests/exp.tests~ [deleted file]
tests/extglob.tests~ [deleted file]
tests/globstar.tests~ [deleted file]
tests/history.tests~ [deleted file]
tests/jobs.tests~ [deleted file]
tests/misc/regress/log.orig [deleted file]
tests/misc/regress/shx.orig [deleted file]
tests/run-glob-test~ [deleted file]
tests/run-globstar~ [deleted file]
tests/run-trap~ [deleted file]
tests/trap.tests~ [deleted file]
tests/trap3.sub~ [deleted file]
tests/vredir2.sub~ [deleted file]
trap.c.save1 [deleted file]
trap.c~ [deleted file]
variables.c~ [deleted file]
variables.h~ [deleted file]
xmalloc.c~ [deleted file]

diff --git a/034-glob-globstar~ b/034-glob-globstar~
deleted file mode 100644 (file)
index e5e6ff2..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-*** ../bash-4.0-patched/lib/glob/glob.c        2009-07-22 23:18:50.000000000 -0400
---- lib/glob/glob.c    2009-09-18 17:53:25.000000000 -0400
-***************
-*** 247,251 ****
-       break;
-      }
-!   pathname[j] = '\0';
-  }
-  
---- 247,252 ----
-       break;
-      }
-!   if (pathname)
-!     pathname[j] = '\0';
-  }
-  
-***************
-*** 280,284 ****
-       break;
-      }
-!   wpathname[j] = L'\0';
-  
-    /* Convert the wide character string into unibyte character set. */
---- 281,286 ----
-       break;
-      }
-!   if (wpathname)
-!     wpathname[j] = L'\0';
-  
-    /* Convert the wide character string into unibyte character set. */
-***************
-*** 308,314 ****
-  #else /* !HAVE_LSTAT */
-  #  if !defined (AFS)
-! #    define GLOB_TESTNAME(name)  (sh_eaccess (nextname, F_OK))
-  #  else /* AFS */
-! #    define GLOB_TESTNAME(name)  (access (nextname, F_OK))
-  #  endif /* AFS */
-  #endif /* !HAVE_LSTAT */
---- 310,316 ----
-  #else /* !HAVE_LSTAT */
-  #  if !defined (AFS)
-! #    define GLOB_TESTNAME(name)  (sh_eaccess (name, F_OK))
-  #  else /* AFS */
-! #    define GLOB_TESTNAME(name)  (access (name, F_OK))
-  #  endif /* AFS */
-  #endif /* !HAVE_LSTAT */
-***************
-*** 321,324 ****
---- 323,327 ----
-    struct stat finfo;
-  
-+ /*itrace("glob_testdir: testing %s", dir);*/
-    if (stat (dir, &finfo) < 0)
-      return (-1);
-***************
-*** 427,431 ****
-    register char *nextname, *npat, *subdir;
-    unsigned int count;
-!   int lose, skip, ndirs, isdir, sdlen, add_current;
-    register char **name_vector;
-    register unsigned int i;
---- 430,434 ----
-    register char *nextname, *npat, *subdir;
-    unsigned int count;
-!   int lose, skip, ndirs, isdir, sdlen, add_current, patlen;
-    register char **name_vector;
-    register unsigned int i;
-***************
-*** 434,437 ****
---- 437,441 ----
-    int nalloca;
-    struct globval *firstmalloc, *tmplink;
-+   char *convfn;
-  
-    lastlink = 0;
-***************
-*** 467,470 ****
---- 471,476 ----
-      }
-  
-+   patlen = strlen (pat);
-+ 
-    /* If the filename pattern (PAT) does not contain any globbing characters,
-       we can dispense with reading the directory, and just see if there is
-***************
-*** 480,485 ****
-  
-        dirlen = strlen (dir);
-!       nextname = (char *)malloc (dirlen + strlen (pat) + 2);
-!       npat = (char *)malloc (strlen (pat) + 1);
-        if (nextname == 0 || npat == 0)
-       lose = 1;
---- 486,491 ----
-  
-        dirlen = strlen (dir);
-!       nextname = (char *)malloc (dirlen + patlen + 2);
-!       npat = (char *)malloc (patlen + 1);
-        if (nextname == 0 || npat == 0)
-       lose = 1;
-***************
-*** 634,639 ****
-             continue;
-           }
-!            
-!        if (strmatch (pat, dp->d_name, mflags) != FNM_NOMATCH)
-           {
-             if (nalloca < ALLOCA_MAX)
---- 640,646 ----
-             continue;
-           }
-! 
-!        convfn = fnx_fromfs (dp->d_name, D_NAMLEN (dp));
-!        if (strmatch (pat, convfn, mflags) != FNM_NOMATCH)
-           {
-             if (nalloca < ALLOCA_MAX)
-***************
-*** 920,928 ****
-         char **temp_results;
-  
-         /* Scan directory even on a NULL filename.  That way, `*h/'
-            returns only directories ending in `h', instead of all
-            files ending in `h' with a `/' appended. */
-         dname = directories[i];
-!        dflags = flags & ~GX_MARKDIRS;
-         if ((flags & GX_GLOBSTAR) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
-           dflags |= GX_ALLDIRS|GX_ADDCURDIR;
---- 927,938 ----
-         char **temp_results;
-  
-+        /* XXX -- we've recursively scanned any directories resulting from
-+           a `**', so turn off the flag.  We turn it on again below if
-+           filename is `**' */
-         /* Scan directory even on a NULL filename.  That way, `*h/'
-            returns only directories ending in `h', instead of all
-            files ending in `h' with a `/' appended. */
-         dname = directories[i];
-!        dflags = flags & ~(GX_MARKDIRS|GX_ALLDIRS|GX_ADDCURDIR);
-         if ((flags & GX_GLOBSTAR) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
-           dflags |= GX_ALLDIRS|GX_ADDCURDIR;
diff --git a/CHANGES-4.1~ b/CHANGES-4.1~
deleted file mode 100644 (file)
index a763831..0000000
+++ /dev/null
@@ -1,6510 +0,0 @@
-This document details the changes between this version, bash-4.1-alpha,
-and the previous version, bash-4.0-release.
-
-1.  Changes to Bash
-
-a.  Fixed bugs in the parser involving new parsing of the commands contained
-    in command substitution when the substitution is read.
-
-b.  Fixed a bug that caused the shell to dump core when performing programmable
-    completion using a shell function.
-
-c.  Fixed a bug in `mapfile' that caused it to invoke callbacks at the wrong
-    time.
-
-d.  Fixed a bug that caused the shell to dump core when listing jobs in the
-    `exit' builtin.
-
-e.  Fixed several bugs encountered when reading subscripts in associative
-    array assignments and expansions.
-
-f.  Fixed a bug that under some circumstances caused an associative array to
-    be converted to an indexed array.
-
-g.  Fixed a bug that caused syntax errors and SIGINT interrupts to not set
-    $? to a value > 128.
-
-h.  Fixed a bug that caused the shell to remove FIFOs associated with process
-    substitution inside shell functions.
-
-i.  Fixed a bug that caused terminal attributes to not be reset when the
-    `read' builtin timed out.
-
-j.  Fixed a bug in brace expansion that caused unwanted zero padding of the
-    expanded terms.
-
-k.  Fixed a bug that prevented the |& construct from working as intended when
-    used with a simple command with additional redirections.
-
-l.  Fixed a bug with the case statment ;& terminator that caused the shell to
-    dereference a NULL pointer.
-
-m.  Fixed a bug that caused assignment statements or redirections preceding
-    a simple command name to inhibit alias expansion.
-
-n.  Fixed the behavior of `set -u' to conform to the latest Posix interpretation:
-    every expansion of an unset variable except $@ and $* will cause the
-    shell to exit.
-
-o.  Fixed a bug that caused double-quoted expansions of $* inside word
-    expansions like ${x#$*} to not expand properly when $IFS is empty.
-
-p.  Fixed a bug that caused traps to set $LINENO to the wrong value when they
-    execute.
-
-q.  Fixed a bug that caused off-by-one errors when computing history lines in
-    the `fc' builtin.
-
-r.  Fixed a bug that caused some terminating signals to not exit the shell
-    quickly enough, forcing the kernel to send the signal (e.g., SIGSEGV)
-    multiple times.
-
-s.  Fixed a bug that caused the shell to attempt to add empty lines to the
-    history list when reading here documents.
-
-t.  Made some internal changes that dramatically speeds up sequential indexed
-    array access.
-
-u.  Fixed a bug that caused the shell to write past the end of a string when
-    completing a double-quoted string ending in a backslash.
-
-v.  Fixed a bug that caused the shell to replace too many characters when a
-    pattern match was null in a ${foo//bar} expansion.
-
-w.  Fixed bugs in the expansion of ** that caused duplicate directory names
-    and the contents of the current directory to be omitted.
-
-x.  Fixed a bug that caused $? to not be set correctly when referencing an
-    unset variable with set -u and set -e enabled.
-
-y.  Fixed a bug caused by executing an external program from the DEBUG trap
-    while a pipeline was running.  The effect was to disturb the pipeline
-    state, occasionally causing it to hang.
-
-z.  Fixed a bug that caused the ** glob expansion to dump core if it
-    encountered an unsearchable directory.
-
-aa. Fixed a bug that caused `command -v' and `command -V' to not honor the
-    path set by the -p option.
-
-bb. Fixed a bug that caused brace expansion to take place too soon in some
-    compound array assignments.
-
-cc. Fixed a bug that caused programmable completion functions' changes to
-    READLINE_POINT to not be reflected back to readline.
-
-dd. Fixed a bug that caused the shell to dump core if a trap was executed
-    during a shell assignment statement.
-
-ee. Fixed an off-by-one error when computing the number of positional
-    parameters for the ${@:0:n} expansion.
-
-ff. Fixed a problem with setting COMP_CWORD for programmable completion
-    functions that could leave it set to -1.
-
-gg. Fixed a bug that caused the ERR trap to be triggered in some cases where
-    `set -e' would not have caused the shell to exit.
-
-hh. Fixed a bug that caused changes made by `compopt' to not persist past the
-    completion function in which compopt was executed.
-
-ii. Fixed a bug that caused the list of hostname completions to not be cleared
-    when HOSTNAME was unset.
-
-jj. Fixed a bug that caused variable expansion in here documents to look in
-    any temporary environment.
-
-kk. Bash and readline can now convert file names between precomposed and
-    decomposed Unicode on Mac OS X ("keyboard" and file system forms,
-    respectively).  This affects filename completion (using new
-    rl_filename_rewrite_hook), globbing, and readline redisplay.
-
-ll. The ERR and EXIT traps now see a non-zero value for $? when a parser
-    error after set -e has been enabled causes the shell to exit.
-
-mm. Fixed a bug that in brace expansion that caused zero-prefixed terms to
-    not contain the correct number of digits.
-
-nn. Fixed a bug that caused the shell to free non-allocated memory when
-    unsetting an associative array which had had a value implicitly assigned
-    to index "0".
-
-oo. Fixed a memory leak in the ${!prefix@} expansion.
-
-pp. Fixed a bug that caused printf to not correctly report all write errors.
-
-qq. Fixed a bug that caused single and double quotes to act as delimiters
-    when splitting a command line into words for programmable completion.
-
-rr. Fixed a bug that caused ** globbing that caused **/path/* to match every
-    directory, not just those matching `path'.
-
-ss. Fixed a bug that caused the shell to dump core when running `help' without
-    arguments if the terminal width was fewer than 7 characters.
-
-2.  Changes to Readline
-
-a.  The SIGWINCH signal handler now avoids calling the redisplay code if
-    one arrives while in the middle of redisplay.
-
-b.  Changes to the timeout code to make sure that timeout values greater
-    than one second are handled better.
-
-c.  Fixed a bug in the redisplay code that was triggered by a prompt
-    containing invisible characters exactly the width of the screen.
-
-d.  Fixed a bug in the redisplay code encountered when running in horizontal
-    scroll mode.
-
-e.  Fixed a bug that prevented menu completion from properly completing
-    filenames.
-
-f.  Fixed a redisplay bug caused by a multibyte character causing a line to
-    wrap.
-
-g.  Fixed a bug that caused key sequences of two characters to not be
-    recognized when a longer sequence identical in the first two characters
-    was bound.
-
-h.  Fixed a bug that caused history expansion to be attempted on $'...'
-    single-quoted strings.
-
-i.  Fixed a bug that caused incorrect redisplay when the prompt contained
-    multibyte characters in an `invisible' sequence bracketed by \[ and
-    \].
-
-j.  Fixed a bug that caused history expansion to short-circuit after
-    encountering a multibyte character.
-
-3.  New Features in Bash
-
-a.  Here-documents within $(...) command substitutions may once more be
-    delimited by the closing right paren, instead of requiring a newline.
-
-b.  Bash's file status checks (executable, readable, etc.) now take file
-    system ACLs into account on file systems that support them.
-
-c.  Bash now passes environment variables with names that are not valid
-    shell variable names through into the environment passed to child
-    processes.
-
-d.  The `execute-unix-command' readline function now attempts to clear and
-    reuse the current line rather than move to a new one after the command
-    executes.
-
-e.  `printf -v' can now assign values to array indices.
-
-f.  New `complete -E' and `compopt -E' options that work on the "empty"
-    completion: completion attempted on an empty command line.
-
-g.  New complete/compgen/compopt -D option to define a `default' completion:
-    a completion to be invoked on command for which no completion has been
-    defined.  If this function returns 124, programmable completion is
-    attempted again, allowing a user to dynamically build a set of completions
-    as completion is attempted by having the default completion function
-    install individual completion functions each time it is invoked.
-
-h.  When displaying associative arrays, subscripts are now quoted.
-
-i.  Changes to dabbrev-expand to make it more `emacs-like': no space appended
-    after matches, completions are not sorted, and most recent history entries
-    are presented first.
-
-j.  The [[ and (( commands are now subject to the setting of `set -e' and the
-    ERR trap.
-
-k.  The source/. builtin now removes NUL bytes from the file before attempting
-    to parse commands.
-
-l.  There is a new configuration option (in config-top.h) that forces bash to
-    forward all history entries to syslog.
-
-m.  A new variable $BASHOPTS to export shell options settable using `shopt' to
-    child processes.
-
-n.  There is a new confgure option that forces the extglob option to be
-    enabled by default.
-
-o.  New variable $BASH_XTRACEFD; when set to an integer bash will write xtrace
-    output to that file descriptor.
-
-p.  If the optional left-hand-side of a redirection is of the form {var}, the
-    shell assigns the file descriptor used to $var or uses $var as the file
-    descriptor to move or close, depending on the redirection operator.
-
-q.  The < and > operators to the [[ conditional command now do string
-    comparison according to the current locale.
-
-r.  Programmable completion now uses the completion for `b' instead of `a'
-    when completion is attempted on a line like: a $(b c.
-
-s.  Force extglob on temporarily when parsing the pattern argument to
-    the == and != operators to the [[ command, for compatibility.
-
-t.  Changed the behavior of interrupting the wait builtin when a SIGCHLD is
-    received and a trap on SIGCHLD is set to be Posix-mode only.
-
-u.  The read builtin has a new `-N nchars' option, which reads exactly NCHARS
-    characters, ignoring delimiters like newline.
-
-4.  New Features in Readline
-
-a.  New bindable function: menu-complete-backward.
-
-b.  In the vi insertion keymap, C-n is now bound to menu-complete by default,
-    and C-p to menu-complete-backward.
-
-c.  When in vi command mode, repeatedly hitting ESC now does nothing, even
-    when ESC introduces a bound key sequence.  This is closer to how
-    historical vi behaves.
-
-d.  New bindable function: skip-csi-sequence.  Can be used as a default to
-    consume key sequences generated by keys like Home and End without having
-    to bind all keys.
-
-e.  New application-settable function: rl_filename_rewrite_hook.  Can be used
-    to rewite or modify filenames read from the file system before they are
-    compared to the word to be completed.
-
-f.  New bindable variable: skip-completed-text, active when completing in the
-    middle of a word.  If enabled, it means that characters in the completion
-    that match characters in the remainder of the word are "skipped" rather
-    than inserted into the line.
-
-g.  The pre-readline-6.0 version of menu completion is available as
-    "old-menu-complete" for users who do not like the readline-6.0 version.
-
-h.  New bindable variable: echo-control-characters.  If enabled, and the
-    tty ECHOCTL bit is set, controls the echoing of characters corresponding
-    to keyboard-generated signals.
-
-i.  New bindable variable: enable-meta-key.  Controls whether or not readline
-    sends the smm/rmm sequences if the terminal indicates it has a meta key
-    that enables eight-bit characters.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-4.0-release,
-and the previous version, bash-4.0-rc1.
-
-1.  Changes to Bash
-
-a.  Changed the message printed when setlocale(3) fails to only include the
-    strerror error text if the call changes errno.
-
-b.  Changed trap command execution to reset the line number before running a
-    trap (except DEBUG and RETURN traps).
-
-c.  Fixed behavior of case-modifiying word expansions to not work on
-    individual words within a variable's value.
-
-d.  Fixed a bug that caused mapfile to not be interruptible when run in an
-    interactive shell.
-
-e.  Fixed a bug that caused mapfile to not run callbacks for the first line
-    read.
-
-f.  Fixed a bug that caused mapfile to not honor EOF typed in an interactive
-    shell.
-
-g.  Fixed the coprocess reaping code to not run straight from a signal handler.
-
-h.  Fixed a bug that caused printf -b to ignore the first % conversion specifier
-    in the format string on 64-bit systems.
-
-i.  Fixed a bug that caused incorrect word splitting when `:', `=', or `~'
-    appeared in $IFS.
-
-j.  Fixed a bug that caused data corruption in the programmable completion code
-    when a shell function called from a completion aborted execution.
-
-k.  Fixed a bug that caused the CPU usage reported by the `time' builtin to be
-    capped at 100%.
-
-l.  Changed behavior of shell when -e option is in effect to reflect consensus
-    of Posix shell standardization working group.
-
-m.  Fixed a bug introduced in bash-4.0-alpha that caused redirections to not
-    be displayed by `type' or `declare' when appearing in functions under
-    certain circumstances.
-
-2.  Changes to Readline
-
-a.  Fixed a bug that caused !(...) extended glob patterns to inhibit later
-    history expansion.
-
-b.  Reworked the signal handling to avoid calling disallowed functions from a
-    signal handler.
-
-3.  New Features in Bash
-
-a.  `readarray' is now a synonym for `mapfile'.
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-4.0-rc1,
-and the previous version, bash-4.0-beta2.
-
-1.  Changes to Bash
-
-a.  Fixed a bug that caused parsing errors when a $()-style command
-    substitution was follwed immediately by a quoted newline.
-
-b.  Fixed a bug that caused extended shell globbing patterns beginning with
-    `*(' to not work when used with pattern substitution word expansions.
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-4.0-beta2,
-and the previous version, bash-4.0-beta.
-
-1.  Changes to Bash
-
-a.  Fixed a bug that caused failed word expansions to set $? but not
-    PIPESTATUS.
-
-b.  Changed filename completion to quote the tilde in a filename with a
-    leading tilde that exists in the current directory.
-
-c.  Fixed a bug that caused a file descriptor leak when performing
-    redirections attached to a compound command.
-
-d.  Fixed a bug that caused expansions of $@ and $* to not exit the shell if
-    the -u option was enabled and there were no posititional parameters.
-
-e.  Fixed a bug that resulted in bash not terminating immediately if a
-    terminating signal was received while performing output.
-
-f.  Fixed a bug that caused the shell to crash after creating 256 process
-    substitutions during word completion.
-
-2.  Changes to Readline
-
-a.  Fixed a bug that caused redisplay errors when using prompts with invisible
-    characters and numeric arguments to a command in a multibyte locale.
-
-b.  Fixed a bug that caused redisplay errors when using prompts with invisible
-    characters spanning more than two physical screen lines.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-4.0-beta,
-and the previous version, bash-4.0-alpha.
-
-1.  Changes to Bash
-
-a.  Fixed a typo that caused a variable to be used before initialization
-    while parsing Posix-style command substitutions.
-
-b.  Fixed a bug that caused stray ^? when the expansion of a parameter used
-    as part of a pattern removal expansion is empty, but part of a non-
-    empty string.
-
-c.  Fixed a bug that could cause strings not converted to numbers by strtol
-    to be treated as if the conversion had been successful.
-
-d.  The `return' builtin now accepts no options and requires a `--' before
-    a negative return value, as Posix requires.
-
-e.  Fixed a bug that caused local variables to be created with the empty
-    string for a value rather than no value.
-
-f.  Changed behavior so the shell now acts as if it received an interrupt
-    when a pipeline is killed by SIGINT while executing a list.
-
-g.  Fixed a bug that caused `declare var' and `typeset var' to initialize
-    `var' to the empty string.
-
-h.  Changed `bind' builtin to print a warning but proceed if invoked when
-    line editing is not active.
-
-i.  Fixed a bug that caused the shell to exit when the `errexit' option is
-    set and a command in a pipeline returns a non-zero exit status.
-
-j.  Fixed a bug that caused the shell to not run the exit trap in a command
-    run with `bash -c' under some circumstances.
-
-k.  Fixed a bug that caused parser errors to occasionally not set $? when
-    running commands with `eval'.
-
-l.  Fixed a bug that caused stray control characters when evaluating compound
-    array assignments containing $'\x7f' escapes.
-
-m.  Fixed a bug that caused redirections involving file descriptor 10 as the
-    target to behave incorrectly.
-
-n.  Fixed a bug that could cause memory to be freed multiple times when
-    assigning to COMP_WORDBREAKS.
-
-o.  Fixed a bug that could cause NULL pointer dereferences when COMP_WORDBREAKS
-    was unset.
-
-2.  Changes to Readline
-
-3.  New Features in Bash
-
-a.  A value of 0 for the -t option to `read' now returns success if there is
-    input available to be read from the specified file descriptor.
-
-b.  CDPATH and GLOBIGNORE are ignored when the shell is running in privileged
-    mode.
-
-c.  New bindable readline functions shell-forward-word and shell-backward-word,
-    which move forward and backward words delimited by shell metacharacters
-    and honor shell quoting.
-
-d.  New bindable readline functions shell-backward-kill-word and shell-kill-word
-    which kill words backward and forward, but use the same word boundaries
-    as shell-forward-word and shell-backward-word.
-
-4.  New Features in Readline
-
-a.  If the kernel supports it, readline displays special characters
-    corresponding to a keyboard-generated signal when the signal is received.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-4.0-alpha,
-and the previous version, bash-3.2-release.
-
-1.  Changes to Bash
-
-a.  Fixed several bugs in old-style `` command substitution parsing, including
-    comment parsing and quoted string handling.
-
-b.  Fixed problems parsing arguments to the [[ command's =~ regular expression
-    matching operator:  metacharacter and whitespace parsing.
-
-c.  Fixed a bug that caused the shell to inappropriately reuse high-numbered
-    file descriptors it used internally.
-
-d.  Fixed a bug in pattern replacement word expansions that caused a `/' as
-    the first character of an expanded pattern to be mistaken for a global
-    replacement specifier.
-
-e.  Fixed several problems with the asprintf and snprintf replacement functions
-    that caused hangs and crashes.
-
-f.  Fixed a bug in the calculation of the current and previous job that caused
-    it to refer to incorrect jobs.
-
-g.  Fixed a bug in the check for the validity of a hashed command pathname that
-    caused unnecessary hash table deletions and additions.
-
-h.  Fixed a bug that caused child processes to inherit the wrong value for $!.
-
-i.  Fixed a bug that caused `.' to fail to read and execute commands from non-
-    regular files such as devices or named pipes.
-
-j.  Fixed a bug in printf formatting for the %x and %X expansions that occurred
-    on some systems.
-
-k.  Fixed a bug that caused the shell to crash when creating temporary files if
-    $TMPDIR named a non-writable directory.
-
-l.  Fixed a bug that caused the shell to ignore $TMPDIR when creating temporary
-    files under some circumstances.
-
-m.  Fixed a bug that caused named pipes created by process substitution to not
-    be cleaned up.
-
-n.  Fixed a bug that caused HISTTIMEFORMAT to not be honored when it appeared
-    in the initial shell environment.
-
-o.  Fixed several bugs in the expansion of $* and $@ (quoted and unquoted)
-    when IFS is null or contains non-whitespace characters; the same changes
-    apply to arrays subscripted with * or @.
-
-p.  Fixed several problems with pattern substitution expansions on the
-    positional parameters and arrays subscripted with * or @ that occurred
-    when $IFS was set to the empty string.
-
-q.  Made a change to the default locale initialization code that should
-    result in better behavior from the locale-aware library functions.
-
-r.  Fixed a bug that caused compacting the jobs list to drop jobs.
-
-s.  Fixed a bug that caused jumps back to the top-level processing loop from
-    a builtin command to leave the shell in an inconsistent state.
-
-t.  Fixed a bug that caused characters that would be escaped internally to be
-    doubled when escaped with a backslash.
-
-u.  Fixed the initialization of mailboxes to not cause maildirs to be read
-    (and stat(2) called for every message file) at shell startup.
-
-v.  Fixed a bug that caused the shell to not display $PS2 when the read builtin
-    reads a line continued with a backslash.
-
-w.  Fixed a bug that caused errors in word splitting when $IFS contained
-    characters used for internal quoting.
-
-x.  Fixed bugs that caused problems with output from shell builtins not being
-    completely displayed on some systems.
-
-y.  Fixed a bug that caused output to be lost when a redirection is acting on
-    the shell's output file descriptor.
-
-z.  Fixed bugs caused by shell builtins not checking for all write errors.
-
-aa. Fixed a problem that caused the shell to dump core if expansions on the
-    pattern passed to the pattern removal word expansions resulted in expansion
-    errors.
-
-bb. Fixed a bug that caused bash to loop infinitely after creating and
-    waiting for 4096 jobs.
-
-cc. Fixed a bug that caused bash to lose the status of a background job under
-    certain circumstances.
-
-dd. Fixed a bug that caused bash to not look in the temporary environment
-    when performing variable lookup under certain circumstances.
-
-ee. Fixed a bug that caused bash to close file descriptors greater than 10
-    when they were used in redirections.
-
-ff. Fixed a problem that caused the shell to attempt to read from the standard
-    input when called as `bash -i script'.
-
-gg. Fixed a memory leak and variable initialization problems when the -v option
-    was supplied to `printf' that could cause incorrect results.
-
-hh. Fixed a bug that caused the `read' builtin to count bytes when the -n option
-    was supplied, rather than (possibly multibyte) characters.
-
-ii. Fixed a bug when displaying a function due to not converting the function
-    to an external form.
-
-jj. Changed job control initialization to ensure that the shell has a tty
-    as its controlling terminal before enabling job control.
-
-kk. Fixed a bug with the `test' builtin that caused it to misinterpret
-    arguments beginning with `-' but containing more than one character.
-
-ll. Fixed bug that could cause the shell to dump core in certain cases where
-    a command sets the SIGINT disposition to the default.
-
-mm. Fixed a bug in the pattern replacement (affecting both word expansion
-    and the `fc' builtin) that occurred when the pattern and replacement
-    strings were empty.
-
-nn. Fixed a bug that caused an arithmetic evaluation error to disable all
-    further evaluation.
-
-oo. Fixed a bug in pathname expansion that caused it to interpret backslashes
-    in the pathname as quoting characters.
-
-pp. Fixed a bug in the replacement getcwd() implementation that could cause
-    memory to be overwritten.
-
-qq. When in Posix mode, the `ulimit' builtin now uses a block size of 512 for
-    the `-c' and `-f' options.
-
-rr. Brace expansion now allows process substitutions to pass through unchanged.
-
-ss. Fixed a problem in the command name completion code to avoid quoting
-    escaped special characters twice when the command name begins with a tilde.
-
-tt. Fixed a problem in the printf builtin that resulted in single-byte
-    output for the "'" escape, even when using multibyte characters.
-
-uu. Fixed a bug that caused the failure exit status to be lost when redirections
-    attached to a compound command failed.
-
-vv. Fixed a bug that caused the internal random number generator to not be
-    re-seeded correctly when creating a subshell.
-
-ww. Fixed a bug that could cause the bash replacement getcwd to overwrite
-    memory.
-
-xx. Fixed a bug that caused the shell to not receive SIGINT if it was sent
-    while the shell was waiting for a command substitution to terminate, and
-    make sure the exit status is correct when it does.
-
-yy. Fixed a bug that resulted in the second and subsequent children spawned
-    by a shell begun to run a command substitution being placed into the
-    wrong process group.
-
-zz. Fixed a bug that caused the results of successful tilde expansion to be
-    subject to pathname expansion and word splitting.
-
-aaa. Fixed a bug that could cause the shell to hang if it encountered an
-     error that caused it to jump back to the top processing loop during a
-     command substitution or `eval' command.
-
-bbb. Fixed a bug that caused the `read' builtin to use the tty's attributes
-     instead of those of the file descriptor passed with the -u option when
-     processing the -n and -d options.
-
-ccc. Fixed a bug that caused incorrect expansion of ${array[@]:foo} if the
-     first character of $IFS was not whitespace.
-
-ddd. Fixed a bug that occurred when scanning for the ending delimiter of a
-     ${parameter/pat/sub} expansion.
-
-eee. Fixed a bug that caused the shell to inappropriately expand command
-     substitutions in words when expanding directory names for completion.
-
-fff. Fixed a bug that caused the `fc' builtin to look too far back in the
-     history list under certain circumstances.
-
-ggg. Fixed a bug that caused a shell running in Posix mode to search $PWD for
-     a file specified as an argument to source/. when the file was not found
-     in $PATH.
-
-hhh. Fixed a bug that caused the shell to modify the case of a command word
-     found via command completion when the shell was performing case-
-     insensitive completion.
-
-iii. Fixed a bug that caused the shell to search $PATH for an argument to
-     source/. even when it contained a `/'.
-
-jjj. Fixed a bug that caused brace expansion to misorder expansions when the
-     locale did not have a collating order like aAbBcC...zZ.
-
-kkk. Fixed a bug that did not allow `set +o history' to have any effect when
-     run in a startup file or from a sourced file.
-
-lll. Fixed a bug with the precedence of the ?: conditional arithmetic operator.
-
-mmm. Fixed a bug that caused side effects of temporary variable assignments
-     to persist in the shell environment.
-
-nnn. Fixed a bug that caused the terminal to be left in non-canonical mode
-     when using editing commands that invoke the an editor on the current
-     command line.
-
-ooo. Fixed a bug that caused globbing characters and characters in $IFS to not
-     be quoted appropriately when displaying assignment statements.
-
-ppp. Fixed a bug that caused the `-e' option to be inherited when sourcing a
-     file or evaluating a command with `eval' even if the return value of the
-     command was supposed to be ignored.
-
-qqq. Fixed a bug that caused the shell to attempt to created variables with
-     invalid names if such names appeared in the initial environment.
-
-rrr. Fixed a bug with quote removal in strings where the final character is a
-     backslash.
-
-sss. Fixed a bug that caused the effects of special variables to persist even
-     when the variables were unset as part of the shell reinitializing itself
-     to execute a shell script.
-
-ttt. Fixed a bug that caused the history to not be saved after `history -c' or
-     `history -d' was executed until a sufficient number of commands had been
-     saved to the history.
-
-uuu. Bash now parses command substitutions according to Posix rules: parsing
-     the command contained in $() to find the closing delimiter.
-
-vvv. Fixed a bug that caused traps on SIGCHLD set in a SIGCHLD handler to
-     not persist.
-
-www. Fixed a bug that didn't allow SIGCHLD to interrupt the `wait' builtin
-     as Posix specifies.
-
-xxx. Invalid numeric arguments to shell builtins no longer cause the shell to
-     short-circuit any executing compound command.
-
-yyy. Fixed a bug that caused the exit status to be lost when `break' was
-     used to short-circuit a loop's execution.
-
-zzz. Fixed a bug that caused stray ^? characters to be left in expansions of
-     "${array[*]}".
-
-aaaa. Bash now prints better error messages for here documents terminated by
-      EOF and for identifying the incorrect token in an invalid arithmetic
-      expression.
-
-bbbb. Fixed a bug in the variable length word expansion that caused it to
-      incorrectly calculate the number of multibyte characters.
-
-cccc. Fixed a race condition that could result in the top-level shell setting
-      the terminal's process group to an incorrect value if the process
-      group was changed by a child of a child of the shell.
-
-dddd. Fixed a bug that caused here documents belonging to commands within a
-      compound command to be displayed in a syntactially-incorrect form, which
-      prevented them from being re-read as input.
-
-eeee. The shell displays more warnings about failures to set the locale.
-
-ffff. Fixed a bug that caused the body of a here-document to not be saved to
-      the history list.
-
-gggg. Fixed a bug that caused configure to incorrectly conclude that FreeBSD
-      had /dev/fd available, resulting in problems with process substitution.
-
-2.  Changes to Readline
-
-a.  Fixed a number of redisplay errors in environments supporting multibyte 
-    characters.
-
-b.  Fixed bugs in vi command mode that caused motion commands to inappropriately
-    set the mark.
-
-c.  When using the arrow keys in vi insertion mode, readline allows movement
-    beyond the current end of the line (unlike command mode).
-
-d.  Fixed bugs that caused readline to loop when the terminal has been taken
-    away and reads return -1/EIO.
-
-e.  Fixed bugs in redisplay occurring when displaying prompts containing
-    invisible characters.
-
-f.  Fixed a bug that caused the completion append character to not be reset to
-    the default after an application-specified completion function changed it.
-
-g.  Fixed a problem that caused incorrect positioning of the cursor while in
-    emacs editing mode when moving forward at the end of a line while using
-    a locale supporting multibyte characters.
-
-h.  Fixed an off-by-one error that caused readline to drop every 511th
-    character of buffered input.
-
-i.  Fixed a bug that resulted in SIGTERM not being caught or cleaned up.
-
-j.  Fixed redisplay bugs caused by multiline prompts with invisible characters
-    or no characters following the final newline.
-
-k.  Fixed redisplay bug caused by prompts consisting solely of invisible
-    characters.
-
-l.  Fixed a bug in the code that buffers characters received very quickly in
-    succession which caused characters to be dropped.
-
-m.  Fixed a bug that caused readline to reference uninitialized data structures
-    if it received a SIGWINCH before completing initialzation.
-
-n.  Fixed a bug that caused the vi-mode `last command' to be set incorrectly
-    and therefore unrepeatable.
-
-o.  Fixed a bug that caused readline to disable echoing when it was being used
-    with an output file descriptor that was not a terminal.
-
-p.  Readline now blocks SIGINT while manipulating internal data structures
-    during redisplay.
-
-q.  Fixed a bug in redisplay that caused readline to segfault when pasting a
-    very long line (over 130,000 characters).
-
-r.  Fixed bugs in redisplay when using prompts with no visible printing
-    characters.
-
-3.  New Features in Bash
-
-a.  When using substring expansion on the positional parameters, a starting
-    index of 0 now causes $0 to be prefixed to the list.
-
-b.  The `help' builtin now prints its columns with entries sorted vertically
-    rather than horizontally.
-
-c.  There is a new variable, $BASHPID, which always returns the process id of
-    the current shell.
-
-d.  There is a new `autocd' option that, when enabled, causes bash to attempt
-    to `cd' to a directory name that is supplied as the first word of a
-    simple command.
-
-e.  There is a new `checkjobs' option that causes the shell to check for and
-    report any running or stopped jobs at exit.
-
-f.  The programmable completion code exports a new COMP_TYPE variable, set to
-    a character describing the type of completion being attempted.
-
-g.  The programmable completion code exports a new COMP_KEY variable, set to
-    the character that caused the completion to be invoked (e.g., TAB).
-
-h.  If creation of a child process fails due to insufficient resources, bash
-    will try again several times before reporting failure.
-
-i.  The programmable completion code now uses the same set of characters as
-    readline when breaking the command line into a list of words.
-
-j.  The block multiplier for the ulimit -c and -f options is now 512 when in
-    Posix mode, as Posix specifies.
-
-k.  Changed the behavior of the read builtin to save any partial input received
-    in the specified variable when the read builtin times out.  This also
-    results in variables specified as arguments to read to be set to the empty
-    string when there is no input available.  When the read builtin times out,
-    it returns an exit status greater than 128.
-
-l.  The shell now has the notion of a `compatibility level', controlled by
-    new variables settable by `shopt'.  Setting this variable currently
-    restores the bash-3.1 behavior when processing quoted strings on the rhs
-    of the `=~' operator to the `[[' command.
-
-m.  The `ulimit' builtin now has new -b (socket buffer size) and -T (number
-    of threads) options.
-
-n.  The -p option to `declare' now displays all variable values and attributes
-    (or function values and attributes if used with -f).
-
-o.  There is a new `compopt' builtin that allows completion functions to modify
-    completion options for existing completions or the completion currently
-    being executed.
-
-p.  The `read' builtin has a new -i option which inserts text into the reply
-    buffer when using readline.
-
-q.  A new `-E' option to the complete builtin allows control of the default
-    behavior for completion on an empty line.
-
-r.  There is now limited support for completing command name words containing
-    globbing characters.
-
-s.  Changed format of internal help documentation for all builtins to roughly
-    follow man page format.
-
-t.  The `help' builtin now has a new -d option, to display a short description,
-    and a -m option, to print help information in a man page-like format.
-
-u.  There is a new `mapfile' builtin to populate an array with lines from a
-    given file.
-
-v.  If a command is not found, the shell attempts to execute a shell function
-    named `command_not_found_handle', supplying the command words as the
-    function arguments.
-
-w.  There is a new shell option: `globstar'.  When enabled, the globbing code
-    treats `**' specially -- it matches all directories (and files within
-    them, when appropriate) recursively.
-
-x.  There is a new shell option: `dirspell'.  When enabled, the filename
-    completion code performs spelling correction on directory names during
-    completion.
-
-y.  The `-t' option to the `read' builtin now supports fractional timeout
-    values.
-
-z.  Brace expansion now allows zero-padding of expanded numeric values and
-    will add the proper number of zeroes to make sure all values contain the
-    same number of digits.
-
-aa. There is a new bash-specific bindable readline function: `dabbrev-expand'.
-    It uses menu completion on a set of words taken from the history list.
-
-bb. The command assigned to a key sequence with `bind -x' now sets two new
-    variables in the environment of the executed command:  READLINE_LINE_BUFFER
-    and READLINE_POINT.  The command can change the current readline line
-    and cursor position by modifying READLINE_LINE_BUFFER and READLINE_POINT,
-    respectively.
-
-cc. There is a new &>> redirection operator, which appends the standard output
-    and standard error to the named file.
-
-dd. The parser now understands `|&' as a synonym for `2>&1 |', which redirects
-    the standard error for a command through a pipe.
-
-ee. The new `;&' case statement action list terminator causes execution to
-    continue with the action associated with the next pattern in the
-    statement rather than terminating the command.
-
-ff. The new `;;&' case statement action list terminator causes the shell to
-    test the next set of patterns after completing execution of the current
-    action, rather than terminating the command.
-
-gg. The shell understands a new variable: PROMPT_DIRTRIM.  When set to an
-    integer value greater than zero, prompt expansion of \w and \W  will
-    retain only that number of trailing pathname components and replace
-    the intervening characters with `...'.
-
-hh. There are new case-modifying word expansions: uppercase (^[^]) and
-    lowercase (,[,]).  They can work on either the first character or
-    array element, or globally.  They accept an optional shell pattern
-    that determines which characters to modify.  There is an optionally-
-    configured feature to include capitalization operators.
-
-ii. The shell provides associative array variables, with the appropriate
-    support to create, delete, assign values to, and expand them.
-
-jj. The `declare' builtin now has new -l (convert value to lowercase upon
-    assignment) and -u (convert value to uppercase upon assignment) options.
-    There is an optionally-configurable -c option to capitalize a value at
-    assignment.
-
-kk. There is a new `coproc' reserved word that specifies a coprocess: an
-    asynchronous command run with two pipes connected to the creating shell.
-    Coprocs can be named.  The input and output file descriptors and the
-    PID of the coprocess are available to the calling shell in variables
-    with coproc-specific names.
-
-4.  New Features in Readline
-
-a.  A new variable, rl_sort_completion_matches; allows applications to inhibit
-    match list sorting (but beware: some things don't work right if
-    applications do this).
-
-b.  A new variable, rl_completion_invoking_key; allows applications to discover
-    the key that invoked rl_complete or rl_menu_complete.
-
-c.  The functions rl_block_sigint and rl_release_sigint are now public and
-    available to calling applications who want to protect critical sections
-    (like redisplay).
-
-d.  The functions rl_save_state and rl_restore_state are now public and
-    available to calling applications; documented rest of readline's state
-    flag values.
-
-e.  A new user-settable variable, `history-size', allows setting the maximum
-    number of entries in the history list.
-
-f.  There is a new implementation of menu completion, with several improvements
-    over the old; the most notable improvement is a better `completions
-    browsing' mode.
-
-g.  The menu completion code now uses the rl_menu_completion_entry_function
-    variable, allowing applications to provide their own menu completion
-    generators.
-
-h.  There is support for replacing a prefix  of a pathname with a `...' when
-    displaying possible completions.  This is controllable by setting the
-    `completion-prefix-display-length' variable.  Matches with a common prefix
-    longer than this value have the common prefix replaced with `...'.
-
-i.  There is a new `revert-all-at-newline' variable.  If enabled, readline will
-    undo all outstanding changes to all history lines when `accept-line' is
-    executed.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-3.2-release,
-and the previous version, bash-3.2-beta.
-
-1.  Changes to Bash
-
-a.  Fixed a bug that caused the temporary environment passed to a command to
-    affect the shell's environment under certain circumstances.
-
-b.  Fixed a bug in the printf builtin that caused the %q format specifier to
-    ignore empty string arguments.
-
-c.  Improved multibyte character environment detection at configuration time.
-
-d.  Fixed a bug in the read builtin that left spurious escape characters in the
-    input after processing backslashes when assigning to an array variable.
-
-2.  Changes to Readline
-
-a.  Fixed a redisplay bug that occurred in multibyte-capable locales when the
-    prompt was one character longer than the screen width.
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-3.2-beta,
-and the previous version, bash-3.2-alpha.
-
-1.  Changes to Bash
-
-a.  Changed the lexical analyzer to treat locale-specific blank characters as
-    white space.
-
-b.  Fixed a bug in command printing to avoid confusion between redirections and
-    process substitution.
-
-c.  Fixed problems with cross-compiling originating from inherited environment
-    variables.
-
-d.  Added write error reporting to printf builtin.
-
-e.  Fixed a bug in the variable expansion code that could cause a core dump in
-    a multi-byte locale.
-
-f.  Fixed a bug that caused substring expansion of a null string to return
-    incorrect results.
-
-g.  BASH_COMMAND now retains its previous value while executing commands as the
-    result of a trap, as the documentation states.
-
-2.  Changes to Readline
-
-a.  Fixed a bug with prompt redisplay in a multi-byte locale to avoid redrawing
-    the prompt and input line multiple times.
-
-b.  Fixed history expansion to not be confused by here-string redirection.
-
-c.  Readline no longer treats read errors by converting them to newlines, as
-    it does with EOF.  This caused partial lines to be returned from readline().
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-3.2-alpha,
-and the previous version, bash-3.1-release.
-
-1.  Changes to Bash
-
-a.  Fixed a source bug that caused the minimal configuration to not compile.
-
-b.  Fixed memory leaks in error handling for the `read' builtin.
-
-c.  Changed the [[ and (( compound commands to set PIPESTATUS with their exit
-    status.
-
-d.  Fixed some parsing problems with compound array assignments.
-
-e.  Added additional configuration changes for: NetBSD (incomplete multibyte
-    character support)
-
-f.  Fixed two bugs with local array variable creation when shadowing a variable
-    of the same name from a previous context.
-
-g.  Fixed the `read' builtin to restore the correct set of completion functions
-    if a timeout occurs.
-
-h.  Added code to defer the initialization of HISTSIZE (and its stifling of the
-    history list) until the history file is loaded, allowing a startup file to
-    override the default value.
-
-i.  Tightened up the arithmetic expression parsing to produce better error
-    messages when presented with invalid operators.
-
-j.  Fixed the cross-compilation support to build the signal list at shell
-    invocation rather than compile time if cross-compiling.
-
-k.  Fixed multibyte support for non-gcc compilers (or compilers that do not
-    allow automatic array variable sizing based on a non-constant value).
-
-l.  Several fixes to the code that manages the list of terminated jobs and
-    their exit statuses, and the list of active and recently-terminated jobs
-    to avoid pid aliasing/wraparound and allocation errors.
-
-m.  Fixed a problem that allowed scripts to die due to SIGINT while waiting
-    for children, even when started in the background or otherwise ignoring
-    SIGINT.
-
-n.  Fixed a bug that caused shells invoked as -/bin/bash from not being
-    recognized as login shells.
-
-o.  Fixed a problem that caused shells in the background to give the terminal
-    to a process group other than the foreground shell process group.
-
-p.  Fixed a problem with extracting the `varname' in ${#varname}.
-
-q.  Fixed the code that handles SIGQUIT to not exit immediately -- thereby
-    calling functions that may not be called in a signal handler context --
-    but set a flag and exit afterward (like SIGINT).
-
-r.  Changed the brace expansion code to skip over braces that don't begin a
-    valid matched brace expansion construct.
-
-s.  Fixed `typeset' and `declare' to not require that their shell function
-    operands to be valid shell identifiers.
-
-t.  Changed `test' to use access(2) with a temporary uid/euid swap when testing
-    file attributes and running setuid, and access(2) in most other cases.
-
-u.  Changed completion code to not attempt command name completion on a line
-    consisting solely of whitespace when no_empty_command_completion is set.
-
-v.  The `hash' builtin now prints nothing in posix mode when the hash table is
-    empty, and prints a message to that effect to stdout instead of stderr
-    when not in posix mode.
-
-w.  Fixed a bug in the extended pattern matching code that caused it to fail to
-    match periods with certain patterns.
-
-x.  Fixed a bug that caused the shell to dump core when performing filename
-    generation in directories with thousands of files.
-
-y.  Returned to the original Bourne shell rules for parsing ``:  no recursive
-    parsing of embedded quoted strings or ${...} constructs.
-
-z.  The inheritence of the DEBUG, RETURN, and ERR traps is now dependent only
-    on the settings of the `functrace' and `errtrace' shell options, rather
-    than whether or not the shell is in debugging mode.
-
-aa. Fixed a problem with $HOME being converted to ~ in the expansion of
-    members of the DIRSTACK array.
-
-bb. Fixed a problem with quoted arguments to arithmetic expansions in certain
-    constructs.
-
-cc. The command word completion code now no longer returns matching directories
-    while searching $PATH.
-
-dd. Fixed a bug with zero-padding and precision handling in snprintf()
-    replacement.
-
-ee. Fixed a bug that caused the command substitution code not to take embedded
-    shell comments into account.
-
-ff. Fixed a bug that caused $((...);(...)) to be misinterpreted as an
-    arithmetic substitution.
-
-gg. Fixed a bug in the prompt expansion code that inappropriately added a
-    \001 before a \002 under certain circumstances.
-
-hh. Fixed a bug that caused `unset LANG' to not properly reset the locale
-    (previous versions would set the locale back to what it was when bash
-    was started rather than the system's "native" locale).
-
-ii. Fixed a bug that could cause file descriptors > 10 to not be closed even
-    when closed explicitly by a script.
-
-jj. Fixed a bug that caused single quotes to be stripped from ANSI-C quoting
-    inside double-quoted command substitutions.
-
-kk. Fixed a bug that could cause core dumps when `return' was executed as the
-    last element of a pipeline inside a shell function.
-
-ll. Fixed a bug that caused DEBUG trap strings to overwrite commands stored in
-    the jobs list.
-
-2.  Changes to Readline
-
-a.  Fixed a problem that caused segmentation faults when using readline in
-    callback mode and typing consecutive DEL characters on an empty line.
-
-b.  Fixed several redisplay problems with multibyte characters, all having to
-    do with the different code paths and variable meanings between single-byte
-    and multibyte character redisplay.
-
-c.  Fixed a problem with key sequence translation when presented with the
-    sequence \M-\C-x.
-
-d.  Fixed a problem that prevented the `a' command in vi mode from being
-    undone and redone properly.
-
-e.  Fixed a problem that prevented empty inserts in vi mode from being undone
-    properly.
-
-f.  Fixed a problem that caused readline to initialize with an incorrect idea
-    of whether or not the terminal can autowrap.
-
-g.  Fixed output of key bindings (like bash `bind -p') to honor the setting of
-    convert-meta and use \e where appropriate.
-
-h.  Changed the default filename completion function to call the filename
-    dequoting function if the directory completion hook isn't set.  This means
-    that any directory completion hooks need to dequote the directory name,
-    since application-specific hooks need to know how the word was quoted,
-    even if no other changes are made.
-
-i.  Fixed a bug with creating the prompt for a non-interactive search string
-    when there are non-printing characters in the primary prompt.
-
-j.  Fixed a bug that caused prompts with invisible characters to be redrawn
-    multiple times in a multibyte locale.
-
-k.  Fixed a bug that could cause the key sequence scanning code to return the
-    wrong function.
-
-l.  Fixed a problem with the callback interface that caused it to fail when
-    using multi-character keyboard macros.
-
-m.  Fixed a bug that could cause a core dump when an edited history entry was
-    re-executed under certain conditions.
-
-n.  Fixed a bug that caused readline to reference freed memory when attmpting
-    to display a portion of the prompt.
-
-3.  New Features in Bash
-
-a.  Changed the parameter pattern replacement functions to not anchor the
-    pattern at the beginning of the string if doing global replacement - that
-    combination doesn't make any sense.
-
-b.  When running in `word expansion only' mode (--wordexp option), inhibit
-    process substitution.
-
-c.  Loadable builtins now work on MacOS X 10.[34].
-
-d.  Shells running in posix mode no longer set $HOME, as POSIX requires.
-
-e.  The code that checks for binary files being executed as shell scripts now
-    checks only for NUL rather than any non-printing character.
-
-f.  Quoting the string argument to the [[ command's  =~ operator now forces
-    string matching, as with the other pattern-matching operators.
-
-4.  New Features in Readline
-
-a.  Calling applications can now set the keyboard timeout to 0, allowing
-    poll-like behavior.
-
-b.  The value of SYS_INPUTRC (configurable at compilation time) is now used as
-    the default last-ditch startup file.
-
-c.  The history file reading functions now allow windows-like \r\n line
-    terminators.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-3.1-release,
-and the previous version, bash-3.1-rc2.
-
-1.  Changes to Readline
-
-a.  Several changes to the multibyte redisplay code to fix problems with
-    prompts containing invisible characters.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-3.1-rc2,
-and the previous version, bash-3.1-rc1.
-
-1.  Changes to Bash
-
-a.  Fixed a bug that caused a DEBUG trap to overwrite a command string that's
-    eventually attached to a background job.
-
-b.  Changed some code so that filenames with leading tildes with spaces in the
-    name aren't tilde-expanded by the bash completion code.
-
-c.  Fixed a bug that caused the pushd builtin to fail to change to
-    directories with leading `-'.
-
-d.  Fixed a small memory leak in the programmable completion code.
-
-2.  Changes to Readline
-
-a.  Fixed a redisplay bug caused by moving the cursor vertically to a line
-    with invisible characters in the prompt in a multibyte locale.
-
-b.  Fixed a bug that could cause the terminal special chars to be bound in the
-    wrong keymap in vi mode.
-
-3.  New Features in Bash
-
-a.  If compiled for strict POSIX conformance, LINES and COLUMNS may now
-    override the true terminal size.
-
-4.  New Features in Readline
-
-a.  A new external application-controllable variable that allows the LINES
-    and COLUMNS environment variables to set the window size regardless of
-    what the kernel returns.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-3.1-rc1,
-and the previous version, bash-3.1-beta1.
-
-1.  Changes to Bash
-
-a.  Fixed a bug that could cause core dumps due to accessing the current
-    pipeline while in the middle of modifying it.
-
-b.  Fixed a bug that caused pathnames with backslashes still quoting characters
-    to be passed to opendir().
-
-c.  Command word completion now obeys the setting of completion-ignore-case.
-
-d.  Fixed a problem with redirection that caused file descriptors greater than
-    2 to be inappropriately marked as close-on-exec.
-
-e.  In Posix mode, after `wait' is called to wait for a particular process
-    explicitly, that process is removed from the list of processes known to
-    the shell, and subsequent attempts to wait for it return errors.
-
-f.  Fixed a bug that caused extended pattern matching to incorrectly scan
-    backslash-escaped pattern characters.
-
-g.  Fixed a synchronization problem that could cause core dumps when handling
-    a SIGWINCH.
-
-h.  Fixed a bug that caused an unmatched backquote to be accepted without an
-    error when processing here documents.
-
-i.  Fixed a small memory leak in the `cd' builtin.
-
-j.  Fix for MacOS X so it gets the values for the HOSTTYPE, MACHTYPE, and
-    OSTYPE variables at build time, to support universal binaries.
-
-k.  Fixed a bug that could cause an exit trap to return the exit status of
-    the trap command rather than the status as it was before the trap was
-    run as the shell's exit status.
-
-2.  New Features in Bash
-
-3.  Changes to Readline
-
-a.  Fixed a bug that caused reversing the incremental search direction to
-    not work correctly.
-
-b.  Fixed the vi-mode `U' command to only undo up to the first time insert mode
-    was entered, as Posix specifies.
-
-c.  Fixed a bug in the vi-mode `r' command that left the cursor in the wrong
-    place.
-
-4.  New Features in Readline
-
-a.  New application-callable auxiliary function, rl_variable_value, returns
-    a string corresponding to a readline variable's value.
-
-b.  When parsing inputrc files and variable binding commands, the parser
-    strips trailing whitespace from values assigned to boolean variables
-    before checking them.
-
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-3.1-beta1,
-and the previous version, bash-3.1-alpha1.
-
-1.  Changes to Bash
-
-a.  Added some system-specific signal names.
-
-b.  Fixed a typo in the ulimit builtin to make `x' the right option to
-    maniuplate the limit on file locks.
-
-c.  Fixed a problem with using += to append to index 0 of an array variable
-    when not using subscript syntax.
-
-d.  A few changes to configure.in to remove calls to obsolete or outdated
-    macros.
-
-e.  Make sure changes to variables bash handles specially (e.g., LC_ALL) are
-    made when the variable is set in the temporary environment to a command.
-
-f.  Make sure changes to variables bash handles specially (e.g., LC_ALL) are
-    made when the variable is modified using `printf -v'.
-
-g.  The export environment is now remade on cygwin when HOME is changed, so
-    DLLs bash is linked against pick up the new value.  This fixes problems
-    with tilde expansion when linking against and already-installed readline.
-
-h.  Small fix to the logic for performing tilde expansion in posix mode, so
-    expansion on the right-hand side of an assignment statement takes place.
-
-i.  Fixed a bug that prevented redirections associated with a shell function
-    from being executed when in a subshell.
-
-j.  Fixed `source' and `.' builtins to not require an executable file when
-    searching $PATH for a file to source.
-
-k.  Fixed a bug that caused incorrect word splitting in a function when IFS
-    was declared local, then unset.
-
-l.  Fixed a problem with the `kill' builtin that prevented sending signals
-    to a process group under certain circumstances when providing a pid < 0.
-
-m.  When in POSIX mode, `pwd' now checks that the value it prints is the same
-    directory as `.', even when displaying $PWD.
-
-n.  Fixed a problem with the `read' builtin when reading a script from standard
-    input and reading data from the same file.
-
-o.  Fixed a problem with the `type' and `command' builtins that caused absolute
-    pathnames to be displayed incorrectly.
-
-p.  Some changes to the `bg' builtin for POSIX conformance.
-
-q.  The `fc' builtin now removes the `fc' command that caused it to invoke an
-    editor on specified history entries from the history entirely, rather than
-    simply ignoring it.
-
-r.  When in POSIX mode, the `v' command in vi editing mode simply invokes vi
-    on the current command, rather than checking $FCEDIT and $EDITOR.
-
-s.  Fixed a small memory leak in the pathname canonicalization code.
-
-t.  Fixed a bug that caused the expanded value of a $'...' string to be
-    incorrectly re-quoted if it occurred within a double-quoted ${...}
-    parameter expansion.
-
-u.  Restored default emacs-mode key binding of M-TAB to dynamic-complete-history.
-
-v.  Fixed a bug that caused core dumps when interrupting loops running builtins
-    on some systems.
-
-w.  Make sure that some of the functions bash provides replacements for are
-    not cpp defines.
-
-x.  The code that scans embedded commands for the parser (`...` and $(...)) is
-    now more aware of embedded comments and their effect on quoted strings.
-
-y.  Changed the `-n' option to the `history' builtin to not reset the number of
-    history lines read in the current session after reading the new lines from
-    the history file if the history is being appended when it is written to
-    the file, since the appending takes care of the problem that the adjustment
-    was intended to solve.
-
-z.  Improved the error message displayed when a shell script fails to execute
-    because the environment and size of command line arguments are too large.
-
-aa. A small fix to make sure that $HISTCMD is evaluated whenever the shell is
-    saving commands to the history list, not just when HISTSIZE is defined.
-
-2.  Changes to Readline
-
-a.  The `change-case' command now correctly changes the case of multibyte
-    characters.
-
-b.  Changes to the shared library construction scripts to deal with Windows
-    DLL naming conventions for Cygwin.
-
-c.  Fixed the redisplay code to avoid core dumps resulting from a poorly-timed
-    SIGWINCH.
-
-d.  Fixed the non-incremental search code in vi mode to dispose of any current
-    undo list when copying a line from the history into the current editing
-    buffer.
-
-e.  The variable assignment code now ignores whitespace at the end of lines
-    when assigning to boolean variables.
-
-f.  The `C-w' binding in incremental search now understands multibyte
-    characters.
-
-3.  New Features in Bash
-
-a.  A new configuration option, `--enable-strict-posix-default', which will
-    build bash to be POSIX conforming by default.
-
-4.  New Features in Readline
-
-a.  If the rl_completion_query_items is set to a value < 0, readline never
-    asks the user whether or not to view the possible completions.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-3.1-alpha1,
-and the previous version, bash-3.0-release.
-
-1.  Changes to Bash
-
-a.  Fixed a bug that caused bash to crash if referencing an unset local array.
-
-b.  Fixed a problem that caused tilde expansion to not be performed before
-    attempting globbing word completion.
-
-c.  Fixed an incompatibility so that a first argument to trap that's a valid
-    signal number will be trated as a signal rather than a command to execute.
-
-d.  Fixed ${#word} expansion to correctly compute the length of a string
-    containing multibyte characters.
-
-e.  Fixed a bug that caused bash to not pass the correct flags for signal
-    disposition to child processes.
-
-f.  Fixed a bug that caused `fc -l' to list one too many history entries.
-
-g.  Some fixes to `fc' for POSIX conformance.
-
-h.  Some fixes to job status display for POSIX conformance.
-
-i.  Fixed a bug that caused `command -v' to display output if a command was not
-    found -- it should be silent.
-
-j.  In POSIX mode, `type' and `command -[vV]' do not report non-executable
-    files, even if the shell will attempt to execute them.
-
-k.  Fixed a bug that caused the `==' operator to the [[ command to not attempt
-    extended pattern matching.
-
-l.  Fixed the brace expansion code to handle characters whose value exceeds 128.
-
-m.  Fixed `printf' to handle strings with a leading `\0' whose length is
-    non-zero.
-
-n.  Fixed a couple of problems with brace expansion where `${' was handled
-    incorrectly.
-
-o.  Fixed off-by-one error when calculating the upper bound of `offset' when
-    processing the ${array[@]:offset:length} expansion.
-
-p.  System-specific configuration changes for: FreeBSD 5.x, Interix, MacOS X
-    10.4, Linux 2.4+ kernels, Linux 3.x kernels, Dragonfly BSD, QNX 6.x,
-    Cygwin
-
-q.  Fixed a bug that caused the shell to ignore the status of the rightmost
-    command in a pipeline when the `pipefail' option was enabled.
-
-r.  Fixed a completion bug that caused core dumps when expanding a directory
-    name.
-
-s.  Fixed a bug that prevented `hash -d' from removing commands from the hash
-    table.
-
-t.  Fixed word splitting to avoid really bad quadratic performance when
-    expanding long lists.
-
-u.  Fixed a bug that caused negative offsets in substring expansion to use the
-    wrong values.
-
-v.  Fixed a bug in printf that caused it to not return failure on write errors.
-
-w.  Fixed a bug that caused commands in subshells to not be properly timed.
-
-x.  The shell parser no longer attempts to parse a compound assignment specially
-    unless in a position where an assignment statement is acceptable or parsing
-    arguments to a builtin that accepts assignment statements.
-
-y.  Fixed a problem that caused a `case' statement to be added to the history
-    incorrectly as a single command if the `case word' was on one line and the
-    `in' on another.
-
-z.  Fixed a problem that caused internal shell quoting characters to be
-    incorrectly quoted with backslashes under some circumstances.
-
-aa. The shell now performs correct word splitting when IFS contains multibyte
-    characters.
-
-bb. The mail checking code now resets the cached file information if the size
-    drops to 0, even if the times don't change.
-
-cc. A completed command name that is found in $PATH as well as the name of a
-    directory in the current directory no longer has a slash appended in certain
-    circumstances:  a single instance found in $PATH when `.' is not in $PATH,
-    and multiple instances found in $PATH, even when `.' is in $PATH.
-
-dd. Incorporated tilde expansion into the word expansion code rather than as a
-    separately-called function, fixing some cases where it was performed
-    inappropriately (e.g., after the second `=' in an assignment statement or
-    in a double-quoted parameter expansion).
-
-ee. Fixed several bugs encountered when parsing compound assignment statements,
-    so that compound assignments appearing as arguments to builtins are no
-    longer double-expanded.
-
-ff. Fixed a bug in the command execution code that caused asynchronous commands
-    containing command substitutions to not put the terminal in the wrong
-    process group.
-
-gg. Bash now handles the case where the WCONTINUED flag causes waitpid() to
-    return -1/EINVAL at runtime as well as configuration time.
-
-hh. Fixed parser to generate an error when the pipeline `argument' to `!' or
-    `time' is NULL.
-
-ii. The shell now takes a little more care when manipulating file descriptors
-    greater than 9 with the `exec' builtin.
-
-jj. Fixed a bug that caused variable assignments preceding the `command' builtin
-    preceding a special builtin to be preserved after the command completed in
-    POSIX mode.
-
-kk. Fixed a bug that allowed variables beginning with a digit to be created.
-
-ll. Fixed a bug that caused a \<newline> to be removed when parsing a $'...'
-    construct.
-
-mm. A shell whose name begins with `-' will now be a restricted shell if the
-    remainder of the name indicates it should be restricted.
-
-nn. Fixed a bug that could cause a core dump if FUNCNAME were changed or unset
-    during a function's execution.
-
-oo. Fixed a bug that caused executing a `return' in a function to not execute
-    a RETURN trap.  The RETURN trap is inherited by shell functions only if
-    function tracing is globally enabled or has been enabled for that function.
-
-pp. Fixed cases where var[@] was not handled exactly like var, when var is a
-    scalar variable.
-
-qq. Fixed a bug that caused the first character after a SIGINT to be discarded
-    under certain circumstances.
-
-rr. Fixed exit status code so that a suspended job returns 128+signal as its
-    exit status (preventing commands after it in `&&' lists from being
-    executed).
-
-ss. Fixed a bug that caused the shell parser state to be changed by executing
-    a shell function as a result of word completion.
-
-tt. Fixed a long-standing bug that caused '\177' characters in variable
-    values to be discarded when expanded in double-quoted strings.
-
-uu. Fixed a bug that caused $RANDOM to be re-seeded multiple times in a
-    subshell environment.
-
-vv. Extensive changes to the job management code to avoid the pid-reuse and
-    pid-aliasing problems caused by retaining the exit status of too many jobs,
-    but still retain as many background job statuses as POSIX requires.
-
-ww. Fixed a parser bug in processing \<newline> that caused things like
-
-               ((echo 5) \
-                (echo 6))
-
-    to not work correctly.
-
-xx. `pwd -P' now sets $PWD to a directory name containing no symbolic links
-    when in posix mode, as POSIX requires.
-
-yy. In posix mode, bash no longer sets $PWD to a name containing no symbolic
-    links if a directory is chosen from $CDPATH.
-
-zz. The word splitting code now treats an IFS character that is not space,
-    tab, or newline and any adjacent IFS white space as a single delimiter, as
-    SUSv3/XPG6 require.
-
-aaa. The `read' builtin now checks whether or not the number of fields read is
-     exactly the same as the number of variables instead of just assigning the
-     rest of the line (minus any trailing IFS white space) to the last
-     variable.  This is what POSIX/SUS/XPG all require.
-
-bbb. Fixed a bug that caused `read' to always check whether or not fd 0 was a
-     pipe, even when reading from another file descriptor.
-
-ccc. Fixed a bug that caused short-circuiting of execution even if the return
-     value was being inverted.
-
-ddd. Fixed a bug that caused a core dump while decoding \W escapes in PS1 if
-     PWD was unset.
-
-eee. Fixed a bug in `read' that counted internal quoting characters for the
-     purposes of `read -n'.
-
-fff. Fixed a bug so that a function definition in a pipeline causes a child
-     process to be forked at the right time.
-
-ggg. Bash will not attempt to link against a readline library that doesn't
-     have rl_gnu_readline_p == 1.
-
-hhh. Fixed a bug that caused `read' to consume one too many characters when
-     reading a fixed number of characters and the Nth character is a backslash.
-
-iii. Fixed a bug that caused `unset' on variables in the temporary environment
-     to leave them set when `unset' completed.
-
-jjj. Fixed a bug that caused bash to close fd 2 if an `exec' failed and the
-     shell didn't exit.
-
-kkk. The completion code is more careful to not turn `/' or `///' into `//',
-     for those systems on which `//' has special meaning.
-
-lll. Fixed a bug that caused command substitution in asynchronous commands to
-     close the wrong file descriptors.
-
-mmm. The shell no longer prints status messages about terminated background
-     processes unless job control is active.
-
-nnn. Fixed a bug that prevented multiple consecutive invocations of `history -s'
-     from adding all the commands to the history list.
-
-ooo. Added a couple of changes to make arithmetic expansion more consistent in
-     all its contexts (still not perfect).
-
-ppp. Fixed a bug that caused the parser to occasionally not find the right
-     terminating "`" in an old-style command substitution.
-
-qqq. Fixed a bug that caused core dumps when the shell was reading its non-
-     interactive input from fd 0 and fd 0 was duplicated and restored using a
-     combination of `exec' (to save) and redirection (to restore).
-
-rrr. Fixed a problem that caused loops in sourced scripts to not be cleaned
-     up properly when a `return' is executed.
-
-sss. Change internal command substitution completion function to append a slash
-     to directory names in the command.
-
-2.  Changes to Readline
-
-a.  Fixed a bug that caused multiliine prompts to be wrapped and displayed
-    incorrectly.
-
-b.  Fixed a bug that caused ^P/^N in emacs mode to fail to display the current
-    line correctly.
-
-c.  Fixed a problem in computing the number of invisible characters on the first
-    line of a prompt whose length exceeds the screen width.
-
-d.  Fixed vi-mode searching so that failure preserves the current line rather
-    than the last line in the history list.
-
-e.  Fixed the vi-mode `~' command (change-case) to have the correct behavior at
-    end-of-line when manipulating multibyte characters.
-
-f.  Fixed the vi-mode `r' command (change-char) to have the correct behavior at
-    end-of-line when manipulating multibyte characters.
-
-g.  Fixed multiple bugs in the redisplay of multibyte characters:  displaying
-    prompts longer than the screen width containing multibyte characters, 
-
-h.  Fix the calculation of the number of physical characters in the prompt
-    string when it contains multibyte characters.
-
-i.  A non-zero value for the `rl_complete_suppress_append' variable now causes
-    no `/' to be appended to a directory name.
-
-j.  Fixed forward-word and backward-word to work when words contained
-    multibyte characters.
-
-k.  Fixed a bug in finding the delimiter of a `?' substring when performing
-    history expansion in a locale that supports multibyte characters.
-
-l.  Fixed a memory leak caused by not freeing the timestamp in a history entry.
-
-m.  Fixed a bug that caused "\M-x" style key bindings to not obey the setting
-    of the `convert-meta' variable.
-
-n.  Fixed saving and restoring primary prompt when prompting for incremental
-    and non-incremental searches; search prompts now display multibyte
-    characters correctly.
-
-o.  Fixed a bug that caused keys originally bound to self-insert but shadowed
-    by a multi-character key sequence to not be inserted.
-
-p.  Fixed code so rl_prep_term_function and rl_deprep_term_function aren't
-    dereferenced if NULL (matching the documentation).
-
-q.  Extensive changes to readline to add enough state so that commands
-    requiring additional characters (searches, multi-key sequences, numeric
-    arguments, commands requiring an additional specifier character like
-    vi-mode change-char, etc.) work without synchronously waiting for
-    additional input.
-
-r.  Lots of changes so readline builds and runs on MinGW.
-
-s.  Readline no longer tries to modify the terminal settings when running in
-    callback mode.
-
-t.  The Readline display code no longer sets the location of the last invisible
-    character in the prompt if the \[\] sequence is empty.
-
-3.  New Features in Bash
-
-a.  Bash now understands LC_TIME as a special variable so that time display
-    tracks the current locale.
-
-b.  BASH_ARGC, BASH_ARGV, BASH_SOURCE, and BASH_LINENO are no longer created
-    as `invisible' variables and may not be unset.
-
-c.  In POSIX mode, if `xpg_echo' option is enabled, the `echo' builtin doesn't
-    try to interpret any options at all, as POSIX requires.
-
-d.  The `bg' builtin now accepts multiple arguments, as POSIX seems to specify.
-
-e.  Fixed vi-mode word completion and glob expansion to perform tilde
-    expansion.
-
-f.  The `**' mathematic exponentiation operator is now right-associative.
-
-g.  The `ulimit' builtin has new options: -i (max number of pending signals),
-    -q (max size of POSIX message queues), and -x (max number of file locks).
-
-h.  A bare `%' once again expands to the current job when used as a job
-    specifier.
-
-i.  The `+=' assignment operator (append to the value of a string or array) is
-    now supported for assignment statements and arguments to builtin commands
-    that accept assignment statements.
-
-j.  BASH_COMMAND now preserves its value when a DEBUG trap is executed.
-
-k.  The `gnu_errfmt' option is enabled automatically if the shell is running
-    in an emacs terminal window.
-
-l.  New configuration option:  --single-help-strings.  Causes long help text
-    to be written as a single string; intended to ease translation.
-
-m.  The COMP_WORDBREAKS variable now causes the list of word break characters
-    to be emptied when the variable is unset.
-
-n.  An unquoted expansion of $* when $IFS is empty now causes the positional
-    parameters to be concatenated if the expansion doesn't undergo word
-    splitting.
-
-o.  Bash now inherits $_ from the environment if it appears there at startup.
-
-p.  New shell option: nocasematch.  If non-zero, shell pattern matching ignores
-    case when used by `case' and `[[' commands.
-
-q.  The `printf' builtin takes a new option: -v var.  That causes the output
-    to be placed into var instead of on stdout.
-
-r.  By default, the shell no longer reports processes dying from SIGPIPE.
-
-s.  Bash now sets the extern variable `environ' to the export environment it
-    creates, so C library functions that call getenv() (and can't use the
-    shell-provided replacement) get current values of environment variables.
-
-4.  New Features in Readline
-
-a.  The key sequence sent by the keypad `delete' key is now automatically
-    bound to delete-char.
-
-b.  A negative argument to menu-complete now cycles backward through the
-    completion list.
-
-c.  A new bindable readline variable:  bind-tty-special-chars.  If non-zero,
-    readline will bind the terminal special characters to their readline
-    equivalents when it's called (on by default).
-
-d.  New bindable command: vi-rubout.  Saves deleted text for possible
-    reinsertion, as with any vi-mode `text modification' command; `X' is bound
-    to this in vi command mode.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-3.0-release,
-and the previous version, bash-3.0-rc1.
-
-1.  Changes to Bash
-
-a.  Fixed a boundary overrun that could cause segmentation faults when the
-    completion code hands an incomplete construct to the word expansion
-    functions.
-
-b.  Changed posix mode behavior so that an error in a variable assignment
-    preceding a special builtin causes a non-interactive shell to exit.
-
-c.  Change the directory expansion portion of the completion code to not
-    expand embedded command substitutions if the directory name appears in
-    the file system.
-
-d.  Fixed a problem that caused `bash -r' to turn on restrictions before
-    reading the startup files.
-
-e.  Fixed a problem with the default operation of the `umask' builtin.
-
-2.  Changes to Readline
-
-a.  Fixed a problem with readline saving the contents of the current line
-    before beginning a non-interactive search.
-
-b.  Fixed a problem with EOF detection when using rl_event_hook.
-
-c.  Fixed a problem with the vi mode `p' and `P' commands ignoring numeric
-    arguments.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-3.0-rc1,
-and the previous version, bash-3.0-beta1.
-
-1.  Changes to Bash
-
-a.  Fixed a bug that caused incorrect behavior when referecing element 0 of
-    an array using $array, element 0 was unset, and `set -u' was enabled.
-
-b.  System-specific changes for: SCO Unix 3.2, Tandem.
-
-c.  Fixed a bug that caused inappropriate word splitting when a variable was
-    expanded within a double-quoted string that also included $@.
-
-d.  Fixed a bug that caused `pwd' to not display anything in physical mode
-    when the file system had changed underneath the shell.
-
-e.  Fixed a bug in the pre- and post- increment and decrement parsing in the
-    expression evaluator that caused errors when the operands and corresponding
-    operators were separated by whitespace.
-
-f.  Fixed a bug that caused `history -p' to add an entry to the history list,
-    counter to the documentation.  (Keeps the history expansions invoked by
-    emacs-mode command line editing from doing that as well.)
-
-g.  Fixed a bug that could cause a core dump if `cd' is asked to print out a
-    pathname longer than PATH_MAX characters.
-
-h.  Fixed a bug that caused jobs to be put into the wrong process group under
-    some circumstances after enabling job control with `set -m'.
-
-i.  `unalias' now  returns failure if no alias name arguments are supplied.
-
-j.  Documented the characters not allowed to appear in an alias name.
-
-k.  $* is no longer expanded as if in double quotes when it appears in the
-    body of a here document, as the SUS seems to require.
-
-l.  The `bashbug' script now uses a directory in $TMPDIR for exclusive
-    access rather than trying to guess how the underlying OS provides for
-    secure temporary file creation.
-
-m.  Fixed a few problems with `cd' and `pwd' when asked to operate on pathnames
-    longer than PATH_MAX characters.
-
-n.  Fixed a memory leak caused when creating multiple local array variables
-    with identical names.
-
-o.  Fixed a problem with calls to getcwd() so that bash now operates better
-    when the full pathname to the current directory is longer than PATH_MAX
-    bytes.
-
-p.  The `trap' builtin now reports an error if a single non-signal argument
-    is specified.
-
-q.  Fixed a bug that caused `umask' to not work correctly when presented
-    with a mask of all 0s.
-
-r.  When `getopts' reaches the end of options, OPTARG is unset, as POSIX
-    appears to specify.
-
-s.  Interactive mode now depends on whether or not stdin and stderr are
-    connected to a tty; formerly it  was stdin and stdout.  POSIX requires
-    this.
-
-t.  Fixed vi-mode completion to work more as POSIX specifies (e.g., doing the
-    right kind of filename generation).
-
-2.  Changes to Readline
-
-a.  Fixed a problem that could cause readline to refer to freed memory when
-    moving between history lines while doing searches.
-
-b.  Improvements to the code that expands and displays prompt strings
-    containing multibyte characters.
-
-c.  Fixed a problem with vi-mode not correctly remembering the numeric argument
-    to the last `c'hange command for later use with `.'.
-
-d.  Fixed a bug in vi-mode that caused multi-digit count arguments to work
-    incorrectly.
-
-e.  Fixed a problem in vi-mode that caused the last text modification command
-    to not be remembered across different command lines.
-
-f.  Fixed problems with changing characters and changing case at the end of
-    the line.
-
-3.  New Features in Bash
-
-a.  The `jobs', `kill', and `wait' builtins now accept job control notation
-    even if job control is not enabled.
-
-b.  The historical behavior of `trap' that allows a missing `action' argument
-    to cause each specified signal's handling to be reset to its default is
-    now only supported when `trap' is given a single non-option argument.
-
-4.  New Features in Readline
-
-a.  When listing completions, directories have a `/' appended if the
-    `mark-directories' option has been enabled.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-3.0-beta1,
-and the previous version, bash-3.0-alpha.
-
-1.  Changes to Bash
-
-a.  Fixes to build correctly when arrays are not compiled into the shell.
-
-b.  Fixed command substitution to run any exit trap defined in the command
-    substitution before returning; the exit trap is not inherited from the
-    calling shell.
-
-c.  Fixes to process group synchronization code so that every child process
-    attempts to set the terminal's process group; fixes some synchronization
-    problems on Linux kernels that schedule the child to always run before
-    the parent.
-
-d.  Fixed processing of octal and hex constants in printf builtin for POSIX.2
-    compliance.
-
-e.  Fixed a couple of core dumps in the pattern removal code.
-
-f.  Fixes to the array subrange extraction code to deal better with sparse
-    arrays.
-
-g.  Parser errors and other errors that result in the shell exiting now cause
-    the exit trap to be run.
-
-h.  Change the command substitution completion functions to not append any
-    closing quote, because it would be inserted a closing "`" or ")".
-
-i.  Fix history initialization so assignments to $histchars made in startup
-    files are honored.
-
-j.  If an exit trap does not contain a call to `exit', the shell now uses
-    the exit status of the last command executed before the trap as the exit
-    status of the shell.
-
-k.  The parser now prompts with $PS2 if it reads a newline while parsing a
-    compound array assignment statement.
-
-l.  When performing a compound array assignment, the parser doesn't treat
-    words of the form [index]=value as assignments if they're the result of
-    expansions.
-
-m.  Fixed a bug that caused `return' executed in a trap command to make the
-    shell think it was still running the trap.
-
-n.  Fixed the value of errno set by the pathname canonicalization functions.
-
-o.  Changed the grammar so that `time' alone on a line times a null command
-    rather than being a syntax error.
-
-p.  The pattern substitution code no longer performs quote removal on the
-    pattern before trying to match it, as the pattern removal functions do.
-
-q.  Fixed a bug that could cause core dumps when checking whether a quoted
-    command name was being completed.
-
-r.  Fixes to the pattern removal and pattern replacement expansions to deal
-    with multibyte characters better (and faster).
-
-s.  Fix to the substring expansion (${param:off[:len]}) to deal with (possibly
-    multibyte) characters instead of raw bytes.
-
-t.  Fixed a bug that caused some key bindings set in an inputrc to be ignored
-    at shell startup.
-
-u.  Fixed a bug that caused unsetting a local variable within a function to
-    not work correctly.
-
-v.  Fixed a bug that caused invalid variables to be created when using
-    `read -a'.
-
-w.  Fixed a bug that caused "$@" to expand incorrectly when used as the right
-    hand side of a parameter expansion such as ${word:="$@"} if the first
-    character of $IFS was not a space.
-
-x.  Fixed a slight cosmetic problem when printing commands containing a
-    `>&word' redirection.
-
-y.  Fixed a problem that could cause here documents to not be created correctly
-    if the system temporary directory did not allow writing.
-
-2.  Changes to Readline
-
-a.  Change to history expansion functions to treat `^' as equivalent to word
-    one, as the documention states.
-
-b.  Some changes to the display code to improve display and redisplay of
-    multibyte characters.
-
-c.  Changes to speed up the multibyte character redisplay code.
-
-d.  Fixed a bug in the vi-mode `E' command that caused it to skip over the
-    last character of a word if invoked while point was on the word's
-    next-to-last character.
-
-e.  Fixed a bug that could cause incorrect filename quoting when
-    case-insensitive completion was enabled and the word being completed
-    contained backslashes quoting word break characters.
-
-f.  Fixed a bug in redisplay triggered when the prompt string contains
-    invisible characters.
-
-g.  Fixed some display (and other) bugs encountered in multibyte locales
-    when a non-ascii character was the last character on a line.
-
-h.  Fixed some display bugs caused by multibyte characters in prompt strings.
-
-i.  Fixed a problem with history expansion caused by non-whitespace characters
-    used as history word delimiters.
-
-3.  New Features in Bash
-
-a.  printf builtin understands two new escape sequences:  \" and \?.
-
-b.  `echo -e' understands two new escape sequences:  \" and \?.
-
-c.  The GNU `gettext' package and libintl have been integrated; the shell's
-    messages can be translated into different languages.
-
-d.  The `\W' prompt expansion now abbreviates $HOME as `~', like `\w'.
-
-e.  The error message printed when bash cannot open a shell script supplied
-    as argument 1 now includes the name of the shell, to better identify
-    the error as coming from bash.
-
-4.  New Features in Readline
-
-a.  New application variable, rl_completion_quote_character, set to any
-    quote character readline finds before it calls the application completion
-    function.
-
-b.  New application variable, rl_completion_suppress_quote, settable by an
-    application completion function.  If set to non-zero, readline does not
-    attempt to append a closing quote to a completed word.
-
-c.  New application variable, rl_completion_found_quote, set to a non-zero
-    value if readline determines that the word to be completed is quoted.
-    Set before readline calls any application completion function.
-
-d.  New function hook, rl_completion_word_break_hook, called when readline
-    needs to break a line into words when completion is attempted.  Allows
-    the word break characters to vary based on position in the line.
-
-e.  New bindable command: unix-filename-rubout.  Does the same thing as
-    unix-word-rubout, but adds `/' to the set of word delimiters.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-3.0-alpha,
-and the previous version, bash-2.05b-release.
-
-1.  Changes to Bash
-
-a.  Fixes so that the shell will compile without some of the default options
-    defined.
-
-b.  Fixed an error message that did not pass enough arguments to printf.
-
-c.  Fixed a bug that caused input redirection to a builtin inside a script
-    being read from standard input to result in the rest of the already-
-    read and buffered script to be discarded.
-
-d.  Fixed a bug that caused subshell initialization to close the file
-    descriptor from which the shell was reading a script under certain
-    circumstances.
-
-e.  Fixed a bug that caused the shell to not advance a string pointer over
-    a null wide character when doing string operations.
-
-f.  Fixed the internal logout code so that shells that time out waiting for
-    input (using $TMOUT) run ~/.bash_logout.
-
-g.  Portability and configuration changes for: cygwin, HP/UX, GNU/FreeBSD.
-
-h.  The parser no longer adds implicit double quotes to ((...)) arithmetic
-    commands.
-
-i.  The ((...)) arithmetic command evaluation code was fixed to not dump core
-    when the expanded string is null.
-
-j.  The ((...)) arithmetic command evaluation code was fixed to not perform
-    variable assignments while expanding the expression.
-
-k.  Fixed a bug that caused word splitting to be performed incorrectly when
-    IFS is set, but null.
-
-l.  Fixed a bug in brace expansion that caused a quoted `$' preceding an
-    open brace to inhibit brace expansion.
-
-m.  Fixed a bug that caused a leading `-' in the shell's name to cause it to
-    not be recognized as a restricted shell.
-
-n.  Fixed a bug in the arithmetic evaluation code that could cause longjmps
-    to an invalid location and result in a core dump.
-
-o.  Fixed a bug in the calculation of how many history lines are new in a
-    single shell session when reading new history lines from a file with
-    `history -n'.
-
-p.  Fixed a bug in pathname canonicalization that caused the shell to dump
-    core when presented with a pathname longer than PATH_MAX.
-
-q.  Fixed the parser so that it doesn't try to compare a char variable to
-    EOF, which fails when chars are unsigned.
-
-r.  Fixed a bug in the simple command execution code that caused occasional
-    core dumps.
-
-s.  The shell does a better job of saving any partial parsing state during
-    operations which cause a command to be executed while a line is being
-    entered and parsed.
-
-t.  The completion code now splits words more like the expansion code when
-    $IFS is used to split.
-
-u.  The locale code does a better job of recomputing the various locale
-    variable values when LC_ALL is unset.
-
-v.  The programmable completion code does a better job of dequoting expanded
-    word lists before comparing them against the word to be matched.
-
-w.  The shell no longer seg faults if the expanded value of $PS4 is null
-    and `set -x' is enabled.
-
-x.  Fixed a bug that caused core dumps when a here string expanded to NULL.
-
-y.  The mail checking code now makes sure the mailbox is bigger before
-    reporting the existence of new mail.
-
-z.  The parser does not try to expand $'...' and $"..." when the appear
-    within double quotes unless the `extquote' option has been enabled with
-    `shopt'.  For backwards compatibility, it is enabled by default.
-
-aa. Fixed a bug that caused `for x; do ...' and `select x; do ... to use
-    $@ instead of "$@" for the implicit list of arguments.
-
-bb. Fixed a bug that caused a subshell of a restricted shell (e.g., one
-    spawned to execute a pipeline) to not exit immediately if attempting
-    to use a command containing a slash.
-
-cc. Fixed a problem with empty replacements for a pattern that doesn't match
-    when performing ${param/word/} expansion.
-
-dd. Word expansions performed while expanding redirections no longer search
-    a command's temporary environment to expand variable values.
-
-ee. Improvements to the alias expansion code when expanding subsequent words
-    because an aliase's value ends with a space.
-
-ff. `cd -' now prints the current working directory after a successful chdir
-    even when the shell is not interactive, as the standard requires.
-
-gg. The shell does a better job of ensuring a child process dies of SIGINT
-    before resending SIGINT to itself.
-
-hh. The arithmetic expansion variable assignment code now does the right
-    thing when assigning to `special' variables like OPTIND.
-
-ii. When history expansion verification is enabled, the bash readline helper
-    functions that do history expansion on the current line don't print
-    the results.
-
-jj. Fixed bugs with multiple consecutive alias expansion when one of the
-    expansions ends with a space.
-
-kk. Fixed a problem in the programmable completion code that could cause core
-    dumps when trying to initialize a set of possible completions from a
-    list of variables.
-
-ll. The \[ and \] escape characters are now ignored when decoding the prompt
-    string if the shell is started with editing disabled.
-
-mm. Fixed a bug that could leave extra characters in a string when doing
-    quoted null character removal.
-
-nn. Command substitution and other subshell operations no longer reset the
-    line number (aids the bash debugger).
-
-oo. Better line number management when executing simple commands, conditional
-    commands, for commands, and select commands.
-
-pp. The globbing code now uses malloc, with its better failure properties,
-    rather than alloca().
-
-qq. Fixed a bug that caused expansions like #{a[2]:=value} to create the
-    appropriate array element instead of a variable named `a[2]'.
-
-rr. Fixed a bug in the handling of a `?(...)' pattern immediately following
-    a `*' when extglob is enabled.
-
-ss. Fixed a bug that caused a `return' invoked in an exit trap when exit is
-    invoked in a function to misbehave.
-
-tt. Fixed a bug that caused CTLESC and CTLNUL characters to not be escaped
-    by the internal shell string quoting functions.
-
-uu. Fixed a bug that caused quoted null characters in an expanded word list
-    to be inappropriately assigned to an array variable when using `read -a'.
-
-vv. Fixed a bug that caused redirections accompanying a null command to persist
-    in the current shell.
-
-ww. Fixed a bug that caused the prompt to be printed when the shell was
-    expanding a multiline alias.
-
-xx. Fixed a bug that resulted in core dumps when the completion for a command
-    changed the compspec.
-
-yy. Fixed a bug that caused evaluation of programmable completions to print
-    notifications of completed jobs.
-
-zz. Bash now disables line editing when $EMACS == `t' and $TERM == `dumb'
-    (which is what emacs shell windows do).
-
-aaa. In posix mode, `kill -l' causes signal names to be displayed without
-     a leading `SIG'.
-
-bbb. Clear error flag on standard output so it doesn't persist across multiple
-     builtin commands.
-
-ccc. In posix mode, `alias' displays alias values without the leading `alias',
-     so the output cannot be used as subsequent input.
-
-ddd. In posix mode, the `trap' builtin doesn't check whether or not its
-     first argument is a signal specification and revert the signal handling
-     to its original disposition if it is.
-
-eee. Fixed several bugs in the handling of "$*" and "${array[*]}" by the
-     pattern substitution and removal expansions.
-
-fff. Fixed several problems with the handling of ${array[@]}, ${array[*]},
-     $@, and $* by the indirect variable expansion code.
-
-ggg. Fixed a bug that did not allow `time' to be aliased.
-
-hhh. Improved the mail checking code so it won't check (and possibly cause an
-     NFS file system mount) until MAILPATH or MAIL is given a value -- there
-     is no default if DEFAULT_MAIL_DIRECTORY is not defined at compile time.
-     (It is computed by configure, but can be #undef'd in config-bot.h.)
-
-iii. If the `chkwinsize' option is enabled, the shell checks for window size
-     changes if a child process exits due to a signal.
-
-jjj. Removed the attempts to avoid adding a slash at the end of a completed
-     executable name if there was a directory with the same name in the
-     current directory.
-
-kkk. Fixed PATH lookup code so it treats the permission bits separately for
-     owner, group, and other, rather than checking them all.
-
-lll. Fixed the locale code to reset the parser's idea of the character class
-     <blank>, which controls how it splits tokens, when the locale changes.
-
-mmm. The shell now binds its special readline functions and key bindings only
-     if the user's inputrc file has not already bound them.
-
-nnn. The shell now reports on processes that dump core due to signals when
-     invoked as `-c command'.
-
-2.  Changes to Readline
-
-a.  Fixes to avoid core dumps because of null pointer references in the
-    multibyte character code.
-
-b.  Fix to avoid infinite recursion caused by certain key combinations.
-
-c.  Fixed a bug that caused the vi-mode `last command' to be set incorrectly.
-
-d.  Readline no longer tries to read ahead more than one line of input, even
-    when more is available.
-
-e.  Fixed the code that adjusts the point to not mishandle null wide
-    characters.
-
-f.  Fixed a bug in the history expansion `g' modifier that caused it to skip
-    every other match.
-
-g.  Fixed a bug that caused the prompt to overwrite previous output when the
-    output doesn't contain a newline and the locale supports multibyte
-    characters.  This same change fixes the problem of readline redisplay
-    slowing down dramatically as the line gets longer in multibyte locales.
-
-h.  History traversal with arrow keys in vi insertion mode causes the cursor
-    to be placed at the end of the new line, like in emacs mode.
-
-i.  The locale initialization code does a better job of using the right
-    precedence and defaulting when checking the appropriate environment
-    variables.
-
-j.  Fixed the history word tokenizer to handle <( and >( better when used as
-    part of bash.
-
-k.  The overwrite mode code received several bug fixes to improve undo.
-
-l.  Many speedups to the multibyte character redisplay code.
-
-m.  The callback character reading interface should not hang waiting to read
-    keyboard input.
-
-n.  Fixed a bug with redoing vi-mode `s' command.
-
-o.  The code that initializes the terminal tracks changes made to the terminal
-    special characters with stty(1) (or equivalent), so that these changes
-    are reflected in the readline bindings.  New application-callable function
-    to make it work:  rl_tty_unset_default_bindings().
-
-p.  Fixed a bug that could cause garbage to be inserted in the buffer when
-    changing character case in vi mode when using a multibyte locale.
-
-q.  Fixed a bug in the redisplay code that caused problems on systems
-    supporting multibyte characters when moving between history lines when the
-    new line has more glyphs but fewer bytes.
-
-r.  Undo and redo now work better after exiting vi insertion mode.
-
-s.  Make sure system calls are restarted after a SIGWINCH is received using
-    SA_RESTART.
-
-t.  Improvements to the code that displays possible completions when using
-    multibyte characters.
-
-u.  Fixed a problem when parsing nested if statements in inputrc files.
-
-v.  The completer now takes multibyte characters into account when looking for
-    quoted substrings on which to perform completion.
-
-w.  The history search functions now perform better bounds checking on the
-    history list.
-
-3.  New Features in Bash
-
-a.  ANSI string expansion now implements the \x{hexdigits} escape.
-
-b.  There is a new loadable `strftime' builtin.
-
-c.  New variable, COMP_WORDBREAKS, which controls the readline completer's
-    idea of word break characters.
-
-d.  The `type' builtin no longer reports on aliases unless alias expansion
-    will actually be performed.    
-
-e.  HISTCONTROL is now a colon-separated list of values, which permits
-    more extensibility and backwards compatibility.
-
-f.  HISTCONTROL may now include the `erasedups' option, which causes all lines
-    matching a line being added to be removed from the history list.
-
-g.  `configure' has a new `--enable-multibyte' argument that permits multibyte
-    character support to be disabled even on systems that support it.
-
-h.  New variables to support the bash debugger:  BASH_ARGC, BASH_ARGV,
-    BASH_SOURCE, BASH_LINENO, BASH_SUBSHELL, BASH_EXECUTION_STRING,
-    BASH_COMMAND
-
-i.  FUNCNAME has been changed to support the debugger: it's now an array
-    variable.
-
-j.  for, case, select, arithmetic commands now keep line number information
-    for the debugger.
-
-k.  There is a new `RETURN' trap executed when a function or sourced script
-    returns (not inherited child processes; inherited by command substitution
-    if function tracing is enabled and the debugger is active).
-
-l.  New invocation option:  --debugger.  Enables debugging and turns on new
-    `extdebug' shell option.
-
-m.  New `functrace' and `errtrace' options to `set -o' cause DEBUG and ERR
-    traps, respectively, to be inherited by shell functions.  Equivalent to
-    `set -T' and `set -E' respectively.  The `functrace' option also controls
-    whether or not the DEBUG trap is inherited by sourced scripts.
-
-n.  The DEBUG trap is run before binding the variable and running the action
-    list in a `for' command, binding the selection variable and running the
-    query in a `select' command, and before attempting a match in a `case'
-    command.
-
-o.  New `--enable-debugger' option to `configure' to compile in the debugger
-    support code.
-
-p.  `declare -F' now prints out extra line number and source file information
-    if the `extdebug' option is set.
-
-q.  If `extdebug' is enabled, a non-zero return value from a DEBUG trap causes
-    the next command to be skipped, and a return value of 2 while in a
-    function or sourced script forces a `return'.
-
-r.  New `caller' builtin to provide a call stack for the bash debugger.
-
-s.  The DEBUG trap is run just before the first command in a function body is
-    executed, for the debugger.
-
-t.  `for', `select', and `case' command heads are printed when `set -x' is
-    enabled.
-
-u.  There is a new {x..y} brace expansion, which is shorthand for {x.x+1,
-    x+2,...,y}.  x and y can be integers or single characters; the sequence
-    may ascend or descend; the increment is always 1.
-
-v.  New ksh93-like ${!array[@]} expansion, expands to all the keys (indices)
-    of array.
-
-w.  New `force_fignore' shopt option; if enabled, suffixes specified by
-    FIGNORE cause words to be ignored when performing word completion even
-    if they're the only possibilities.
-
-x.  New `gnu_errfmt' shopt option; if enabled, error messages follow the `gnu
-    style' (filename:lineno:message) format.
-
-y.  New `-o bashdefault' option to complete and compgen; if set, causes the
-    whole set of bash completions to be performed if the compspec doesn't
-    result in a match.
-
-z.  New `-o plusdirs' option to complete and compgen; if set, causes directory
-    name completion to be performed and the results added to the rest of the
-    possible completions.
-
-aa. `kill' is available as a builtin even when the shell is built without
-    job control.
-
-bb. New HISTTIMEFORMAT variable; value is a format string to pass to
-    strftime(3).  If set and not null, the `history' builtin prints out
-    timestamp information according to the specified format when displaying
-    history entries.  If set, bash tells the history library to write out
-    timestamp information when the history file is written.
-
-cc. The [[ ... ]] command has a new binary `=~' operator that performs
-    extended regular expression (egrep-like) matching.
-
-dd. `configure' has a new `--enable-cond-regexp' option (enabled by default)
-    to enable the =~ operator and regexp matching in [[ ... ]].
-
-ee. Subexpressions matched by the =~ operator are placed in the new
-    BASH_REMATCH array variable.
-
-ff. New `failglob' option that causes an expansion error when pathname
-    expansion fails to produce a match.
-
-gg. New `set -o pipefail' option that causes a pipeline to return a failure
-    status if any of the processes in the pipeline fail, not just the last
-    one.
-
-4.  New Features in Readline
-
-a.  History expansion has a new `a' modifier equivalent to the `g' modifier
-    for compatibility with the BSD csh.
-
-b.  History expansion has a new `G' modifier equivalent to the BSD csh `g'
-    modifier, which performs a substitution once per word.
-
-c.  All non-incremental search operations may now undo the operation of
-    replacing the current line with the history line.
-
-d.  The text inserted by an `a' command in vi mode can be reinserted with
-    `.'.
-
-e.  New bindable variable, `show-all-if-unmodified'.  If set, the readline
-    completer will list possible completions immediately if there is more
-    than one completion and partial completion cannot be performed.
-
-f.  There is a new application-callable `free_history_entry()' function.
-
-g.  History list entries now contain timestamp information; the history file
-    functions know how to read and write timestamp information associated
-    with each entry.
-
-h.  Four new key binding functions have been added:
-
-       rl_bind_key_if_unbound()
-       rl_bind_key_if_unbound_in_map()
-       rl_bind_keyseq_if_unbound()
-       rl_bind_keyseq_if_unbound_in_map()
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.05b-release,
-and the previous version, bash-2.05b-beta2.
-
-1.  Changes to Bash
-
-a.  Fixed an off-by-one error in the function that translates job
-    specifications.
-
-b.  Note that we're running under Emacs and disable line editing if
-    $EMACS == `t'.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.05b-beta2,
-and the previous version, bash-2.05b-beta1.
-
-1.  Changes to Bash
-
-a.  Fixed the /= and %= arithmetic operators to catch division by zero.
-
-b.  Added putenv, setenv, unsetenv to getenv replacement for completeness.
-
-c.  Fixed a bug that could cause the -O expand_aliases invocation option
-    to not take effect.
-
-d.  Fixed a problem with process substitution that resulted in incorrect
-    behavior when the number of process substitutions in an individual
-    command approached 64.
-
-2.  Changes to Readline
-
-a.  Fixed a problem with backward-char-search when on a system with support
-    for multibyte characters when running in a locale without any multibyte
-    characters.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.05b-beta1,
-and the previous version, bash-2.05b-alpha1.
-
-1.  Changes to Bash
-
-a.  Fixed a problem when parsing a POSIX.2 character class name while
-    evaluating a bracket expression containing multibyte characters.
-
-b.  Changed the help text for `bind' to make it clear that any command
-    that may be placed in ~/.inputrc is a valid argument to `bind'.
-
-c.  Added `help' builtin entries for `((', `[[', and arithmetic for.
-
-d.  malloc updated again:
-       o slightly better overflow and underflow detection by putting the
-         chunk size at the beginning and end of the chunk and making
-         sure they match in free/realloc
-       o partial page allocated to make things page-aligned no longer
-         completely wasted
-       o block coalescing now enabled by default
-       o splitting and coalescing enabled for 32-byte chunks, the most
-         common size requested
-       o fixed a problem that resulted in spurious underflow messages and
-         aborts
-       o bin sizes are precomputed and stored in an array rather than
-         being computed at run time
-       o malloc will return memory blocks back to the system if the block
-         being freed is at the top of the heap and of sufficient size to
-         make it worthwhile
-       o malloc/free/realloc now inline memset instead of calling the
-         libc function; uses Duff's device for good performance
-
-e.  Check for getservent(); make the service name completion code dependent
-    on its presence.
-
-f.  Changed the readline callback that executes a command bound to a key
-    sequence to not save the executed command on the history list and to
-    save and restore the parsing state.
-
-g.  Changes to lib/sh/snprintf.c:  fixed some bugs in the `g' and `G'
-    floating point format display; implemented the "'" flag character
-    that turns on thousands' grouping; fixed behavior on systems where
-    MB_CUR_MAX does not evaluate to a constant.
-
-h.  The `unset' builtin no longer returns a failure status when asked to
-    unset a previously-unset variable or function.
-
-i.  Changes to the build system to make it easier to cross-compile bash
-    for different systems.
-
-j.  Added `,' to  the characters that are backslash-escaped during filename
-    completion, to avoid problems with complete-into-braces and RCS filenames
-    containing commas.
-
-k.  Some changes to the multibyte character support code to avoid many calls
-    to strlen().
-
-l.  Bash now correctly honors setting LANG to some value when LC_ALL does not
-    already have a value.
-
-m.  Fixed a bug that could cause SIGSEGV when processing nested traps with
-    trap handlers.
-
-n.  The `source/.' builtin now restores the positional parameters when it
-    returns unless they were changed using the `set' builtin during the file's
-    execution.
-
-o.  Fixed a bug that caused a syntax error when a command was terminated by
-    EOF.
-
-2.  New Features in Bash
-
-a.  There is now support for placing the long help text into separate files
-    installed into ${datadir}/bash.  Not enabled by default; can be turned
-    on with `--enable-separate-helpfiles' option to configure.
-
-b.  All builtins that take operands accept a `--' pseudo-option, except
-    `echo'.
-
-c.  The `echo' builtin now accepts \0xxx (zero to three octal digits following
-    the `0') in addition to \xxx (one to three octal digits) for SUSv3/XPG6/
-    POSIX.1-2001 compliance.
-
-3.  Changes to Readline
-
-a.  Fixed a small problem in _rl_insert_char with multibyte characters.
-
-b.  Fixes from IBM for line wrapping problems when using multibyte characters.
-
-c.  Fixed a problem which caused the display to be messed up when the last
-    line of a multi-line prompt (possibly containing invisible characters)
-    was longer than the screen width.
-
-d.  Fixed a problem with the vi-mode `r' command that ocurred on systems with
-    support for multibyte characters when running in a locale without any
-    multibyte characters.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.05b-alpha1,
-and the previous version, bash-2.05a-release.
-
-1.  Changes to Bash
-
-a.  Some changes to work around inlining differences between compilers.
-
-b.  Added more prototypes for internal shell typedefs, to catch argument
-    passing errors when using pointers to functions.
-
-c.  The `cd' builtin now fails in posix mode when a valid directory cannot be
-    constructed from a relative pathname argument and the $PWD using pathname
-    canonicalization, and the -P option has not been supplied.  Previously,
-    the shell would attempt to use what the user typed, leading to weird
-    values for $PWD and discrepancies between the value of $PWD and the
-    actual working directory.
-
-d.  The `cd' builtin now resets $PWD when canonicalization fails but a chdir
-    to the pathname passed as an argument succeeds (when not in posix mode).
-
-e.  The `fc' builtin has been fixed, as POSIX requires, to use the closest
-    history position in range when given an out-of-range argument.
-
-f.  The history file loading code was changed to allow lines to be saved in
-    the history list from the shell startup files.
-
-g.  `history -s args' now works better in compound commands.
-
-h.  The tilde expansion code was fixed to better recognize when it's being
-    invoked in an assignment context, which enables expansion after `='
-    and `:'.
-
-i.  Fixed the command name completion code so a slash is no longer appended
-    to a single match if there happens to be a directory with that name in
-    $PWD.
-
-j.  Fixed compound array assignment to no longer perform alias expansion, to
-    allow reserved words as array members, and to not produce extra output
-    when the `-v' option had been enabled.
-
-k.  Fixed the programmable completion code to better handle newlines in lists
-    of possible completions (e.g., `complete -W').
-
-l.  Removed the reserved words from the `bash-builtins' manual page.
-
-m.  Parser error reporting now attempts to do a better job of identifying the
-    token in error rather than doing straight textual analysis.
-
-n.  Fixes for Inf/NaN, locales, wide/multibyte characters and zero-length
-    arguments in the library snprintf(3) replacement.
-
-o.  `read -e' no longer does command name completion on the first word on
-    the line being read.
-
-p.  `select' now returns failure if the read of the user's selection fails.
-
-q.  Fixed a bug that could cause a core dump when setting $PIPESTATUS.
-
-r.  Fixes to not allocate so many job slots when the shell is running a loop
-    with job control enabled in a subshell of an interactive shell.
-
-s.  Fixed a bug in the trap code that caused traps to be inherited by
-    command substitutions in some cases.
-
-t.  Fixed a bug that could cause alias expansion to inappropriately expand
-    the word following the alias.
-
-u.  Fixed a bug in the `kill' builtin that mishandled negative pid arguments.
-
-v.  The parser is less lenient when parsing assignment statements where the
-    characters before the `=' don't comprise a valid identifier.
-
-w.  The arithmetic expression evaluation code now honors the setting of the
-    `-u' option when expanding variable names.
-
-x.  Fixed the arithmetic evaluation code to allow array subscripts to be
-    assigned (`let b[7]=42') and auto-incremented and auto-decremented
-    (e.g., b[7]++).
-
-y.  Reimplemented the existing prompt string date and time expansions using
-    strftime(3), which changed the output of \@ in some locales.
-
-z.  Fixed a bug that could cause a core dump when a special shell variable
-    (like RANDOM) was converted to an array with a variable assignment.
-
-aa. Fixed a bug that would reset the handler for a signal the user had
-    trapped to a function that would exit the shell when setting the exit
-    trap in a non-interactive shell.
-
-bb. Changed the execve(2) wrapper code to check whether or not a failing
-    command is a directory before looking at whether a `#!' interpreter
-    failed for some reason.
-
-cc. Fixed a bug in the command printing code so it no longer inserts a `;'
-    after a newline, which produces a syntax error when reused as input.
-
-dd. The code that expands $PS4 no longer inherits the `-x' flag.
-
-ee. The bash-specific completion functions may now take advantage of the
-    double-TAB and M-?  features of the standard readline completion
-    functions.
-
-ff. The mail checking code no longer prints a message if the checked file's
-    size has not increased, even if the access time is less than the modification time.
-
-gg. Rewrote the variable symbol table code: there is now a stack of
-    contexts, each possibly including a separate symbol table; there can
-    be more than one temporary environment supplied to nested invocations
-    of `./source'; the temporary environments no longer require so much
-    special-case code; shell functions now handle the temporary environment
-    and local variables more consistently; function scope exit is faster now
-    that the entire symbol table does not have to be traversed to dispose of
-    local variables; it is now easier to push vars from the temporary
-    environment to the shell's variable table in posix mode; some duplicated
-    code has been removed.
-
-hh. Regularized the error message printing code; builtin_error is now called
-    more consistently, and common error message strings are handled by small
-    functions.  This should make eventual message translation easier.
-
-ii. Error messages now include the line number in a script when the shell
-    is not interactive.
-
-jj. Array subscript expansion now takes place even when the array variable is
-    unset, so side effects will take place.
-
-kk. Fixed a bug in the SICGHLD child-reaping code so that it won't find
-    jobs already marked as terminated if the OS reuses pids quickly enough.
-
-ll. Fixed a bug that could cause a signal to not interrupt the `wait'
-    builtin while it was waiting for a background process to terminate.
-
-mm. A couple of changes to make it easier for multiple shells to share history
-    files using `history -n', `history -r', and `history -w'.
-
-nn. The `getopts' builtin always increments OPTIND to point to the next
-    option to be handled when an option is returned, whether it's valid
-    or not, as POSIX 1003.x-2001 requires.
-
-oo. Changed some parts of the expansion code to avoid allocating and
-    immediately freeing memory without using the results for anything.
-
-pp. The shell now keeps track of $IFS internally, updating its internal map
-    each time the variable is assigned a new value (or at local scope exit).
-    This saves thousands of hash lookups for IFS, which, while individually
-    cheap, add up.
-
-qq. Rewrote the hash table code:  searching and insertion are much faster now,
-    and it uses a better string hashing function; augmented the function
-    interface to simplify other parts of the code and remove duplicated code
-
-rr. The shell now uses a simple, generic `object cache' for allocating and
-    caching words and word lists, which were the major users of
-    malloc/free.
-
-ss. Fixed the assignment statement parsing code to allow whitespace and
-    newlines in subscripts when performing array element assignment.
-
-tt. The shell now issues many fewer calls to sigprocmask and other signal
-    masking system calls.
-
-uu. Fixed the `test' and conditional command file comparison operators to
-    work right when one file has a non-positive timestamp and the other
-    does not exist.
-
-vv. Fixed some cases where the special characters '\001' and '\177' in the
-    values of variables or positional parameters caused incorrect expansion
-    results.
-
-2.  Changes to Readline
-
-a.  Fixed output of comment-begin character when listing variable values.
-
-b.  Added some default key bindings for common escape sequences produced by
-    HOME and END keys.
-
-c.  Fixed the mark handling code to be more emacs-compatible.
-
-d.  A bug was fixed in the code that prints possible completions to keep it
-    from printing empty strings in certain circumstances.
-
-e.  Change the key sequence printing code to print ESC as M\- if ESC is a
-    meta-prefix character -- it's easier for users to understand than \e.
-
-f.  Fixed unstifle_history() to return values that match the documentation.
-
-g.  Fixed the event loop (rl_event_hook) to handle the case where the input
-    file descriptor is invalidated.
-
-h.  Fixed the prompt display code to work better when the application has a
-    custom redisplay function.
-
-i.  Changes to make reading and writing the history file a little faster, and
-    to cope with huge history files without calling abort(3) from xmalloc.
-
-j.  The vi-mode `S' and `s' commands are now undone correctly.
-
-3.  New Features in Bash
-
-a.  If set, TMOUT is the default timeout for the `read' builtin.
-
-b.  `type' has two new options:  `-f' suppresses shell function lookup, and
-    `-P' forces a $PATH search.
-
-c.  New code to handle multibyte characters.
-
-d.  `select' was changed to be more ksh-compatible, in that the menu is
-    reprinted each time through the loop only if REPLY is set to NULL.
-    The previous behavior is available as a compile-time option.
-
-e.  `complete -d' and `complete -o dirnames' now force a slash to be
-    appended to names which are symlinks to directories.
-
-f.  There is now a bindable edit-and-execute-command readline command,
-    like the vi-mode `v' command, bound to C-xC-e in emacs mode.
-
-g.  Added support for ksh93-like [:word:] character class in pattern matching.
-
-h.  The  $'...' quoting construct now expands \cX to Control-X.
-
-i.  A new \D{...} prompt expansion; passes the `...' to strftime and inserts
-    the result into the expanded prompt.
-
-j.  The shell now performs arithmetic in the largest integer size the
-    machine supports (intmax_t), instead of long.
-
-k.  If a numeric argument is supplied to one of the bash globbing completion
-    functions, a `*' is appended to the word before expansion is attempted.
-
-l.  The bash globbing completion functions now allow completions to be listed
-    with double tabs or if `show-all-if-ambiguous' is set.
-
-m.  New `-o nospace' option for `complete' and `compgen' builtins; suppresses
-    readline's appending a space to the completed word.
-
-n.  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).
-
-p.  There is a new configuration option `--enable-mem-scramble', controls
-    bash malloc behavior of writing garbage characters into memory at
-    allocation and free time.
-
-q.  The `complete' and `compgen' builtins now have a new `-s/-A service'
-    option to complete on names from /etc/services.
-
-r.  `read' has a new `-u fd' option to read from a specified file descriptor.
-
-s.  Fix the completion code so that expansion errors in a directory name
-    don't cause a longjmp back to the command loop.
-
-t.  Fixed word completion inside command substitution to work a little more
-    intuitively.
-
-u.  The `printf' %q format specifier now uses $'...' quoting to print the
-    argument if it contains non-printing characters.
-
-v.  The `declare' and `typeset' builtins have a new `-t' option.  When applied
-    to functions, it causes the DEBUG trap to be inherited by the named
-    function.  Currently has no effect on variables.
-
-w.  The DEBUG trap is now run *before* simple commands, ((...)) commands,
-    [[...]] conditional commands, and for ((...)) loops.
-
-x.  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.
-
-y.  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.  Code
-    from Gary Vaughan.
-
-z.  New [n]<&word- and [n]>&word- redirections from ksh93 -- move fds (dup
-    and close).
-
-aa. There is a new `-l' invocation option, equivalent to `--login'.
-
-bb. The `hash' builtin has a new `-l' option to list contents in a reusable
-    format, and a `-d' option to remove a name from the hash table.
-
-4.  New Features in Readline
-
-a.  Support for key `subsequences':  allows, e.g., ESC and ESC-a to both
-    be bound to readline functions.  Now the arrow keys may be used in vi
-    insert mode.
-
-b.  When listing completions, and the number of lines displayed is more than
-    the screen length, readline uses an internal pager to display the results.
-    This is controlled by the `page-completions' variable (default on).
-
-c.  New code to handle editing and displaying multibyte characters.
-
-d.  The behavior introduced in bash-2.05a of deciding whether or not to
-    append a slash to a completed name that is a symlink to a directory has
-    been made optional, controlled by the `mark-symlinked-directories'
-    variable (default is the 2.05a behavior).
-
-e.  The `insert-comment' command now acts as a toggle if given a numeric
-    argument:  if the first characters on the line don't specify a
-    comment, insert one; if they do, delete the comment text
-
-f.  New application-settable completion variable:
-    rl_completion_mark_symlink_dirs, allows an application's completion
-    function to temporarily override the user's preference for appending
-    slashes to names which are symlinks to directories.
-
-g.  New function available to application completion functions:
-    rl_completion_mode, to tell how the completion function was invoked
-    and decide which argument to supply to rl_complete_internal (to list
-    completions, etc.).
-
-h.  Readline now has an overwrite mode, toggled by the `overwrite-mode'
-    bindable command, which could be bound to `Insert'.
-
-i.  New application-settable completion variable:
-    rl_completion_suppress_append, inhibits appending of
-    rl_completion_append_character to completed words.
-
-j.  New key bindings when reading an incremental search string:  ^W yanks
-    the currently-matched word out of the current line into the search
-    string; ^Y yanks the rest of the current line into the search string,
-    DEL or ^H deletes characters from the search string.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.05a-release,
-and the previous version, bash-2.05a-rc1.
-
-1.  Changes to Bash
-
-a.  Fixed the `printf' builtin so that the variable name supplied as an
-    argument to a %n conversion must be a valid shell identifier.
-
-b.  Improved the random number generator slightly.
-
-c.  Changes to configuration to not put -I/usr/include into $CFLAGS, since
-    it messes up some includes.
-
-d.  Corrected description of POSIXLY_CORRECT in man page and info manual.
-
-e.  Fixed a couple of cases of incorrect function prototypes that sneaked
-    through and caused compilation problems.
-
-f.  A few changes to avoid potential core dumps in the programmable completion
-    code.
-
-g.  Fixed a configure problem that could cause a non-existent file to show
-    up in LIBOBJS.
-
-h.  Fixed a configure problem that could cause siglist.o to not be built when
-    required.
-
-i.  Changes to the strtoimax and strtoumax replacement functions to work
-    around buggy compilers.
-
-j.  Fixed a problem with the snprintf replacement function that could
-    potentially cause a core dump.
-
-2.  Changes to Readline
-
-a.  Fixed a locale-specific problem in the vi-mode `goto mark' command.
-
-b.  Fixed Makefile to not put -I/usr/include into CFLAGS, since it can cause
-    include file problems.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.05a-rc1,
-and the previous version, bash-2.05a-beta1.
-
-1.  Changes to Bash
-
-a.  Fixed the snprintf replacement to correctly implement the `alternate form'
-    of the %g and %G conversions.
-
-b.  Fixed snprintf to correctly handle the optional precision with the %g and
-    %G conversions.
-
-c.  Fixed the arithmetic evaluation code to correct the values of `@' and `_'
-    when translating base-64 constants (they were backwards).
-
-d.  New library functions for formatting long and long long ints.
-
-e.  Fixed a few places where negative array subscripts could have occurred,
-    mostly as the result of systems using signed characters.
-
-f.  Fixed a few places that assumed a pid_t was no wider than an int.
-
-g.  Fixed the `maildir' mail checking code to work on systems where a
-    `struct stat' doesn't include an `st_blocks' member.
-
-h.  Fixed snprintf to make `unsigned long long' conversion formats (%llu)
-    work better.
-
-i.  Fixed snprintf to not print a sign when asked to do an unsigned conversion.
-
-j.  Made configure changes to avoid compiling empty source files in lib/sh.
-
-k.  New replacement functions (if necessary) for strtoull, strtoll, strtoimax,
-    strtoumax.
-
-l.  The `printf' builtin now handles the `ll' and `j' length modifiers
-    directly, since they can affect the type and width of the argument
-    passed to printf(3).
-
-m.  Renamed a number of the bash-specific autoconf macros in aclocal.m4 to
-    have more sytematic naming, with accompanying changes to configure.in.
-
-n.  Fixed snprintf to handle long doubles and the %a/%A conversions by
-    falling back to sprintf, as long as sprintf supports them.
-
-o.  Fixed return value from vsnprintf/snprintf to be the number of characters
-    that would have been printed, even if that number exceeds the buffer
-    size passed as an argument.
-
-p.  Bash no longer attempts to define its own versions of some ctype macros
-    if they are implemented as functions in libc but not as macros in
-    <ctype.h>.
-
-q.  Changed the variable printing code (used by `set', `export', etc.) to
-    not use the $'...' syntax when in posix mode, since that caused
-    interoperability problems with other shells (most notably with autoconf).
-    When not in posix mode, it uses $'...' if the string to be printed
-    contains non-printing characters and regular single quotes otherwise.
-
-r.  snprintf now recognizes the %F conversion.
-
-s.  Fixed a bug that could cause the wrong status to be returned by a shell
-    function when the shell is compiled without job control and a null
-    command containing a command substutition was executed in the function.
-
-t.  When in posix mode, the default value for MAILCHECK is 600.
-
-u.  Bash only initializes FUNCNAME, GROUPS, and DIRSTACK as special variables
-    if they're not in the initial environment.
-
-v.  If SECONDS appears in the initial environment with a valid integer value,
-    bash uses that as the starting value, as if an assignment had been
-    performed.
-
-w.  Bash no longer auto-exports HOME, PATH, SHELL, or TERM, even though it
-    gives them default values if they don't appear in the initial environment.
-
-x.  Bash no longer auto-exports HOSTNAME, HOSTTYPE, MACHTYPE, or OSTYPE,
-    even if it assigns them default values.
-
-y.  Bash no longer removes the export attribute from SSH_CLIENT or SSH2_CLIENT
-    if they appear in the initial environment.
-
-z.  Bash no longer attempts to discover if it's being run by sshd in order to
-    run the startup files.  If the SSH_SOURCE_BASHRC is uncommented in
-    config-top.h it will attempt to do so as previously, but that's commented
-    out in the distributed version.
-
-aa. Fixed a typo in the code that tests for LC_NUMERIC.
-
-bb. The POSIXLY_CORRECT shell variable and its effects are now documented.
-
-cc. Some changes to several of the support shell scripts included in the
-    definitions to try to avoid race conditions and attacks.
-
-dd. Several changes to avoid warnings from `gcc -Wall'.
-
-ee. Fixed a problem with the `unset' builtin that could cause incorrect
-    results if asked to unset a variable and an array subscript in the
-    same command.
-
-ff. A few changes to the shell's temporary file creation code to avoid
-    potential file descriptor leaks and to prefer the system's idea of
-    the temporary directory to use.
-
-gg. Fixes to build with the C alloca in lib/malloc/alloca.c if the system
-    requires it but the shell has been configured --without-bash-malloc.
-
-hh. Updated the documentation to note that only interactive shells resend
-    SIGHUP to all jobs before exiting.
-
-ii. Fixes to only pass unquoted tilde words to tilde_expand, rather than
-    rely on tilde_expand or getpwnam(3) to handle the quotes (MacOS 10.x
-    will remove backslashes in any login name passed to getpwnam(3)).
-
-jj. Small change from Paul Eggert to make LINENO right in commands run with
-    `bash -c'.
-
-2.  New Features in Bash
-
-a.  The `printf' builtin now handles the %a and %A conversions if they're
-    implemented by printf(3).
-
-b.  The `printf' builtin now handles the %F conversion (just about like %f).
-
-c.  The `printf' builtin now handles the %n conversion like printf(3).  The
-    corresponding argument is the name of a shell variable to which the
-    value is assigned.
-
-3.  Changes to Readline
-
-a.  Fixed a few places where negative array subscripts could have occurred.
-
-b.  Fixed the vi-mode code to use a better method to determine the bounds of
-    the array used to hold the marks.
-
-c.  Fixed the defines in chardefs.h to work better when chars are signed.
-
-d.  Fixed configure.in to use the new names for bash autoconf macros.
-
-e.  Readline no longer attempts to define its own versions of some ctype
-    macros if they are implemented as functions in libc but not as macros in
-    <ctype.h>.
-
-f.  Fixed a problem where rl_backward could possibly set point to before
-    the beginning of the line.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.05a-beta1,
-and the previous version, bash-2.05a-alpha1.
-
-1.  Changes to Bash
-
-a.  Fixed a bug in the evalution of arithmetic `for' statements when the
-    expanded expression is NULL.
-
-b.  Fixed an unassigned variable problem in the redirection printing code.
-
-c.  Added more prototypes to extern function declarations in the header
-    files and to static function declarations in C source files.
-
-d.  Make sure called functions have a prototype in scope, to get the arguments
-    and return values right instead of casting.  Removed extern function
-    declarations from C source files that were already included in header
-    files.
-
-e.  Changed some function arguments to use function typedefs in general.h so
-    the prototypes can be checked.  The only use of Function and VFunction
-    now is for unwind-protects.
-
-f.  More const changes to function arguments and appropriate variables.
-
-g.  Changed the mail checking support to handle `maildir'-style mail
-    directories.
-
-h.  Augmented the bash malloc to pass in the file and line number information
-    for each malloc, realloc, and free.  This should result in better error
-    messages.
-
-i.  The `old' gnu malloc is no longer a configuration option.
-
-j.  Augmented the bash malloc with optional tracing and registering allocated
-    and freed memory.
-
-k.  Prompt string decoding now saves and restores the value of $? when it
-    expands the prompt string, so command substitutions don't change $?.
-
-i.  Array indices are now `long', since shell arithmetic is performed as long,
-    and the internal arrayind_t type is used consistently.
-
-j.  Some more `unsigned char *' fixes from Paul Eggert.
-
-k.  Fixed a bad call to builtin_error that could cause core dumps when making
-    local variables.
-
-l.  `return' may no longer be used to terminate a `select' command, for
-    compatibility with ksh.
-
-m.  Changed code that reads octal numbers to do a better job of detecting
-    overflows.
-
-n.  The time formatting code no longer uses absolute indices into a buffer,
-    because the buffer size changes depending on the size of a `time_t'.
-
-o.  `umask' now prints four digits when printing in octal mode, for
-    compatibility with other shells.
-
-p.  Lots of changes to the `printf' builtin from Paul Eggert:  it handles `L'
-    formats and long doubles better, and internal functions have been
-    simpified where appropriate.
-
-q.  Some `time_t' fixes for machines were a time_t is bigger than a long.
-
-r.  Replaced some bash-specific autoconf macros with standard equivalents.
-
-s.  Improvmed the code that constructs temporary filenames to make the
-    generated names a bit more random.
-
-t.  Added code that checks for ascii before calling any of the is* ctype
-    functions.
-
-u.  Changed some places where a `char' was used as an array subscript to use
-    `unsigned char', since a `char' can be negative if it's signed by default.
-
-v.  Lots of changes to the `ulimit' builtin from Paul Eggert to add support
-    for the new POSIX-200x RLIM_SAVED_CUR and RLIM_SAVED_MAX values and
-    simplify the code.
-
-w.  `ulimit' now prints the description of a resource in any error message
-    relating to fetching or setting that resource's limits.
-
-x.  The `snprintf' replacement now computes maximum values at compile
-    time rather than using huge constants for things like long long.
-
-y.  Interactive shells now ignore `set -n'.
-
-z.  Changed the malloc bookkeeping information so that it's now 8 bytes
-    instead of 12 on most 32-bit machines (saving 4 bytes per allocation),
-    restoring 8-byte alignment.
-
-aa. The malloc error reporting code now attempts to print the file and line
-    number of the call that caused the error.
-
-bb. Changed the redirection error reporting code to catch EBADF errors and
-    report the file descriptor number rather than the file being redirected
-    to or from (e.g., things like `exec 4242<x' where 4242 is an out-of-range
-    file descriptor).
-
-cc. `printf', `echo -e', and the $'...' code now process only two hex digits
-    after a `\x' escape sequence for compatibility with other shells, and
-    the documentation was changed to note that the octal and hex escape
-    sequences result in an eight-bit value rather than strict ASCII.
-
-2.  Changes to Readline
-
-a.  The completion code now attempts to do a better job of preserving the
-    case of the word the user typed if ignoring case in completions.
-
-b.  Readline defaults to not echoing the input and lets the terminal
-    initialization code enable echoing if there is a controlling terminal.
-
-c.  The key binding code now processes only two hex digits after a `\x'
-    escape sequence, and the documentation was changed to note that the
-    octal and hex escape sequences result in an eight-bit value rather
-    than strict ASCII.
-
-3.  New Features in Bash
-
-a.  The builtin `ulimit' now takes two new non-numeric arguments:  `hard',
-    meaning the current hard limit, and `soft', meaning the current soft
-    limit, in addition to `unlimited'
-
-b.  `ulimit' now prints the option letter associated with a particular
-    resource when printing more than one limit.
-
-c.  `ulimit' prints `hard' or `soft' when a value is not `unlimited' but is
-    one of RLIM_SAVED_MAX or RLIM_SAVED_CUR, respectively.
-
-4.  New Features in Readline
-
-a.  New bindable variable `history-preserve-point'.  If set, the history
-    code attempts to place the user at the same location on each history
-    line retrived with previous-history or next-history.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.05a-alpha1,
-and the previous version, bash-2.05-release.
-
-1.  Changes to Bash
-
-a.  Better checks in the redirection code for write errors.
-
-b.  bashbug now uses $TMPDIR, defaulting to /tmp, and uses mktemp(1) more
-    portably.
-
-c.  System-specific configuration changes for:  Interix, OpenBSD, FreeBSD,
-    MacOS X.
-
-d.  Some more `const' cleanups through the code.
-
-e.  Fixed a typo in the /dev/fd redirection code, better checks for valid
-    numeric fds in /dev/fd.
-
-f.  Fixed many parts of the shell to handle integer overflow more gracefully
-    and to do more stringent checks for valid numbers.
-
-g.  Fixed mksignames to include config.h.
-
-h.  Fixed an uninitialized variable problem that could cause the shell to core
-    dump when replacing characters in a string.
-
-i.  New mechanism for updating the patch level when official patches are
-    released (patchlevel.h).
-
-j.  configure.in changed to no longer require external files _distribution and
-    _patchlevel.
-
-k.  Fixed non-interactive shell initialization problem when bash started as
-    `bash -i filename'.
-
-l.  Fixed printf builtin conversion error handling to be POSIX.2-conformant.
-
-m.  autoconf-2.52 is now used to build configure; autoconf-2.50 or newer is
-    required.  Some of the bash-specific macros were removed, since they are
-    now standard.
-
-n.  Startup files and files read with source or `.' are no longer required to
-    be regular files.
-
-o.  Fixed core dump in builtin printf when user-supplied precision or field
-    width is 0.
-
-p.  Fixed builtin printf to treat a negative field width as a positive field
-    width with left-justification.
-
-r.  New unwind-protect implementation from Paul Eggert.
-
-s.  Fixed an inadvertently-unclosed comment in the bash completion code that
-    caused programmable completions to not add trailing slashes or spaces to
-    completions.
-
-t.  Fixed the process substitution code to cope better when stdin is closed.
-
-v.  Fixes, mostly from Paul Eggert, for a few possible buffer overflows in
-    the shell.
-
-w.  Fixes from Paul Eggert to avoid most of the type casts in the shell code,
-    and use more appropriate types for a number of variables.
-
-x.  Command substition no longer inherits the DEBUG trap.
-
-y.  Some fixes to the process substition code on machines without /dev/fd so
-    that named pipes are not removed inappropriately.
-
-z.  The loadable `getconf' builtin is now much more complete, and will become
-    part of the shell in the future.
-
-aa. The select command no longer terminates on a `return', so it can be used
-    to return from an enclosing function (as ksh does it).
-
-bb. Fixed the extended pattern matching code to behave better when presented
-    with incorrectly-formed patterns.
-
-cc. Some changes were made with the intent of making cross-compilation easier.
-
-dd. The network code (/dev/tcp and /dev/udp redirections) uses getaddrinfo(3)
-    if it's available, which adds support for IPv6.
-
-ee. Subshells of login shells no longer source ~/.bash_logout when they exit.
-
-ff. Fixes so that subshells don't exit inappropriately if the -e option has
-    been set.
-
-gg. Restricted shells no longer allow functions to be exported.
-
-hh. Changes to the pattern matching code so extended pattern matching works
-    on systems with deficient shared library implementations, like MacOS X.
-
-ii. Better error messages when a script with a leading `#!interp' fails
-    to execute because of problems with `interp'.
-
-jj. Fixed `compgen' to handle the `-o default' option better.
-
-kk. Fixed the job control code to force an asynchronous process's standard
-    input to /dev/null only if job control is not active.
-
-ll. Fixed a possible infinite recursion problem when `fc ""=abc' (a null
-    pattern) is used to re-execute a previous command.
-
-mm. Fixed `declare [-a] var=value' to assign VALUE to element 0 if VAR is an
-    array variable.  Similarly for `declare [-a] var[N]=value'.  This is like
-    ksh93.
-
-nn. Fixed a bug that caused `read -a aname' to work even if ANAME had been
-    declared readonly.
-
-oo. Fixed a possible integer overflow problem when constructing names for
-    temporary files.
-
-2.  New Features in Bash
-
-a.  Added support for DESTDIR installation root prefix, so you can do a
-    `make install DESTDIR=bash-root' and do easier binary packaging.
-
-b.  Added support for builtin printf "'" flag character as per latest POSIX
-    drafts.
-
-c.  Support for POSIX.2 printf(1) length specifiers `j', `t', and `z' (from
-    ISO C99).
-
-d.  New autoconf macro, RL_LIB_READLINE_VERSION, for use by other applications
-    (bash doesn't use very much of what it returns).
-
-e.  `set [-+]o nolog' is recognized as required by the latest POSIX drafts,
-    but ignored.
-
-f.  New read-only `shopt' option:  login_shell.  Set to non-zero value if the
-    shell is a login shell.
-
-g.  New `\A' prompt string escape sequence; expands to time in 24 HH:MM format.
-
-h.  New `-A group/-g' option to complete and compgen; does group name
-    completion.
-
-i.  New `-t' option to `hash' to list hash values for each filename argument.
-
-j.  New [-+]O invocation option to set and unset `shopt' options at startup.
-
-k.  configure's `--with-installed-readline' option now takes an optional
-    `=PATH' suffix to set the root of the tree where readline is installed
-    to PATH.
-
-l.  The ksh-like `ERR' trap has been added.  The `ERR' trap will be run
-    whenever the shell would have exited if the -e option were enabled.
-    It is not inherited by shell functions.
-
-m.  `readonly', `export', and `declare' now print variables which have been
-    given attributes but not set by assigning a value as just a command and
-    a variable name (like `export foo') when listing, as the latest POSIX
-    drafts require.
-
-n.  `bashbug' now requires that the subject be changed from the default.
-
-o.  configure has a new `--enable-largefile' option, like other GNU utilities.
-
-p.  `for' loops now allow empty word lists after `in', like the latest POSIX
-    drafts require.
-
-3.  Changes to Readline
-
-a.  More `const' and type casting fixes.
-
-b.  Changed rl_message() to use vsnprintf(3) (if available) to fix buffer
-    overflow problems.
-
-c.  The completion code no longer appends a `/' or ` ' to a match when
-    completing a symbolic link that resolves to a directory name, unless
-    the match does not add anything to the word being completed.  This
-    means that a tab will complete the word up to the full name, but not
-    add anything, and a subsequent tab will add a slash.
-
-d.  Fixed a trivial typo that made the vi-mode `dT' command not work.
-
-e.  Fixed the tty code so that ^S and ^Q can be inserted with rl_quoted_insert.
-
-f.  Fixed the tty code so that ^V works more than once.
-
-g.  Changed the use of __P((...)) for function prototypes to PARAMS((...))
-    because the use of __P in typedefs conflicted g++ and glibc.
-
-4.  New Features in Readline
-
-a.  Added extern declaration for rl_get_termcap to readline.h, making it a
-    public function (it was always there, just not in readline.h).
-
-b.  New #defines in readline.h:  RL_READLINE_VERSION, currently 0x0402,
-    RL_VERSION_MAJOR, currently 4, and RL_VERSION_MINOR, currently 2.
-
-c.  New readline variable:  rl_readline_version, mirrors RL_READLINE_VERSION.
-
-d.  New bindable boolean readline variable:  match-hidden-files.  Controls
-    completion of files beginning with a `.' (on Unix).  Enabled by default.
-
-e.  The history expansion code now allows any character to terminate a
-    `:first-' modifier, like csh.
-
-f.  The incremental search code remembers the last search string and uses
-    it if ^R^R is typed without a search string.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.05-release,
-and the previous version, bash-2.05-beta2.
-
-1.  Changes to Bash
-
-a.  Make sure we note that the first line of a multi-line command was not
-    saved in the history if the tests for HISTCONTROL succeed, but the
-    HISTIGNORE check fails.
-
-b.  Fixed a bug in the pattern matching code that caused `[' to be treated
-    as a special character inside a `[...]' bracket expression.
-
-c.  Fixed a bug in the pattern matching code that caused `]' to terminate
-    a bracket expression even if it was the first character after the `['
-    (or a leading `!' or `^').
-
-d.  Made a small change to report a more user-friendly error message if
-    execve(2) fails because of an error with the interpreter in a script
-    with a leading `#! interpreter'.
-
-e.  If the OS does not support an exec(2) magic number of `#!', make sure we
-    have a non-null interpreter name before attempting to execute it.
-
-f.  Fixed a bug that caused the shell process to end up in a different
-    process group than the controlling terminal if a job-control shell was
-    run with `exec' in the startup files.
-
-g.  When started in POSIX mode, either by `bash --posix', `bash -o posix', or
-    `sh', $SHELLOPTS includes `posix' and POSIXLY_CORRECT is set.
-
-h.  Fixed a problem that caused the `\W' prompt string escape sequence to
-    expand to nothing when $PWD was `//'.
-
-i.  The `bashbug' shell script no longer uses $(...) command substitution.
-
-j.  When `set' is invoked without options in POSIX mode, it no longer prints
-    the names and definitions of shell functions.
-
-2.  Changes to Readline
-
-a.  rl_set_paren_blink_timeout() is now documented.
-
-b.  Corrected history.3 man page: `$' is not in the default value of
-    history_word_delimiters.
-
-c.  If a hook function assigned to rl_event_hook sets rl_done to a non-zero
-    value, rl_read_key() now immediately returns '\n' (which is assumed to
-    be bound to accept-line).
-
-3.  New Features in Bash
-
-a.  The `>&word' redirection now works in POSIX mode as it does by default,
-    since POSIX.2 leaves it unspecified.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.05-beta2,
-and the previous version, bash-2.05-beta1.
-
-1.  Changes to Bash
-
-a.  Fixed a bug in the arithmetic evaluation code so that a^=b is supported.
-
-b.  Fixed startup so posixly_correct is retained across subshells begun to
-    execute scripts without a leading `#!'.
-
-c.  Fixed a bug that caused $(< file) to not work in a (...) subshell.
-
-d.  Added config support for Linux running on the IBM S390.
-
-e.  Fixed a bug that caused bash to get its input pointer out of sync when
-    reading commands through a pipe and running a command with standard
-    input redirected from a file.
-
-f.  Made a change so that command completion now makes about half as many
-    stat(2) calls when searching the $PATH.
-
-g.  Fixed a bug that caused variable assignments preceding `return' to not
-    be propagated to the shell environment in POSIX mode.
-
-h.  Fixed a bug with ${parameter[:]?word} -- tilde expansion was not performed
-    on `word'.
-
-i.  In POSIX mode, `break' and `continue' do not complain and return success
-    if called when the shell is not executing a loop.
-
-j.  Fixed `bash -o posix' to work the same as `bash --posix'.
-
-k.  Fixed a bug where variable assignments preceding `eval' or `source/.'
-    would not show up in the environment exported to subshells run by the
-    commands.
-
-l.  In POSIX mode, shells started to execute command substitutions inherit
-    the value of the `-e' option from their parent shell.
-
-m.  In POSIX mode, aliases are expanded even in non-interactive shells.
-
-n.  Changed some of the job control messages to display the text required by
-    POSIX.2 when the shell is in POSIX mode.
-
-o.  Fixed a bug in `test' that caused it to occasionally return incorrect
-    results when non-numeric arguments were supplied to `-t'.
-
-2.  Changes to Readline
-
-a.  Some changes were made to avoid gcc warnings with -Wall.
-
-b.  rl_get_keymap_by_name now finds keymaps case-insensitively, so
-    `set keymap EMACS' works.
-
-c.  The history file writing and truncation functions now return a useful
-    status on error.
-
-d.  Fixed a bug that could cause applications to dereference a NULL pointer
-    if a NULL second argument was passed to history_expand().
-
-3.  New Features in Bash
-
-a.  doc/readline.3 has been moved to the readline distribution.
-
-4.  New Features in Readline
-
-a.  New function, rl_get_screen_size (int *rows, int *columns), returns
-    readline's idea of the screen dimensions.
-
-b.  The timeout in rl_gather_tyi (readline keyboard input polling function)
-    is now settable via a function (rl_set_keyboard_input_timeout()).
-
-c.  Renamed the max_input_history variable to history_max_entries; the old
-    variable is maintained for backwards compatibility.
-
-d.  The list of characters that separate words for the history tokenizer is
-    now settable with a variable:  history_word_delimiters.  The default
-    value is as before.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.05-beta1,
-and the previous version, bash-2.05-alpha1.
-
-1.  Changes to Bash
-
-a.  Changes to allow shared library and object building on the GNU Hurd.
-
-b.  Fixes to the way exported functions are placed into the environment and
-    cached.
-
-c.  The globbing library once again respects locales when processing ranges
-    in bracket expressions while doing pattern matching.
-
-d.  System-specific configuration changes for:  Tru 64, Interix
-
-e.  Bashbug now uses /usr/bin/editor as one of the editing alternatives, and
-    will use mktemp(1) or tempfile(1), if present, for temporary file creation.
-
-f.  Bash no longer performs a binary file check on a script argument that's
-    really a tty (like /dev/fd/0 or /dev/stdin).
-
-g.  Fixed a bug in the execution of shell scripts that caused the effects of
-    $BASH_ENV to be undone in some cases.
-
-h.  Fixed several bugs that made `bash [-i] /dev/stdin' not work correctly.
-
-i.  Several changes to the job control code to avoid some signal state
-    manipulation.
-
-j.  The Bash malloc no longer blocks signals as often, which should make it
-    faster.
-
-k.  Fixed a parsing bug that did not allow backslash to escape a single quote
-    inside a $'...' construct.
-
-l.  Fixed a bug that caused things like ${var:=$'value'} to be parsed
-    incorrectly.  This showed up in newer versions of autoconf.
-
-m.  Fixed a bug in the bash-specific readline initialization that caused
-    key bindings to bash-specific function names appearing in .inputrc to
-    not be honored.
-
-n.  Bash now sets the file descriptor it uses to save the file descriptor
-    opened on a shell script to close on exec.
-
-o.  Fixed a bug in the prompt string decoding that caused it to misbehave
-    when presented an octal sequence of fewer than three characters.
-
-p.  Fixed the `test' builtin to return an error if `[' is supplied a single
-    argument that is not `]'.
-
-q.  Fixed a bug that caused subshells started to run executable shell scripts
-    without a leading `#!' to incorrectly inherit an argument list preceding
-    a shell builtin (like such a script called from a script sourced with `.',
-    where there were variable assignments preceding the `.' command)
-
-r.  Fixed a bug that caused changes to variables supplied in an assignment
-    statement preceding a shell builtin to not be honored (like a script
-    run with `.').
-
-s.  HOSTTYPE, OSTYPE, and MACHTYPE are set only if they do not have values
-    when the shell is started.
-
-t.  Fixed a bug that caused SIGINT to kill shell scripts after the script
-    called `wait'.
-
-u.  The `fc' builtin now tries to create its temporary files in the directory
-    named by $TMPDIR.
-
-v.  Bash no longer calls any Readline functions or uses any Readline variables
-    not declared in readline.h.
-
-w.  Fixed a bug that caused some substitutions involving $@ to not be split
-    correctly, especially expansions of the form ${paramterOPword}.
-
-x.  SSH2_CLIENT is now treated like SSH_CLIENT and not auto-exported if it
-    appears in the initial environment.
-
-y.  Fixed a couple of problems with shell scripts without a leading `#!'
-    being executed out of shell functions that could cause core dumps if
-    such a script attempted to execute `return'.
-
-z.  Fixed a problem with the `-nt' and `-ot' binary operators for the
-    `test/[' builtin and the `[[' conditional command that caused wrong
-    return values if one of the file arguments did not exist.
-
-aa. Fixed a bug that caused non-interactive shells which had previously
-    executed `shopt -s expand_aliases' to fail to expand aliases in a
-    command like `(command) &'.
-2.  Changes to Readline
-
-a.  Changes to make most (but not yet all -- there is still crlf()) of the
-    exported readline functions declared in readline.h have an rl_ prefix.
-
-b.  More `const' changes in function arguments, mostly for completion
-    functions.
-
-c.  Fixed a bug in rl_forward that could cause the point to be set to before
-    the beginning of the line in vi mode.
-
-d.  Fixed a bug in the callback read-char interface to make it work when a
-    readline function pushes some input onto the input stream with
-    rl_execute_next (like the incremental search functions).
-
-e.  Fixed a file descriptor leak in the history file manipulation code that
-    was tripped when attempting to truncate a non-regular file (like
-    /dev/null).
-
-f.  Some existing variables are now documented and part of the public
-    interface (declared in readline.h):  rl_explict_arg, rl_numeric_arg,
-    rl_editing_mode, rl_last_func.
-
-g.  Renamed rltty_set_default_bindings to rl_tty_set_default_bindings and
-    crlf to rl_crlf, so there are no public functions declared in readline.h
-    without an `rl_' prefix.  The old functions still exist for backwards
-    compatibility.
-
-3.  New Features in Bash
-
-a.  A new loadable builtin, realpath, which canonicalizes and expands symlinks
-    in pathname arguments.
-
-b.  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.
-
-4.  New Features in Readline
-
-a.  New application-callable function rl_set_prompt(const char *prompt):
-    expands its prompt string argument and sets rl_prompt to the result.
-
-b.  New application-callable function rl_set_screen_size(int rows, int cols):
-    public method for applications to set readline's idea of the screen
-    dimensions.
-
-c.  The history example program (examples/histexamp.c) is now built as one
-    of the examples.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.05-alpha1,
-and the previous version, bash-2.04-release.
-
-1.  Changes to Bash
-
-a.  A fix was made to allow newlines in compond array assignments.
-
-b.  configure now checks for real-time signals with unusable values.
-
-c.  Interactive shells no longer exit if a substitution fails because of an
-    unset variable within a sourced file.
-
-d.  Fixed a problem with incorrect matching of extended glob patterns when
-    doing pattern substitution.
-
-e.  `{' is now quoted by the completion code when it appears in a filename.
-
-f.  Fixed an error in pattern matching that caused the matcher to not
-    correctly skip the rest of a bracket expression after a character
-    matched.
-
-g.  Fixed a bug in the IFS word splitting code to make a non-whitespace IFS
-    character preceded by IFS whitespace part of the current delimiter rather
-    than generating a separate field.
-
-h.  The {!prefix@} expansion now generates separate words, analogous to $@,
-    when double-quoted.
-
-i.  Command substitution now ignores NUL bytes in the command output, and the
-    parser ignores them on input.
-
-j.  A fix was made to the job control code to prevent hanging processes when
-    the shell thinks background processes are running but the kernel returns
-    -1/ECHILD from waitpid().
-
-k.  `pwd' now prints an error message if the write fails when displaying the
-    current directory.
-
-l.  When in POSIX mode, the shell prints trap dispostions without a leading
-    `SIG' in the signal specification.
-
-m.  Fixed a parser bug that caused the current command's line count to be
-    messed up by a compound array assignment.
-
-n.  Fixed a bug in the unwind-protect code that caused bad behavior on machines
-    where ints and pointers are not the same size.
-
-o.  System-specific configure changes for:  MacOS X.
-
-p.  Changes for Cygwin to translate \r\n and \r to \n and to set file
-    descriptors used for reading input to text mode in various places.
-
-q.  Fixed a bug that caused `!' to occasionally not be honored when in
-    a (...) subshell.
-
-r.  Bash no longer assumes that getcwd() will return any useful error message
-    in the buffer passed as an argument if the call fails.
-
-s.  The `source', `.', and `fc' builtins no longer check whether a file is
-    binary before reading commands from it.
-
-t.  Subshells no longer turn off job control when they exit, since that
-    sometimes resulted in the terminal being reset to the wrong process
-    group.
-
-u.  The history code no longer tries to save the second and subsequent lines
-    of a multi-line command if the first line was not saved.
-
-v.  The history saving code now does a better job of saving blank lines in a
-    multi-line command.
-
-w.  Removed a `feature' that made `ulimit' silently translate `unlimited' to
-    the current hard limit, which obscured some kernel error returns.
-
-x.  Fixed the grammar so that `}' is recognized as a reserved word after
-    another reserved word, rather than requiring a `;' or newline.  This
-    means that constructs like
-
-       { { echo a b c ; } }
-
-    work as expected.
-
-y.  Conditional commands ([[...]]) now perform tilde expansion on their
-    arguments.
-
-z.  Noted in the documentation that `set -a' will cause functions to be
-    exported if they are defined after `set -a' is executed.
-
-aa. When an interactive login shell starts, if $PWD and $HOME refer to the
-    same directory but are not the same string, $PWD is set to $HOME.
-
-bb. Fixed `printf' to handle invalid floating point numbers better.
-
-cc. Temporary files are now created with random filenames, to improve security.
-
-dd. The readline initialization code now binds the custom bash functions and
-    key bindings after the readline defaults are set up.
-
-ee. Fixed the `source' builtin to no longer overwrite a shell function's
-    argument list, even if the sourced file changes the positional parameters.
-
-ff. A bug fix was made in the expansion of `$*' in contexts where it should
-    not be split, like assignment statements.
-
-gg. Fixed a bug in the parameter substring expansion to handle conditional
-    arithmetic expressions ( exp ? val1 : val2 ) without cutting the expression
-    off at the wrong `:'.
-
-hh. The `<>' redirection is no longer subject to the current setting of
-    `noclobber', as POSIX.2 specifies.
-
-ii. Fixed a bug in the conditional command parsing code that caused expressions
-    in parentheses to occasionally be parsed incorrectly.
-
-jj. Fixed a bug in the ((...)) arithmetic command to allow do...done or
-    {...} to follow the )) without an intervening list terminator.
-
-kk. `printf' now treats `\E' the same as `\e' when performing backslash escape
-    expansion for the `%b' format specifier.
-
-ll. When in POSIX mode, the shell no longer searches the current directory for
-    a file to be sourced with `.' or `source' if `.' is not in $PATH.
-
-mm. Interactive comments are no longer turned off when POSIX mode is disabled.
-
-nn. The UID, EUID, HOSTNAME variables are not set if they are in the shell's
-    environment when it starts up.
-
-oo. Fixed a bug in the `command' builtin so the effect of a command like
-    `command exec 4<file' is as if the `command' had been omitted.
-
-pp. ${foo[@]} and ${foo[*]} now work as in ksh93 if `foo' is not an array
-    variable.
-
-qq. ${#foo[X]}, where X is 0, @, or *, now work as in ksh93 if `foo' is not
-    an array variable.
-
-rr. The shell's idea of an absolute pathname now takes into account a
-    possible drive specification on Cygwin and other Windows systems.
-
-ss. Fixed a bug which caused incorrect parsing of some multi-character
-    constructs if they were split across input lines with backslash-newline
-    line continuation.
-
-tt. Fixed a bug that caused restricted shell mode to be set inappropriately
-    when trying to execute a shell script without a leading `#!'.
-
-uu. Shell function definitions no longer require that the body be a group
-    command ( {...} ), as POSIX.2 requires.
-
-vv. The `cd' and `pwd' builtins now process symlinks in pathnames internally
-    and should require many fewer calls to getcwd().
-
-ww. Fixed a bug that caused a pipeline's process group to be set incorrectly
-    if one of the pipeline elements contained a command substitution.
-
-xx. Fixed a bug that caused core dumps when expanding the value of HISTIGNORE.
-
-yy. The output of `set' is now quoted using $'...' so invisible characters are
-    displayed as escape sequences.
-
-zz. Fixed the help text for `unset', since PATH and IFS may both be unset.
-
-aaa. The shell no longer puts directory names into the command hash table.
-
-bbb. Fixed a bug in `read' that caused it to occasionally free memory twice if
-     it was interrupted after reading a large amount of data.
-
-ccc. Assignment statements that attempt to assign values to readonly variables
-     now cause the command to return an error status.
-
-ddd. Fixed a bug that could cause incorrect output if a $(<file) construct was
-     interrupted.
-
-eee. GROUPS and FUNCNAME now return an error status when assignment is
-     attempted, but may be unset (in which case they lose their special
-     properties).  In all respects except unsetting, they are readonly.
-
-fff. The string-to-integer conversion code now ignores trailing whitespace in
-     the string, even if strtol(3) does not.
-
-ggg. The tcsh magic-space function now does a better job of inserting the
-     space close to where the point was before the history expansion, rather
-     than just appending it.
-
-hhh. Fixed a bug which caused a file sourced from an interactive shell to
-     fill up the jobs table if it ran lots of jobs.
-
-iii. Fixed a bug in the parameter pattern substitution code to avoid infinite
-     recursion on zero-length matches.
-
-2.  Changes to Readline
-
-a.  When setting the terminal attributes on systems using `struct termio',
-    readline waits for output to drain before changing the attributes.
-
-b.  A fix was made to the history word tokenization code to avoid attempts to
-    dereference a null pointer.
-
-c.  Readline now defaults rl_terminal_name to $TERM if the calling application
-    has left it unset, and tries to initialize with the resultant value.
-
-d.  Instead of calling (*rl_getc_function)() directly to get input in certain
-    places, readline now calls rl_read_key() consistently.
-
-e.  Fixed a bug in the completion code that allowed a backslash to quote a
-    single quote inside a single-quoted string.
-
-f.  rl_prompt is no longer assigned directly from the argument to readline(),
-    but uses memory allocated by readline.  This allows constant strings to
-    be passed to readline without problems arising when the prompt processing
-    code wants to modify the string.
-
-g.  Fixed a bug that caused non-interactive history searches to return the
-    wrong line when performing multiple searches backward for the same string.
-
-h.  Many variables, function arguments, and function return values are now
-    declared `const' where appropriate, to improve behavior when linking with
-    C++ code.
-
-i.  The control character detection code now works better on systems where
-    `char' is unsigned by default.
-
-j.  The vi-mode numeric argument is now capped at 999999, just like emacs mode.
-
-k.  The Function, CPFunction, CPPFunction, and VFunction typedefs have been
-    replaced with a set of specific prototyped typedefs, though they are
-    still in the readline header files for backwards compatibility.
-
-m.  Nearly all of the (undocumented) internal global variables in the library
-    now have an _rl_ prefix -- there were a number that did not, like
-    screenheight, screenwidth, alphabetic, etc.
-
-n.  The ding() convenience function has been renamed to rl_ding(), though the
-    old function is still defined for backwards compatibility.
-
-o.  The completion convenience functions filename_completion_function,
-    username_completion_function, and completion_matches now have an rl_
-    prefix, though the old names are still defined for backwards compatibility.
-
-p.  The functions shared by readline and bash (linkage is satisfied from bash
-    when compiling with bash, and internally otherwise) now have an sh_ prefix.
-
-q.  Changed the shared library creation procedure on Linux and BSD/OS 4.x so
-    that the `soname' contains only the major version number rather than the
-    major and minor numbers.
-
-r.  Fixed a redisplay bug that occurred when the prompt spanned more than one
-    physical line and contained invisible characters.
-
-3.  New Features in Bash
-
-a.  Added a new `--init-file' invocation argument as a synonym for `--rcfile',
-    per the new GNU coding standards.
-
-b.  The /dev/tcp and /dev/udp redirections now accept service names as well as
-    port numbers.
-
-c.  `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
-
-4.  New Features in Readline
-
-a.  The blink timeout for paren matching is now settable by applications.
-
-b.  _rl_executing_macro has been renamed to rl_executing_macro, which means
-    it's now part of the public interface.
-
-c.  Readline has a new variable, rl_readline_state, which is a bitmap that
-    encapsulates the current state of the library; intended for use by
-    callbacks and hook functions.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.04-release,
-and the previous version, bash-2.04-beta5.
-
-1.  Changes to Bash
-
-a.  Better compile-time and configure-time checks for the necessity of
-    inet_aton().
-
-b.  A bug was fixed in the expansion of "${@:-}" when there are positional
-    parameters.
-
-c.  A typo was fixed in the output of `complete'.
-
-d.  The matches generated for a word by the `-W' argument to complete and
-    compgen are now matched against the word being completed, and only
-    matches are returned as the result.
-
-e.  Some fixes were made for systems which do not restart read(2) when a
-    signal caught by bash is received.
-
-f.  A bug was fixed which caused the umask to be set to 0 when an invalid
-    symbolic mode mask was parsed.
-
-g.  Fixed a bug that could cause a core dump if a SIGCHLD was received while
-    performing an assignment statement using command substitution.
-
-h.  Changed the word splitting function for programmable completion so cases
-    in which the cursor is between words are handled a bit better.
-
-2.  Changes to Readline
-
-a.  rl_funmap_names() is now documented.
-
-3.  New Features in Bash
-
-a.  The LC_NUMERIC variable is now treated specially, and used to set the
-    LC_NUMERIC locale category for number formatting, e.g., when `printf'
-    displays floating-point numbers.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.04-beta5,
-and the previous version, bash-2.04-beta4.
-
-1.  Changes to Bash
-
-a.  A couple of changes were made to the Makefiles for easier building on
-    non-Unix systems.
-
-b.  Fixed a bug where the current prompt would be set to $PS2 at startup.
-
-c.  The shell script that tests an already-installed version was changed to
-    remove the directory it created its test programs in at exit.
-
-d.  Several changes were made to the code that tokenizes an input line for
-    the programmable completion code.  Shell metacharacters will now appear
-    as individual words in the word list passed to the completion functions.
-    Some of the example completion shell functions were changed to understand
-    redirection operators.
-
-e.  A bug was fixed that, under obscure circumstances, could confuse the
-    parser when a shell function was run by the programmable completion code.
-
-f.  A bug was fixed in the ulimit builtin for systems not using getrlimit().
-
-g.  The execution code now propagates the correct exit status back to the rest
-    of the code if the return value of a subshell command was being inverted.
-    Some new test cases for inverting return values with the `!' reserved
-    word have been added.
-
-h.  Negative exponents in the arithmetic evaluation of v**e now return an
-    evaluation error.
-
-i.  A bug that caused bash to check the wrong process in a pipeline for
-    abnormal termination (and consequently resetting the terminal attributes)
-    was fixed.
-
-j.  Fixed a bug that caused $PS2 to be displayed after PROMPT_COMMAND was
-    executed.
-
-2.  Changes to Readline
-
-1.  Fixed a bug in a C preprocessor define that caused the keypad control
-    functions to be compiled out for all platforms except DJGPP.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.04-beta4,
-and the previous version, bash-2.04-beta3.
-
-1.  Changes to Bash
-
-a.  A couple of changes were made to the redirection to attempt to avoid
-    race conditions and malicious file replacement.
-
-2.  A change was made to the string evaluation code (used for command 
-    substitution, `eval', and the `.' builtin) to fix an obscure core
-    dump on alpha machines.
-
-3.  A bug that caused $LINENO to be wrong when executing arithmetic for
-    commands was fixed.
-
-4.  A couple of memory leaks in the programmable completion code were fixed.
-
-5.  A bug that could cause a core dump by freeing memory twice during a call
-    to `eval' if `set -u' had been enabled and an undefined variable was
-    referenced was fixed.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.04-beta3,
-and the previous version, bash-2.04-beta2.
-
-1.  Changes to Bash
-
-a.  Bash should run the appropriate startup files when invoked by ssh2.
-
-b.  Fixed a bug in the parsing of conditional commands that could cause a
-    core dump.
-
-c.  Fixed a bug in parsing job specifications that occasionally caused
-    core dumps when an out-of-range job was referenced.
-
-d.  Fixed the `type' and `command' builtins to do better reporting of
-    commands that are not found in $PATH or the hash table.
-
-e.  Fixed a POSIX.2 compliance problem in the command builtin -- commands
-    are supposed to be reported as full pathnames.
-
-f.  The `echo' builtin now returns failure if a write error occurs.
-
-g.  Fixed a bug which caused the locale to not be reset correctly when
-    LC_ALL was unset.
-
-h.  Changed description of `getopts' in man page and reference manual to make
-    it clear that option characters may be characters other than letters.
-
-i.  If the shell exits while in a function, make sure that any trap on EXIT
-    doesn't think the function is still executing.
-
-j.  Bashbug now tries harder to find a usable editor if $EDITOR is not set,
-    rather than simply defaulting to `emacs'.
-
-k.  Changes to the scripts that guess and canonicalize the system type, from
-    the latest `automake' distribution via Debian.
-
-l.  When using named pipes for process substitution, make sure the file
-    descriptors opened for reading are set to non-blocking mode.
-
-m.  Fixed a bug that caused termination of pipelines that are killed by a
-    signal to not be reported in some cases.
-
-n.  When not in literal-history mode, shell comment lines are not added to
-    the history list.
-
-o.  When running in POSIX.2 mode, bash no longer performs word splitting on
-    the expanded value of the word supplied as the filename argument to
-    redirection operators.
-
-p.  The prompt string decoding code now backslash-quotes only characters that
-    are special within double quotes when expanding the \w and \W escape
-    sequences.
-
-q.  Fixed a bug in the prompt decoding code that could cause a non-interactive
-    shell to seg fault if `\u' was used in PS4 and the shell was in xtrace
-    mode.
-
-r.  Fixed a bug that caused function definitions to be printed with any
-    redirections that should be attached to the entire function before the
-    closing brace.
-
-s.  Changed the tilde expansion code for Cygwin systems to avoid creating
-    pathnames beginning with `//' if $HOME == `/'.
-
-t.  Fixed a couple of autoconf tests to avoid creating files with fixed names
-    in /tmp.
-
-u.  The `trap' and `kill' builtins now know the names of the POSIX.1b real-
-    time signals on systems which support them.
-
-2.  Changes to Readline
-
-a.  Fixed a problem with the single-quote quoting function that could cause
-    buffer overflows.
-
-b.  Fixed a bug that caused incorrect `stat characters' to be printed if
-    the files being completed were in the root directory and visible-stats
-    was enabled.
-
-3.  New Features in Bash
-
-a.  There is a new `rbash.1' manual page, from the Debian release.
-
-b.  The `--enable-usg-echo-default' option to `configure' has been renamed to
-    `--enable-xpg-echo-default'.  The old option is still there for backwards
-    compatibility.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.04-beta2,
-and the previous version, bash-2.04-beta1.
-
-1.  Changes to Bash
-
-a.  Fixed a bug that could cause pipes to be closed inappropriately in
-    some obscure cases.
-
-b.  Fixed a bug that caused creation of the exported environment to clobber
-    the current command string if there were any exported shell functions.
-
-c.  Some changes were made to reduce bash's memory usage.
-
-d.  Fixed a problem with programmable completion and filenames to be
-    completed containing quote characters.
-
-e.  Changed the code the removes named pipes created for the <(...) and >(...)
-    expansions to defer removal until after any current shell function has
-    finished executing.
-
-f.  Fixed a bug in `select' which caused it to not handle the `continue'
-    builtin correctly.
-
-g.  Autoconf tests added for cygwin32 and mingw32.
-
-2.  New Features in Bash
-
-a.  The `--with-bash-malloc' configure option replaces `--with-gnu-malloc'
-    (which is still there for backwards compatibility).
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.04-beta1,
-and the previous version, bash-2.04-alpha1.
-
-1.  Changes to Bash
-
-a.  Fixed a bug in the programmable completion code that occurred when
-    trying to complete command lines containing a `;' or `@'.
-
-b.  The file descriptor from which the shell is reading a script is now
-    moved to a file descriptor above the user-addressible range.
-
-c.  Changes to `printf' so that it can handle integers beginning with 0
-    or 0x as octal and hex, respectively.
-
-d.  Fixes to the programmable completion code so it handles nonsense like
-    `compgen -C xyz' gracefully.
-
-e.  The shell no longer modifies the signal handler for SIGPROF, allowing
-    profiling again on certain systems.
-
-f.  The shell checks for a new window size, if the user has requested it,
-    after a process exits due to a signal.
-
-g.  Fixed a bug with variables with null values in a program's temporary
-    environment and the bash getenv() replacement.
-
-h.  `declare' and the other builtins that take variable assignments as
-    arguments now honor `set -a' and mark modified variables for export.
-
-i.  Some changes were made for --dump-po-strings mode when writing strings
-    with embedded newlines.
-
-j.  The code that caches export strings from the initial environment now
-    duplicates the string rather than just pointing into the environment.
-
-k.  The filename completion quoting code now uses single quotes by default
-    if the filename being completed contains newlines, since \<newline>
-    has a special meaning to the parser.
-
-l.  Bash now uses typedefs bits32_t and u_bits32_t instead of int32_t and
-    u_int32_t, respectively to avoid conflicts on certain Unix versions.
-
-m.  Configuration changes were made for: Rhapsody, Mac OS, FreeBSD-3.x.
-
-n.  Fixed a problem with hostname-to-ip-address translation in the
-    /dev/(tcp|udp)/hostname/port redirection code.
-
-o.  The texinfo manual has been reorganized slightly.
-
-p.  Filename generation (globbing) range comparisons in bracket expressions
-    no longer use strcoll(3) even if it is available, since it has unwanted
-    effects in certain locales.
-
-q.  Fixed a cosmetic problem in the source that caused the shell to not
-    compile if DPAREN_ARITHMETIC was not defined but ARITH_FOR_COMMAND was.
-
-r.  Fixed a bug in the here-document code tripped when the file descriptor
-    opened to the file containing the text of the here document was the
-    same as a redirector specified by the user.
-
-s.  Fixed a bug where the INVERT_RETURN flag was not being set for `pipeline'
-    in `time ! pipeline'.
-
-t.  Fixed a bug with the `wait' builtin which manifested itself when an
-    interrupt was received while the shell was waiting for asynchronous
-    processes in a shell script.
-
-u.  Fixed the DEBUG trap code so that it has the correct value of $?.
-
-v.  Fixed a bug in the parameter pattern substitution code that could cause
-    the shell to attempt to free unallocated memory if the pattern started
-    with `/' and an expansion error occurs.
-
-w.  Fixed a bug in the positional parameter substring code that could
-    cause the shell to loop freeing freed memory.
-
-x.  Fixed a bug in the positional parameter pattern substitution code so
-    that it correctly handles null replacement strings with a pattern
-    string prefixed with `%' or `#'.
-
-y.  The shell no longer attempts to import functions from the environment if
-    started with `-n'.
-
-z.  Fixed a bug that caused `return' in a command substitution executed in
-    a shell function to return from the function in a subshell and continue
-    execution.
-
-aa. `hash -p /pathname/with/slashes name' is no longer allowed when the shell
-    is restricted.
-
-bb. The wait* job control functions now behave better if called when there
-    are no unwaited-for children.
-
-cc. Command substitution no longer unconditionally disables job control in
-    the subshell started to run the command.
-
-dd. A bug was fixed that occasionally caused traps to mess up the parser
-    state.
-
-ee. `bashbug' now honors user headers in the mail message it sends.
-
-ff. A bug was fixed that caused the `:p' history modifier to not print the
-    history expansion if the `histverify' option was set.
-
-2.  Changes to Readline
-
-a.  Fixed a bug in the redisplay code for lines with more than 256 line
-    breaks.
-
-b.  A bug was fixed which caused invisible character markers to not be
-    stripped from the prompt string if the terminal was in no-echo mode.
-
-c.  Readline no longer tries to get the variables it needs for redisplay
-    from the termcap entry if the calling application has specified its
-    own redisplay function.  Readline treats the terminal as `dumb' in
-    this case.
-
-d.  Fixes to the SIGWINCH code so that a multiple-line prompt with escape
-    sequences is redrawn correctly.
-
-3.  New Features in Bash
-
-a.  `bashbug' now accepts `--help' and `--version' options.
-
-b.  There is a new `xpg_echo' option to `shopt' that controls the behavior
-    of echo with respect to backslash-escaped characters at runtime.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.04-alpha1,
-and the previous version, bash-2.04-devel.
-
-1.  Changes to Bash
-
-a.  Fixed a bug that could cause core dumps when performing substring
-    expansion.
-
-b.  Shared object configuration changes for:  Solaris, OSF/1
-
-c.  The POSIX_GLOB_LIBRARY code that uses the POSIX.2 globbing facilities
-    for pathname expansion now understands GLOBIGNORE.
-
-d.  The code that implements `eval' was changed to save the value of the
-    current prompt, so an eval in a shell function called by the programmable
-    completion code will not change the prompt to $PS2.
-
-e.  Restored the undocumented NON_INTERACTIVE_LOGIN_SHELLS #define to
-    config-top.h.  If this is defined, all login shells will read the
-    startup files, not just interactive and non-interactive started with
-    the `--login' option.
-
-f.  Fixed a bug that caused the expansion code to occasionally dump core if
-    IFS contained characters > 128.
-
-g.  Fixed a problem with the grammar so that a newline is not required
-    after the `))' in the new-style arithmetic for statement; a semicolon
-    may be used as expected.
-
-h.  Variable indirection may now reference the shell's special variables.
-
-i.  The $'...' and $"..." constructs are now added to the history correctly
-    if they contain newlines and command-oriented history is enabled.
-
-j.  It is now an error to try to assign a value to a function-local copy
-    of a readonly shell variable (declared with the `local' builtin).
-
-2.  Changes to Readline
-
-a.  The history file code now uses O_BINARY mode when reading and writing
-    the history file on cygwin32.
-
-3.  New Features in Bash
-
-a.  A new programmable completion facility, with two new builtin commands:
-    complete and compgen.
-
-b.  configure has a new option, `--enable-progcomp', to compile in the
-    programmable completion features (enabled by default).
-
-c.  `shopt' has a new option, `progcomp', to enable and disable programmable
-    completion at runtime.
-
-d.  Unsetting HOSTFILE now clears the list of hostnames used for completion.
-
-4.  New Features in Readline
-
-a.  A new variable, rl_gnu_readline_p, always 1.  The intent is that an
-    application can verify whether or not it is linked with the `real'
-    readline library or some substitute.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.04-devel,
-and the previous version, bash-2.03-release.
-
-1.  Changes to Bash
-
-a.  System-specific configuration and source changes for:  Interix, Rhapsody
-
-b.  Fixed a bug in execute_cmd.c that resulted in a compile-time error if
-    JOB_CONTROL was not defined.
-
-c.  An obscure race condition in the trap code was fixed.
-
-d.  The string resulting from $'...' is now requoted to avoid any further
-    expansion.
-
-e.  The $'...' quoting syntax now allows backslash to escape a single quote,
-    for ksh-93 compatibility.
-
-f.  The $"..." quoting syntax now escapes backslashes and double quotes in
-    the translated string when displaying them with the --dump-po-strings
-    option.
-
-g.  `echo -e' no longer converts \' to '.
-
-h.  Fixes were made to the extended globbing code to handle embedded (...)
-    patterns better.
-
-i.  Some improvements were made to the code that unsets `nodelay' mode on
-    the file descriptor from which bash is reading input.
-
-j.  Some changes were made to the replacement termcap library for better
-    operation on MS-DOS.
-
-k.  Some changes were made to the tilde expansion code to handle backslash
-    as a pathname separator on MS-DOS.
-
-l.  The source has been reorganized a little bit -- there is now an `include'
-    subdirectory, and lib/posixheaders has been removed.
-
-m.  Improvements were made to the `read' builtin so that it makes many
-    fewer read(2) system calls.
-
-n.  The expansion of $- will include `c' and `s' when those options are
-    supplied at shell invocation.
-
-o.  Several improvments were made to the completion code:  variable completion
-    now works better when there are unterminated expansions, command
-    completion understands quotes better, and completion now works in certain
-    unclosed $(... constructs.
-
-p.  The arithmetic expansion code was fixed to not need the value of a
-    variable being assigned a value (fixes the "ss=09; let ss=10" bug).
-
-q.  Some changes were made to make exported environment creation faster.
-
-r.  The html documentation will be installed into $(htmldir) if that variable
-    has a value when `make install' is run.
-
-s.  Fixed a bug that would cause the bashrc file to be sourced inappropriately
-    when bash is started by sshd.
-
-t.  The SSH_CLIENT environment variable is no longer auto-exported.
-
-u.  A bug that caused redirections with (...) subshells to be performed in
-    the wrong order was fixed.
-
-v.  A bug that occasionally caused inappropriate expansion of assignment
-    statements in compound array assignments was fixed.
-
-w.  The code that parses the words in a compound array assignment was
-    simplified considerably and should work better now.
-
-x.  Fixes to the non-job-control code in nojobs.c to make it POSIX.2-compliant
-    when a user attempts to retrieve the status of a terminated background
-    process.
-
-y.  Fixes to the `printf' builtin so that it doesn't try to expand all
-    backslash escape sequences in the format string before parsing it for
-    % format specifiers.
-
-2.  Changes to Readline
-
-a.  The history library tries to truncate the history file only if it is a
-    regular file.
-
-b.  A bug that caused _rl_dispatch to address negative array indices on
-    systems with signed chars was fixed.
-
-c.  rl-yank-nth-arg now leaves the history position the same as when it was
-    called.
-
-d.  Changes to the completion code to handle MS-DOS drive-letter:pathname
-    filenames.
-
-e.  Completion is now case-insensitive by default on MS-DOS.
-
-f.  Fixes to the history file manipulation code for MS-DOS.
-
-g.  Readline attempts to bind the arrow keys to appropriate defaults on MS-DOS.
-
-h.  Some fixes were made to the redisplay code for better operation on MS-DOS.
-
-i.  The quoted-insert code will now insert tty special chars like ^C.
-
-j.  A bug was fixed that caused the display code to reference memory before
-    the start of the prompt string.
-
-k.  More support for __EMX__ (OS/2).
-
-l.  A bug was fixed in readline's signal handling that could cause infinite
-    recursion in signal handlers.
-
-m.  A bug was fixed that caused the point to be less than zero when rl_forward
-    was given a very large numeric argument.
-
-n.  The vi-mode code now gets characters via the application-settable value
-    of rl_getc_function rather than calling rl_getc directly.
-
-3.  New Features in Bash
-
-a.  The history builtin has a `-d offset' option to delete the history entry
-    at position `offset'.
-
-b.  The prompt expansion code has two new escape sequences: \j, the number of
-    active jobs; and \l, the basename of the shell's tty device name.
-
-c.  The `bind' builtin has a new `-x' option to bind key sequences to shell
-    commands.
-
-d.  There is a new shell option, no_empty_command_completion, which, when
-    enabled, disables command completion when TAB is typed on an empty line.
-
-e.  The `help' builtin has a `-s' option to just print a builtin's usage
-    synopsys.
-
-f.  There are several new arithmetic operators:  id++, id-- (variable
-    post-increment/decrement), ++id, --id (variabl pre-increment/decrement),
-    expr1 , expr2 (comma operator).
-
-g.  There is a new ksh-93 style arithmetic for command:
-       for ((expr1 ; expr2; expr3 )); do list; done
-
-h.  The `read' builtin has a number of new options:
-       -t timeout      only wait timeout seconds for input
-       -n nchars       only read nchars from input instead of a full line
-       -d delim        read until delim rather than newline
-       -s              don't echo input chars as they are read
-
-i.  The redirection code now handles several filenames specially:
-    /dev/fd/N, /dev/stdin, /dev/stdout, and /dev/stderr, whether or
-    not they are present in the file system.
-
-j.  The redirection code now recognizes pathnames of the form
-    /dev/tcp/host/port and /dev/udp/host/port, and tries to open a socket
-    of the appropriate type to the specified port on the specified host.
-
-k.  The ksh-93 ${!prefix*} expansion, which expands to the names of all
-    shell variables whose names start with prefix, has been implemented.
-
-l.  There is a new dynamic variable, FUNCNAME, which expands to the name of
-    a currently-executing function.  Assignments to FUNCNAME have no effect.
-
-m.  The GROUPS variable is no longer readonly; assignments to it are silently
-    discarded.  This means it can be unset.
-
-4.  New Features in Readline
-
-a.  Parentheses matching is now always compiled into readline, and enabled
-    or disabled when the value of the `blink-matching-paren' variable is
-    changed.
-
-b.  MS-DOS systems now use ~/_inputrc as the last-ditch inputrc filename.
-
-c.  MS-DOS systems now use ~/_history as the default history file.
-
-d.  history-search-{forward,backward} now leave the point at the end of the
-    line when the string to search for is empty, like
-    {reverse,forward}-search-history.
-
-e.  history-search-{forward,backward} now leave the last history line found
-    in the readline buffer if the second or subsequent search fails.
-
-f.  New function for use by applications:  rl_on_new_line_with_prompt, used
-    when an application displays the prompt itself before calling readline().
-
-g.  New variable for use by applications:  rl_already_prompted.  An application
-    that displays the prompt itself before calling readline() must set this to
-    a non-zero value.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.03-release,
-and the previous version, bash-2.03-beta2.
-
-1.  Changes to Bash
-
-a.  A file descriptor leak in the `fc' builtin was fixed.
-
-b.  A bug was fixed in the `read' builtin that caused occasional spurious
-    failures when using `read -e'.
-
-c.  The version code needed to use the value of the cpp variable
-    CONF_MACHTYPE rather than MACHTYPE.
-
-d.  A new test was added to exercise the command printing and copying code.
-
-e.  A bug was fixed that caused `time' to be recognized as a reserved word
-    if it was the first pattern in a `case' statement pattern list.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.03-beta2,
-and the previous version, bash-2.03-beta1.
-
-1.  Changes to Bash
-
-a.  Slight additions to support/shobj-conf, mostly for the benefit of AIX 4.2.
-
-b.  config.{guess,sub} support added for the NEC SX4.
-
-c.  Changed some of the cross-compiling sections of the configure macros in
-    aclocal.m4 so that configure won't abort.
-
-d.  Slight changes to how the HTML versions of the bash and readline manuals
-    are generated.
-
-e.  Fixed conditional command printing to avoid interpreting printf `%'-escapes
-    in arguments to [[.
-
-f.  Don't include the bash malloc on all variants of the alpha processor.
-
-g.  Changes to configure to make --enable-profiling work on Solaris 2.x.
-
-h.  Fixed a bug that manifested itself when shell functions were called
-    between calls to `getopts'.
-
-i.  Fixed pattern substitution so that a bare `#'as a pattern causes the
-    replacement string to be prefixed to the search string, and a bare
-    `%' causes the replacement string to be appended to the search string.
-
-j.  Fixed a bug in the command execution code that caused child processes
-    to occasionally have the wrong value for $!.
-
-2.  Changes to Readline
-
-a.  Added code to the history library to catch history substitutions using
-    `&' without a previous history substitution or search having been
-    performed.
-
-3.  New Features in Bash
-
-4.  New Features in Readline
-
-a.  New bindable variable: `isearch-terminators'.
-
-b.  New bindable function: `forward-backward-delete-char' (unbound by default).
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.03-beta1,
-and the previous version, bash-2.03-alpha.
-    
-1.  Changes to Bash
-
-a.  A change was made to the help text for `{...}' to make it clear that a
-    semicolon is required before the closing brace.
-
-b.  A fix was made to the `test' builtin so that syntax errors cause test
-    to return an exit status > 1.
-
-c.  Globbing is no longer performed on assignment statements that appear as
-    arguments to `assignment builtins' such as `export'.
-
-d.  System-specific configuration changes were made for:  Rhapsody,
-    AIX 4.2/gcc, BSD/OS 4.0.
-
-e.  New loadable builtins: ln, unlink.
-
-f.  Some fixes were made to the globbing code to handle extended glob patterns
-    which immediately follow a `*'.
-
-g.  A fix was made to the command printing code to ensure that redirections
-    following compound commands have a space separating them from the rest
-    of the command.
-
-h.  The pathname canonicalization code was changed to produce fewer leading
-    `//' sequences, since those are interpreted as network file system
-    pathnames on some systems.
-
-i.  A fix was made so that loops containing `eval' commands in commands passed
-    to `bash -c' would not exit prematurely.
-
-j.  Some changes were made to the job reaping code when the shell is not
-    interactive, so the shell will retain exit statuses longer for examination
-    by `wait'.
-
-k.  A fix was made so that `jobs | command' works again.
-
-l.  The erroneous compound array assignment var=((...)) is now a syntax error.
-
-m.  A change was made to the dynamic loading code in `enable' to support
-    Tenon's MachTen.
-
-n.  A fix was made to the globbing code so that extended globbing patterns
-    will correctly match `.' in a bracket expression.
-
-2.  Changes to Readline
-
-a.  A fix was made to the completion code in which a typo caused the wrong
-    value to be passed to the function that computed the longest common
-    prefix of the list of matches.
-
-b.  The completion code now checks the value of rl_filename_completion_desired,
-    which is set by application-supplied completion functions to indicate
-    that filename completion is being performed, to decide whether or not to
-    call an application-supplied `ignore completions' function.
-
-3.  New Features in Bash
-
-a.  A change was made to the startup file code so that any shell begun with
-    the `--login' option, even non-interactive shells, will source the login
-    shell startup files.
-
-4.  New Features in Readline
-
-a.  A new variable, rl_erase_empty_line, which, if set by an application using
-    readline, will cause readline to erase, prompt and all, lines on which the
-    only thing typed was a newline.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.03-alpha,
-and the previous version, bash-2.02.1-release.
-
-1.  Changes to Bash
-
-a.  System-specific configuration changes were made for: Irix 6.x, Unixware 7.
-
-b.  The texi2dvi and texi2html scripts were updated to the latest versions
-    from the net.
-
-c.  The configure tests that determine which native type is 32 bits were
-    changed to not require a compiled program.
-
-d.  Fixed a bug in shell_execve that could cause memory to be freed twice
-    after a failed exec.
-
-e.  The `printf' test uses `diff -a' if it's available to prevent confusion
-    due to the non-ascii output.
-
-f.  Shared object configuration is now performed by a shell script,
-    support/shobj-conf, which generates values to be substituted into
-    makefiles by configure.
-
-g.  Some changes were made to `ulimit' to avoid the use of RLIM_INVALID as a
-    return value.
-
-h.  Changes were made to `ulimit' to work around HPUX 9.x's peculiar
-    handling of RLIMIT_FILESIZE.
-
-i.  Some new loadable builtins were added: id, printenv, sync, whoami, push,
-    mkdir.  `pushd', `popd', and `dirs' can now be built as regular or
-    loadable builtins from the same source file.
-
-j.  Changes were made to `printf' to handle NUL bytes in the expanded format
-    string.
-
-k.  The various `make clean' Makefile targets now descend into lib/sh.
-
-l.  The `type' builtin was changed to use the internal `getopt' so that things
-    like `type -ap' work as expected.
-
-m.  There is a new configuration option, --with-installed-readline, to link
-    bash with a locally-installed version of readline.  Only readline version
-    4.0 and later releases can support this.  Shared and static libraries
-    are supported.  The installed include files are used.
-
-n.  There is a new autoconf macro used to find which basic type is 64 bits.
-
-o.  Dynamic linking and loadable builtins should now work on SCO 3.2v5*,
-    AIX 4.2 with gcc, Unixware 7, and many other systems using gcc, where
-    the `-shared' options works correctly.
-
-p.  A bug was fixed in the bash filename completion code that caused memory to
-    be freed twice if a directory name containing an unset variable was
-    completed and the -u option was set.
-
-q.  The prompt expansion code now quotes the `$' in the `\$' expansion so it
-    is not processed by subsequent parameter expansion.
-
-r.  Fixed a parsing bug that caused a single or double quote after a `$$' to
-    trigger ANSI C expansion or locale translation.
-
-s.  Fixed a bug in the globbing code that caused quoted filenames containing
-    no globbing characters to sometimes be incorrectly expanded.
-
-t.  Changes to the default prompt strings if prompt string decoding is not
-    compiled into the shell.
-
-u.  Added `do', `then', `else', `{', and `(' to the list of keywords that may
-    precede the `time' reserved word.
-
-v.  The shell may now be cross-built for BeOS as well as cygwin32.
-
-w.  The conditional command execution code now treats `=' the same as `=='
-    for deciding when to perform pattern matching.
-
-x.  The `-e' option no longer causes the shell to exit if a command exits
-    with a non-zero status while running the startup files.
-
-y.  The `printf' builtin no longer dumps core if a modifier is supplied in
-    the format string without a conversion character (e.g. `%h').
-
-z.  Array assignments of the form a=(...) no longer show up in the history
-    list.
-
-aa. The parser was fixed to obey the POSIX.2 rules for finding the closing
-    `}' in a ${...} expression.
-
-bb. The history file is now opened with mode 0600 rather than 0666, so bash
-    no longer relies on the user's umask being set appropriately.
-
-cc. Setting LANG no longer causes LC_ALL to be assigned a value; bash now
-    relies on proper behavior from the C library.
-
-dd. Minor changes were made to allow quoted variable expansions using
-    ${...} to be completed correctly if there is no closing `"'.
-
-ee. Changes were made to builtins/Makefile.in so that configuring the shell
-    with `--enable-profiling' works right and builtins/mkbuiltins is
-    generated.
-
-2.  Changes to Readline
-
-a.  The version number is now 4.0.
-
-b.  There is no longer any #ifdef SHELL code in the source files.
-
-c.  Some changes were made to the key binding code to fix memory leaks and
-    better support Win32 systems.
-
-d.  Fixed a silly typo in the paren matching code -- it's microseconds, not
-    milliseconds.
-
-e.  The readline library should be compilable by C++ compilers.
-
-f.  The readline.h public header file now includes function prototypes for
-    all readline functions, and some changes were made to fix errors in the
-    source files uncovered by the use of prototypes.
-
-g.  The maximum numeric argument is now clamped at 1000000.
-
-h.  Fixes to rl_yank_last_arg to make it behave better.
-
-i.  Fixed a bug in the display code that caused core dumps if the prompt
-    string length exceeded 1024 characters.
-
-j.  The menu completion code was fixed to properly insert a single completion
-    if there is only one match.
-
-k.  A bug was fixed that caused the display code to improperly display tabs
-    after newlines.
-
-3.  New Features in Bash
-
-a.  New `shopt' option, `restricted_shell', indicating whether or not the
-    shell was started in restricted mode, for use in startup files.
-
-b.  Filename generation is now performed on the words between ( and ) in
-    array assignments (which it probably should have done all along).
-
-c.  OLDPWD is now auto-exported, as POSIX.2 seems to require.
-
-d.  ENV and BASH_ENV are read-only variables in a restricted shell.
-
-4.  New Features in Readline
-
-a.  Many changes to the signal handling:
-       o Readline now catches SIGQUIT and cleans up the tty before returning;
-       o A new variable, rl_catch_signals, is available to application writers 
-         to indicate to readline whether or not it should install its own
-         signal handlers for SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP,
-         SIGTTIN, and SIGTTOU;
-       o A new variable, rl_catch_sigwinch, is available to application
-         writers to indicate to readline whether or not it should install its
-         own signal handler for SIGWINCH, which will chain to the calling
-         applications's SIGWINCH handler, if one is installed;
-       o There is a new function, rl_free_line_state, for application signal
-         handlers to call to free up the state associated with the current
-         line after receiving a signal;
-       o There is a new function, rl_cleanup_after_signal, to clean up the
-         display and terminal state after receiving a signal;
-       o There is a new function, rl_reset_after_signal, to reinitialize the
-         terminal and display state after an application signal handler
-         returns and readline continues
-
-b.  There is a new function, rl_resize_terminal, to reset readline's idea of
-    the screen size after a SIGWINCH.
-
-c.  New public functions: rl_save_prompt and rl_restore_prompt.  These were
-    previously private functions with a `_' prefix.
-
-d.  New function hook: rl_pre_input_hook, called just before readline starts
-    reading input, after initialization.
-
-e.  New function hook: rl_display_matches_hook, called when readline would
-    display the list of completion matches.  The new function
-    rl_display_match_list is what readline uses internally, and is available
-    for use by application functions called via this hook.
-
-f.  New bindable function, delete-char-or-list, like tcsh.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.02.1-release,
-and the previous version, bash-2.02-release.
-
-1.  Changes to Bash
-
-a.  A bug that caused the bash readline support to not compile unless aliases
-    and csh-style history were configured into the shell was fixed.
-
-b.  Fixed a bug that could cause a core dump when here documents contained
-    more than 1000 characters.
-
-c.  Fixed a bug that caused a CDPATH entry of "" to not be treated the same
-    as the current directory when in POSIX mode.
-
-d.  Fixed an alignment problem with the memory returned by the bash malloc,
-    so returned memory is now 64-bit aligned.
-
-e.  Fixed a bug that caused command substitutions executed within pipelines
-    to put the terminal in the wrong process group.
-
-f.  Fixes to support/config.sub for: alphas, SCO Open Server and Open Desktop,
-    Unixware 2, and Unixware 7.
-
-g.  Fixes to the pattern matching code to make it work correctly for eight-bit
-    characters.
-
-h.  Fixed a problem that occasionally caused the shell to display the wrong
-    value for the new working directory when changing to a directory found
-    in $CDPATH when in physical mode.
-
-i.  Fixed a bug that caused core dumps when using conditional commands in
-    shell functions.
-
-j.  Fixed a bug that caused the printf builtin to loop forever if the format
-    string did not consume any of the arguments.
-
-k.  Fixed a bug in the parameter expansion code that caused "$@" to be
-    incorrectly split if $IFS did not contain a space character.
-
-l.  Fixed a bug that could cause a core dump when completing hostnames if
-    the number of matching hostnames was an exact multiple of 16.
-
-m.  Fixed a bug that caused the shell to fork too early when a command
-    such as `%2 &' was given.
-
-2.  Changes to Readline
-
-a.  Fixed a problem with redisplay that showed up when the prompt string was
-    longer than the screen width and the prompt contained invisible characters.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.02-release,
-and the previous version, bash-2.02-beta2.
-
-1.  Changes to Bash
-
-a.  A bug was fixed that caused the terminal process group to be set
-    incorrectly when performing command substitution of builtins in a
-    pipeline.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.02-beta2,
-and the previous version, bash-2.02-beta1.
-
-1.  Changes to Bash
-
-a.  Attempting to `wait' for stopped jobs now generates a warning message.
-
-b.  Pipelines which exit due to SIGPIPE in non-interactive shells are now
-    not reported if the shell is compiled -DDONT_REPORT_SIGPIPE.
-
-c.  Some changes were made to builtins/psize.sh and support/bashbug.sh to
-    attempt to avoid some /tmp file races and surreptitious file
-    substitutions.
-
-d.  Fixed a bug that caused the shell not to compile if configured with
-    dparen arithmetic but without aliases.
-
-e.  Fixed a bug that caused the input stream to be switched when assigning
-    empty arrays with `bash -c'.
-
-f.  A bug was fixed in the readline expansion glue code that caused bash to
-    dump core when expanding lines with an unclosed single quote.
-
-g.  A fix was made to the `cd' builtin so that using a non-empty directory
-    from $CDPATH results in an absolute pathname of the new current working
-    directory to be displayed after the current directory is changed.
-
-h.  Fixed a bug in the variable assignment code that caused the shell to
-    dump core when referencing an unset variable with `set -u' enabled in
-    an assignment statement preceding a command.
-
-i.  Fixed a bug in the exit trap code that caused reserved words to not be
-    recognized under certain circumstances.
-
-j.  Fixed a bug in the parameter pattern substitution code so that quote
-    removal is performed.
-
-k.  The shell should now configure correctly on Apple Rhapsody systems.
-
-l.  The `kill' builtin now prints a usage message if it is not passed any
-    arguments.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.02-beta1,
-and the previous version, bash-2.02-alpha1.
-
-1.  Changes to Bash
-
-a.  A few compilation bugs were fixed in the new extended globbing code.
-
-b.  Executing arithmetic commands now sets the command name to `((' so
-    error messages look right.
-
-c.  Fixed some build problems with various configuration options.
-
-d.  The `printf' builtin now aborts immediately if an illegal format
-    character is encountered.
-
-e.  The code that creates here-documents now behaves better if the file it's
-    trying to create already exists for some reason.
-
-f.  Fixed a problem with the extended globbing code that made patterns like
-    `x+*' expand incorrectly.
-
-g.  The prompt string expansion code no longer quotes tildes with backslashes.
-
-h.  The bash getcwd() implementation in lib/sh/getcwd.c now behaves better in
-    the presence of lstat(2) failures.
-
-i.  Fixed a bug with strsub() that caused core dumps when executing `fc -s'.
-
-j.  The mail checking code now ensures that it has a valid default mailpath.
-
-k.  A bug was fixed that caused local variables to be unset inappropriately
-    when sourcing a script from within another sourced script.
-
-l.  A bug was fixed in the history saving code so that functions are saved
-    in the history list correctly if `cmdhist' is enabled, but `lithist'
-    is not.
-
-m.  A bug was fixed that caused printf overflows when displaying error
-    messages.
-
-n.  It should be easier to build the loadble builtins in examples/loadables,
-    though some manual editing of the generated Makefile is still required.
-
-o.  The user's primary group is now always ${GROUPS[0]}.
-
-p.  Some updates were made to support/config.guess from the GNU master copy.
-
-q.  Some changes were made to the autoconf support for Solaris 2.6 large
-    files.
-
-r.  The `command' builtins now does the right thing when confstr(3) cannot
-    find a value for _CS_PATH.
-
-s.  Extended globbing expressions like `*.!(c)' are not history expanded if
-    `extglob' is enabled.
-
-t.  Using the `-P' option to `cd' will force the value that is assigned to
-    PWD to not contain any symbolic links.
-
-2.  Changes to Readline
-
-a.  The code that prints completion listings now behaves better if one or
-    more of the filenames contains non-printable characters.
-
-b.  The time delay when showing matching parentheses is now 0.5 seconds.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.02-alpha1,
-and the previous version, bash-2.01.1-release.
-
-1.  Changes to Bash
-
-a.  OS-specific configuration changes for:  BSD/OS 3.x, Minix 2.x,
-    Solaris 2.6, SINIX SVR4.
-
-b.  Changes were made to the generated `info' files so that `install-info'
-    works correctly.
-
-c.  PWD is now auto-exported.
-
-d.  A fix was made to the pipeline code to make sure that the shell forks
-    to execute simple commands consisting solely of assignment statements.
-
-e.  Changes to the test suite for systems with 14-character filenames.
-
-f.  The default sizes of some internal hash tables have been made smaller
-    to reduce the shell's memory footprint.
-
-g.  The `((...))' arithmetic command is now executed directly instead of
-    being translated into `let "..."'.
-
-h.  Fixes were made to the expansion code so that "$*", "$@", "${array[@]}",
-    and "${array[@]}" expand correctly when IFS does not contain a space
-    character, is unset, or is set to NULL.
-
-i.  The indirect expansion code (${!var}) was changed so that the only
-    valid values of `var' are variable names, positional parameters, `#',
-    `@', and `*'.
-
-j.  An arithmetic expression error in a $((...)) expansion now causes a
-    non-interactive shell running in posix mode to exit.
-
-k.  Compound array assignment now splits the words within the parentheses
-    on shell metacharacters like the parser would before expansing them
-    and performing the assignment.  This is for compatibility with ksh-93.
-
-l.  The internal shell backslash-quoting code (used in the output of `set'
-    and completion) now quotes tildes if they appear at the start of the
-    string or after a `=' or `:'.
-
-m.  A couple of bugs with `shopt -o' were fixed.
-
-n.  `bash +o' now displays the same output as `set +o' before starting an
-    interactive shell.
-
-o.  A bug that caused command substitution and the `eval' builtin to
-    occasionally free memory twice when an error was encountered was fixed.
-
-p.  The filename globbing code no longer requires read permission for a
-    directory when the filename to be matched does not contain any globbing
-    characters, as POSIX.2 specifies.
-
-q.  A bug was fixed so that the job containing the last asynchronous
-    process is not removed from the job table until a `wait' is executed
-    for that process or another asynchronous process is started.  This
-    satisfies a POSIX.2 requirement.
-
-r.  A `select' bug was fixed so that a non-numeric user response is treated
-    the same as a numeric response that is out of range.
-
-s.  The shell no longer parses the value of SHELLOPTS from the environment
-    if it is restricted, running setuid, or running in `privileged mode'.
-
-t.  Fixes were made to enable large file support on systems such as
-    Solaris 2.6, where the size of a file may be larger than can be held
-    in an `int'.
-
-u.  The filename hashing code was fixed to not add `./' to the beginning of
-    filenames which already begin with `./'.
-
-v.  The configure script was changed so that the GNU termcap library is not
-    compiled in if `prefer-curses' has been specified.
-
-w.  HISTCONTROL and HISTIGNORE are no longer applied to the second and
-    subsequent lines of a multi-line command.
-
-x.  A fix was made to `disown' so that it does a better job of catching
-    out-of-range jobs.
-
-y.  Non-interactive shells no longer report the status of processes terminated
-    due to SIGINT, even if the standard output is a terminal.
-
-z.  A bug that caused the output of `jobs' to have extra carriage returns
-    was fixed.
-
-aa. A bug that caused PIPESTATUS to not be set when builtins or shell
-    functions were executed in the foreground was fixed.
-
-bb. Bash now attempts to detect when it is being run by sshd, and treats
-    that case identically to being run by rshd.
-
-cc. A bug that caused `set -a' to export SHELLOPTS when one of the shell
-    options was changed was fixed.
-
-dd. The `kill' builtin now disallows empty or missing process id arguments
-    instead of treating them as identical to `0', which means the current
-    process.
-
-ee. `var=value declare -x var' now behaves identically to
-    `var=value export var'.  Similarly for `var=value declare -r var' and
-    `var=value readonly var'.
-
-ff. A few memory leaks were fixed.
-
-gg. `alias' and `unalias' now print error messages when passed an argument
-    that is not an alias for printing or deletion, even when the shell is
-    not interactive, as POSIX.2 specifies.
-
-hh. `alias' and `alias -p' now return a status of 0 when no aliases are
-    defined, as POSIX.2 specifes.
-
-ii. `cd -' now prints the pathname of the new working directory if the shell
-    is interactive.
-
-jj. A fix was made so that the code that binds $PWD now copes with getcwd()
-    returning NULL.
-
-kk. `unset' now checks whether or not a function name it's trying to unset
-    is a valid shell identifier only when the shell is running in posix mode.
-
-ll. A change was made to the code that generates filenames for here documents
-    to make them less prone to name collisions.
-
-mm. The parser was changed so that `time' is recognized as a reserved word
-    only at the beginning of a pipeline.
-
-nn. The pathname canonicalization code was changed so that `//' is converted
-    into `/', but all other pathnames beginning with `//' are left alone, as
-    POSIX.2 specifies.
-
-oo. The `logout' builtin will no longer exit a non-interactive non-login
-    shell.
-
-2.  Changes to Readline
-
-a.  Fixed a problem in the readline test program rltest.c that caused a core
-    dump.
-
-b.  The code that handles parser directives in inputrc files now displays
-    more error messages.
-
-c.  The history expansion code was fixed so that the appearance of the
-    history comment character at the beginning of a word inhibits history
-    expansion for that word and the rest of the input line.
-
-3.  New Features in Bash
-
-a.  A new version of malloc, based on the older GNU malloc, that has many
-    changes, is more page-based, is more conservative with memory usage,
-    and does not `orphan' large blocks when they are freed.
-
-b.  A new version of gmalloc, based on the old GLIBC malloc, with many
-    changes and range checking included by default.
-
-c.  A new implementation of fnmatch(3) that includes full POSIX.2 Basic
-    Regular Expression matching, including character classes, collating
-    symbols, equivalence classes, and support for case-insensitive pattern
-    matching.
-
-d.  ksh-88 egrep-style extended pattern matching ([@+*?!](patlist)) has been
-    implemented, controlled by a new `shopt' option, `extglob'.
-
-e.  There is a new ksh-like `[[' compound command, which implements
-    extended `test' functionality.
-
-f.  There is a new `printf' builtin, implemented according to the POSIX.2
-    specification.
-
-g.  There is a new feature for command substitution: $(< filename) now expands
-    to the contents of `filename', with any trailing newlines removed
-    (equivalent to $(cat filename)).
-
-h.  There are new tilde prefixes which expand to directories from the
-    directory stack.
-
-i.  There is a new `**' arithmetic operator to do exponentiation.
-
-j.  There are new configuration options to control how bash is linked:
-    `--enable-profiling', to allow bash to be profiled with gprof, and
-    `--enable-static-link', to allow bash to be linked statically.
-
-k.  There is a new configuration option, `--enable-cond-command', which
-    controls whether or not the `[[' command is included.  It is on by
-    default.
-
-l.  There is a new configuration option, `--enable-extended-glob', which
-    controls whether or not the ksh extended globbing feature is included.
-    It is enabled by default.
-
-m.  There is a new configuration #define in config.h.top that, when enabled,
-    will cause all login shells to source /etc/profile and one of the user-
-    specific login shell startup files, whether or not the shell is
-    interactive.
-
-n.  There is a new invocation option, `--dump-po-strings', to dump
-    a shell script's translatable strings ($"...") in GNU `po' format.
-
-o.  There is a new `shopt' option, `nocaseglob', to enable case-insensitive
-    pattern matching when globbing filenames and using the `case' construct.
-
-p.  There is a new `shopt' option, `huponexit', which, when enabled, causes
-    the shell to send SIGHUP to all jobs when an interactive login shell
-    exits.
-
-q.  `bind' has a new `-u' option, which takes a readline function name as an
-    argument and unbinds all key sequences bound to that function in a
-    specified keymap.
-
-r.  `disown' now has `-a' and `-r' options, to limit operation to all jobs
-    and running jobs, respectively.
-
-s.  The `shopt' `-p' option now causes output to be displayed in a reusable
-    format.
-
-t.  `test' has a new `-N' option, which returns true if the filename argument
-    has been modified since it was last accessed.
-
-u.  `umask' now has a `-p' option to print output in a reusable format.
-
-v.  A new escape sequence, `\xNNN', has been added to the `echo -e' and $'...'
-    translation code.  It expands to the character whose ascii code is NNN
-    in hexadecimal.
-
-w.  The prompt string expansion code has a new `\r' escape sequence.
-
-x.  The shell may now be cross-compiled for the CYGWIN32 environment on
-    a Unix machine.
-
-4.  New Features in Readline
-
-a.  There is now an option for `iterative' yank-last-arg handline, so a user
-    can keep entering `M-.', yanking the last argument of successive history
-    lines.
-
-b.  New variable, `print-completions-horizontally', which causes completion
-    matches to be displayed across the screen (like `ls -x') rather than up
-    and down the screen (like `ls').
-
-c.  New variable, `completion-ignore-case', which causes filename completion
-    and matching to be performed case-insensitively.
-
-d.  There is a new bindable command, `magic-space', which causes history
-    expansion to be performed on the current readline buffer and a space to
-    be inserted into the result.
-
-e.  There is a new bindable command, `menu-complete', which enables tcsh-like
-    menu completion (successive executions of menu-complete insert a single
-    completion match, cycling through the list of possible completions).
-
-f.  There is a new bindable command, `paste-from-clipboard', for use on Win32
-    systems, to insert the text from the Win32 clipboard into the editing
-    buffer.
-
-g.  The key sequence translation code now understands printf-style backslash
-    escape sequences, including \NNN octal escapes.  These escape sequences
-    may be used in key sequence definitions or macro values.
-
-h.  An `$include' inputrc file parser directive has been added.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.01.1-release,
-and the previous version, bash-2.01-release.
-
-1.  Changes to Bash
-
-a.  The select command was fixed to check the validity of the user's
-    input more strenuously.
-
-b.  A bug was fixed that prevented `time' from timing commands correctly
-    when supplied as an argument to `bash -c'.
-
-c.  A fix was made to the mail checking code to keep from adding the same
-    mail file to the list of files to check multiple times when parsing
-    $MAILPATH.
-
-d.  Fixed an off-by-one error in the tilde expansion library.
-
-e.  When using the compound array assignment syntax, the old value of
-    the array is cleared before assigning the new value.
-
-f.  Fixed a bug that could cause a core dump when a trap handler was reset
-    to the default in the trap command associated with that signal.
-
-g.  Fixed a bug in the locale code that occurred when assigning a value
-    to LC_ALL.
-
-h.  A change was made to the parser so that words of the form xxx=(...)
-    are not considered compound assignment statements unless there are
-    characters before the `='.
-
-i.  A fix was made to the command tracing code to correctly quote each
-    word of output.
-
-j.  Some changes were made to the bash-specific autoconf tests to make them
-    more portable.
-
-k.  Completion of words with globbing characters now correctly quotes the
-    result.
-
-l.  The directory /var/spool/mail is now preferred to /usr/spool/mail when
-    configure is deciding on the default mail directory.
-
-m.  The brace completion code was fixed to not quote the `{' and `}'.
-
-n.  Some fixes were made to make $RANDOM more random in subshells.
-
-o.  System-specific changes were made to configure for: SVR4.2
-
-p.  Changes were made so that completion of words containing globbing chars
-    substitutes the result only if a single filename was matched.
-
-q.  The window size is now recomputed after a job is stopped with SIGTSTP if
-    the user has set `checkwinsize' with `shopt'.
-
-r.  When doing substring expansion, out-of-range substring specifiers now
-    cause nothing to be substituted rather than an expansion error.
-
-s.  A fix was made so that you can no longer trap `SIGEXIT' or `SIGDEBUG' --
-    only `EXIT' and `DEBUG' are accepted.
-
-t.  The display of trapped signals now uses the signal number if signals
-    for which bash does not know the name are trapped.
-
-u.  A fix was made so that `bash -r' does not turn on restricted mode until
-    after the startup files are executed.
-
-v.  A bug was fixed that occasionally caused a core dump when a variable
-    found in the temporary environment of export/declare/readonly had a
-    null value.
-
-w.  A bug that occasionally caused unallocated memory to be passed to free()
-    when doing arithmetic substitution was fixed.
-
-x.  A bug that caused a buffer overrun when expanding a prompt string
-    containing `\w' and ${#PWD} exceeded PATH_MAX was fixed.
-
-y.  A problem with the completion code that occasionally caused it to
-    refer to a character before the beginning of the readline line buffer
-    was fixed.
-
-z.  A bug was fixed so that the `read' builtin restarts reads when
-    interrupted by signals other than SIGINT.
-
-aa. Fixed a bug that caused a command to be freed twice when there was
-    an evaluation error in the `eval' command.
-
-2.  Changes to Readline
-
-a.  Added a missing `extern' to a declaration in readline.h that kept
-    readline from compiling cleanly on some systems.
-
-b.  The history file is now opened with mode 0600 when it is written for
-    better security.
-
-c.  Changes were made to the SIGWINCH handling code so that prompt redisplay
-    is done better.
-
-d.  ^G now interrupts incremental searches correctly.
-
-e.  A bug that caused a core dump when the set of characters to be quoted
-    when completing words was empty was fixed.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.01-release,
-and the previous version, bash-2.01-beta2.
-
-1.  Changes to Bash
-
-a.  The `distclean' target should remove the `printenv' executable if it
-    has been created.
-
-b.  The test suite was changed slightly to ensure that the error messages
-    are printed in English.
-
-c.  A bug that caused the shell to dump core when a filename containing a
-    `/' was passed to `hash' was fixed.
-
-d.  Pathname canonicalization now leaves a leading `//' intact, as POSIX.1
-    requires.
-
-e.  A memory leak when completing commands was fixed.
-
-f.  A memory leak that occurred when checking the hash table for commands
-    with relative paths was fixed.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.01-beta2,
-and the previous version, bash-2.01-beta1.
-
-1.  Changes to Bash
-
-a.  The `ulimit' builtin translates RLIM_INFINITY to the hard limit only if
-    the current (soft) limit is less than or equal to the hard limit.
-
-b.  Fixed a bug that caused the bash emulation of strcasecmp to produce
-    incorrect results.
-
-c.  A bug that caused memory to be freed twice when a trap handler resets
-    the trap more than once was fixed.
-
-d.  A bug that caused machines where sizeof (pointer) > sizeof (int) to
-    fail (and possibly dump core) when trying to unwind-protect a null
-    pointer was fixed.
-
-e.  The startup files should not be run with job control enabled.  This fix
-    allows SIGINT to once again interrupt startup file execution.
-
-f.  Bash should not change the SIGPROF handler if it is set to something
-    other than SIG_DFL.
-
-g.  The completion code that provides bash-specific completions for readline
-    now quotes characters that the readline code would treat as word break
-    characters if they appear in a file name.
-
-h.  The completion code now correctly quotes filenames containing a `!',
-    even if the user attempted to use double quotes when attempting
-    completion.
-
-i.  A bug that caused the shell to dump core when `disown' was called without
-    arguments and there was no current job was fixed.
-
-j.  A construct like $((foo);bar) is now processed as a command substitution
-    rather than as a bad arithmetic substitution.
-
-k.  A couple of bugs that caused `fc' to not obey the `cmdhist' and `lithist'
-    shell options when editing and re-executing a series of commands were
-    fixed.
-
-l.  A fix was made to the grammar -- the list of commands between `do' and
-    `done' in the body of a `for' command should be treated the same as a
-    while loop.
-
-2.  Changes to Readline
-
-a.  A couple of bugs that caused the history search functions to attempt to
-    free a NULL pointer were fixed.
-
-b.  If the C library provides setlocale(3), readline does not need to look
-    at various environment variables to decide whether or not to go into
-    eight-bit mode automatically -- just check whether the current locale
-    is not `C' or `POSIX'.
-
-c.  If the filename completion function finds that a directory was not closed
-    by a previous (interrupted) completion, it closes the directory with
-    closedir().
-
-3.  New Features in Bash
-
-a.  New bindable readline commands:  history-and-alias-expand-line and
-    alias-expand-line.  The code was always in there, there was just no
-    way to execute it.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.01-beta1,
-and the previous version, bash-2.01-alpha1.
-
-1.  Changes to Bash
-
-a.  Fixed a problem that could cause file descriptors used for process
-    substitution to conflict with those used explicitly in redirections.
-
-b.  Made it easier to regenerate configure if the user changes configure.in.
-
-c.  ${GROUPS[0]} should always be the primary group, even on systems without
-    multiple groups.
-
-d.  Spelling correction is no longer enabled by default.
-
-e.  Fixes to quoting problems in `bashbug'.
-
-f.  OS-specific configuration changes were made for: Irix 6.
-
-g.  OS-specific code changes were made for: QNX.
-
-h.  A more meaningful message is now printed when the file in /tmp for a
-    here document cannot be created.
-
-i.  Many changes to the shell's variable initialization code to speed
-    non-interactive startup.
-
-j.  Changes to the non-job-control code so that it does not try to open
-    /dev/tty.
-
-k.  The output of `set' and `export' is once again sorted, as POSIX wants.
-
-l.  Fixed a problem caused by a recursive call reparsing the value of
-    $SHELLOPTS.
-
-m.  The tilde code no longer calls getenv() when it's compiled as part of
-    the shell, which should eliminate problems on systems that cannot
-    redefine getenv(), like the NeXT OS.
-
-n.  Fixed a problem that caused `bash -o' or `bash +o' to not list all
-    the shell options.
-
-o.  Fixed `ulimit' to convert RLIM_INFINITY to the appropriate hard limit
-    only if the hard limit is greater than the current (soft) limit.
-
-p.  Fixed a problem that arose when building bash in a different directory
-    than the source and y.tab.[ch] were remade with something other than
-    bison.  This came up most often on NetBSD.
-
-q.  Fixed a problem with completion -- it thought that `pwd`/[TAB] indicated
-    an unfinished command completion (`/), which generated errors.
-
-r.  The bash special tilde expansions (~-, ~+) are now attempted before
-    calling the standard tilde expansion code, which should eliminate the
-    problems people have been seeing with this on Solaris 2.5.1.
-
-s.  Added support for <stdarg.h> to places where it was missing.
-
-t.  Changed the code that reads the output of a command substitution to not
-    go through stdio.  This reduces the memory requirements and is faster.
-
-u.  A number of changes to speed up export environment creation were made.
-
-v.  A number of memory leaks were fixed as the result of running the test
-    scripts through Purify.
-
-w.  Fixed a bug that caused subshells forked to interpret executable
-    scripts without a leading `#!' to not reinitialize the values of
-    the shell options.
-
-2.  Changes to Readline
-
-a.  History library has less `#ifdef SHELL' code -- abstracted stuff out
-    into application-specific function hooks.
-
-b.  Readline no longer calls getenv() if it's compiled as part of the shell,
-    which should eliminate problems on systems that cannot redefine getenv(),
-    like the NeXT OS.
-
-c.  Fixed translation of ESC when `untranslating' macro values.
-
-d.  The region kill operation now fixes the mark if it ends up beyond the
-    boundaries of the line after the region is deleted.
-
-3.  New Features in Bash
-
-a.  New argument for `configure':  `--with-curses'.  This can be used to
-    override the selection of the termcap library on systems where it is
-    deficient.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.01-alpha1,
-and the previous version, bash-2.0-release.
-
-1.  Changes to Bash
-
-a.  System-specific configuration changes for: FreeBSD, SunOS4, Irix,
-    MachTen, QNX 4.2, Harris Night Hawk, SunOS5.
-
-b.  System-specific code changes were made for: Linux, 4.4 BSD, QNX 4.2,
-    HP-UX, AIX 4.2.
-
-c.  A bug that caused the exec builtin to fail because the full pathname of
-    the command could not be found was fixed.
-
-d.  The code that performs output redirections is now more resistant to
-    race conditions and possible security exploits.
-
-e.  A bug that caused the shell to dump core when performing pattern
-    substitutions on variable values was fixed.
-
-f.  More hosts are now recognized by the auto-configuration mechanism
-    (OpenBSD, QNX, others).
-
-g.  Assignments to read-only variables that attempt to convert them to
-    arrays are now errors.
-
-h.  A bug that caused shell scripts using array assignments in POSIX mode
-    to exit after the assignment was performed was fixed.
-
-i.  The substring expansion code is now more careful about running off the
-    ends of the expanded variable value.
-
-j.  A bug that caused completion to fail if a backquoted command substitution
-    appeared anywhere on the line was fixed.
-
-k.  The `source' builtin no longer turns off history if it has been enabled
-    in a non-interactive shell.
-
-l.  A bug that caused the shell to crash when `disown' was given a pid
-    instead of a job number was fixed.
-
-m.  The `cd' spelling correction code will not try to change to `.' if no
-    directory entries match a single-character argument.
-
-n.  A bad variable name supplied to `declare', `export', or `readonly' no
-    longer causes a non-interactive shell in POSIX mode to exit.
-
-o.  Some fixes were made to the test suite to handle peculiarities of
-    various Unix versions.
-
-p.  The bash completion code now quotes characters that readline would
-    treat as word breaks for completion but are not shell metacharacters.
-
-q.  Bad options supplied at invocation now cause a usage message to be
-    displayed.
-
-r.  Fixes were made to the code that handles DEBUG traps so that the trap
-    string is not freed inappropriately.
-
-s.  Some changes were made to the bash debugger in examples/bashdb -- it
-    should be closer to working now.
-
-t.  A problem that caused the default filename used for mail checking to be
-    wrong was fixed.
-
-u.  A fix was made to the `echo' builtin so that NUL characters printed with
-    `echo -e' do not cause the output to be truncated.
-
-v.  A fix was made to the job control code so that the shell behaves better
-    when monitor mode is enabled in a non-interactive shell.
-
-w.  Bash no longer catches all of the terminating signals in a non-
-    interactive shell until a trap is set on EXIT, which should result in
-    quicker startup.
-
-x.  A fix was made to the command timing code so that `time' can be used in
-    a loop.
-
-y.  A fix was made to the parser so that `((cmd); cmd2)' is now parsed as
-    a nested subshell rather than strictly as an (erroneous) arithmetic
-    command.
-
-z.  A fix was made to the globbing code so that it correctly matches quoted
-    filenames beginning with a `.'.
-
-aa. A bug in `fc' that caused some multi-line commands to not be stored as
-    one command in the history when they were re-executed after editing
-    (with `fc -e') was fixed.
-
-bb. The `ulimit' builtin now attempts to catch some classes of integer
-    overflows.
-
-cc. The command-oriented-history code no longer attempts to add `;'
-    inappropriately when a newline appears while reading a $(...) command
-    substitution.
-
-dd. A bug that caused the shell to dump core when `help --' was executed
-    was fixed.
-
-ee. A bug that caused the shell to crash when an unset variable appeared
-    in the body of a here document after `set -u' had been executed was
-    fixed.
-
-ff. Implicit input redirections from /dev/null for asynchronous commands
-    are now handled better.
-
-gg. A bug that caused the shell to fail to compile when configured with
-    `--disable-readline' was fixed.
-
-hh. The globbing code should now be interruptible.
-
-ii. Bash now notices when the `kill' builtin is used to send SIGCONT to a
-    stopped job and adjusts the data structures accordingly, as if `bg' had
-    been executed instead.
-
-jj. A bug that caused the shell to crash when mixing calls to `getopts'
-    and `shift' on the same set of positional parameters was fixed.
-
-kk. The command printing code now preserves the `-p' flag to `time'.
-
-ll. The command printing code now handles here documents better when there
-    are other redirections associated with the command.
-
-mm. The special glibc environment variable (NNN_GNU_nonoption_argv_flags_)
-    is no longer placed into the environment of executed commands -- users
-    of glibc had too many problems with it.
-
-nn. Reorganized the code that generates signames.h.  The signal_names list
-    is now more complete but may be slightly different (SIGABRT is favored
-    over SIGIOT, for example).  The preferred signal names are those
-    listed in the POSIX.2 standard.
-
-oo. `bashbug' now uses a filename shorter than 14 characters for its
-    temporary file, and asks for confirmation before sending the bug
-    report.
-
-pp. A bug that caused TAB completion in vi editing mode to not be turned
-    off when `set -o posix' was executed or back on when `set +o posix'
-    was executed was fixed.
-
-qq. A bug in the brace expansion code that caused brace expansions appearing
-    in new-style $(...) command substitutions to be inappropriately expanded
-    was fixed.
-
-rr. A bug in the readline hook shell-expand-line that could cause memory to
-    be inappropriately freed was fixed.
-
-ss. A bug that caused some arithmetic expressions containing `&&' and `||'
-    to be parsed with the wrong precedence has been fixed.
-
-tt. References to unbound variables after `set -u' has been executed now
-    cause the shell to exit immediately, as they should.
-
-uu. A bug that caused the shell to exit inappropriately when `set -e' had
-    been executed and a command's return status was being inverted with the
-    `!' reserved word was fixed.
-
-vv. A bug that could occasionally cause the shell to crash with a
-    divide-by-zero error when timing a command was fixed.
-
-ww. A bug that caused parameter pattern substitution to leave stray
-    backslashes in the replacement string when the expression is in
-    double quotes was fixed.
-
-xx. The `break' and `continue' builtins now break out of all loops when an
-    invalid count argument is supplied.
-
-yy. Fixed a bug that caused PATH to be set to the empty string if
-    `command -p' is executed with PATH unset.
-
-zz. Fixed `kill -l signum' to print the signal name without the `SIG' prefix,
-    as POSIX specifies.
-
-aaa. Fixed a bug that caused the shell to crash while setting $SHELLOPTS
-     if there were no shell options set.
-
-bbb. Fixed `export -p' and `readonly -p' so that when the shell is in POSIX
-     mode, their output is as POSIX.2 specifies.
-
-ccc. Fixed a bug in `readonly' so that `readonly -a avar=(...)' actually
-     creates an array variable.
-
-ddd. Fixed a bug that prevented `time' from correctly timing background
-     pipelines.
-
-2.  Changes to Readline
-
-a.  A bug that caused an extra newline to be printed when the cursor was on
-    an otherwise empty line was fixed.
-
-b.  An instance of memory being used after it was freed was corrected.
-
-c.  The redisplay code now works when the prompt is longer than the screen
-    width.
-
-d.  `dump-macros' is now a bindable name, as it should have been all along.
-
-e.  Non-printable characters are now expanded when displaying macros and
-    their values.
-
-f.  The `dump-variables' and `dump-macros' commands now output a leading
-    newline if they're called as the result of a key sequence, rather
-    than directly by an application.
-
-3.  New Features in Bash
-
-a.  There is a new builtin array variable: GROUPS, the set of groups to which
-    the user belongs.  This is used by the test suite.
-
-4.  New Features in Readline
-
-a.  If a key sequence bound to `universal-argument' is read while reading a
-    numeric argument started with `universal-argument', it terminates the
-    argument but is otherwise ignored.  This provides a way to insert multiple
-    instances of a digit string, and is how GNU emacs does it.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.0-release,
-and the previous version, bash-2.0-beta3.
-
-1.  Changes to Bash
-
-a.  Fix to the `getopts' builtin so that it does the right thing when a
-    required option argument is not present.
-
-b.  The completion code now updates the common prefix of matched names
-    after FIGNORE processing is done, since any names that were removed
-    may have changed the common prefix.
-
-c.  Fixed a bug that made messages in MAILPATH entries not work correctly.
-
-d.  Fixed a serious documentation error in the description of the new
-    ${parameter:offset[:length]} expansion.
-
-e.  Fixes to make parameter substring expansion ({$param:offset[:length]})
-    work when within double quotes.
-
-f.  Fixes to make ^A (CTLESC) survive an unquoted expansion of positional
-    parameters.
-
-g.  Corrected a misspelling of `unlimited' in the output of `ulimit'.
-
-h.  Fixed a bug that caused executable scripts without a leading `#!' to
-    occasionally pick up the wrong set of positional parameters.
-
-i.  Linux systems now have a working `ulimit -v', using RLIMIT_AS.
-
-j.  Updated config.guess so that many more machine types are recognized.
-
-k.  Fixed a bug with backslash-quoted slashes in the ${param/pat[/sub]}
-    expansion.
-
-l.  If the shell is named `-su', and `-c command' is supplied, read and
-    execute the login shell startup files even though the shell is not
-    interactive.  This is to support the `-' option to `su'.
-
-m.  Fixed a bug that caused core dumps when the DEBUG trap was ignored
-    with `trap "" DEBUG' and a shell function was subsequently executed.
-
-n.  Fixed a bug that caused core dumps in the read builtin when IFS was
-    set to the null string and the input had leading whitespace.
-
-2.  Changes to Readline
-
-a.  Fixed a bug that caused a numeric argument of 1024 to be ignored when
-    inserting text.
-
-b.  Fixed the display code so that the numeric argument is displayed as it's
-    being entered.
-
-c.  Fixed the numeric argument reading code so that `M-- command' is
-    equivalent to `M--1 command', as the prompt implies.
-
-3.  New Features in Bash
-
-a.  `ulimit' now sets both hard and soft limits and reports the soft limit
-    by default (when neither -H nor -S is specified).  This is compatible
-    with versions of sh and ksh that implement `ulimit'.
-
-b.  Integer constants have been extended to base 64.
-
-4.  New Features in Readline
-
-a.  The `home' and `end' keys are now bound to beginning-of-line and
-    end-of-line, respectively, if the corresponding termcap capabilities
-    are present.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.0-beta3,
-and the previous version, bash-2.0-beta2.
-
-1.  Changes to Bash
-
-a.  System-specific changes for: AIX 4.2, SCO 3.2v[45], HP-UX.
-
-b.  When in POSIX mode, variable assignments preceding a special builtin
-    persist in the shell environment after the builtin completes.
-
-c.  Changed all calls to getwd() to getcwd().  Improved check for systems
-    where the libc getcwd() calls popen(), since that breaks on some
-    systems when job control is being used.
-
-d.  Fixed a bug that caused seg faults when executing scripts with the
-    execute bit set but without a leading `#!'.
-
-e.  The environment passed to executed commands is never sorted.
-
-f.  A bug was fixed in the code that expands ${name[@]} to the number of
-    elements in an array variable.
-
-g.  A bug was fixed in the array compound assignment code ( A=( ... ) ).
-
-h.  Window size changes now correctly propagate down to readline if
-    the shopt `checkwinsize' option is enabled.
-
-i.  A fix was made in the code that expands to the length of a variable
-    value (${#var}).
-
-j.  A fix was made to the command builtin so that it did not turn on the
-    `no fork' flag inappropriately.
-
-k.  A fix was made to make `set -n' work more reliably.
-
-l.  A fix was made to the job control initialization code so that the
-    terminal process group is set to the shell's process group if the
-    shell changes its own process group.
-
-2.  Changes to Readline
-
-a.  System-specific changes for: SCO 3.2v[45].
-
-b.  The behavior of the vi-mode `.' when redoing an `i' command was changed
-    to insert the text previously inserted by the `i' command rather than
-    simply entering insert mode.
-
-3.  New features in Bash
-
-a.  There is a new version of the autoload function package, in
-    examples/functions/autoload.v2, that uses arrays and provides more
-    functionality.
-
-b.  Support for LC_COLLATE and locale-specific sorting of the results of
-    pathname expansion if strcoll() is available.
-
-4.  New Features in Readline
-
-a.  Support for locale-specific sorting of completion possibilities if
-    strcoll() is available.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.0-beta2,
-and the previous version, bash-2.0-beta1.
-
-1.  Changes to Bash
-
-a.  `pushd -' is once again equivalent to `pushd $OLDPWD'.
-
-b.  OS-specific changes for: SCO 3.2v[45].
-
-c.  A change was made to the fix for the recently-reported security hole
-    when reading characters with octal value 255 to make it work better on
-    systems with restartable system calls when not using readline.
-
-d.  Some changes were made to the test suite so that it works if you
-    configure bash with --enable-usg-echo-default.
-
-e.  A fix was made to the parsing of conditional arithmetic expressions.
-
-f.  Illegal arithmetic bases now cause an arithmetic evaluation error rather
-    than being silently reset.
-
-g.  Multiple arithmetic bases now cause an arithmetic evaluation error
-    instead of being ignored.
-
-h.  A fix was made to the evaluation of ${param?word} to conform to POSIX.2.
-
-i.  A bug that sometimes caused array indices to be evaluated twice (which
-    would cause errors when they contained assignment statements) was fixed.
-
-j.  `ulimit' was rewritten to avoid problems with getrlimit(2) returning
-    unsigned values and to simplify the code.
-
-k.  A bug in the command-oriented-history code that caused it to sometimes
-    put semicolons after right parens inappropriately was fixed.
-
-l.  The values inserted into the prompt by the \w and \W escape sequences
-    are now quoted to prevent further expansion.
-
-m.  An interactive shell invoked as `sh' now reads and executes commands
-    from the file named by $ENV when it starts up.  If it's a login shell,
-    it does this after reading /etc/profile and ~/.profile.
-
-n.  The file named by $ENV is never read by non-interactive shells.
-
-2.  Changes to Readline
-
-a.  A few changes were made to hide some macros and functions that should not
-    be public.
-
-b.  An off-by-one error that caused seg faults in the history expansion code
-    was fixed.
-
-3.  New Features in Bash
-
-a.  The ksh-style ((...)) arithmetic command was implemented.  It is exactly
-    identical to let "...".  This is controlled by a new option to configure,
-    `--enable-dparen-arithmetic', which is on by default.
-
-b.  There is a new #define available in config.h.top: SYS_BASH_LOGOUT.  If
-    defined to a filename, bash reads and executes commands from that file
-    when a login shell exits.  It's commented out by default.
-
-c.  `ulimit' has a `-l' option that reports the maximum amount of data that
-    may be locked into memory on 4.4BSD-based systems.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.0-beta1,
-and the previous version, bash-2.0-alpha4.
-
-1.  Changes to Bash
-
-a.  A bug that sometimes caused traps to be ignored on signals the
-    shell treats specially was fixed.
-
-b.  The internationalization code was changed to track the values of
-    LC_* variables and call setlocale() as appropriate.  The TEXTDOMAIN
-    and TEXTDOMAINDIR variables are also tracked; changes cause calls
-    to textdomain() and bindtextdomain(), if available.
-
-c.  A bug was fixed that sometimes caused double-quoted strings to be
-    parsed incorrectly.
-
-d.  Changes were made so that the siglist code compiles correctly on
-    Solaris 2.5.
-
-e.  Added `:' to the set of characters that cause word breaks for the
-    completion code so that pathnames in assignments to $PATH can be
-    completed.
-
-f.  The `select' command was fixed to print $PS3 to stderr.
-
-g.  Fixed an error in the manual page section describing the effect that
-    setting and unsetting GLOBIGNORE has on the setting of the `dotglob'
-    option.
-
-h.  The time conversion code now uses CLK_TCK rather than CLOCKS_PER_SEC
-    on systems without gettimeofday() and resources.
-
-i.  The getopt static variables are now initialized each time a subshell
-    is started, so subshells using `getopts' work right.
-
-j.  A sign-extension bug that caused a possible security hole was fixed.
-
-k.  The parser now reads characters between backquotes within a double-
-    quoted string as a single word, so double quotes in the backquoted
-    string don't terminate the enclosing double-quoted string.
-
-l.  A bug that caused `^O' to work incorrectly when typed as the first
-    thing to an interactive shell was fixed.
-
-m.  A rarely-exercised off-by-one error in the code that quotes variable
-    values was fixed.
-
-n.  Some memory and file descriptor leaks encountered when running a
-    shell script that is executable but does not have a leading `#!'
-    were plugged.
-
-2.  Changes to Readline
-
-a.  A bug that sometimes caused incorrect results when trying to read
-    typeahead on systems without FIONREAD was fixed.
-
-3.  New Features in Bash
-
-a.  The command timing code now uses the value of the TIMEFORMAT variable
-    to format and display timing statistics.
-
-b.  The `time' reserved word now accepts a `-p' option to force the
-    POSIX.2 output format.
-
-c.  There are a couple of new and updated scripts to convert csh startup
-    files to bash format.
-
-d.  There is a new builtin array variable: BASH_VERSINFO.  The various
-    members hold the parts of the version information in BASH_VERSION,
-    plus the value of MACHTYPE.
-
-4.  New Features in Readline
-
-a.  Setting LANG to `en_US.ISO8859-1' now causes readline to enter
-    eight-bit mode.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.0-alpha4,
-and the previous version, bash-2.0-alpha3.
-
-1.  Changes to Bash
-
-a.  There is better detection of rsh connections on Solaris 2.
-
-b.  Assignments to read-only variables preceding a command name are now
-    variable assignment errors.  Variable assignment errors cause
-    non-interactive shells running in posix mode to exit.
-
-c.  The word tokenizer was rewritten to handle nested quotes and pairs
-    ('', "", ``, ${...}, $(...), $[...], $'...', $"...", <(...), >(...))
-    correctly.  Some of the parameter expansion code was updated as a
-    consequence.
-
-d.  A fix was made to `test' when given three arguments so that a binary
-    operator is checked for first, before checking that the first argument
-    is `!'.
-
-e.  2''>/dev/null is no longer equivalent to 2>/dev/null.
-
-f.  Parser error messages were regularized, and in most cases the name of
-    the shell script being read by a non-interactive shell is not printed
-    twice.
-
-g.  A fix was made to the completion code so that it no longer removes the
-    text the user typed in some cases.
-
-h.  The special glibc `getopt' environment variable is no longer put into
-    the environment on machines with small values of ARG_MAX.
-
-i.  The expansion of ${...} now follows the POSIX.2 rules for finding the
-    closing `}'.
-
-j.  The shell no longer displays spurious status messages for background
-    jobs in shell scripts that complete successfully when the script is
-    run from a terminal.
-
-k.  `shopt -o' now correctly updates $SHELLOPTS.
-
-l.  A bug that caused the $PATH searching code to return a non-executable
-    file even when an executable file with the same name appeared later in
-    $PATH was fixed.
-
-m.  The shell now does tilde expansions on unquoted `:~' in assignment
-    statements when not in posix mode.
-
-n.  Variable assignment errors when a command consists only of assignments
-    now cause non-interactive shells to exit when in posix mode.
-
-o.  If the variable in a `for' or `select' command is read-only, or not a
-    legal shell identifier, a variable assignment error occurs.
-
-p.  `test' now handles `-a' and `-o' as binary operators when three arguments
-    are supplied, and correctly parses `( word )' as equivalent to `word'.
-
-q.  `test' was fixed so that file names of the form /dev/fd/NN mean the same
-    thing on all systems, even Linux.
-
-r.  Fixed a bug in the globbing code that caused patterns with multiple
-    consecutive `*'s to not be matched correctly.
-
-s.  Fixed a bug that caused $PS2 to not be printed when an interactive shell
-    not using readline is reading a here document.
-
-t.  Fixed a bug that caused history expansion to be performed inappropriately
-    when a single-quoted string spanned more than one line.
-
-u.  `getopts' now checks that the variable name passed by the user as the
-    second argument is a legal shell identifier and that the variable is
-    not read-only.
-
-v.  Fixed `getopts' to obey POSIX.2 rules for setting $OPTIND when it
-    encounters an error.
-
-w.  Fixed `set' to display variable values in a form that can be re-read.
-
-x.  Fixed a bug in the code that keeps track of whether or not local variables
-    have been declared at the current level of function nesting.
-
-y.  Non-interactive shells in posix mode now exit if the name in a function
-    declaration is not a legal identifier.
-
-z.  The job control code now ignores stopped children when the shell is not
-    interactive.
-
-aa. The `cd' builtin no longer attempts spelling correction on the directory
-    name if the shell is not interactive, regardless of the setting of the
-    `cdspell' option.
-
-bb. Some OS-specific changes were made for SCO 3.2v[45] and AIX 4.2.
-
-cc. `time' now prints its output to stderr, as POSIX.2 specifies.
-
-2.  Fixes to Readline
-
-a.  After printing possible completions, all lines of a multi-line prompt
-    are redisplayed.
-
-b.  Some changes were made to the terminal handling code in rltty.c to
-    work around AIX 4.2 bugs.
-
-3.  New Features in Bash
-
-a.  There is a new loadable builtin: sprintf, with calling syntax
-               sprintf var format [args]
-    This provides an easy way to simulate ksh left- and right-justified
-    variable values.
-
-b.  The expansions of \h and \H in prompt strings were swapped.  \h now
-    expands to the hostname up to the first `.', as in bash-1.14.
-
-4.  New Features in Readline
-
-a.  The bash-1.14 behavior when ^M is typed while doing an incremental
-    search was restored.  ^J may now be used to terminate the search without
-    accepting the line.
-
-b.  There is a new bindable variable: disable-completion.  This inhibits
-    word completion and causes the completion character to be inserted as
-    if it had been bound to self-insert.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.0-alpha3,
-and the previous version, bash-2.0-alpha2.
-
-There is now a file `COMPAT' included in the distribution that lists the
-user-visible incompatibilities between 1.14 and 2.0.
-
-1. Changes to Bash
-
-a. Some work was done so that word splitting of the rhs of assignment
-   statements conforms more closely to historical practice.
-
-b. A couple of errant memory frees were fixed.
-
-c. A fix was made to the test builtin so it recognizes `<' and `>' as
-   binary operators.
-
-d. The GNU malloc in lib/malloc/malloc.c now scrambles memory as it's
-   allocated and freed.  This is to catch callers that refer to freed
-   memory or assume something about newly-allocated memory.
-
-e. Fixed a problem with conversion to 12-hour time in the prompt
-   expansion code.
-
-f. Fixed a problem with configure's argument parsing order.  Now you can
-   correctly turn on specific options after using --enable-minimal-config.
-
-g. The configure script now automatically disables the use of GNU malloc
-   on systems where it's appropriate (better than having people read the
-   NOTES file and do it manually).
-
-h. There are new prompt expansions (\v and \V) to insert version information
-   into the prompt strings.
-
-i. The default prompt string now includes the version number.
-
-j. Most of the builtins that take no options were changed to use the
-   internal getopt so they can produce proper error messages for -?
-   and incorrect options.
-
-k. Some system-specific changes were made for SVR4.2 and Solaris 2.5.
-
-l. Bash now uses PATH_MAX instead of MAXPATHLEN and NAME_MAX instead of
-   MAXNAMLEN.
-
-m. A couple of problems caused by uninitialized variables were fixed.
-
-n. There are a number of new loadable builtin examples: logname, basename,
-   dirname, tty, pathchk, tee, head, and rmdir.  All of these conform to
-   POSIX.2.
-
-o. Bash now notices changes in TZ and calls tzset() if present, so
-   changing TZ will alter the time printed by prompt expansions.
-
-p. The source was reorganized a bit so I don't have to wait so long for
-   some files to compile, and to facilitate the creation of a `shell
-   library' at some future point.
-
-q. Bash no longer turns off job control if called as `sh', since the
-   POSIX.2 spec includes job control as a standard feature.
-
-r. `bash -o posix' now works as intended.
-
-s. Fixed a problem with the completion code: when completing a filename
-   that contained globbing characters, if show-all-if-ambiguous was set,
-   the completion code would remove the user's text.
-
-t. Fixed ulimit so that (hopefully) the full range of limits is available
-   on HPUX systems.
-
-u. A new `shopt' option (`hostcomplete') enables and disables hostname
-   completion.
-
-v. The shell no longer attempts to save the history on an abort(),
-   which is usually called by programming_error().
-
-w. The `-s' option to `fc' was changed to echo the command to be executed
-   to stderr instead of stdout.
-
-x. If the editor invoked by `fc -e' exits with a non-zero status, no
-   commands are executed.
-
-y. Fixed a bug that made the shopt `histverify' option work incorrectly.
-
-z. There is a new variable `MACHTYPE' whose value is the GNU-style
-   `cpu-company-system' system description as set by configure.  (The
-   values of MACHTYPE and HOSTTYPE should really be swapped.)
-
-aa. The `ulimit' builtin now allows the maximum virtual memory size to be
-    set via setrlimit(2) if RLIMIT_VMEM is defined.
-
-bb. `bash -nc 'command'' no longer runs `command'.
-
-2. Changes to Readline
-
-a. Fixed a typo in the code that checked for FIONREAD in input.c.
-
-b. Fixed a bug in the code that outputs keybindings, so things like C-\
-   are quoted properly.
-
-c. Fixed a bug in the inputrc file parsing code to handle the problems
-   caused by inputrc files created from the output of `bind -p' in
-   previous versions of bash.  The problem was due to the bug fixed
-   in item b above.
-
-d. Readline no longer turns off the terminal's meta key, and turns it on
-   once the first time it's called.
-
-------------------------------------------------------------------------------
-This file documents the changes between this version, bash-2.0-alpha2,
-and the previous version, bash-2.0-alpha.
-
-1. Changes to Bash
-
-a. The shell no longer thinks directories are executable.
-
-b. `disown' has a new option, `h', which inhibits the resending of SIGHUP
-   but does not remove the job from the jobs table.
-
-c. The varargs functions in error.c now use ANSI-C `stdarg' if available.
-
-d. The build process now treats the `build version' in .build as local to
-   the build directory, so different versions built from the same source
-   tree have different `build versions'.
-
-e. Some problems with the grammar have been fixed. (It used `list' in a few
-   productions where `compound_list' was needed.  A `list' must be terminated
-   with a newline or semicolon; a `compound_list' need not be.)
-
-f. A fix was made to keep `wait' from hanging when waiting for all background
-   jobs.
-
-g. `bash --help' now writes its output to stdout, like the GNU Coding Standards
-   specify, and includes the machine type (the value of MACHTYPE).
-
-h. `bash --version' now prints more information and exits successfully, like
-   the GNU Coding Standards specify.
-
-i. The output of `time' and `times' now prints fractional seconds with three
-   places after the decimal point.
-
-j. A bug that caused process substitutions to screw up the pipeline printed
-   by `jobs' was fixed.
-
-k. Fixes were made to the code that implements $'...' and $"..." so they
-   work as documented.
-
-l. The process substitution code now opens named pipes for reading with
-   O_NONBLOCK to avoid hanging.
-
-m. Fixes were made to the trap code so the shell cleans up correctly if the
-   trap command contains a `return' and we're executing a function or
-   sourcing a script with `.'.
-
-n. Fixes to doc/Makefile.in so that it doesn't try to remake all of the
-   documentation (ps, dvi, etc.) on a `make install'.
-
-o. Fixed an auto-increment error that caused bash -c args to sometimes dump
-   core.
-
-p. Fixed a bug that caused $HISTIGNORE to fail when the history line
-   contained globbing characters.
-
-2. Changes to Readline
-
-a. There is a new string variable, rl_library_version, available for use by
-   applications.  The current value is "2.1".
-
-b. A bug encountered when expand-tilde was enabled and file completion was
-   attempted on a word beginning with `~/' was fixed.
-
-c. A slight change was made to the incremental search termination behavior.
-   ESC still terminates the search, but if input is pending or arrives
-   within 0.1 seconds (on systems with select(2)), it is used as a prefix
-   character.  This is intented to allow users to terminate searches with
-   the arrow keys and get the behavior they expect.
diff --git a/CHANGES~ b/CHANGES~
deleted file mode 100644 (file)
index 9ae3324..0000000
--- a/CHANGES~
+++ /dev/null
@@ -1,6565 +0,0 @@
-This document details the changes between this version, bash-4.1-beta,
-and the previous version, bash-4.1-alpha.
-
-1.  Changes to Bash
-
-a.  Fixed a bug in mapfile that caused the shell to crash if it was passed the
-    name of an associative array.
-
-b.  Fixed a bug that caused the shell to incorrectly split case patterns if
-    they contained characters in $IFS.
-
-c.  Fixed a bug that caused the shell to set $? to the wrong value when using
-    a construct ending with a variable assignment with set -x enabled and PS4
-    containing a command substitution.
-
-d.  Fixed a bug that caused the shell to read commands incorrectly if an
-    expansion error occurred under certain conditions in a user-specified
-    subshell.
-
-e.  Fixed a bug that caused the shell to set $? incorrectly if a parse error
-    occurred in an evaluation context ("eval", trap command, dot script, etc.)
-
-f.  Fixed a bug that caused the shell to attempt command substitution
-    completion within a single-quoted string.
-
-g.  Fixed a bug that caused the shell to insert an extra single quote during
-    word completion.
-
-h.  Fixed a bug that caused the shell to crash if invoked with the environment
-    variable EMACS having a null value.
-
-i.  Fixed a bug that caused bash to incorrectly report the presence of new
-    mail in a `maildir' environment.
-
-j.  Fixed a bug that caused the shell to not recognize a here-document ending
-    delimiter inside a command substitution.
-
-k.  Fixed a bug that caused the shell to crash when a a dynamic array variable
-    was assigned a scalar value.
-
-2.  Changes to Readline
-
-3.  New Features in Bash
-
-a.  The mapfile/readarray builtin no longer stores the commands it invokes via
-    callbacks in the history list.
-
-b.  There is a new `compat40' shopt option.
-
-c.  The < and > operators to [[ do string comparisons using the current locale
-    only if the compatibility level is greater than 40 (set to 41 by default).
-
-4.  New Features in Readline
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-4.1-alpha,
-and the previous version, bash-4.0-release.
-
-1.  Changes to Bash
-
-a.  Fixed bugs in the parser involving new parsing of the commands contained
-    in command substitution when the substitution is read.
-
-b.  Fixed a bug that caused the shell to dump core when performing programmable
-    completion using a shell function.
-
-c.  Fixed a bug in `mapfile' that caused it to invoke callbacks at the wrong
-    time.
-
-d.  Fixed a bug that caused the shell to dump core when listing jobs in the
-    `exit' builtin.
-
-e.  Fixed several bugs encountered when reading subscripts in associative
-    array assignments and expansions.
-
-f.  Fixed a bug that under some circumstances caused an associative array to
-    be converted to an indexed array.
-
-g.  Fixed a bug that caused syntax errors and SIGINT interrupts to not set
-    $? to a value > 128.
-
-h.  Fixed a bug that caused the shell to remove FIFOs associated with process
-    substitution inside shell functions.
-
-i.  Fixed a bug that caused terminal attributes to not be reset when the
-    `read' builtin timed out.
-
-j.  Fixed a bug in brace expansion that caused unwanted zero padding of the
-    expanded terms.
-
-k.  Fixed a bug that prevented the |& construct from working as intended when
-    used with a simple command with additional redirections.
-
-l.  Fixed a bug with the case statment ;& terminator that caused the shell to
-    dereference a NULL pointer.
-
-m.  Fixed a bug that caused assignment statements or redirections preceding
-    a simple command name to inhibit alias expansion.
-
-n.  Fixed the behavior of `set -u' to conform to the latest Posix interpretation:
-    every expansion of an unset variable except $@ and $* will cause the
-    shell to exit.
-
-o.  Fixed a bug that caused double-quoted expansions of $* inside word
-    expansions like ${x#$*} to not expand properly when $IFS is empty.
-
-p.  Fixed a bug that caused traps to set $LINENO to the wrong value when they
-    execute.
-
-q.  Fixed a bug that caused off-by-one errors when computing history lines in
-    the `fc' builtin.
-
-r.  Fixed a bug that caused some terminating signals to not exit the shell
-    quickly enough, forcing the kernel to send the signal (e.g., SIGSEGV)
-    multiple times.
-
-s.  Fixed a bug that caused the shell to attempt to add empty lines to the
-    history list when reading here documents.
-
-t.  Made some internal changes that dramatically speeds up sequential indexed
-    array access.
-
-u.  Fixed a bug that caused the shell to write past the end of a string when
-    completing a double-quoted string ending in a backslash.
-
-v.  Fixed a bug that caused the shell to replace too many characters when a
-    pattern match was null in a ${foo//bar} expansion.
-
-w.  Fixed bugs in the expansion of ** that caused duplicate directory names
-    and the contents of the current directory to be omitted.
-
-x.  Fixed a bug that caused $? to not be set correctly when referencing an
-    unset variable with set -u and set -e enabled.
-
-y.  Fixed a bug caused by executing an external program from the DEBUG trap
-    while a pipeline was running.  The effect was to disturb the pipeline
-    state, occasionally causing it to hang.
-
-z.  Fixed a bug that caused the ** glob expansion to dump core if it
-    encountered an unsearchable directory.
-
-aa. Fixed a bug that caused `command -v' and `command -V' to not honor the
-    path set by the -p option.
-
-bb. Fixed a bug that caused brace expansion to take place too soon in some
-    compound array assignments.
-
-cc. Fixed a bug that caused programmable completion functions' changes to
-    READLINE_POINT to not be reflected back to readline.
-
-dd. Fixed a bug that caused the shell to dump core if a trap was executed
-    during a shell assignment statement.
-
-ee. Fixed an off-by-one error when computing the number of positional
-    parameters for the ${@:0:n} expansion.
-
-ff. Fixed a problem with setting COMP_CWORD for programmable completion
-    functions that could leave it set to -1.
-
-gg. Fixed a bug that caused the ERR trap to be triggered in some cases where
-    `set -e' would not have caused the shell to exit.
-
-hh. Fixed a bug that caused changes made by `compopt' to not persist past the
-    completion function in which compopt was executed.
-
-ii. Fixed a bug that caused the list of hostname completions to not be cleared
-    when HOSTNAME was unset.
-
-jj. Fixed a bug that caused variable expansion in here documents to look in
-    any temporary environment.
-
-kk. Bash and readline can now convert file names between precomposed and
-    decomposed Unicode on Mac OS X ("keyboard" and file system forms,
-    respectively).  This affects filename completion (using new
-    rl_filename_rewrite_hook), globbing, and readline redisplay.
-
-ll. The ERR and EXIT traps now see a non-zero value for $? when a parser
-    error after set -e has been enabled causes the shell to exit.
-
-mm. Fixed a bug that in brace expansion that caused zero-prefixed terms to
-    not contain the correct number of digits.
-
-nn. Fixed a bug that caused the shell to free non-allocated memory when
-    unsetting an associative array which had had a value implicitly assigned
-    to index "0".
-
-oo. Fixed a memory leak in the ${!prefix@} expansion.
-
-pp. Fixed a bug that caused printf to not correctly report all write errors.
-
-qq. Fixed a bug that caused single and double quotes to act as delimiters
-    when splitting a command line into words for programmable completion.
-
-rr. Fixed a bug that caused ** globbing that caused **/path/* to match every
-    directory, not just those matching `path'.
-
-ss. Fixed a bug that caused the shell to dump core when running `help' without
-    arguments if the terminal width was fewer than 7 characters.
-
-2.  Changes to Readline
-
-a.  The SIGWINCH signal handler now avoids calling the redisplay code if
-    one arrives while in the middle of redisplay.
-
-b.  Changes to the timeout code to make sure that timeout values greater
-    than one second are handled better.
-
-c.  Fixed a bug in the redisplay code that was triggered by a prompt
-    containing invisible characters exactly the width of the screen.
-
-d.  Fixed a bug in the redisplay code encountered when running in horizontal
-    scroll mode.
-
-e.  Fixed a bug that prevented menu completion from properly completing
-    filenames.
-
-f.  Fixed a redisplay bug caused by a multibyte character causing a line to
-    wrap.
-
-g.  Fixed a bug that caused key sequences of two characters to not be
-    recognized when a longer sequence identical in the first two characters
-    was bound.
-
-h.  Fixed a bug that caused history expansion to be attempted on $'...'
-    single-quoted strings.
-
-i.  Fixed a bug that caused incorrect redisplay when the prompt contained
-    multibyte characters in an `invisible' sequence bracketed by \[ and
-    \].
-
-j.  Fixed a bug that caused history expansion to short-circuit after
-    encountering a multibyte character.
-
-3.  New Features in Bash
-
-a.  Here-documents within $(...) command substitutions may once more be
-    delimited by the closing right paren, instead of requiring a newline.
-
-b.  Bash's file status checks (executable, readable, etc.) now take file
-    system ACLs into account on file systems that support them.
-
-c.  Bash now passes environment variables with names that are not valid
-    shell variable names through into the environment passed to child
-    processes.
-
-d.  The `execute-unix-command' readline function now attempts to clear and
-    reuse the current line rather than move to a new one after the command
-    executes.
-
-e.  `printf -v' can now assign values to array indices.
-
-f.  New `complete -E' and `compopt -E' options that work on the "empty"
-    completion: completion attempted on an empty command line.
-
-g.  New complete/compgen/compopt -D option to define a `default' completion:
-    a completion to be invoked on command for which no completion has been
-    defined.  If this function returns 124, programmable completion is
-    attempted again, allowing a user to dynamically build a set of completions
-    as completion is attempted by having the default completion function
-    install individual completion functions each time it is invoked.
-
-h.  When displaying associative arrays, subscripts are now quoted.
-
-i.  Changes to dabbrev-expand to make it more `emacs-like': no space appended
-    after matches, completions are not sorted, and most recent history entries
-    are presented first.
-
-j.  The [[ and (( commands are now subject to the setting of `set -e' and the
-    ERR trap.
-
-k.  The source/. builtin now removes NUL bytes from the file before attempting
-    to parse commands.
-
-l.  There is a new configuration option (in config-top.h) that forces bash to
-    forward all history entries to syslog.
-
-m.  A new variable $BASHOPTS to export shell options settable using `shopt' to
-    child processes.
-
-n.  There is a new confgure option that forces the extglob option to be
-    enabled by default.
-
-o.  New variable $BASH_XTRACEFD; when set to an integer bash will write xtrace
-    output to that file descriptor.
-
-p.  If the optional left-hand-side of a redirection is of the form {var}, the
-    shell assigns the file descriptor used to $var or uses $var as the file
-    descriptor to move or close, depending on the redirection operator.
-
-q.  The < and > operators to the [[ conditional command now do string
-    comparison according to the current locale.
-
-r.  Programmable completion now uses the completion for `b' instead of `a'
-    when completion is attempted on a line like: a $(b c.
-
-s.  Force extglob on temporarily when parsing the pattern argument to
-    the == and != operators to the [[ command, for compatibility.
-
-t.  Changed the behavior of interrupting the wait builtin when a SIGCHLD is
-    received and a trap on SIGCHLD is set to be Posix-mode only.
-
-u.  The read builtin has a new `-N nchars' option, which reads exactly NCHARS
-    characters, ignoring delimiters like newline.
-
-4.  New Features in Readline
-
-a.  New bindable function: menu-complete-backward.
-
-b.  In the vi insertion keymap, C-n is now bound to menu-complete by default,
-    and C-p to menu-complete-backward.
-
-c.  When in vi command mode, repeatedly hitting ESC now does nothing, even
-    when ESC introduces a bound key sequence.  This is closer to how
-    historical vi behaves.
-
-d.  New bindable function: skip-csi-sequence.  Can be used as a default to
-    consume key sequences generated by keys like Home and End without having
-    to bind all keys.
-
-e.  New application-settable function: rl_filename_rewrite_hook.  Can be used
-    to rewite or modify filenames read from the file system before they are
-    compared to the word to be completed.
-
-f.  New bindable variable: skip-completed-text, active when completing in the
-    middle of a word.  If enabled, it means that characters in the completion
-    that match characters in the remainder of the word are "skipped" rather
-    than inserted into the line.
-
-g.  The pre-readline-6.0 version of menu completion is available as
-    "old-menu-complete" for users who do not like the readline-6.0 version.
-
-h.  New bindable variable: echo-control-characters.  If enabled, and the
-    tty ECHOCTL bit is set, controls the echoing of characters corresponding
-    to keyboard-generated signals.
-
-i.  New bindable variable: enable-meta-key.  Controls whether or not readline
-    sends the smm/rmm sequences if the terminal indicates it has a meta key
-    that enables eight-bit characters.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-4.0-release,
-and the previous version, bash-4.0-rc1.
-
-1.  Changes to Bash
-
-a.  Changed the message printed when setlocale(3) fails to only include the
-    strerror error text if the call changes errno.
-
-b.  Changed trap command execution to reset the line number before running a
-    trap (except DEBUG and RETURN traps).
-
-c.  Fixed behavior of case-modifiying word expansions to not work on
-    individual words within a variable's value.
-
-d.  Fixed a bug that caused mapfile to not be interruptible when run in an
-    interactive shell.
-
-e.  Fixed a bug that caused mapfile to not run callbacks for the first line
-    read.
-
-f.  Fixed a bug that caused mapfile to not honor EOF typed in an interactive
-    shell.
-
-g.  Fixed the coprocess reaping code to not run straight from a signal handler.
-
-h.  Fixed a bug that caused printf -b to ignore the first % conversion specifier
-    in the format string on 64-bit systems.
-
-i.  Fixed a bug that caused incorrect word splitting when `:', `=', or `~'
-    appeared in $IFS.
-
-j.  Fixed a bug that caused data corruption in the programmable completion code
-    when a shell function called from a completion aborted execution.
-
-k.  Fixed a bug that caused the CPU usage reported by the `time' builtin to be
-    capped at 100%.
-
-l.  Changed behavior of shell when -e option is in effect to reflect consensus
-    of Posix shell standardization working group.
-
-m.  Fixed a bug introduced in bash-4.0-alpha that caused redirections to not
-    be displayed by `type' or `declare' when appearing in functions under
-    certain circumstances.
-
-2.  Changes to Readline
-
-a.  Fixed a bug that caused !(...) extended glob patterns to inhibit later
-    history expansion.
-
-b.  Reworked the signal handling to avoid calling disallowed functions from a
-    signal handler.
-
-3.  New Features in Bash
-
-a.  `readarray' is now a synonym for `mapfile'.
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-4.0-rc1,
-and the previous version, bash-4.0-beta2.
-
-1.  Changes to Bash
-
-a.  Fixed a bug that caused parsing errors when a $()-style command
-    substitution was follwed immediately by a quoted newline.
-
-b.  Fixed a bug that caused extended shell globbing patterns beginning with
-    `*(' to not work when used with pattern substitution word expansions.
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-4.0-beta2,
-and the previous version, bash-4.0-beta.
-
-1.  Changes to Bash
-
-a.  Fixed a bug that caused failed word expansions to set $? but not
-    PIPESTATUS.
-
-b.  Changed filename completion to quote the tilde in a filename with a
-    leading tilde that exists in the current directory.
-
-c.  Fixed a bug that caused a file descriptor leak when performing
-    redirections attached to a compound command.
-
-d.  Fixed a bug that caused expansions of $@ and $* to not exit the shell if
-    the -u option was enabled and there were no posititional parameters.
-
-e.  Fixed a bug that resulted in bash not terminating immediately if a
-    terminating signal was received while performing output.
-
-f.  Fixed a bug that caused the shell to crash after creating 256 process
-    substitutions during word completion.
-
-2.  Changes to Readline
-
-a.  Fixed a bug that caused redisplay errors when using prompts with invisible
-    characters and numeric arguments to a command in a multibyte locale.
-
-b.  Fixed a bug that caused redisplay errors when using prompts with invisible
-    characters spanning more than two physical screen lines.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-4.0-beta,
-and the previous version, bash-4.0-alpha.
-
-1.  Changes to Bash
-
-a.  Fixed a typo that caused a variable to be used before initialization
-    while parsing Posix-style command substitutions.
-
-b.  Fixed a bug that caused stray ^? when the expansion of a parameter used
-    as part of a pattern removal expansion is empty, but part of a non-
-    empty string.
-
-c.  Fixed a bug that could cause strings not converted to numbers by strtol
-    to be treated as if the conversion had been successful.
-
-d.  The `return' builtin now accepts no options and requires a `--' before
-    a negative return value, as Posix requires.
-
-e.  Fixed a bug that caused local variables to be created with the empty
-    string for a value rather than no value.
-
-f.  Changed behavior so the shell now acts as if it received an interrupt
-    when a pipeline is killed by SIGINT while executing a list.
-
-g.  Fixed a bug that caused `declare var' and `typeset var' to initialize
-    `var' to the empty string.
-
-h.  Changed `bind' builtin to print a warning but proceed if invoked when
-    line editing is not active.
-
-i.  Fixed a bug that caused the shell to exit when the `errexit' option is
-    set and a command in a pipeline returns a non-zero exit status.
-
-j.  Fixed a bug that caused the shell to not run the exit trap in a command
-    run with `bash -c' under some circumstances.
-
-k.  Fixed a bug that caused parser errors to occasionally not set $? when
-    running commands with `eval'.
-
-l.  Fixed a bug that caused stray control characters when evaluating compound
-    array assignments containing $'\x7f' escapes.
-
-m.  Fixed a bug that caused redirections involving file descriptor 10 as the
-    target to behave incorrectly.
-
-n.  Fixed a bug that could cause memory to be freed multiple times when
-    assigning to COMP_WORDBREAKS.
-
-o.  Fixed a bug that could cause NULL pointer dereferences when COMP_WORDBREAKS
-    was unset.
-
-2.  Changes to Readline
-
-3.  New Features in Bash
-
-a.  A value of 0 for the -t option to `read' now returns success if there is
-    input available to be read from the specified file descriptor.
-
-b.  CDPATH and GLOBIGNORE are ignored when the shell is running in privileged
-    mode.
-
-c.  New bindable readline functions shell-forward-word and shell-backward-word,
-    which move forward and backward words delimited by shell metacharacters
-    and honor shell quoting.
-
-d.  New bindable readline functions shell-backward-kill-word and shell-kill-word
-    which kill words backward and forward, but use the same word boundaries
-    as shell-forward-word and shell-backward-word.
-
-4.  New Features in Readline
-
-a.  If the kernel supports it, readline displays special characters
-    corresponding to a keyboard-generated signal when the signal is received.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-4.0-alpha,
-and the previous version, bash-3.2-release.
-
-1.  Changes to Bash
-
-a.  Fixed several bugs in old-style `` command substitution parsing, including
-    comment parsing and quoted string handling.
-
-b.  Fixed problems parsing arguments to the [[ command's =~ regular expression
-    matching operator:  metacharacter and whitespace parsing.
-
-c.  Fixed a bug that caused the shell to inappropriately reuse high-numbered
-    file descriptors it used internally.
-
-d.  Fixed a bug in pattern replacement word expansions that caused a `/' as
-    the first character of an expanded pattern to be mistaken for a global
-    replacement specifier.
-
-e.  Fixed several problems with the asprintf and snprintf replacement functions
-    that caused hangs and crashes.
-
-f.  Fixed a bug in the calculation of the current and previous job that caused
-    it to refer to incorrect jobs.
-
-g.  Fixed a bug in the check for the validity of a hashed command pathname that
-    caused unnecessary hash table deletions and additions.
-
-h.  Fixed a bug that caused child processes to inherit the wrong value for $!.
-
-i.  Fixed a bug that caused `.' to fail to read and execute commands from non-
-    regular files such as devices or named pipes.
-
-j.  Fixed a bug in printf formatting for the %x and %X expansions that occurred
-    on some systems.
-
-k.  Fixed a bug that caused the shell to crash when creating temporary files if
-    $TMPDIR named a non-writable directory.
-
-l.  Fixed a bug that caused the shell to ignore $TMPDIR when creating temporary
-    files under some circumstances.
-
-m.  Fixed a bug that caused named pipes created by process substitution to not
-    be cleaned up.
-
-n.  Fixed a bug that caused HISTTIMEFORMAT to not be honored when it appeared
-    in the initial shell environment.
-
-o.  Fixed several bugs in the expansion of $* and $@ (quoted and unquoted)
-    when IFS is null or contains non-whitespace characters; the same changes
-    apply to arrays subscripted with * or @.
-
-p.  Fixed several problems with pattern substitution expansions on the
-    positional parameters and arrays subscripted with * or @ that occurred
-    when $IFS was set to the empty string.
-
-q.  Made a change to the default locale initialization code that should
-    result in better behavior from the locale-aware library functions.
-
-r.  Fixed a bug that caused compacting the jobs list to drop jobs.
-
-s.  Fixed a bug that caused jumps back to the top-level processing loop from
-    a builtin command to leave the shell in an inconsistent state.
-
-t.  Fixed a bug that caused characters that would be escaped internally to be
-    doubled when escaped with a backslash.
-
-u.  Fixed the initialization of mailboxes to not cause maildirs to be read
-    (and stat(2) called for every message file) at shell startup.
-
-v.  Fixed a bug that caused the shell to not display $PS2 when the read builtin
-    reads a line continued with a backslash.
-
-w.  Fixed a bug that caused errors in word splitting when $IFS contained
-    characters used for internal quoting.
-
-x.  Fixed bugs that caused problems with output from shell builtins not being
-    completely displayed on some systems.
-
-y.  Fixed a bug that caused output to be lost when a redirection is acting on
-    the shell's output file descriptor.
-
-z.  Fixed bugs caused by shell builtins not checking for all write errors.
-
-aa. Fixed a problem that caused the shell to dump core if expansions on the
-    pattern passed to the pattern removal word expansions resulted in expansion
-    errors.
-
-bb. Fixed a bug that caused bash to loop infinitely after creating and
-    waiting for 4096 jobs.
-
-cc. Fixed a bug that caused bash to lose the status of a background job under
-    certain circumstances.
-
-dd. Fixed a bug that caused bash to not look in the temporary environment
-    when performing variable lookup under certain circumstances.
-
-ee. Fixed a bug that caused bash to close file descriptors greater than 10
-    when they were used in redirections.
-
-ff. Fixed a problem that caused the shell to attempt to read from the standard
-    input when called as `bash -i script'.
-
-gg. Fixed a memory leak and variable initialization problems when the -v option
-    was supplied to `printf' that could cause incorrect results.
-
-hh. Fixed a bug that caused the `read' builtin to count bytes when the -n option
-    was supplied, rather than (possibly multibyte) characters.
-
-ii. Fixed a bug when displaying a function due to not converting the function
-    to an external form.
-
-jj. Changed job control initialization to ensure that the shell has a tty
-    as its controlling terminal before enabling job control.
-
-kk. Fixed a bug with the `test' builtin that caused it to misinterpret
-    arguments beginning with `-' but containing more than one character.
-
-ll. Fixed bug that could cause the shell to dump core in certain cases where
-    a command sets the SIGINT disposition to the default.
-
-mm. Fixed a bug in the pattern replacement (affecting both word expansion
-    and the `fc' builtin) that occurred when the pattern and replacement
-    strings were empty.
-
-nn. Fixed a bug that caused an arithmetic evaluation error to disable all
-    further evaluation.
-
-oo. Fixed a bug in pathname expansion that caused it to interpret backslashes
-    in the pathname as quoting characters.
-
-pp. Fixed a bug in the replacement getcwd() implementation that could cause
-    memory to be overwritten.
-
-qq. When in Posix mode, the `ulimit' builtin now uses a block size of 512 for
-    the `-c' and `-f' options.
-
-rr. Brace expansion now allows process substitutions to pass through unchanged.
-
-ss. Fixed a problem in the command name completion code to avoid quoting
-    escaped special characters twice when the command name begins with a tilde.
-
-tt. Fixed a problem in the printf builtin that resulted in single-byte
-    output for the "'" escape, even when using multibyte characters.
-
-uu. Fixed a bug that caused the failure exit status to be lost when redirections
-    attached to a compound command failed.
-
-vv. Fixed a bug that caused the internal random number generator to not be
-    re-seeded correctly when creating a subshell.
-
-ww. Fixed a bug that could cause the bash replacement getcwd to overwrite
-    memory.
-
-xx. Fixed a bug that caused the shell to not receive SIGINT if it was sent
-    while the shell was waiting for a command substitution to terminate, and
-    make sure the exit status is correct when it does.
-
-yy. Fixed a bug that resulted in the second and subsequent children spawned
-    by a shell begun to run a command substitution being placed into the
-    wrong process group.
-
-zz. Fixed a bug that caused the results of successful tilde expansion to be
-    subject to pathname expansion and word splitting.
-
-aaa. Fixed a bug that could cause the shell to hang if it encountered an
-     error that caused it to jump back to the top processing loop during a
-     command substitution or `eval' command.
-
-bbb. Fixed a bug that caused the `read' builtin to use the tty's attributes
-     instead of those of the file descriptor passed with the -u option when
-     processing the -n and -d options.
-
-ccc. Fixed a bug that caused incorrect expansion of ${array[@]:foo} if the
-     first character of $IFS was not whitespace.
-
-ddd. Fixed a bug that occurred when scanning for the ending delimiter of a
-     ${parameter/pat/sub} expansion.
-
-eee. Fixed a bug that caused the shell to inappropriately expand command
-     substitutions in words when expanding directory names for completion.
-
-fff. Fixed a bug that caused the `fc' builtin to look too far back in the
-     history list under certain circumstances.
-
-ggg. Fixed a bug that caused a shell running in Posix mode to search $PWD for
-     a file specified as an argument to source/. when the file was not found
-     in $PATH.
-
-hhh. Fixed a bug that caused the shell to modify the case of a command word
-     found via command completion when the shell was performing case-
-     insensitive completion.
-
-iii. Fixed a bug that caused the shell to search $PATH for an argument to
-     source/. even when it contained a `/'.
-
-jjj. Fixed a bug that caused brace expansion to misorder expansions when the
-     locale did not have a collating order like aAbBcC...zZ.
-
-kkk. Fixed a bug that did not allow `set +o history' to have any effect when
-     run in a startup file or from a sourced file.
-
-lll. Fixed a bug with the precedence of the ?: conditional arithmetic operator.
-
-mmm. Fixed a bug that caused side effects of temporary variable assignments
-     to persist in the shell environment.
-
-nnn. Fixed a bug that caused the terminal to be left in non-canonical mode
-     when using editing commands that invoke the an editor on the current
-     command line.
-
-ooo. Fixed a bug that caused globbing characters and characters in $IFS to not
-     be quoted appropriately when displaying assignment statements.
-
-ppp. Fixed a bug that caused the `-e' option to be inherited when sourcing a
-     file or evaluating a command with `eval' even if the return value of the
-     command was supposed to be ignored.
-
-qqq. Fixed a bug that caused the shell to attempt to created variables with
-     invalid names if such names appeared in the initial environment.
-
-rrr. Fixed a bug with quote removal in strings where the final character is a
-     backslash.
-
-sss. Fixed a bug that caused the effects of special variables to persist even
-     when the variables were unset as part of the shell reinitializing itself
-     to execute a shell script.
-
-ttt. Fixed a bug that caused the history to not be saved after `history -c' or
-     `history -d' was executed until a sufficient number of commands had been
-     saved to the history.
-
-uuu. Bash now parses command substitutions according to Posix rules: parsing
-     the command contained in $() to find the closing delimiter.
-
-vvv. Fixed a bug that caused traps on SIGCHLD set in a SIGCHLD handler to
-     not persist.
-
-www. Fixed a bug that didn't allow SIGCHLD to interrupt the `wait' builtin
-     as Posix specifies.
-
-xxx. Invalid numeric arguments to shell builtins no longer cause the shell to
-     short-circuit any executing compound command.
-
-yyy. Fixed a bug that caused the exit status to be lost when `break' was
-     used to short-circuit a loop's execution.
-
-zzz. Fixed a bug that caused stray ^? characters to be left in expansions of
-     "${array[*]}".
-
-aaaa. Bash now prints better error messages for here documents terminated by
-      EOF and for identifying the incorrect token in an invalid arithmetic
-      expression.
-
-bbbb. Fixed a bug in the variable length word expansion that caused it to
-      incorrectly calculate the number of multibyte characters.
-
-cccc. Fixed a race condition that could result in the top-level shell setting
-      the terminal's process group to an incorrect value if the process
-      group was changed by a child of a child of the shell.
-
-dddd. Fixed a bug that caused here documents belonging to commands within a
-      compound command to be displayed in a syntactially-incorrect form, which
-      prevented them from being re-read as input.
-
-eeee. The shell displays more warnings about failures to set the locale.
-
-ffff. Fixed a bug that caused the body of a here-document to not be saved to
-      the history list.
-
-gggg. Fixed a bug that caused configure to incorrectly conclude that FreeBSD
-      had /dev/fd available, resulting in problems with process substitution.
-
-2.  Changes to Readline
-
-a.  Fixed a number of redisplay errors in environments supporting multibyte 
-    characters.
-
-b.  Fixed bugs in vi command mode that caused motion commands to inappropriately
-    set the mark.
-
-c.  When using the arrow keys in vi insertion mode, readline allows movement
-    beyond the current end of the line (unlike command mode).
-
-d.  Fixed bugs that caused readline to loop when the terminal has been taken
-    away and reads return -1/EIO.
-
-e.  Fixed bugs in redisplay occurring when displaying prompts containing
-    invisible characters.
-
-f.  Fixed a bug that caused the completion append character to not be reset to
-    the default after an application-specified completion function changed it.
-
-g.  Fixed a problem that caused incorrect positioning of the cursor while in
-    emacs editing mode when moving forward at the end of a line while using
-    a locale supporting multibyte characters.
-
-h.  Fixed an off-by-one error that caused readline to drop every 511th
-    character of buffered input.
-
-i.  Fixed a bug that resulted in SIGTERM not being caught or cleaned up.
-
-j.  Fixed redisplay bugs caused by multiline prompts with invisible characters
-    or no characters following the final newline.
-
-k.  Fixed redisplay bug caused by prompts consisting solely of invisible
-    characters.
-
-l.  Fixed a bug in the code that buffers characters received very quickly in
-    succession which caused characters to be dropped.
-
-m.  Fixed a bug that caused readline to reference uninitialized data structures
-    if it received a SIGWINCH before completing initialzation.
-
-n.  Fixed a bug that caused the vi-mode `last command' to be set incorrectly
-    and therefore unrepeatable.
-
-o.  Fixed a bug that caused readline to disable echoing when it was being used
-    with an output file descriptor that was not a terminal.
-
-p.  Readline now blocks SIGINT while manipulating internal data structures
-    during redisplay.
-
-q.  Fixed a bug in redisplay that caused readline to segfault when pasting a
-    very long line (over 130,000 characters).
-
-r.  Fixed bugs in redisplay when using prompts with no visible printing
-    characters.
-
-3.  New Features in Bash
-
-a.  When using substring expansion on the positional parameters, a starting
-    index of 0 now causes $0 to be prefixed to the list.
-
-b.  The `help' builtin now prints its columns with entries sorted vertically
-    rather than horizontally.
-
-c.  There is a new variable, $BASHPID, which always returns the process id of
-    the current shell.
-
-d.  There is a new `autocd' option that, when enabled, causes bash to attempt
-    to `cd' to a directory name that is supplied as the first word of a
-    simple command.
-
-e.  There is a new `checkjobs' option that causes the shell to check for and
-    report any running or stopped jobs at exit.
-
-f.  The programmable completion code exports a new COMP_TYPE variable, set to
-    a character describing the type of completion being attempted.
-
-g.  The programmable completion code exports a new COMP_KEY variable, set to
-    the character that caused the completion to be invoked (e.g., TAB).
-
-h.  If creation of a child process fails due to insufficient resources, bash
-    will try again several times before reporting failure.
-
-i.  The programmable completion code now uses the same set of characters as
-    readline when breaking the command line into a list of words.
-
-j.  The block multiplier for the ulimit -c and -f options is now 512 when in
-    Posix mode, as Posix specifies.
-
-k.  Changed the behavior of the read builtin to save any partial input received
-    in the specified variable when the read builtin times out.  This also
-    results in variables specified as arguments to read to be set to the empty
-    string when there is no input available.  When the read builtin times out,
-    it returns an exit status greater than 128.
-
-l.  The shell now has the notion of a `compatibility level', controlled by
-    new variables settable by `shopt'.  Setting this variable currently
-    restores the bash-3.1 behavior when processing quoted strings on the rhs
-    of the `=~' operator to the `[[' command.
-
-m.  The `ulimit' builtin now has new -b (socket buffer size) and -T (number
-    of threads) options.
-
-n.  The -p option to `declare' now displays all variable values and attributes
-    (or function values and attributes if used with -f).
-
-o.  There is a new `compopt' builtin that allows completion functions to modify
-    completion options for existing completions or the completion currently
-    being executed.
-
-p.  The `read' builtin has a new -i option which inserts text into the reply
-    buffer when using readline.
-
-q.  A new `-E' option to the complete builtin allows control of the default
-    behavior for completion on an empty line.
-
-r.  There is now limited support for completing command name words containing
-    globbing characters.
-
-s.  Changed format of internal help documentation for all builtins to roughly
-    follow man page format.
-
-t.  The `help' builtin now has a new -d option, to display a short description,
-    and a -m option, to print help information in a man page-like format.
-
-u.  There is a new `mapfile' builtin to populate an array with lines from a
-    given file.
-
-v.  If a command is not found, the shell attempts to execute a shell function
-    named `command_not_found_handle', supplying the command words as the
-    function arguments.
-
-w.  There is a new shell option: `globstar'.  When enabled, the globbing code
-    treats `**' specially -- it matches all directories (and files within
-    them, when appropriate) recursively.
-
-x.  There is a new shell option: `dirspell'.  When enabled, the filename
-    completion code performs spelling correction on directory names during
-    completion.
-
-y.  The `-t' option to the `read' builtin now supports fractional timeout
-    values.
-
-z.  Brace expansion now allows zero-padding of expanded numeric values and
-    will add the proper number of zeroes to make sure all values contain the
-    same number of digits.
-
-aa. There is a new bash-specific bindable readline function: `dabbrev-expand'.
-    It uses menu completion on a set of words taken from the history list.
-
-bb. The command assigned to a key sequence with `bind -x' now sets two new
-    variables in the environment of the executed command:  READLINE_LINE_BUFFER
-    and READLINE_POINT.  The command can change the current readline line
-    and cursor position by modifying READLINE_LINE_BUFFER and READLINE_POINT,
-    respectively.
-
-cc. There is a new &>> redirection operator, which appends the standard output
-    and standard error to the named file.
-
-dd. The parser now understands `|&' as a synonym for `2>&1 |', which redirects
-    the standard error for a command through a pipe.
-
-ee. The new `;&' case statement action list terminator causes execution to
-    continue with the action associated with the next pattern in the
-    statement rather than terminating the command.
-
-ff. The new `;;&' case statement action list terminator causes the shell to
-    test the next set of patterns after completing execution of the current
-    action, rather than terminating the command.
-
-gg. The shell understands a new variable: PROMPT_DIRTRIM.  When set to an
-    integer value greater than zero, prompt expansion of \w and \W  will
-    retain only that number of trailing pathname components and replace
-    the intervening characters with `...'.
-
-hh. There are new case-modifying word expansions: uppercase (^[^]) and
-    lowercase (,[,]).  They can work on either the first character or
-    array element, or globally.  They accept an optional shell pattern
-    that determines which characters to modify.  There is an optionally-
-    configured feature to include capitalization operators.
-
-ii. The shell provides associative array variables, with the appropriate
-    support to create, delete, assign values to, and expand them.
-
-jj. The `declare' builtin now has new -l (convert value to lowercase upon
-    assignment) and -u (convert value to uppercase upon assignment) options.
-    There is an optionally-configurable -c option to capitalize a value at
-    assignment.
-
-kk. There is a new `coproc' reserved word that specifies a coprocess: an
-    asynchronous command run with two pipes connected to the creating shell.
-    Coprocs can be named.  The input and output file descriptors and the
-    PID of the coprocess are available to the calling shell in variables
-    with coproc-specific names.
-
-4.  New Features in Readline
-
-a.  A new variable, rl_sort_completion_matches; allows applications to inhibit
-    match list sorting (but beware: some things don't work right if
-    applications do this).
-
-b.  A new variable, rl_completion_invoking_key; allows applications to discover
-    the key that invoked rl_complete or rl_menu_complete.
-
-c.  The functions rl_block_sigint and rl_release_sigint are now public and
-    available to calling applications who want to protect critical sections
-    (like redisplay).
-
-d.  The functions rl_save_state and rl_restore_state are now public and
-    available to calling applications; documented rest of readline's state
-    flag values.
-
-e.  A new user-settable variable, `history-size', allows setting the maximum
-    number of entries in the history list.
-
-f.  There is a new implementation of menu completion, with several improvements
-    over the old; the most notable improvement is a better `completions
-    browsing' mode.
-
-g.  The menu completion code now uses the rl_menu_completion_entry_function
-    variable, allowing applications to provide their own menu completion
-    generators.
-
-h.  There is support for replacing a prefix  of a pathname with a `...' when
-    displaying possible completions.  This is controllable by setting the
-    `completion-prefix-display-length' variable.  Matches with a common prefix
-    longer than this value have the common prefix replaced with `...'.
-
-i.  There is a new `revert-all-at-newline' variable.  If enabled, readline will
-    undo all outstanding changes to all history lines when `accept-line' is
-    executed.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-3.2-release,
-and the previous version, bash-3.2-beta.
-
-1.  Changes to Bash
-
-a.  Fixed a bug that caused the temporary environment passed to a command to
-    affect the shell's environment under certain circumstances.
-
-b.  Fixed a bug in the printf builtin that caused the %q format specifier to
-    ignore empty string arguments.
-
-c.  Improved multibyte character environment detection at configuration time.
-
-d.  Fixed a bug in the read builtin that left spurious escape characters in the
-    input after processing backslashes when assigning to an array variable.
-
-2.  Changes to Readline
-
-a.  Fixed a redisplay bug that occurred in multibyte-capable locales when the
-    prompt was one character longer than the screen width.
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-3.2-beta,
-and the previous version, bash-3.2-alpha.
-
-1.  Changes to Bash
-
-a.  Changed the lexical analyzer to treat locale-specific blank characters as
-    white space.
-
-b.  Fixed a bug in command printing to avoid confusion between redirections and
-    process substitution.
-
-c.  Fixed problems with cross-compiling originating from inherited environment
-    variables.
-
-d.  Added write error reporting to printf builtin.
-
-e.  Fixed a bug in the variable expansion code that could cause a core dump in
-    a multi-byte locale.
-
-f.  Fixed a bug that caused substring expansion of a null string to return
-    incorrect results.
-
-g.  BASH_COMMAND now retains its previous value while executing commands as the
-    result of a trap, as the documentation states.
-
-2.  Changes to Readline
-
-a.  Fixed a bug with prompt redisplay in a multi-byte locale to avoid redrawing
-    the prompt and input line multiple times.
-
-b.  Fixed history expansion to not be confused by here-string redirection.
-
-c.  Readline no longer treats read errors by converting them to newlines, as
-    it does with EOF.  This caused partial lines to be returned from readline().
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-3.2-alpha,
-and the previous version, bash-3.1-release.
-
-1.  Changes to Bash
-
-a.  Fixed a source bug that caused the minimal configuration to not compile.
-
-b.  Fixed memory leaks in error handling for the `read' builtin.
-
-c.  Changed the [[ and (( compound commands to set PIPESTATUS with their exit
-    status.
-
-d.  Fixed some parsing problems with compound array assignments.
-
-e.  Added additional configuration changes for: NetBSD (incomplete multibyte
-    character support)
-
-f.  Fixed two bugs with local array variable creation when shadowing a variable
-    of the same name from a previous context.
-
-g.  Fixed the `read' builtin to restore the correct set of completion functions
-    if a timeout occurs.
-
-h.  Added code to defer the initialization of HISTSIZE (and its stifling of the
-    history list) until the history file is loaded, allowing a startup file to
-    override the default value.
-
-i.  Tightened up the arithmetic expression parsing to produce better error
-    messages when presented with invalid operators.
-
-j.  Fixed the cross-compilation support to build the signal list at shell
-    invocation rather than compile time if cross-compiling.
-
-k.  Fixed multibyte support for non-gcc compilers (or compilers that do not
-    allow automatic array variable sizing based on a non-constant value).
-
-l.  Several fixes to the code that manages the list of terminated jobs and
-    their exit statuses, and the list of active and recently-terminated jobs
-    to avoid pid aliasing/wraparound and allocation errors.
-
-m.  Fixed a problem that allowed scripts to die due to SIGINT while waiting
-    for children, even when started in the background or otherwise ignoring
-    SIGINT.
-
-n.  Fixed a bug that caused shells invoked as -/bin/bash from not being
-    recognized as login shells.
-
-o.  Fixed a problem that caused shells in the background to give the terminal
-    to a process group other than the foreground shell process group.
-
-p.  Fixed a problem with extracting the `varname' in ${#varname}.
-
-q.  Fixed the code that handles SIGQUIT to not exit immediately -- thereby
-    calling functions that may not be called in a signal handler context --
-    but set a flag and exit afterward (like SIGINT).
-
-r.  Changed the brace expansion code to skip over braces that don't begin a
-    valid matched brace expansion construct.
-
-s.  Fixed `typeset' and `declare' to not require that their shell function
-    operands to be valid shell identifiers.
-
-t.  Changed `test' to use access(2) with a temporary uid/euid swap when testing
-    file attributes and running setuid, and access(2) in most other cases.
-
-u.  Changed completion code to not attempt command name completion on a line
-    consisting solely of whitespace when no_empty_command_completion is set.
-
-v.  The `hash' builtin now prints nothing in posix mode when the hash table is
-    empty, and prints a message to that effect to stdout instead of stderr
-    when not in posix mode.
-
-w.  Fixed a bug in the extended pattern matching code that caused it to fail to
-    match periods with certain patterns.
-
-x.  Fixed a bug that caused the shell to dump core when performing filename
-    generation in directories with thousands of files.
-
-y.  Returned to the original Bourne shell rules for parsing ``:  no recursive
-    parsing of embedded quoted strings or ${...} constructs.
-
-z.  The inheritence of the DEBUG, RETURN, and ERR traps is now dependent only
-    on the settings of the `functrace' and `errtrace' shell options, rather
-    than whether or not the shell is in debugging mode.
-
-aa. Fixed a problem with $HOME being converted to ~ in the expansion of
-    members of the DIRSTACK array.
-
-bb. Fixed a problem with quoted arguments to arithmetic expansions in certain
-    constructs.
-
-cc. The command word completion code now no longer returns matching directories
-    while searching $PATH.
-
-dd. Fixed a bug with zero-padding and precision handling in snprintf()
-    replacement.
-
-ee. Fixed a bug that caused the command substitution code not to take embedded
-    shell comments into account.
-
-ff. Fixed a bug that caused $((...);(...)) to be misinterpreted as an
-    arithmetic substitution.
-
-gg. Fixed a bug in the prompt expansion code that inappropriately added a
-    \001 before a \002 under certain circumstances.
-
-hh. Fixed a bug that caused `unset LANG' to not properly reset the locale
-    (previous versions would set the locale back to what it was when bash
-    was started rather than the system's "native" locale).
-
-ii. Fixed a bug that could cause file descriptors > 10 to not be closed even
-    when closed explicitly by a script.
-
-jj. Fixed a bug that caused single quotes to be stripped from ANSI-C quoting
-    inside double-quoted command substitutions.
-
-kk. Fixed a bug that could cause core dumps when `return' was executed as the
-    last element of a pipeline inside a shell function.
-
-ll. Fixed a bug that caused DEBUG trap strings to overwrite commands stored in
-    the jobs list.
-
-2.  Changes to Readline
-
-a.  Fixed a problem that caused segmentation faults when using readline in
-    callback mode and typing consecutive DEL characters on an empty line.
-
-b.  Fixed several redisplay problems with multibyte characters, all having to
-    do with the different code paths and variable meanings between single-byte
-    and multibyte character redisplay.
-
-c.  Fixed a problem with key sequence translation when presented with the
-    sequence \M-\C-x.
-
-d.  Fixed a problem that prevented the `a' command in vi mode from being
-    undone and redone properly.
-
-e.  Fixed a problem that prevented empty inserts in vi mode from being undone
-    properly.
-
-f.  Fixed a problem that caused readline to initialize with an incorrect idea
-    of whether or not the terminal can autowrap.
-
-g.  Fixed output of key bindings (like bash `bind -p') to honor the setting of
-    convert-meta and use \e where appropriate.
-
-h.  Changed the default filename completion function to call the filename
-    dequoting function if the directory completion hook isn't set.  This means
-    that any directory completion hooks need to dequote the directory name,
-    since application-specific hooks need to know how the word was quoted,
-    even if no other changes are made.
-
-i.  Fixed a bug with creating the prompt for a non-interactive search string
-    when there are non-printing characters in the primary prompt.
-
-j.  Fixed a bug that caused prompts with invisible characters to be redrawn
-    multiple times in a multibyte locale.
-
-k.  Fixed a bug that could cause the key sequence scanning code to return the
-    wrong function.
-
-l.  Fixed a problem with the callback interface that caused it to fail when
-    using multi-character keyboard macros.
-
-m.  Fixed a bug that could cause a core dump when an edited history entry was
-    re-executed under certain conditions.
-
-n.  Fixed a bug that caused readline to reference freed memory when attmpting
-    to display a portion of the prompt.
-
-3.  New Features in Bash
-
-a.  Changed the parameter pattern replacement functions to not anchor the
-    pattern at the beginning of the string if doing global replacement - that
-    combination doesn't make any sense.
-
-b.  When running in `word expansion only' mode (--wordexp option), inhibit
-    process substitution.
-
-c.  Loadable builtins now work on MacOS X 10.[34].
-
-d.  Shells running in posix mode no longer set $HOME, as POSIX requires.
-
-e.  The code that checks for binary files being executed as shell scripts now
-    checks only for NUL rather than any non-printing character.
-
-f.  Quoting the string argument to the [[ command's  =~ operator now forces
-    string matching, as with the other pattern-matching operators.
-
-4.  New Features in Readline
-
-a.  Calling applications can now set the keyboard timeout to 0, allowing
-    poll-like behavior.
-
-b.  The value of SYS_INPUTRC (configurable at compilation time) is now used as
-    the default last-ditch startup file.
-
-c.  The history file reading functions now allow windows-like \r\n line
-    terminators.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-3.1-release,
-and the previous version, bash-3.1-rc2.
-
-1.  Changes to Readline
-
-a.  Several changes to the multibyte redisplay code to fix problems with
-    prompts containing invisible characters.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-3.1-rc2,
-and the previous version, bash-3.1-rc1.
-
-1.  Changes to Bash
-
-a.  Fixed a bug that caused a DEBUG trap to overwrite a command string that's
-    eventually attached to a background job.
-
-b.  Changed some code so that filenames with leading tildes with spaces in the
-    name aren't tilde-expanded by the bash completion code.
-
-c.  Fixed a bug that caused the pushd builtin to fail to change to
-    directories with leading `-'.
-
-d.  Fixed a small memory leak in the programmable completion code.
-
-2.  Changes to Readline
-
-a.  Fixed a redisplay bug caused by moving the cursor vertically to a line
-    with invisible characters in the prompt in a multibyte locale.
-
-b.  Fixed a bug that could cause the terminal special chars to be bound in the
-    wrong keymap in vi mode.
-
-3.  New Features in Bash
-
-a.  If compiled for strict POSIX conformance, LINES and COLUMNS may now
-    override the true terminal size.
-
-4.  New Features in Readline
-
-a.  A new external application-controllable variable that allows the LINES
-    and COLUMNS environment variables to set the window size regardless of
-    what the kernel returns.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-3.1-rc1,
-and the previous version, bash-3.1-beta1.
-
-1.  Changes to Bash
-
-a.  Fixed a bug that could cause core dumps due to accessing the current
-    pipeline while in the middle of modifying it.
-
-b.  Fixed a bug that caused pathnames with backslashes still quoting characters
-    to be passed to opendir().
-
-c.  Command word completion now obeys the setting of completion-ignore-case.
-
-d.  Fixed a problem with redirection that caused file descriptors greater than
-    2 to be inappropriately marked as close-on-exec.
-
-e.  In Posix mode, after `wait' is called to wait for a particular process
-    explicitly, that process is removed from the list of processes known to
-    the shell, and subsequent attempts to wait for it return errors.
-
-f.  Fixed a bug that caused extended pattern matching to incorrectly scan
-    backslash-escaped pattern characters.
-
-g.  Fixed a synchronization problem that could cause core dumps when handling
-    a SIGWINCH.
-
-h.  Fixed a bug that caused an unmatched backquote to be accepted without an
-    error when processing here documents.
-
-i.  Fixed a small memory leak in the `cd' builtin.
-
-j.  Fix for MacOS X so it gets the values for the HOSTTYPE, MACHTYPE, and
-    OSTYPE variables at build time, to support universal binaries.
-
-k.  Fixed a bug that could cause an exit trap to return the exit status of
-    the trap command rather than the status as it was before the trap was
-    run as the shell's exit status.
-
-2.  New Features in Bash
-
-3.  Changes to Readline
-
-a.  Fixed a bug that caused reversing the incremental search direction to
-    not work correctly.
-
-b.  Fixed the vi-mode `U' command to only undo up to the first time insert mode
-    was entered, as Posix specifies.
-
-c.  Fixed a bug in the vi-mode `r' command that left the cursor in the wrong
-    place.
-
-4.  New Features in Readline
-
-a.  New application-callable auxiliary function, rl_variable_value, returns
-    a string corresponding to a readline variable's value.
-
-b.  When parsing inputrc files and variable binding commands, the parser
-    strips trailing whitespace from values assigned to boolean variables
-    before checking them.
-
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-3.1-beta1,
-and the previous version, bash-3.1-alpha1.
-
-1.  Changes to Bash
-
-a.  Added some system-specific signal names.
-
-b.  Fixed a typo in the ulimit builtin to make `x' the right option to
-    maniuplate the limit on file locks.
-
-c.  Fixed a problem with using += to append to index 0 of an array variable
-    when not using subscript syntax.
-
-d.  A few changes to configure.in to remove calls to obsolete or outdated
-    macros.
-
-e.  Make sure changes to variables bash handles specially (e.g., LC_ALL) are
-    made when the variable is set in the temporary environment to a command.
-
-f.  Make sure changes to variables bash handles specially (e.g., LC_ALL) are
-    made when the variable is modified using `printf -v'.
-
-g.  The export environment is now remade on cygwin when HOME is changed, so
-    DLLs bash is linked against pick up the new value.  This fixes problems
-    with tilde expansion when linking against and already-installed readline.
-
-h.  Small fix to the logic for performing tilde expansion in posix mode, so
-    expansion on the right-hand side of an assignment statement takes place.
-
-i.  Fixed a bug that prevented redirections associated with a shell function
-    from being executed when in a subshell.
-
-j.  Fixed `source' and `.' builtins to not require an executable file when
-    searching $PATH for a file to source.
-
-k.  Fixed a bug that caused incorrect word splitting in a function when IFS
-    was declared local, then unset.
-
-l.  Fixed a problem with the `kill' builtin that prevented sending signals
-    to a process group under certain circumstances when providing a pid < 0.
-
-m.  When in POSIX mode, `pwd' now checks that the value it prints is the same
-    directory as `.', even when displaying $PWD.
-
-n.  Fixed a problem with the `read' builtin when reading a script from standard
-    input and reading data from the same file.
-
-o.  Fixed a problem with the `type' and `command' builtins that caused absolute
-    pathnames to be displayed incorrectly.
-
-p.  Some changes to the `bg' builtin for POSIX conformance.
-
-q.  The `fc' builtin now removes the `fc' command that caused it to invoke an
-    editor on specified history entries from the history entirely, rather than
-    simply ignoring it.
-
-r.  When in POSIX mode, the `v' command in vi editing mode simply invokes vi
-    on the current command, rather than checking $FCEDIT and $EDITOR.
-
-s.  Fixed a small memory leak in the pathname canonicalization code.
-
-t.  Fixed a bug that caused the expanded value of a $'...' string to be
-    incorrectly re-quoted if it occurred within a double-quoted ${...}
-    parameter expansion.
-
-u.  Restored default emacs-mode key binding of M-TAB to dynamic-complete-history.
-
-v.  Fixed a bug that caused core dumps when interrupting loops running builtins
-    on some systems.
-
-w.  Make sure that some of the functions bash provides replacements for are
-    not cpp defines.
-
-x.  The code that scans embedded commands for the parser (`...` and $(...)) is
-    now more aware of embedded comments and their effect on quoted strings.
-
-y.  Changed the `-n' option to the `history' builtin to not reset the number of
-    history lines read in the current session after reading the new lines from
-    the history file if the history is being appended when it is written to
-    the file, since the appending takes care of the problem that the adjustment
-    was intended to solve.
-
-z.  Improved the error message displayed when a shell script fails to execute
-    because the environment and size of command line arguments are too large.
-
-aa. A small fix to make sure that $HISTCMD is evaluated whenever the shell is
-    saving commands to the history list, not just when HISTSIZE is defined.
-
-2.  Changes to Readline
-
-a.  The `change-case' command now correctly changes the case of multibyte
-    characters.
-
-b.  Changes to the shared library construction scripts to deal with Windows
-    DLL naming conventions for Cygwin.
-
-c.  Fixed the redisplay code to avoid core dumps resulting from a poorly-timed
-    SIGWINCH.
-
-d.  Fixed the non-incremental search code in vi mode to dispose of any current
-    undo list when copying a line from the history into the current editing
-    buffer.
-
-e.  The variable assignment code now ignores whitespace at the end of lines
-    when assigning to boolean variables.
-
-f.  The `C-w' binding in incremental search now understands multibyte
-    characters.
-
-3.  New Features in Bash
-
-a.  A new configuration option, `--enable-strict-posix-default', which will
-    build bash to be POSIX conforming by default.
-
-4.  New Features in Readline
-
-a.  If the rl_completion_query_items is set to a value < 0, readline never
-    asks the user whether or not to view the possible completions.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-3.1-alpha1,
-and the previous version, bash-3.0-release.
-
-1.  Changes to Bash
-
-a.  Fixed a bug that caused bash to crash if referencing an unset local array.
-
-b.  Fixed a problem that caused tilde expansion to not be performed before
-    attempting globbing word completion.
-
-c.  Fixed an incompatibility so that a first argument to trap that's a valid
-    signal number will be trated as a signal rather than a command to execute.
-
-d.  Fixed ${#word} expansion to correctly compute the length of a string
-    containing multibyte characters.
-
-e.  Fixed a bug that caused bash to not pass the correct flags for signal
-    disposition to child processes.
-
-f.  Fixed a bug that caused `fc -l' to list one too many history entries.
-
-g.  Some fixes to `fc' for POSIX conformance.
-
-h.  Some fixes to job status display for POSIX conformance.
-
-i.  Fixed a bug that caused `command -v' to display output if a command was not
-    found -- it should be silent.
-
-j.  In POSIX mode, `type' and `command -[vV]' do not report non-executable
-    files, even if the shell will attempt to execute them.
-
-k.  Fixed a bug that caused the `==' operator to the [[ command to not attempt
-    extended pattern matching.
-
-l.  Fixed the brace expansion code to handle characters whose value exceeds 128.
-
-m.  Fixed `printf' to handle strings with a leading `\0' whose length is
-    non-zero.
-
-n.  Fixed a couple of problems with brace expansion where `${' was handled
-    incorrectly.
-
-o.  Fixed off-by-one error when calculating the upper bound of `offset' when
-    processing the ${array[@]:offset:length} expansion.
-
-p.  System-specific configuration changes for: FreeBSD 5.x, Interix, MacOS X
-    10.4, Linux 2.4+ kernels, Linux 3.x kernels, Dragonfly BSD, QNX 6.x,
-    Cygwin
-
-q.  Fixed a bug that caused the shell to ignore the status of the rightmost
-    command in a pipeline when the `pipefail' option was enabled.
-
-r.  Fixed a completion bug that caused core dumps when expanding a directory
-    name.
-
-s.  Fixed a bug that prevented `hash -d' from removing commands from the hash
-    table.
-
-t.  Fixed word splitting to avoid really bad quadratic performance when
-    expanding long lists.
-
-u.  Fixed a bug that caused negative offsets in substring expansion to use the
-    wrong values.
-
-v.  Fixed a bug in printf that caused it to not return failure on write errors.
-
-w.  Fixed a bug that caused commands in subshells to not be properly timed.
-
-x.  The shell parser no longer attempts to parse a compound assignment specially
-    unless in a position where an assignment statement is acceptable or parsing
-    arguments to a builtin that accepts assignment statements.
-
-y.  Fixed a problem that caused a `case' statement to be added to the history
-    incorrectly as a single command if the `case word' was on one line and the
-    `in' on another.
-
-z.  Fixed a problem that caused internal shell quoting characters to be
-    incorrectly quoted with backslashes under some circumstances.
-
-aa. The shell now performs correct word splitting when IFS contains multibyte
-    characters.
-
-bb. The mail checking code now resets the cached file information if the size
-    drops to 0, even if the times don't change.
-
-cc. A completed command name that is found in $PATH as well as the name of a
-    directory in the current directory no longer has a slash appended in certain
-    circumstances:  a single instance found in $PATH when `.' is not in $PATH,
-    and multiple instances found in $PATH, even when `.' is in $PATH.
-
-dd. Incorporated tilde expansion into the word expansion code rather than as a
-    separately-called function, fixing some cases where it was performed
-    inappropriately (e.g., after the second `=' in an assignment statement or
-    in a double-quoted parameter expansion).
-
-ee. Fixed several bugs encountered when parsing compound assignment statements,
-    so that compound assignments appearing as arguments to builtins are no
-    longer double-expanded.
-
-ff. Fixed a bug in the command execution code that caused asynchronous commands
-    containing command substitutions to not put the terminal in the wrong
-    process group.
-
-gg. Bash now handles the case where the WCONTINUED flag causes waitpid() to
-    return -1/EINVAL at runtime as well as configuration time.
-
-hh. Fixed parser to generate an error when the pipeline `argument' to `!' or
-    `time' is NULL.
-
-ii. The shell now takes a little more care when manipulating file descriptors
-    greater than 9 with the `exec' builtin.
-
-jj. Fixed a bug that caused variable assignments preceding the `command' builtin
-    preceding a special builtin to be preserved after the command completed in
-    POSIX mode.
-
-kk. Fixed a bug that allowed variables beginning with a digit to be created.
-
-ll. Fixed a bug that caused a \<newline> to be removed when parsing a $'...'
-    construct.
-
-mm. A shell whose name begins with `-' will now be a restricted shell if the
-    remainder of the name indicates it should be restricted.
-
-nn. Fixed a bug that could cause a core dump if FUNCNAME were changed or unset
-    during a function's execution.
-
-oo. Fixed a bug that caused executing a `return' in a function to not execute
-    a RETURN trap.  The RETURN trap is inherited by shell functions only if
-    function tracing is globally enabled or has been enabled for that function.
-
-pp. Fixed cases where var[@] was not handled exactly like var, when var is a
-    scalar variable.
-
-qq. Fixed a bug that caused the first character after a SIGINT to be discarded
-    under certain circumstances.
-
-rr. Fixed exit status code so that a suspended job returns 128+signal as its
-    exit status (preventing commands after it in `&&' lists from being
-    executed).
-
-ss. Fixed a bug that caused the shell parser state to be changed by executing
-    a shell function as a result of word completion.
-
-tt. Fixed a long-standing bug that caused '\177' characters in variable
-    values to be discarded when expanded in double-quoted strings.
-
-uu. Fixed a bug that caused $RANDOM to be re-seeded multiple times in a
-    subshell environment.
-
-vv. Extensive changes to the job management code to avoid the pid-reuse and
-    pid-aliasing problems caused by retaining the exit status of too many jobs,
-    but still retain as many background job statuses as POSIX requires.
-
-ww. Fixed a parser bug in processing \<newline> that caused things like
-
-               ((echo 5) \
-                (echo 6))
-
-    to not work correctly.
-
-xx. `pwd -P' now sets $PWD to a directory name containing no symbolic links
-    when in posix mode, as POSIX requires.
-
-yy. In posix mode, bash no longer sets $PWD to a name containing no symbolic
-    links if a directory is chosen from $CDPATH.
-
-zz. The word splitting code now treats an IFS character that is not space,
-    tab, or newline and any adjacent IFS white space as a single delimiter, as
-    SUSv3/XPG6 require.
-
-aaa. The `read' builtin now checks whether or not the number of fields read is
-     exactly the same as the number of variables instead of just assigning the
-     rest of the line (minus any trailing IFS white space) to the last
-     variable.  This is what POSIX/SUS/XPG all require.
-
-bbb. Fixed a bug that caused `read' to always check whether or not fd 0 was a
-     pipe, even when reading from another file descriptor.
-
-ccc. Fixed a bug that caused short-circuiting of execution even if the return
-     value was being inverted.
-
-ddd. Fixed a bug that caused a core dump while decoding \W escapes in PS1 if
-     PWD was unset.
-
-eee. Fixed a bug in `read' that counted internal quoting characters for the
-     purposes of `read -n'.
-
-fff. Fixed a bug so that a function definition in a pipeline causes a child
-     process to be forked at the right time.
-
-ggg. Bash will not attempt to link against a readline library that doesn't
-     have rl_gnu_readline_p == 1.
-
-hhh. Fixed a bug that caused `read' to consume one too many characters when
-     reading a fixed number of characters and the Nth character is a backslash.
-
-iii. Fixed a bug that caused `unset' on variables in the temporary environment
-     to leave them set when `unset' completed.
-
-jjj. Fixed a bug that caused bash to close fd 2 if an `exec' failed and the
-     shell didn't exit.
-
-kkk. The completion code is more careful to not turn `/' or `///' into `//',
-     for those systems on which `//' has special meaning.
-
-lll. Fixed a bug that caused command substitution in asynchronous commands to
-     close the wrong file descriptors.
-
-mmm. The shell no longer prints status messages about terminated background
-     processes unless job control is active.
-
-nnn. Fixed a bug that prevented multiple consecutive invocations of `history -s'
-     from adding all the commands to the history list.
-
-ooo. Added a couple of changes to make arithmetic expansion more consistent in
-     all its contexts (still not perfect).
-
-ppp. Fixed a bug that caused the parser to occasionally not find the right
-     terminating "`" in an old-style command substitution.
-
-qqq. Fixed a bug that caused core dumps when the shell was reading its non-
-     interactive input from fd 0 and fd 0 was duplicated and restored using a
-     combination of `exec' (to save) and redirection (to restore).
-
-rrr. Fixed a problem that caused loops in sourced scripts to not be cleaned
-     up properly when a `return' is executed.
-
-sss. Change internal command substitution completion function to append a slash
-     to directory names in the command.
-
-2.  Changes to Readline
-
-a.  Fixed a bug that caused multiliine prompts to be wrapped and displayed
-    incorrectly.
-
-b.  Fixed a bug that caused ^P/^N in emacs mode to fail to display the current
-    line correctly.
-
-c.  Fixed a problem in computing the number of invisible characters on the first
-    line of a prompt whose length exceeds the screen width.
-
-d.  Fixed vi-mode searching so that failure preserves the current line rather
-    than the last line in the history list.
-
-e.  Fixed the vi-mode `~' command (change-case) to have the correct behavior at
-    end-of-line when manipulating multibyte characters.
-
-f.  Fixed the vi-mode `r' command (change-char) to have the correct behavior at
-    end-of-line when manipulating multibyte characters.
-
-g.  Fixed multiple bugs in the redisplay of multibyte characters:  displaying
-    prompts longer than the screen width containing multibyte characters, 
-
-h.  Fix the calculation of the number of physical characters in the prompt
-    string when it contains multibyte characters.
-
-i.  A non-zero value for the `rl_complete_suppress_append' variable now causes
-    no `/' to be appended to a directory name.
-
-j.  Fixed forward-word and backward-word to work when words contained
-    multibyte characters.
-
-k.  Fixed a bug in finding the delimiter of a `?' substring when performing
-    history expansion in a locale that supports multibyte characters.
-
-l.  Fixed a memory leak caused by not freeing the timestamp in a history entry.
-
-m.  Fixed a bug that caused "\M-x" style key bindings to not obey the setting
-    of the `convert-meta' variable.
-
-n.  Fixed saving and restoring primary prompt when prompting for incremental
-    and non-incremental searches; search prompts now display multibyte
-    characters correctly.
-
-o.  Fixed a bug that caused keys originally bound to self-insert but shadowed
-    by a multi-character key sequence to not be inserted.
-
-p.  Fixed code so rl_prep_term_function and rl_deprep_term_function aren't
-    dereferenced if NULL (matching the documentation).
-
-q.  Extensive changes to readline to add enough state so that commands
-    requiring additional characters (searches, multi-key sequences, numeric
-    arguments, commands requiring an additional specifier character like
-    vi-mode change-char, etc.) work without synchronously waiting for
-    additional input.
-
-r.  Lots of changes so readline builds and runs on MinGW.
-
-s.  Readline no longer tries to modify the terminal settings when running in
-    callback mode.
-
-t.  The Readline display code no longer sets the location of the last invisible
-    character in the prompt if the \[\] sequence is empty.
-
-3.  New Features in Bash
-
-a.  Bash now understands LC_TIME as a special variable so that time display
-    tracks the current locale.
-
-b.  BASH_ARGC, BASH_ARGV, BASH_SOURCE, and BASH_LINENO are no longer created
-    as `invisible' variables and may not be unset.
-
-c.  In POSIX mode, if `xpg_echo' option is enabled, the `echo' builtin doesn't
-    try to interpret any options at all, as POSIX requires.
-
-d.  The `bg' builtin now accepts multiple arguments, as POSIX seems to specify.
-
-e.  Fixed vi-mode word completion and glob expansion to perform tilde
-    expansion.
-
-f.  The `**' mathematic exponentiation operator is now right-associative.
-
-g.  The `ulimit' builtin has new options: -i (max number of pending signals),
-    -q (max size of POSIX message queues), and -x (max number of file locks).
-
-h.  A bare `%' once again expands to the current job when used as a job
-    specifier.
-
-i.  The `+=' assignment operator (append to the value of a string or array) is
-    now supported for assignment statements and arguments to builtin commands
-    that accept assignment statements.
-
-j.  BASH_COMMAND now preserves its value when a DEBUG trap is executed.
-
-k.  The `gnu_errfmt' option is enabled automatically if the shell is running
-    in an emacs terminal window.
-
-l.  New configuration option:  --single-help-strings.  Causes long help text
-    to be written as a single string; intended to ease translation.
-
-m.  The COMP_WORDBREAKS variable now causes the list of word break characters
-    to be emptied when the variable is unset.
-
-n.  An unquoted expansion of $* when $IFS is empty now causes the positional
-    parameters to be concatenated if the expansion doesn't undergo word
-    splitting.
-
-o.  Bash now inherits $_ from the environment if it appears there at startup.
-
-p.  New shell option: nocasematch.  If non-zero, shell pattern matching ignores
-    case when used by `case' and `[[' commands.
-
-q.  The `printf' builtin takes a new option: -v var.  That causes the output
-    to be placed into var instead of on stdout.
-
-r.  By default, the shell no longer reports processes dying from SIGPIPE.
-
-s.  Bash now sets the extern variable `environ' to the export environment it
-    creates, so C library functions that call getenv() (and can't use the
-    shell-provided replacement) get current values of environment variables.
-
-4.  New Features in Readline
-
-a.  The key sequence sent by the keypad `delete' key is now automatically
-    bound to delete-char.
-
-b.  A negative argument to menu-complete now cycles backward through the
-    completion list.
-
-c.  A new bindable readline variable:  bind-tty-special-chars.  If non-zero,
-    readline will bind the terminal special characters to their readline
-    equivalents when it's called (on by default).
-
-d.  New bindable command: vi-rubout.  Saves deleted text for possible
-    reinsertion, as with any vi-mode `text modification' command; `X' is bound
-    to this in vi command mode.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-3.0-release,
-and the previous version, bash-3.0-rc1.
-
-1.  Changes to Bash
-
-a.  Fixed a boundary overrun that could cause segmentation faults when the
-    completion code hands an incomplete construct to the word expansion
-    functions.
-
-b.  Changed posix mode behavior so that an error in a variable assignment
-    preceding a special builtin causes a non-interactive shell to exit.
-
-c.  Change the directory expansion portion of the completion code to not
-    expand embedded command substitutions if the directory name appears in
-    the file system.
-
-d.  Fixed a problem that caused `bash -r' to turn on restrictions before
-    reading the startup files.
-
-e.  Fixed a problem with the default operation of the `umask' builtin.
-
-2.  Changes to Readline
-
-a.  Fixed a problem with readline saving the contents of the current line
-    before beginning a non-interactive search.
-
-b.  Fixed a problem with EOF detection when using rl_event_hook.
-
-c.  Fixed a problem with the vi mode `p' and `P' commands ignoring numeric
-    arguments.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-3.0-rc1,
-and the previous version, bash-3.0-beta1.
-
-1.  Changes to Bash
-
-a.  Fixed a bug that caused incorrect behavior when referecing element 0 of
-    an array using $array, element 0 was unset, and `set -u' was enabled.
-
-b.  System-specific changes for: SCO Unix 3.2, Tandem.
-
-c.  Fixed a bug that caused inappropriate word splitting when a variable was
-    expanded within a double-quoted string that also included $@.
-
-d.  Fixed a bug that caused `pwd' to not display anything in physical mode
-    when the file system had changed underneath the shell.
-
-e.  Fixed a bug in the pre- and post- increment and decrement parsing in the
-    expression evaluator that caused errors when the operands and corresponding
-    operators were separated by whitespace.
-
-f.  Fixed a bug that caused `history -p' to add an entry to the history list,
-    counter to the documentation.  (Keeps the history expansions invoked by
-    emacs-mode command line editing from doing that as well.)
-
-g.  Fixed a bug that could cause a core dump if `cd' is asked to print out a
-    pathname longer than PATH_MAX characters.
-
-h.  Fixed a bug that caused jobs to be put into the wrong process group under
-    some circumstances after enabling job control with `set -m'.
-
-i.  `unalias' now  returns failure if no alias name arguments are supplied.
-
-j.  Documented the characters not allowed to appear in an alias name.
-
-k.  $* is no longer expanded as if in double quotes when it appears in the
-    body of a here document, as the SUS seems to require.
-
-l.  The `bashbug' script now uses a directory in $TMPDIR for exclusive
-    access rather than trying to guess how the underlying OS provides for
-    secure temporary file creation.
-
-m.  Fixed a few problems with `cd' and `pwd' when asked to operate on pathnames
-    longer than PATH_MAX characters.
-
-n.  Fixed a memory leak caused when creating multiple local array variables
-    with identical names.
-
-o.  Fixed a problem with calls to getcwd() so that bash now operates better
-    when the full pathname to the current directory is longer than PATH_MAX
-    bytes.
-
-p.  The `trap' builtin now reports an error if a single non-signal argument
-    is specified.
-
-q.  Fixed a bug that caused `umask' to not work correctly when presented
-    with a mask of all 0s.
-
-r.  When `getopts' reaches the end of options, OPTARG is unset, as POSIX
-    appears to specify.
-
-s.  Interactive mode now depends on whether or not stdin and stderr are
-    connected to a tty; formerly it  was stdin and stdout.  POSIX requires
-    this.
-
-t.  Fixed vi-mode completion to work more as POSIX specifies (e.g., doing the
-    right kind of filename generation).
-
-2.  Changes to Readline
-
-a.  Fixed a problem that could cause readline to refer to freed memory when
-    moving between history lines while doing searches.
-
-b.  Improvements to the code that expands and displays prompt strings
-    containing multibyte characters.
-
-c.  Fixed a problem with vi-mode not correctly remembering the numeric argument
-    to the last `c'hange command for later use with `.'.
-
-d.  Fixed a bug in vi-mode that caused multi-digit count arguments to work
-    incorrectly.
-
-e.  Fixed a problem in vi-mode that caused the last text modification command
-    to not be remembered across different command lines.
-
-f.  Fixed problems with changing characters and changing case at the end of
-    the line.
-
-3.  New Features in Bash
-
-a.  The `jobs', `kill', and `wait' builtins now accept job control notation
-    even if job control is not enabled.
-
-b.  The historical behavior of `trap' that allows a missing `action' argument
-    to cause each specified signal's handling to be reset to its default is
-    now only supported when `trap' is given a single non-option argument.
-
-4.  New Features in Readline
-
-a.  When listing completions, directories have a `/' appended if the
-    `mark-directories' option has been enabled.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-3.0-beta1,
-and the previous version, bash-3.0-alpha.
-
-1.  Changes to Bash
-
-a.  Fixes to build correctly when arrays are not compiled into the shell.
-
-b.  Fixed command substitution to run any exit trap defined in the command
-    substitution before returning; the exit trap is not inherited from the
-    calling shell.
-
-c.  Fixes to process group synchronization code so that every child process
-    attempts to set the terminal's process group; fixes some synchronization
-    problems on Linux kernels that schedule the child to always run before
-    the parent.
-
-d.  Fixed processing of octal and hex constants in printf builtin for POSIX.2
-    compliance.
-
-e.  Fixed a couple of core dumps in the pattern removal code.
-
-f.  Fixes to the array subrange extraction code to deal better with sparse
-    arrays.
-
-g.  Parser errors and other errors that result in the shell exiting now cause
-    the exit trap to be run.
-
-h.  Change the command substitution completion functions to not append any
-    closing quote, because it would be inserted a closing "`" or ")".
-
-i.  Fix history initialization so assignments to $histchars made in startup
-    files are honored.
-
-j.  If an exit trap does not contain a call to `exit', the shell now uses
-    the exit status of the last command executed before the trap as the exit
-    status of the shell.
-
-k.  The parser now prompts with $PS2 if it reads a newline while parsing a
-    compound array assignment statement.
-
-l.  When performing a compound array assignment, the parser doesn't treat
-    words of the form [index]=value as assignments if they're the result of
-    expansions.
-
-m.  Fixed a bug that caused `return' executed in a trap command to make the
-    shell think it was still running the trap.
-
-n.  Fixed the value of errno set by the pathname canonicalization functions.
-
-o.  Changed the grammar so that `time' alone on a line times a null command
-    rather than being a syntax error.
-
-p.  The pattern substitution code no longer performs quote removal on the
-    pattern before trying to match it, as the pattern removal functions do.
-
-q.  Fixed a bug that could cause core dumps when checking whether a quoted
-    command name was being completed.
-
-r.  Fixes to the pattern removal and pattern replacement expansions to deal
-    with multibyte characters better (and faster).
-
-s.  Fix to the substring expansion (${param:off[:len]}) to deal with (possibly
-    multibyte) characters instead of raw bytes.
-
-t.  Fixed a bug that caused some key bindings set in an inputrc to be ignored
-    at shell startup.
-
-u.  Fixed a bug that caused unsetting a local variable within a function to
-    not work correctly.
-
-v.  Fixed a bug that caused invalid variables to be created when using
-    `read -a'.
-
-w.  Fixed a bug that caused "$@" to expand incorrectly when used as the right
-    hand side of a parameter expansion such as ${word:="$@"} if the first
-    character of $IFS was not a space.
-
-x.  Fixed a slight cosmetic problem when printing commands containing a
-    `>&word' redirection.
-
-y.  Fixed a problem that could cause here documents to not be created correctly
-    if the system temporary directory did not allow writing.
-
-2.  Changes to Readline
-
-a.  Change to history expansion functions to treat `^' as equivalent to word
-    one, as the documention states.
-
-b.  Some changes to the display code to improve display and redisplay of
-    multibyte characters.
-
-c.  Changes to speed up the multibyte character redisplay code.
-
-d.  Fixed a bug in the vi-mode `E' command that caused it to skip over the
-    last character of a word if invoked while point was on the word's
-    next-to-last character.
-
-e.  Fixed a bug that could cause incorrect filename quoting when
-    case-insensitive completion was enabled and the word being completed
-    contained backslashes quoting word break characters.
-
-f.  Fixed a bug in redisplay triggered when the prompt string contains
-    invisible characters.
-
-g.  Fixed some display (and other) bugs encountered in multibyte locales
-    when a non-ascii character was the last character on a line.
-
-h.  Fixed some display bugs caused by multibyte characters in prompt strings.
-
-i.  Fixed a problem with history expansion caused by non-whitespace characters
-    used as history word delimiters.
-
-3.  New Features in Bash
-
-a.  printf builtin understands two new escape sequences:  \" and \?.
-
-b.  `echo -e' understands two new escape sequences:  \" and \?.
-
-c.  The GNU `gettext' package and libintl have been integrated; the shell's
-    messages can be translated into different languages.
-
-d.  The `\W' prompt expansion now abbreviates $HOME as `~', like `\w'.
-
-e.  The error message printed when bash cannot open a shell script supplied
-    as argument 1 now includes the name of the shell, to better identify
-    the error as coming from bash.
-
-4.  New Features in Readline
-
-a.  New application variable, rl_completion_quote_character, set to any
-    quote character readline finds before it calls the application completion
-    function.
-
-b.  New application variable, rl_completion_suppress_quote, settable by an
-    application completion function.  If set to non-zero, readline does not
-    attempt to append a closing quote to a completed word.
-
-c.  New application variable, rl_completion_found_quote, set to a non-zero
-    value if readline determines that the word to be completed is quoted.
-    Set before readline calls any application completion function.
-
-d.  New function hook, rl_completion_word_break_hook, called when readline
-    needs to break a line into words when completion is attempted.  Allows
-    the word break characters to vary based on position in the line.
-
-e.  New bindable command: unix-filename-rubout.  Does the same thing as
-    unix-word-rubout, but adds `/' to the set of word delimiters.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-3.0-alpha,
-and the previous version, bash-2.05b-release.
-
-1.  Changes to Bash
-
-a.  Fixes so that the shell will compile without some of the default options
-    defined.
-
-b.  Fixed an error message that did not pass enough arguments to printf.
-
-c.  Fixed a bug that caused input redirection to a builtin inside a script
-    being read from standard input to result in the rest of the already-
-    read and buffered script to be discarded.
-
-d.  Fixed a bug that caused subshell initialization to close the file
-    descriptor from which the shell was reading a script under certain
-    circumstances.
-
-e.  Fixed a bug that caused the shell to not advance a string pointer over
-    a null wide character when doing string operations.
-
-f.  Fixed the internal logout code so that shells that time out waiting for
-    input (using $TMOUT) run ~/.bash_logout.
-
-g.  Portability and configuration changes for: cygwin, HP/UX, GNU/FreeBSD.
-
-h.  The parser no longer adds implicit double quotes to ((...)) arithmetic
-    commands.
-
-i.  The ((...)) arithmetic command evaluation code was fixed to not dump core
-    when the expanded string is null.
-
-j.  The ((...)) arithmetic command evaluation code was fixed to not perform
-    variable assignments while expanding the expression.
-
-k.  Fixed a bug that caused word splitting to be performed incorrectly when
-    IFS is set, but null.
-
-l.  Fixed a bug in brace expansion that caused a quoted `$' preceding an
-    open brace to inhibit brace expansion.
-
-m.  Fixed a bug that caused a leading `-' in the shell's name to cause it to
-    not be recognized as a restricted shell.
-
-n.  Fixed a bug in the arithmetic evaluation code that could cause longjmps
-    to an invalid location and result in a core dump.
-
-o.  Fixed a bug in the calculation of how many history lines are new in a
-    single shell session when reading new history lines from a file with
-    `history -n'.
-
-p.  Fixed a bug in pathname canonicalization that caused the shell to dump
-    core when presented with a pathname longer than PATH_MAX.
-
-q.  Fixed the parser so that it doesn't try to compare a char variable to
-    EOF, which fails when chars are unsigned.
-
-r.  Fixed a bug in the simple command execution code that caused occasional
-    core dumps.
-
-s.  The shell does a better job of saving any partial parsing state during
-    operations which cause a command to be executed while a line is being
-    entered and parsed.
-
-t.  The completion code now splits words more like the expansion code when
-    $IFS is used to split.
-
-u.  The locale code does a better job of recomputing the various locale
-    variable values when LC_ALL is unset.
-
-v.  The programmable completion code does a better job of dequoting expanded
-    word lists before comparing them against the word to be matched.
-
-w.  The shell no longer seg faults if the expanded value of $PS4 is null
-    and `set -x' is enabled.
-
-x.  Fixed a bug that caused core dumps when a here string expanded to NULL.
-
-y.  The mail checking code now makes sure the mailbox is bigger before
-    reporting the existence of new mail.
-
-z.  The parser does not try to expand $'...' and $"..." when the appear
-    within double quotes unless the `extquote' option has been enabled with
-    `shopt'.  For backwards compatibility, it is enabled by default.
-
-aa. Fixed a bug that caused `for x; do ...' and `select x; do ... to use
-    $@ instead of "$@" for the implicit list of arguments.
-
-bb. Fixed a bug that caused a subshell of a restricted shell (e.g., one
-    spawned to execute a pipeline) to not exit immediately if attempting
-    to use a command containing a slash.
-
-cc. Fixed a problem with empty replacements for a pattern that doesn't match
-    when performing ${param/word/} expansion.
-
-dd. Word expansions performed while expanding redirections no longer search
-    a command's temporary environment to expand variable values.
-
-ee. Improvements to the alias expansion code when expanding subsequent words
-    because an aliase's value ends with a space.
-
-ff. `cd -' now prints the current working directory after a successful chdir
-    even when the shell is not interactive, as the standard requires.
-
-gg. The shell does a better job of ensuring a child process dies of SIGINT
-    before resending SIGINT to itself.
-
-hh. The arithmetic expansion variable assignment code now does the right
-    thing when assigning to `special' variables like OPTIND.
-
-ii. When history expansion verification is enabled, the bash readline helper
-    functions that do history expansion on the current line don't print
-    the results.
-
-jj. Fixed bugs with multiple consecutive alias expansion when one of the
-    expansions ends with a space.
-
-kk. Fixed a problem in the programmable completion code that could cause core
-    dumps when trying to initialize a set of possible completions from a
-    list of variables.
-
-ll. The \[ and \] escape characters are now ignored when decoding the prompt
-    string if the shell is started with editing disabled.
-
-mm. Fixed a bug that could leave extra characters in a string when doing
-    quoted null character removal.
-
-nn. Command substitution and other subshell operations no longer reset the
-    line number (aids the bash debugger).
-
-oo. Better line number management when executing simple commands, conditional
-    commands, for commands, and select commands.
-
-pp. The globbing code now uses malloc, with its better failure properties,
-    rather than alloca().
-
-qq. Fixed a bug that caused expansions like #{a[2]:=value} to create the
-    appropriate array element instead of a variable named `a[2]'.
-
-rr. Fixed a bug in the handling of a `?(...)' pattern immediately following
-    a `*' when extglob is enabled.
-
-ss. Fixed a bug that caused a `return' invoked in an exit trap when exit is
-    invoked in a function to misbehave.
-
-tt. Fixed a bug that caused CTLESC and CTLNUL characters to not be escaped
-    by the internal shell string quoting functions.
-
-uu. Fixed a bug that caused quoted null characters in an expanded word list
-    to be inappropriately assigned to an array variable when using `read -a'.
-
-vv. Fixed a bug that caused redirections accompanying a null command to persist
-    in the current shell.
-
-ww. Fixed a bug that caused the prompt to be printed when the shell was
-    expanding a multiline alias.
-
-xx. Fixed a bug that resulted in core dumps when the completion for a command
-    changed the compspec.
-
-yy. Fixed a bug that caused evaluation of programmable completions to print
-    notifications of completed jobs.
-
-zz. Bash now disables line editing when $EMACS == `t' and $TERM == `dumb'
-    (which is what emacs shell windows do).
-
-aaa. In posix mode, `kill -l' causes signal names to be displayed without
-     a leading `SIG'.
-
-bbb. Clear error flag on standard output so it doesn't persist across multiple
-     builtin commands.
-
-ccc. In posix mode, `alias' displays alias values without the leading `alias',
-     so the output cannot be used as subsequent input.
-
-ddd. In posix mode, the `trap' builtin doesn't check whether or not its
-     first argument is a signal specification and revert the signal handling
-     to its original disposition if it is.
-
-eee. Fixed several bugs in the handling of "$*" and "${array[*]}" by the
-     pattern substitution and removal expansions.
-
-fff. Fixed several problems with the handling of ${array[@]}, ${array[*]},
-     $@, and $* by the indirect variable expansion code.
-
-ggg. Fixed a bug that did not allow `time' to be aliased.
-
-hhh. Improved the mail checking code so it won't check (and possibly cause an
-     NFS file system mount) until MAILPATH or MAIL is given a value -- there
-     is no default if DEFAULT_MAIL_DIRECTORY is not defined at compile time.
-     (It is computed by configure, but can be #undef'd in config-bot.h.)
-
-iii. If the `chkwinsize' option is enabled, the shell checks for window size
-     changes if a child process exits due to a signal.
-
-jjj. Removed the attempts to avoid adding a slash at the end of a completed
-     executable name if there was a directory with the same name in the
-     current directory.
-
-kkk. Fixed PATH lookup code so it treats the permission bits separately for
-     owner, group, and other, rather than checking them all.
-
-lll. Fixed the locale code to reset the parser's idea of the character class
-     <blank>, which controls how it splits tokens, when the locale changes.
-
-mmm. The shell now binds its special readline functions and key bindings only
-     if the user's inputrc file has not already bound them.
-
-nnn. The shell now reports on processes that dump core due to signals when
-     invoked as `-c command'.
-
-2.  Changes to Readline
-
-a.  Fixes to avoid core dumps because of null pointer references in the
-    multibyte character code.
-
-b.  Fix to avoid infinite recursion caused by certain key combinations.
-
-c.  Fixed a bug that caused the vi-mode `last command' to be set incorrectly.
-
-d.  Readline no longer tries to read ahead more than one line of input, even
-    when more is available.
-
-e.  Fixed the code that adjusts the point to not mishandle null wide
-    characters.
-
-f.  Fixed a bug in the history expansion `g' modifier that caused it to skip
-    every other match.
-
-g.  Fixed a bug that caused the prompt to overwrite previous output when the
-    output doesn't contain a newline and the locale supports multibyte
-    characters.  This same change fixes the problem of readline redisplay
-    slowing down dramatically as the line gets longer in multibyte locales.
-
-h.  History traversal with arrow keys in vi insertion mode causes the cursor
-    to be placed at the end of the new line, like in emacs mode.
-
-i.  The locale initialization code does a better job of using the right
-    precedence and defaulting when checking the appropriate environment
-    variables.
-
-j.  Fixed the history word tokenizer to handle <( and >( better when used as
-    part of bash.
-
-k.  The overwrite mode code received several bug fixes to improve undo.
-
-l.  Many speedups to the multibyte character redisplay code.
-
-m.  The callback character reading interface should not hang waiting to read
-    keyboard input.
-
-n.  Fixed a bug with redoing vi-mode `s' command.
-
-o.  The code that initializes the terminal tracks changes made to the terminal
-    special characters with stty(1) (or equivalent), so that these changes
-    are reflected in the readline bindings.  New application-callable function
-    to make it work:  rl_tty_unset_default_bindings().
-
-p.  Fixed a bug that could cause garbage to be inserted in the buffer when
-    changing character case in vi mode when using a multibyte locale.
-
-q.  Fixed a bug in the redisplay code that caused problems on systems
-    supporting multibyte characters when moving between history lines when the
-    new line has more glyphs but fewer bytes.
-
-r.  Undo and redo now work better after exiting vi insertion mode.
-
-s.  Make sure system calls are restarted after a SIGWINCH is received using
-    SA_RESTART.
-
-t.  Improvements to the code that displays possible completions when using
-    multibyte characters.
-
-u.  Fixed a problem when parsing nested if statements in inputrc files.
-
-v.  The completer now takes multibyte characters into account when looking for
-    quoted substrings on which to perform completion.
-
-w.  The history search functions now perform better bounds checking on the
-    history list.
-
-3.  New Features in Bash
-
-a.  ANSI string expansion now implements the \x{hexdigits} escape.
-
-b.  There is a new loadable `strftime' builtin.
-
-c.  New variable, COMP_WORDBREAKS, which controls the readline completer's
-    idea of word break characters.
-
-d.  The `type' builtin no longer reports on aliases unless alias expansion
-    will actually be performed.    
-
-e.  HISTCONTROL is now a colon-separated list of values, which permits
-    more extensibility and backwards compatibility.
-
-f.  HISTCONTROL may now include the `erasedups' option, which causes all lines
-    matching a line being added to be removed from the history list.
-
-g.  `configure' has a new `--enable-multibyte' argument that permits multibyte
-    character support to be disabled even on systems that support it.
-
-h.  New variables to support the bash debugger:  BASH_ARGC, BASH_ARGV,
-    BASH_SOURCE, BASH_LINENO, BASH_SUBSHELL, BASH_EXECUTION_STRING,
-    BASH_COMMAND
-
-i.  FUNCNAME has been changed to support the debugger: it's now an array
-    variable.
-
-j.  for, case, select, arithmetic commands now keep line number information
-    for the debugger.
-
-k.  There is a new `RETURN' trap executed when a function or sourced script
-    returns (not inherited child processes; inherited by command substitution
-    if function tracing is enabled and the debugger is active).
-
-l.  New invocation option:  --debugger.  Enables debugging and turns on new
-    `extdebug' shell option.
-
-m.  New `functrace' and `errtrace' options to `set -o' cause DEBUG and ERR
-    traps, respectively, to be inherited by shell functions.  Equivalent to
-    `set -T' and `set -E' respectively.  The `functrace' option also controls
-    whether or not the DEBUG trap is inherited by sourced scripts.
-
-n.  The DEBUG trap is run before binding the variable and running the action
-    list in a `for' command, binding the selection variable and running the
-    query in a `select' command, and before attempting a match in a `case'
-    command.
-
-o.  New `--enable-debugger' option to `configure' to compile in the debugger
-    support code.
-
-p.  `declare -F' now prints out extra line number and source file information
-    if the `extdebug' option is set.
-
-q.  If `extdebug' is enabled, a non-zero return value from a DEBUG trap causes
-    the next command to be skipped, and a return value of 2 while in a
-    function or sourced script forces a `return'.
-
-r.  New `caller' builtin to provide a call stack for the bash debugger.
-
-s.  The DEBUG trap is run just before the first command in a function body is
-    executed, for the debugger.
-
-t.  `for', `select', and `case' command heads are printed when `set -x' is
-    enabled.
-
-u.  There is a new {x..y} brace expansion, which is shorthand for {x.x+1,
-    x+2,...,y}.  x and y can be integers or single characters; the sequence
-    may ascend or descend; the increment is always 1.
-
-v.  New ksh93-like ${!array[@]} expansion, expands to all the keys (indices)
-    of array.
-
-w.  New `force_fignore' shopt option; if enabled, suffixes specified by
-    FIGNORE cause words to be ignored when performing word completion even
-    if they're the only possibilities.
-
-x.  New `gnu_errfmt' shopt option; if enabled, error messages follow the `gnu
-    style' (filename:lineno:message) format.
-
-y.  New `-o bashdefault' option to complete and compgen; if set, causes the
-    whole set of bash completions to be performed if the compspec doesn't
-    result in a match.
-
-z.  New `-o plusdirs' option to complete and compgen; if set, causes directory
-    name completion to be performed and the results added to the rest of the
-    possible completions.
-
-aa. `kill' is available as a builtin even when the shell is built without
-    job control.
-
-bb. New HISTTIMEFORMAT variable; value is a format string to pass to
-    strftime(3).  If set and not null, the `history' builtin prints out
-    timestamp information according to the specified format when displaying
-    history entries.  If set, bash tells the history library to write out
-    timestamp information when the history file is written.
-
-cc. The [[ ... ]] command has a new binary `=~' operator that performs
-    extended regular expression (egrep-like) matching.
-
-dd. `configure' has a new `--enable-cond-regexp' option (enabled by default)
-    to enable the =~ operator and regexp matching in [[ ... ]].
-
-ee. Subexpressions matched by the =~ operator are placed in the new
-    BASH_REMATCH array variable.
-
-ff. New `failglob' option that causes an expansion error when pathname
-    expansion fails to produce a match.
-
-gg. New `set -o pipefail' option that causes a pipeline to return a failure
-    status if any of the processes in the pipeline fail, not just the last
-    one.
-
-4.  New Features in Readline
-
-a.  History expansion has a new `a' modifier equivalent to the `g' modifier
-    for compatibility with the BSD csh.
-
-b.  History expansion has a new `G' modifier equivalent to the BSD csh `g'
-    modifier, which performs a substitution once per word.
-
-c.  All non-incremental search operations may now undo the operation of
-    replacing the current line with the history line.
-
-d.  The text inserted by an `a' command in vi mode can be reinserted with
-    `.'.
-
-e.  New bindable variable, `show-all-if-unmodified'.  If set, the readline
-    completer will list possible completions immediately if there is more
-    than one completion and partial completion cannot be performed.
-
-f.  There is a new application-callable `free_history_entry()' function.
-
-g.  History list entries now contain timestamp information; the history file
-    functions know how to read and write timestamp information associated
-    with each entry.
-
-h.  Four new key binding functions have been added:
-
-       rl_bind_key_if_unbound()
-       rl_bind_key_if_unbound_in_map()
-       rl_bind_keyseq_if_unbound()
-       rl_bind_keyseq_if_unbound_in_map()
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.05b-release,
-and the previous version, bash-2.05b-beta2.
-
-1.  Changes to Bash
-
-a.  Fixed an off-by-one error in the function that translates job
-    specifications.
-
-b.  Note that we're running under Emacs and disable line editing if
-    $EMACS == `t'.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.05b-beta2,
-and the previous version, bash-2.05b-beta1.
-
-1.  Changes to Bash
-
-a.  Fixed the /= and %= arithmetic operators to catch division by zero.
-
-b.  Added putenv, setenv, unsetenv to getenv replacement for completeness.
-
-c.  Fixed a bug that could cause the -O expand_aliases invocation option
-    to not take effect.
-
-d.  Fixed a problem with process substitution that resulted in incorrect
-    behavior when the number of process substitutions in an individual
-    command approached 64.
-
-2.  Changes to Readline
-
-a.  Fixed a problem with backward-char-search when on a system with support
-    for multibyte characters when running in a locale without any multibyte
-    characters.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.05b-beta1,
-and the previous version, bash-2.05b-alpha1.
-
-1.  Changes to Bash
-
-a.  Fixed a problem when parsing a POSIX.2 character class name while
-    evaluating a bracket expression containing multibyte characters.
-
-b.  Changed the help text for `bind' to make it clear that any command
-    that may be placed in ~/.inputrc is a valid argument to `bind'.
-
-c.  Added `help' builtin entries for `((', `[[', and arithmetic for.
-
-d.  malloc updated again:
-       o slightly better overflow and underflow detection by putting the
-         chunk size at the beginning and end of the chunk and making
-         sure they match in free/realloc
-       o partial page allocated to make things page-aligned no longer
-         completely wasted
-       o block coalescing now enabled by default
-       o splitting and coalescing enabled for 32-byte chunks, the most
-         common size requested
-       o fixed a problem that resulted in spurious underflow messages and
-         aborts
-       o bin sizes are precomputed and stored in an array rather than
-         being computed at run time
-       o malloc will return memory blocks back to the system if the block
-         being freed is at the top of the heap and of sufficient size to
-         make it worthwhile
-       o malloc/free/realloc now inline memset instead of calling the
-         libc function; uses Duff's device for good performance
-
-e.  Check for getservent(); make the service name completion code dependent
-    on its presence.
-
-f.  Changed the readline callback that executes a command bound to a key
-    sequence to not save the executed command on the history list and to
-    save and restore the parsing state.
-
-g.  Changes to lib/sh/snprintf.c:  fixed some bugs in the `g' and `G'
-    floating point format display; implemented the "'" flag character
-    that turns on thousands' grouping; fixed behavior on systems where
-    MB_CUR_MAX does not evaluate to a constant.
-
-h.  The `unset' builtin no longer returns a failure status when asked to
-    unset a previously-unset variable or function.
-
-i.  Changes to the build system to make it easier to cross-compile bash
-    for different systems.
-
-j.  Added `,' to  the characters that are backslash-escaped during filename
-    completion, to avoid problems with complete-into-braces and RCS filenames
-    containing commas.
-
-k.  Some changes to the multibyte character support code to avoid many calls
-    to strlen().
-
-l.  Bash now correctly honors setting LANG to some value when LC_ALL does not
-    already have a value.
-
-m.  Fixed a bug that could cause SIGSEGV when processing nested traps with
-    trap handlers.
-
-n.  The `source/.' builtin now restores the positional parameters when it
-    returns unless they were changed using the `set' builtin during the file's
-    execution.
-
-o.  Fixed a bug that caused a syntax error when a command was terminated by
-    EOF.
-
-2.  New Features in Bash
-
-a.  There is now support for placing the long help text into separate files
-    installed into ${datadir}/bash.  Not enabled by default; can be turned
-    on with `--enable-separate-helpfiles' option to configure.
-
-b.  All builtins that take operands accept a `--' pseudo-option, except
-    `echo'.
-
-c.  The `echo' builtin now accepts \0xxx (zero to three octal digits following
-    the `0') in addition to \xxx (one to three octal digits) for SUSv3/XPG6/
-    POSIX.1-2001 compliance.
-
-3.  Changes to Readline
-
-a.  Fixed a small problem in _rl_insert_char with multibyte characters.
-
-b.  Fixes from IBM for line wrapping problems when using multibyte characters.
-
-c.  Fixed a problem which caused the display to be messed up when the last
-    line of a multi-line prompt (possibly containing invisible characters)
-    was longer than the screen width.
-
-d.  Fixed a problem with the vi-mode `r' command that ocurred on systems with
-    support for multibyte characters when running in a locale without any
-    multibyte characters.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.05b-alpha1,
-and the previous version, bash-2.05a-release.
-
-1.  Changes to Bash
-
-a.  Some changes to work around inlining differences between compilers.
-
-b.  Added more prototypes for internal shell typedefs, to catch argument
-    passing errors when using pointers to functions.
-
-c.  The `cd' builtin now fails in posix mode when a valid directory cannot be
-    constructed from a relative pathname argument and the $PWD using pathname
-    canonicalization, and the -P option has not been supplied.  Previously,
-    the shell would attempt to use what the user typed, leading to weird
-    values for $PWD and discrepancies between the value of $PWD and the
-    actual working directory.
-
-d.  The `cd' builtin now resets $PWD when canonicalization fails but a chdir
-    to the pathname passed as an argument succeeds (when not in posix mode).
-
-e.  The `fc' builtin has been fixed, as POSIX requires, to use the closest
-    history position in range when given an out-of-range argument.
-
-f.  The history file loading code was changed to allow lines to be saved in
-    the history list from the shell startup files.
-
-g.  `history -s args' now works better in compound commands.
-
-h.  The tilde expansion code was fixed to better recognize when it's being
-    invoked in an assignment context, which enables expansion after `='
-    and `:'.
-
-i.  Fixed the command name completion code so a slash is no longer appended
-    to a single match if there happens to be a directory with that name in
-    $PWD.
-
-j.  Fixed compound array assignment to no longer perform alias expansion, to
-    allow reserved words as array members, and to not produce extra output
-    when the `-v' option had been enabled.
-
-k.  Fixed the programmable completion code to better handle newlines in lists
-    of possible completions (e.g., `complete -W').
-
-l.  Removed the reserved words from the `bash-builtins' manual page.
-
-m.  Parser error reporting now attempts to do a better job of identifying the
-    token in error rather than doing straight textual analysis.
-
-n.  Fixes for Inf/NaN, locales, wide/multibyte characters and zero-length
-    arguments in the library snprintf(3) replacement.
-
-o.  `read -e' no longer does command name completion on the first word on
-    the line being read.
-
-p.  `select' now returns failure if the read of the user's selection fails.
-
-q.  Fixed a bug that could cause a core dump when setting $PIPESTATUS.
-
-r.  Fixes to not allocate so many job slots when the shell is running a loop
-    with job control enabled in a subshell of an interactive shell.
-
-s.  Fixed a bug in the trap code that caused traps to be inherited by
-    command substitutions in some cases.
-
-t.  Fixed a bug that could cause alias expansion to inappropriately expand
-    the word following the alias.
-
-u.  Fixed a bug in the `kill' builtin that mishandled negative pid arguments.
-
-v.  The parser is less lenient when parsing assignment statements where the
-    characters before the `=' don't comprise a valid identifier.
-
-w.  The arithmetic expression evaluation code now honors the setting of the
-    `-u' option when expanding variable names.
-
-x.  Fixed the arithmetic evaluation code to allow array subscripts to be
-    assigned (`let b[7]=42') and auto-incremented and auto-decremented
-    (e.g., b[7]++).
-
-y.  Reimplemented the existing prompt string date and time expansions using
-    strftime(3), which changed the output of \@ in some locales.
-
-z.  Fixed a bug that could cause a core dump when a special shell variable
-    (like RANDOM) was converted to an array with a variable assignment.
-
-aa. Fixed a bug that would reset the handler for a signal the user had
-    trapped to a function that would exit the shell when setting the exit
-    trap in a non-interactive shell.
-
-bb. Changed the execve(2) wrapper code to check whether or not a failing
-    command is a directory before looking at whether a `#!' interpreter
-    failed for some reason.
-
-cc. Fixed a bug in the command printing code so it no longer inserts a `;'
-    after a newline, which produces a syntax error when reused as input.
-
-dd. The code that expands $PS4 no longer inherits the `-x' flag.
-
-ee. The bash-specific completion functions may now take advantage of the
-    double-TAB and M-?  features of the standard readline completion
-    functions.
-
-ff. The mail checking code no longer prints a message if the checked file's
-    size has not increased, even if the access time is less than the modification time.
-
-gg. Rewrote the variable symbol table code: there is now a stack of
-    contexts, each possibly including a separate symbol table; there can
-    be more than one temporary environment supplied to nested invocations
-    of `./source'; the temporary environments no longer require so much
-    special-case code; shell functions now handle the temporary environment
-    and local variables more consistently; function scope exit is faster now
-    that the entire symbol table does not have to be traversed to dispose of
-    local variables; it is now easier to push vars from the temporary
-    environment to the shell's variable table in posix mode; some duplicated
-    code has been removed.
-
-hh. Regularized the error message printing code; builtin_error is now called
-    more consistently, and common error message strings are handled by small
-    functions.  This should make eventual message translation easier.
-
-ii. Error messages now include the line number in a script when the shell
-    is not interactive.
-
-jj. Array subscript expansion now takes place even when the array variable is
-    unset, so side effects will take place.
-
-kk. Fixed a bug in the SICGHLD child-reaping code so that it won't find
-    jobs already marked as terminated if the OS reuses pids quickly enough.
-
-ll. Fixed a bug that could cause a signal to not interrupt the `wait'
-    builtin while it was waiting for a background process to terminate.
-
-mm. A couple of changes to make it easier for multiple shells to share history
-    files using `history -n', `history -r', and `history -w'.
-
-nn. The `getopts' builtin always increments OPTIND to point to the next
-    option to be handled when an option is returned, whether it's valid
-    or not, as POSIX 1003.x-2001 requires.
-
-oo. Changed some parts of the expansion code to avoid allocating and
-    immediately freeing memory without using the results for anything.
-
-pp. The shell now keeps track of $IFS internally, updating its internal map
-    each time the variable is assigned a new value (or at local scope exit).
-    This saves thousands of hash lookups for IFS, which, while individually
-    cheap, add up.
-
-qq. Rewrote the hash table code:  searching and insertion are much faster now,
-    and it uses a better string hashing function; augmented the function
-    interface to simplify other parts of the code and remove duplicated code
-
-rr. The shell now uses a simple, generic `object cache' for allocating and
-    caching words and word lists, which were the major users of
-    malloc/free.
-
-ss. Fixed the assignment statement parsing code to allow whitespace and
-    newlines in subscripts when performing array element assignment.
-
-tt. The shell now issues many fewer calls to sigprocmask and other signal
-    masking system calls.
-
-uu. Fixed the `test' and conditional command file comparison operators to
-    work right when one file has a non-positive timestamp and the other
-    does not exist.
-
-vv. Fixed some cases where the special characters '\001' and '\177' in the
-    values of variables or positional parameters caused incorrect expansion
-    results.
-
-2.  Changes to Readline
-
-a.  Fixed output of comment-begin character when listing variable values.
-
-b.  Added some default key bindings for common escape sequences produced by
-    HOME and END keys.
-
-c.  Fixed the mark handling code to be more emacs-compatible.
-
-d.  A bug was fixed in the code that prints possible completions to keep it
-    from printing empty strings in certain circumstances.
-
-e.  Change the key sequence printing code to print ESC as M\- if ESC is a
-    meta-prefix character -- it's easier for users to understand than \e.
-
-f.  Fixed unstifle_history() to return values that match the documentation.
-
-g.  Fixed the event loop (rl_event_hook) to handle the case where the input
-    file descriptor is invalidated.
-
-h.  Fixed the prompt display code to work better when the application has a
-    custom redisplay function.
-
-i.  Changes to make reading and writing the history file a little faster, and
-    to cope with huge history files without calling abort(3) from xmalloc.
-
-j.  The vi-mode `S' and `s' commands are now undone correctly.
-
-3.  New Features in Bash
-
-a.  If set, TMOUT is the default timeout for the `read' builtin.
-
-b.  `type' has two new options:  `-f' suppresses shell function lookup, and
-    `-P' forces a $PATH search.
-
-c.  New code to handle multibyte characters.
-
-d.  `select' was changed to be more ksh-compatible, in that the menu is
-    reprinted each time through the loop only if REPLY is set to NULL.
-    The previous behavior is available as a compile-time option.
-
-e.  `complete -d' and `complete -o dirnames' now force a slash to be
-    appended to names which are symlinks to directories.
-
-f.  There is now a bindable edit-and-execute-command readline command,
-    like the vi-mode `v' command, bound to C-xC-e in emacs mode.
-
-g.  Added support for ksh93-like [:word:] character class in pattern matching.
-
-h.  The  $'...' quoting construct now expands \cX to Control-X.
-
-i.  A new \D{...} prompt expansion; passes the `...' to strftime and inserts
-    the result into the expanded prompt.
-
-j.  The shell now performs arithmetic in the largest integer size the
-    machine supports (intmax_t), instead of long.
-
-k.  If a numeric argument is supplied to one of the bash globbing completion
-    functions, a `*' is appended to the word before expansion is attempted.
-
-l.  The bash globbing completion functions now allow completions to be listed
-    with double tabs or if `show-all-if-ambiguous' is set.
-
-m.  New `-o nospace' option for `complete' and `compgen' builtins; suppresses
-    readline's appending a space to the completed word.
-
-n.  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).
-
-p.  There is a new configuration option `--enable-mem-scramble', controls
-    bash malloc behavior of writing garbage characters into memory at
-    allocation and free time.
-
-q.  The `complete' and `compgen' builtins now have a new `-s/-A service'
-    option to complete on names from /etc/services.
-
-r.  `read' has a new `-u fd' option to read from a specified file descriptor.
-
-s.  Fix the completion code so that expansion errors in a directory name
-    don't cause a longjmp back to the command loop.
-
-t.  Fixed word completion inside command substitution to work a little more
-    intuitively.
-
-u.  The `printf' %q format specifier now uses $'...' quoting to print the
-    argument if it contains non-printing characters.
-
-v.  The `declare' and `typeset' builtins have a new `-t' option.  When applied
-    to functions, it causes the DEBUG trap to be inherited by the named
-    function.  Currently has no effect on variables.
-
-w.  The DEBUG trap is now run *before* simple commands, ((...)) commands,
-    [[...]] conditional commands, and for ((...)) loops.
-
-x.  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.
-
-y.  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.  Code
-    from Gary Vaughan.
-
-z.  New [n]<&word- and [n]>&word- redirections from ksh93 -- move fds (dup
-    and close).
-
-aa. There is a new `-l' invocation option, equivalent to `--login'.
-
-bb. The `hash' builtin has a new `-l' option to list contents in a reusable
-    format, and a `-d' option to remove a name from the hash table.
-
-4.  New Features in Readline
-
-a.  Support for key `subsequences':  allows, e.g., ESC and ESC-a to both
-    be bound to readline functions.  Now the arrow keys may be used in vi
-    insert mode.
-
-b.  When listing completions, and the number of lines displayed is more than
-    the screen length, readline uses an internal pager to display the results.
-    This is controlled by the `page-completions' variable (default on).
-
-c.  New code to handle editing and displaying multibyte characters.
-
-d.  The behavior introduced in bash-2.05a of deciding whether or not to
-    append a slash to a completed name that is a symlink to a directory has
-    been made optional, controlled by the `mark-symlinked-directories'
-    variable (default is the 2.05a behavior).
-
-e.  The `insert-comment' command now acts as a toggle if given a numeric
-    argument:  if the first characters on the line don't specify a
-    comment, insert one; if they do, delete the comment text
-
-f.  New application-settable completion variable:
-    rl_completion_mark_symlink_dirs, allows an application's completion
-    function to temporarily override the user's preference for appending
-    slashes to names which are symlinks to directories.
-
-g.  New function available to application completion functions:
-    rl_completion_mode, to tell how the completion function was invoked
-    and decide which argument to supply to rl_complete_internal (to list
-    completions, etc.).
-
-h.  Readline now has an overwrite mode, toggled by the `overwrite-mode'
-    bindable command, which could be bound to `Insert'.
-
-i.  New application-settable completion variable:
-    rl_completion_suppress_append, inhibits appending of
-    rl_completion_append_character to completed words.
-
-j.  New key bindings when reading an incremental search string:  ^W yanks
-    the currently-matched word out of the current line into the search
-    string; ^Y yanks the rest of the current line into the search string,
-    DEL or ^H deletes characters from the search string.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.05a-release,
-and the previous version, bash-2.05a-rc1.
-
-1.  Changes to Bash
-
-a.  Fixed the `printf' builtin so that the variable name supplied as an
-    argument to a %n conversion must be a valid shell identifier.
-
-b.  Improved the random number generator slightly.
-
-c.  Changes to configuration to not put -I/usr/include into $CFLAGS, since
-    it messes up some includes.
-
-d.  Corrected description of POSIXLY_CORRECT in man page and info manual.
-
-e.  Fixed a couple of cases of incorrect function prototypes that sneaked
-    through and caused compilation problems.
-
-f.  A few changes to avoid potential core dumps in the programmable completion
-    code.
-
-g.  Fixed a configure problem that could cause a non-existent file to show
-    up in LIBOBJS.
-
-h.  Fixed a configure problem that could cause siglist.o to not be built when
-    required.
-
-i.  Changes to the strtoimax and strtoumax replacement functions to work
-    around buggy compilers.
-
-j.  Fixed a problem with the snprintf replacement function that could
-    potentially cause a core dump.
-
-2.  Changes to Readline
-
-a.  Fixed a locale-specific problem in the vi-mode `goto mark' command.
-
-b.  Fixed Makefile to not put -I/usr/include into CFLAGS, since it can cause
-    include file problems.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.05a-rc1,
-and the previous version, bash-2.05a-beta1.
-
-1.  Changes to Bash
-
-a.  Fixed the snprintf replacement to correctly implement the `alternate form'
-    of the %g and %G conversions.
-
-b.  Fixed snprintf to correctly handle the optional precision with the %g and
-    %G conversions.
-
-c.  Fixed the arithmetic evaluation code to correct the values of `@' and `_'
-    when translating base-64 constants (they were backwards).
-
-d.  New library functions for formatting long and long long ints.
-
-e.  Fixed a few places where negative array subscripts could have occurred,
-    mostly as the result of systems using signed characters.
-
-f.  Fixed a few places that assumed a pid_t was no wider than an int.
-
-g.  Fixed the `maildir' mail checking code to work on systems where a
-    `struct stat' doesn't include an `st_blocks' member.
-
-h.  Fixed snprintf to make `unsigned long long' conversion formats (%llu)
-    work better.
-
-i.  Fixed snprintf to not print a sign when asked to do an unsigned conversion.
-
-j.  Made configure changes to avoid compiling empty source files in lib/sh.
-
-k.  New replacement functions (if necessary) for strtoull, strtoll, strtoimax,
-    strtoumax.
-
-l.  The `printf' builtin now handles the `ll' and `j' length modifiers
-    directly, since they can affect the type and width of the argument
-    passed to printf(3).
-
-m.  Renamed a number of the bash-specific autoconf macros in aclocal.m4 to
-    have more sytematic naming, with accompanying changes to configure.in.
-
-n.  Fixed snprintf to handle long doubles and the %a/%A conversions by
-    falling back to sprintf, as long as sprintf supports them.
-
-o.  Fixed return value from vsnprintf/snprintf to be the number of characters
-    that would have been printed, even if that number exceeds the buffer
-    size passed as an argument.
-
-p.  Bash no longer attempts to define its own versions of some ctype macros
-    if they are implemented as functions in libc but not as macros in
-    <ctype.h>.
-
-q.  Changed the variable printing code (used by `set', `export', etc.) to
-    not use the $'...' syntax when in posix mode, since that caused
-    interoperability problems with other shells (most notably with autoconf).
-    When not in posix mode, it uses $'...' if the string to be printed
-    contains non-printing characters and regular single quotes otherwise.
-
-r.  snprintf now recognizes the %F conversion.
-
-s.  Fixed a bug that could cause the wrong status to be returned by a shell
-    function when the shell is compiled without job control and a null
-    command containing a command substutition was executed in the function.
-
-t.  When in posix mode, the default value for MAILCHECK is 600.
-
-u.  Bash only initializes FUNCNAME, GROUPS, and DIRSTACK as special variables
-    if they're not in the initial environment.
-
-v.  If SECONDS appears in the initial environment with a valid integer value,
-    bash uses that as the starting value, as if an assignment had been
-    performed.
-
-w.  Bash no longer auto-exports HOME, PATH, SHELL, or TERM, even though it
-    gives them default values if they don't appear in the initial environment.
-
-x.  Bash no longer auto-exports HOSTNAME, HOSTTYPE, MACHTYPE, or OSTYPE,
-    even if it assigns them default values.
-
-y.  Bash no longer removes the export attribute from SSH_CLIENT or SSH2_CLIENT
-    if they appear in the initial environment.
-
-z.  Bash no longer attempts to discover if it's being run by sshd in order to
-    run the startup files.  If the SSH_SOURCE_BASHRC is uncommented in
-    config-top.h it will attempt to do so as previously, but that's commented
-    out in the distributed version.
-
-aa. Fixed a typo in the code that tests for LC_NUMERIC.
-
-bb. The POSIXLY_CORRECT shell variable and its effects are now documented.
-
-cc. Some changes to several of the support shell scripts included in the
-    definitions to try to avoid race conditions and attacks.
-
-dd. Several changes to avoid warnings from `gcc -Wall'.
-
-ee. Fixed a problem with the `unset' builtin that could cause incorrect
-    results if asked to unset a variable and an array subscript in the
-    same command.
-
-ff. A few changes to the shell's temporary file creation code to avoid
-    potential file descriptor leaks and to prefer the system's idea of
-    the temporary directory to use.
-
-gg. Fixes to build with the C alloca in lib/malloc/alloca.c if the system
-    requires it but the shell has been configured --without-bash-malloc.
-
-hh. Updated the documentation to note that only interactive shells resend
-    SIGHUP to all jobs before exiting.
-
-ii. Fixes to only pass unquoted tilde words to tilde_expand, rather than
-    rely on tilde_expand or getpwnam(3) to handle the quotes (MacOS 10.x
-    will remove backslashes in any login name passed to getpwnam(3)).
-
-jj. Small change from Paul Eggert to make LINENO right in commands run with
-    `bash -c'.
-
-2.  New Features in Bash
-
-a.  The `printf' builtin now handles the %a and %A conversions if they're
-    implemented by printf(3).
-
-b.  The `printf' builtin now handles the %F conversion (just about like %f).
-
-c.  The `printf' builtin now handles the %n conversion like printf(3).  The
-    corresponding argument is the name of a shell variable to which the
-    value is assigned.
-
-3.  Changes to Readline
-
-a.  Fixed a few places where negative array subscripts could have occurred.
-
-b.  Fixed the vi-mode code to use a better method to determine the bounds of
-    the array used to hold the marks.
-
-c.  Fixed the defines in chardefs.h to work better when chars are signed.
-
-d.  Fixed configure.in to use the new names for bash autoconf macros.
-
-e.  Readline no longer attempts to define its own versions of some ctype
-    macros if they are implemented as functions in libc but not as macros in
-    <ctype.h>.
-
-f.  Fixed a problem where rl_backward could possibly set point to before
-    the beginning of the line.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.05a-beta1,
-and the previous version, bash-2.05a-alpha1.
-
-1.  Changes to Bash
-
-a.  Fixed a bug in the evalution of arithmetic `for' statements when the
-    expanded expression is NULL.
-
-b.  Fixed an unassigned variable problem in the redirection printing code.
-
-c.  Added more prototypes to extern function declarations in the header
-    files and to static function declarations in C source files.
-
-d.  Make sure called functions have a prototype in scope, to get the arguments
-    and return values right instead of casting.  Removed extern function
-    declarations from C source files that were already included in header
-    files.
-
-e.  Changed some function arguments to use function typedefs in general.h so
-    the prototypes can be checked.  The only use of Function and VFunction
-    now is for unwind-protects.
-
-f.  More const changes to function arguments and appropriate variables.
-
-g.  Changed the mail checking support to handle `maildir'-style mail
-    directories.
-
-h.  Augmented the bash malloc to pass in the file and line number information
-    for each malloc, realloc, and free.  This should result in better error
-    messages.
-
-i.  The `old' gnu malloc is no longer a configuration option.
-
-j.  Augmented the bash malloc with optional tracing and registering allocated
-    and freed memory.
-
-k.  Prompt string decoding now saves and restores the value of $? when it
-    expands the prompt string, so command substitutions don't change $?.
-
-i.  Array indices are now `long', since shell arithmetic is performed as long,
-    and the internal arrayind_t type is used consistently.
-
-j.  Some more `unsigned char *' fixes from Paul Eggert.
-
-k.  Fixed a bad call to builtin_error that could cause core dumps when making
-    local variables.
-
-l.  `return' may no longer be used to terminate a `select' command, for
-    compatibility with ksh.
-
-m.  Changed code that reads octal numbers to do a better job of detecting
-    overflows.
-
-n.  The time formatting code no longer uses absolute indices into a buffer,
-    because the buffer size changes depending on the size of a `time_t'.
-
-o.  `umask' now prints four digits when printing in octal mode, for
-    compatibility with other shells.
-
-p.  Lots of changes to the `printf' builtin from Paul Eggert:  it handles `L'
-    formats and long doubles better, and internal functions have been
-    simpified where appropriate.
-
-q.  Some `time_t' fixes for machines were a time_t is bigger than a long.
-
-r.  Replaced some bash-specific autoconf macros with standard equivalents.
-
-s.  Improvmed the code that constructs temporary filenames to make the
-    generated names a bit more random.
-
-t.  Added code that checks for ascii before calling any of the is* ctype
-    functions.
-
-u.  Changed some places where a `char' was used as an array subscript to use
-    `unsigned char', since a `char' can be negative if it's signed by default.
-
-v.  Lots of changes to the `ulimit' builtin from Paul Eggert to add support
-    for the new POSIX-200x RLIM_SAVED_CUR and RLIM_SAVED_MAX values and
-    simplify the code.
-
-w.  `ulimit' now prints the description of a resource in any error message
-    relating to fetching or setting that resource's limits.
-
-x.  The `snprintf' replacement now computes maximum values at compile
-    time rather than using huge constants for things like long long.
-
-y.  Interactive shells now ignore `set -n'.
-
-z.  Changed the malloc bookkeeping information so that it's now 8 bytes
-    instead of 12 on most 32-bit machines (saving 4 bytes per allocation),
-    restoring 8-byte alignment.
-
-aa. The malloc error reporting code now attempts to print the file and line
-    number of the call that caused the error.
-
-bb. Changed the redirection error reporting code to catch EBADF errors and
-    report the file descriptor number rather than the file being redirected
-    to or from (e.g., things like `exec 4242<x' where 4242 is an out-of-range
-    file descriptor).
-
-cc. `printf', `echo -e', and the $'...' code now process only two hex digits
-    after a `\x' escape sequence for compatibility with other shells, and
-    the documentation was changed to note that the octal and hex escape
-    sequences result in an eight-bit value rather than strict ASCII.
-
-2.  Changes to Readline
-
-a.  The completion code now attempts to do a better job of preserving the
-    case of the word the user typed if ignoring case in completions.
-
-b.  Readline defaults to not echoing the input and lets the terminal
-    initialization code enable echoing if there is a controlling terminal.
-
-c.  The key binding code now processes only two hex digits after a `\x'
-    escape sequence, and the documentation was changed to note that the
-    octal and hex escape sequences result in an eight-bit value rather
-    than strict ASCII.
-
-3.  New Features in Bash
-
-a.  The builtin `ulimit' now takes two new non-numeric arguments:  `hard',
-    meaning the current hard limit, and `soft', meaning the current soft
-    limit, in addition to `unlimited'
-
-b.  `ulimit' now prints the option letter associated with a particular
-    resource when printing more than one limit.
-
-c.  `ulimit' prints `hard' or `soft' when a value is not `unlimited' but is
-    one of RLIM_SAVED_MAX or RLIM_SAVED_CUR, respectively.
-
-4.  New Features in Readline
-
-a.  New bindable variable `history-preserve-point'.  If set, the history
-    code attempts to place the user at the same location on each history
-    line retrived with previous-history or next-history.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.05a-alpha1,
-and the previous version, bash-2.05-release.
-
-1.  Changes to Bash
-
-a.  Better checks in the redirection code for write errors.
-
-b.  bashbug now uses $TMPDIR, defaulting to /tmp, and uses mktemp(1) more
-    portably.
-
-c.  System-specific configuration changes for:  Interix, OpenBSD, FreeBSD,
-    MacOS X.
-
-d.  Some more `const' cleanups through the code.
-
-e.  Fixed a typo in the /dev/fd redirection code, better checks for valid
-    numeric fds in /dev/fd.
-
-f.  Fixed many parts of the shell to handle integer overflow more gracefully
-    and to do more stringent checks for valid numbers.
-
-g.  Fixed mksignames to include config.h.
-
-h.  Fixed an uninitialized variable problem that could cause the shell to core
-    dump when replacing characters in a string.
-
-i.  New mechanism for updating the patch level when official patches are
-    released (patchlevel.h).
-
-j.  configure.in changed to no longer require external files _distribution and
-    _patchlevel.
-
-k.  Fixed non-interactive shell initialization problem when bash started as
-    `bash -i filename'.
-
-l.  Fixed printf builtin conversion error handling to be POSIX.2-conformant.
-
-m.  autoconf-2.52 is now used to build configure; autoconf-2.50 or newer is
-    required.  Some of the bash-specific macros were removed, since they are
-    now standard.
-
-n.  Startup files and files read with source or `.' are no longer required to
-    be regular files.
-
-o.  Fixed core dump in builtin printf when user-supplied precision or field
-    width is 0.
-
-p.  Fixed builtin printf to treat a negative field width as a positive field
-    width with left-justification.
-
-r.  New unwind-protect implementation from Paul Eggert.
-
-s.  Fixed an inadvertently-unclosed comment in the bash completion code that
-    caused programmable completions to not add trailing slashes or spaces to
-    completions.
-
-t.  Fixed the process substitution code to cope better when stdin is closed.
-
-v.  Fixes, mostly from Paul Eggert, for a few possible buffer overflows in
-    the shell.
-
-w.  Fixes from Paul Eggert to avoid most of the type casts in the shell code,
-    and use more appropriate types for a number of variables.
-
-x.  Command substition no longer inherits the DEBUG trap.
-
-y.  Some fixes to the process substition code on machines without /dev/fd so
-    that named pipes are not removed inappropriately.
-
-z.  The loadable `getconf' builtin is now much more complete, and will become
-    part of the shell in the future.
-
-aa. The select command no longer terminates on a `return', so it can be used
-    to return from an enclosing function (as ksh does it).
-
-bb. Fixed the extended pattern matching code to behave better when presented
-    with incorrectly-formed patterns.
-
-cc. Some changes were made with the intent of making cross-compilation easier.
-
-dd. The network code (/dev/tcp and /dev/udp redirections) uses getaddrinfo(3)
-    if it's available, which adds support for IPv6.
-
-ee. Subshells of login shells no longer source ~/.bash_logout when they exit.
-
-ff. Fixes so that subshells don't exit inappropriately if the -e option has
-    been set.
-
-gg. Restricted shells no longer allow functions to be exported.
-
-hh. Changes to the pattern matching code so extended pattern matching works
-    on systems with deficient shared library implementations, like MacOS X.
-
-ii. Better error messages when a script with a leading `#!interp' fails
-    to execute because of problems with `interp'.
-
-jj. Fixed `compgen' to handle the `-o default' option better.
-
-kk. Fixed the job control code to force an asynchronous process's standard
-    input to /dev/null only if job control is not active.
-
-ll. Fixed a possible infinite recursion problem when `fc ""=abc' (a null
-    pattern) is used to re-execute a previous command.
-
-mm. Fixed `declare [-a] var=value' to assign VALUE to element 0 if VAR is an
-    array variable.  Similarly for `declare [-a] var[N]=value'.  This is like
-    ksh93.
-
-nn. Fixed a bug that caused `read -a aname' to work even if ANAME had been
-    declared readonly.
-
-oo. Fixed a possible integer overflow problem when constructing names for
-    temporary files.
-
-2.  New Features in Bash
-
-a.  Added support for DESTDIR installation root prefix, so you can do a
-    `make install DESTDIR=bash-root' and do easier binary packaging.
-
-b.  Added support for builtin printf "'" flag character as per latest POSIX
-    drafts.
-
-c.  Support for POSIX.2 printf(1) length specifiers `j', `t', and `z' (from
-    ISO C99).
-
-d.  New autoconf macro, RL_LIB_READLINE_VERSION, for use by other applications
-    (bash doesn't use very much of what it returns).
-
-e.  `set [-+]o nolog' is recognized as required by the latest POSIX drafts,
-    but ignored.
-
-f.  New read-only `shopt' option:  login_shell.  Set to non-zero value if the
-    shell is a login shell.
-
-g.  New `\A' prompt string escape sequence; expands to time in 24 HH:MM format.
-
-h.  New `-A group/-g' option to complete and compgen; does group name
-    completion.
-
-i.  New `-t' option to `hash' to list hash values for each filename argument.
-
-j.  New [-+]O invocation option to set and unset `shopt' options at startup.
-
-k.  configure's `--with-installed-readline' option now takes an optional
-    `=PATH' suffix to set the root of the tree where readline is installed
-    to PATH.
-
-l.  The ksh-like `ERR' trap has been added.  The `ERR' trap will be run
-    whenever the shell would have exited if the -e option were enabled.
-    It is not inherited by shell functions.
-
-m.  `readonly', `export', and `declare' now print variables which have been
-    given attributes but not set by assigning a value as just a command and
-    a variable name (like `export foo') when listing, as the latest POSIX
-    drafts require.
-
-n.  `bashbug' now requires that the subject be changed from the default.
-
-o.  configure has a new `--enable-largefile' option, like other GNU utilities.
-
-p.  `for' loops now allow empty word lists after `in', like the latest POSIX
-    drafts require.
-
-3.  Changes to Readline
-
-a.  More `const' and type casting fixes.
-
-b.  Changed rl_message() to use vsnprintf(3) (if available) to fix buffer
-    overflow problems.
-
-c.  The completion code no longer appends a `/' or ` ' to a match when
-    completing a symbolic link that resolves to a directory name, unless
-    the match does not add anything to the word being completed.  This
-    means that a tab will complete the word up to the full name, but not
-    add anything, and a subsequent tab will add a slash.
-
-d.  Fixed a trivial typo that made the vi-mode `dT' command not work.
-
-e.  Fixed the tty code so that ^S and ^Q can be inserted with rl_quoted_insert.
-
-f.  Fixed the tty code so that ^V works more than once.
-
-g.  Changed the use of __P((...)) for function prototypes to PARAMS((...))
-    because the use of __P in typedefs conflicted g++ and glibc.
-
-4.  New Features in Readline
-
-a.  Added extern declaration for rl_get_termcap to readline.h, making it a
-    public function (it was always there, just not in readline.h).
-
-b.  New #defines in readline.h:  RL_READLINE_VERSION, currently 0x0402,
-    RL_VERSION_MAJOR, currently 4, and RL_VERSION_MINOR, currently 2.
-
-c.  New readline variable:  rl_readline_version, mirrors RL_READLINE_VERSION.
-
-d.  New bindable boolean readline variable:  match-hidden-files.  Controls
-    completion of files beginning with a `.' (on Unix).  Enabled by default.
-
-e.  The history expansion code now allows any character to terminate a
-    `:first-' modifier, like csh.
-
-f.  The incremental search code remembers the last search string and uses
-    it if ^R^R is typed without a search string.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.05-release,
-and the previous version, bash-2.05-beta2.
-
-1.  Changes to Bash
-
-a.  Make sure we note that the first line of a multi-line command was not
-    saved in the history if the tests for HISTCONTROL succeed, but the
-    HISTIGNORE check fails.
-
-b.  Fixed a bug in the pattern matching code that caused `[' to be treated
-    as a special character inside a `[...]' bracket expression.
-
-c.  Fixed a bug in the pattern matching code that caused `]' to terminate
-    a bracket expression even if it was the first character after the `['
-    (or a leading `!' or `^').
-
-d.  Made a small change to report a more user-friendly error message if
-    execve(2) fails because of an error with the interpreter in a script
-    with a leading `#! interpreter'.
-
-e.  If the OS does not support an exec(2) magic number of `#!', make sure we
-    have a non-null interpreter name before attempting to execute it.
-
-f.  Fixed a bug that caused the shell process to end up in a different
-    process group than the controlling terminal if a job-control shell was
-    run with `exec' in the startup files.
-
-g.  When started in POSIX mode, either by `bash --posix', `bash -o posix', or
-    `sh', $SHELLOPTS includes `posix' and POSIXLY_CORRECT is set.
-
-h.  Fixed a problem that caused the `\W' prompt string escape sequence to
-    expand to nothing when $PWD was `//'.
-
-i.  The `bashbug' shell script no longer uses $(...) command substitution.
-
-j.  When `set' is invoked without options in POSIX mode, it no longer prints
-    the names and definitions of shell functions.
-
-2.  Changes to Readline
-
-a.  rl_set_paren_blink_timeout() is now documented.
-
-b.  Corrected history.3 man page: `$' is not in the default value of
-    history_word_delimiters.
-
-c.  If a hook function assigned to rl_event_hook sets rl_done to a non-zero
-    value, rl_read_key() now immediately returns '\n' (which is assumed to
-    be bound to accept-line).
-
-3.  New Features in Bash
-
-a.  The `>&word' redirection now works in POSIX mode as it does by default,
-    since POSIX.2 leaves it unspecified.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.05-beta2,
-and the previous version, bash-2.05-beta1.
-
-1.  Changes to Bash
-
-a.  Fixed a bug in the arithmetic evaluation code so that a^=b is supported.
-
-b.  Fixed startup so posixly_correct is retained across subshells begun to
-    execute scripts without a leading `#!'.
-
-c.  Fixed a bug that caused $(< file) to not work in a (...) subshell.
-
-d.  Added config support for Linux running on the IBM S390.
-
-e.  Fixed a bug that caused bash to get its input pointer out of sync when
-    reading commands through a pipe and running a command with standard
-    input redirected from a file.
-
-f.  Made a change so that command completion now makes about half as many
-    stat(2) calls when searching the $PATH.
-
-g.  Fixed a bug that caused variable assignments preceding `return' to not
-    be propagated to the shell environment in POSIX mode.
-
-h.  Fixed a bug with ${parameter[:]?word} -- tilde expansion was not performed
-    on `word'.
-
-i.  In POSIX mode, `break' and `continue' do not complain and return success
-    if called when the shell is not executing a loop.
-
-j.  Fixed `bash -o posix' to work the same as `bash --posix'.
-
-k.  Fixed a bug where variable assignments preceding `eval' or `source/.'
-    would not show up in the environment exported to subshells run by the
-    commands.
-
-l.  In POSIX mode, shells started to execute command substitutions inherit
-    the value of the `-e' option from their parent shell.
-
-m.  In POSIX mode, aliases are expanded even in non-interactive shells.
-
-n.  Changed some of the job control messages to display the text required by
-    POSIX.2 when the shell is in POSIX mode.
-
-o.  Fixed a bug in `test' that caused it to occasionally return incorrect
-    results when non-numeric arguments were supplied to `-t'.
-
-2.  Changes to Readline
-
-a.  Some changes were made to avoid gcc warnings with -Wall.
-
-b.  rl_get_keymap_by_name now finds keymaps case-insensitively, so
-    `set keymap EMACS' works.
-
-c.  The history file writing and truncation functions now return a useful
-    status on error.
-
-d.  Fixed a bug that could cause applications to dereference a NULL pointer
-    if a NULL second argument was passed to history_expand().
-
-3.  New Features in Bash
-
-a.  doc/readline.3 has been moved to the readline distribution.
-
-4.  New Features in Readline
-
-a.  New function, rl_get_screen_size (int *rows, int *columns), returns
-    readline's idea of the screen dimensions.
-
-b.  The timeout in rl_gather_tyi (readline keyboard input polling function)
-    is now settable via a function (rl_set_keyboard_input_timeout()).
-
-c.  Renamed the max_input_history variable to history_max_entries; the old
-    variable is maintained for backwards compatibility.
-
-d.  The list of characters that separate words for the history tokenizer is
-    now settable with a variable:  history_word_delimiters.  The default
-    value is as before.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.05-beta1,
-and the previous version, bash-2.05-alpha1.
-
-1.  Changes to Bash
-
-a.  Changes to allow shared library and object building on the GNU Hurd.
-
-b.  Fixes to the way exported functions are placed into the environment and
-    cached.
-
-c.  The globbing library once again respects locales when processing ranges
-    in bracket expressions while doing pattern matching.
-
-d.  System-specific configuration changes for:  Tru 64, Interix
-
-e.  Bashbug now uses /usr/bin/editor as one of the editing alternatives, and
-    will use mktemp(1) or tempfile(1), if present, for temporary file creation.
-
-f.  Bash no longer performs a binary file check on a script argument that's
-    really a tty (like /dev/fd/0 or /dev/stdin).
-
-g.  Fixed a bug in the execution of shell scripts that caused the effects of
-    $BASH_ENV to be undone in some cases.
-
-h.  Fixed several bugs that made `bash [-i] /dev/stdin' not work correctly.
-
-i.  Several changes to the job control code to avoid some signal state
-    manipulation.
-
-j.  The Bash malloc no longer blocks signals as often, which should make it
-    faster.
-
-k.  Fixed a parsing bug that did not allow backslash to escape a single quote
-    inside a $'...' construct.
-
-l.  Fixed a bug that caused things like ${var:=$'value'} to be parsed
-    incorrectly.  This showed up in newer versions of autoconf.
-
-m.  Fixed a bug in the bash-specific readline initialization that caused
-    key bindings to bash-specific function names appearing in .inputrc to
-    not be honored.
-
-n.  Bash now sets the file descriptor it uses to save the file descriptor
-    opened on a shell script to close on exec.
-
-o.  Fixed a bug in the prompt string decoding that caused it to misbehave
-    when presented an octal sequence of fewer than three characters.
-
-p.  Fixed the `test' builtin to return an error if `[' is supplied a single
-    argument that is not `]'.
-
-q.  Fixed a bug that caused subshells started to run executable shell scripts
-    without a leading `#!' to incorrectly inherit an argument list preceding
-    a shell builtin (like such a script called from a script sourced with `.',
-    where there were variable assignments preceding the `.' command)
-
-r.  Fixed a bug that caused changes to variables supplied in an assignment
-    statement preceding a shell builtin to not be honored (like a script
-    run with `.').
-
-s.  HOSTTYPE, OSTYPE, and MACHTYPE are set only if they do not have values
-    when the shell is started.
-
-t.  Fixed a bug that caused SIGINT to kill shell scripts after the script
-    called `wait'.
-
-u.  The `fc' builtin now tries to create its temporary files in the directory
-    named by $TMPDIR.
-
-v.  Bash no longer calls any Readline functions or uses any Readline variables
-    not declared in readline.h.
-
-w.  Fixed a bug that caused some substitutions involving $@ to not be split
-    correctly, especially expansions of the form ${paramterOPword}.
-
-x.  SSH2_CLIENT is now treated like SSH_CLIENT and not auto-exported if it
-    appears in the initial environment.
-
-y.  Fixed a couple of problems with shell scripts without a leading `#!'
-    being executed out of shell functions that could cause core dumps if
-    such a script attempted to execute `return'.
-
-z.  Fixed a problem with the `-nt' and `-ot' binary operators for the
-    `test/[' builtin and the `[[' conditional command that caused wrong
-    return values if one of the file arguments did not exist.
-
-aa. Fixed a bug that caused non-interactive shells which had previously
-    executed `shopt -s expand_aliases' to fail to expand aliases in a
-    command like `(command) &'.
-2.  Changes to Readline
-
-a.  Changes to make most (but not yet all -- there is still crlf()) of the
-    exported readline functions declared in readline.h have an rl_ prefix.
-
-b.  More `const' changes in function arguments, mostly for completion
-    functions.
-
-c.  Fixed a bug in rl_forward that could cause the point to be set to before
-    the beginning of the line in vi mode.
-
-d.  Fixed a bug in the callback read-char interface to make it work when a
-    readline function pushes some input onto the input stream with
-    rl_execute_next (like the incremental search functions).
-
-e.  Fixed a file descriptor leak in the history file manipulation code that
-    was tripped when attempting to truncate a non-regular file (like
-    /dev/null).
-
-f.  Some existing variables are now documented and part of the public
-    interface (declared in readline.h):  rl_explict_arg, rl_numeric_arg,
-    rl_editing_mode, rl_last_func.
-
-g.  Renamed rltty_set_default_bindings to rl_tty_set_default_bindings and
-    crlf to rl_crlf, so there are no public functions declared in readline.h
-    without an `rl_' prefix.  The old functions still exist for backwards
-    compatibility.
-
-3.  New Features in Bash
-
-a.  A new loadable builtin, realpath, which canonicalizes and expands symlinks
-    in pathname arguments.
-
-b.  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.
-
-4.  New Features in Readline
-
-a.  New application-callable function rl_set_prompt(const char *prompt):
-    expands its prompt string argument and sets rl_prompt to the result.
-
-b.  New application-callable function rl_set_screen_size(int rows, int cols):
-    public method for applications to set readline's idea of the screen
-    dimensions.
-
-c.  The history example program (examples/histexamp.c) is now built as one
-    of the examples.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.05-alpha1,
-and the previous version, bash-2.04-release.
-
-1.  Changes to Bash
-
-a.  A fix was made to allow newlines in compond array assignments.
-
-b.  configure now checks for real-time signals with unusable values.
-
-c.  Interactive shells no longer exit if a substitution fails because of an
-    unset variable within a sourced file.
-
-d.  Fixed a problem with incorrect matching of extended glob patterns when
-    doing pattern substitution.
-
-e.  `{' is now quoted by the completion code when it appears in a filename.
-
-f.  Fixed an error in pattern matching that caused the matcher to not
-    correctly skip the rest of a bracket expression after a character
-    matched.
-
-g.  Fixed a bug in the IFS word splitting code to make a non-whitespace IFS
-    character preceded by IFS whitespace part of the current delimiter rather
-    than generating a separate field.
-
-h.  The {!prefix@} expansion now generates separate words, analogous to $@,
-    when double-quoted.
-
-i.  Command substitution now ignores NUL bytes in the command output, and the
-    parser ignores them on input.
-
-j.  A fix was made to the job control code to prevent hanging processes when
-    the shell thinks background processes are running but the kernel returns
-    -1/ECHILD from waitpid().
-
-k.  `pwd' now prints an error message if the write fails when displaying the
-    current directory.
-
-l.  When in POSIX mode, the shell prints trap dispostions without a leading
-    `SIG' in the signal specification.
-
-m.  Fixed a parser bug that caused the current command's line count to be
-    messed up by a compound array assignment.
-
-n.  Fixed a bug in the unwind-protect code that caused bad behavior on machines
-    where ints and pointers are not the same size.
-
-o.  System-specific configure changes for:  MacOS X.
-
-p.  Changes for Cygwin to translate \r\n and \r to \n and to set file
-    descriptors used for reading input to text mode in various places.
-
-q.  Fixed a bug that caused `!' to occasionally not be honored when in
-    a (...) subshell.
-
-r.  Bash no longer assumes that getcwd() will return any useful error message
-    in the buffer passed as an argument if the call fails.
-
-s.  The `source', `.', and `fc' builtins no longer check whether a file is
-    binary before reading commands from it.
-
-t.  Subshells no longer turn off job control when they exit, since that
-    sometimes resulted in the terminal being reset to the wrong process
-    group.
-
-u.  The history code no longer tries to save the second and subsequent lines
-    of a multi-line command if the first line was not saved.
-
-v.  The history saving code now does a better job of saving blank lines in a
-    multi-line command.
-
-w.  Removed a `feature' that made `ulimit' silently translate `unlimited' to
-    the current hard limit, which obscured some kernel error returns.
-
-x.  Fixed the grammar so that `}' is recognized as a reserved word after
-    another reserved word, rather than requiring a `;' or newline.  This
-    means that constructs like
-
-       { { echo a b c ; } }
-
-    work as expected.
-
-y.  Conditional commands ([[...]]) now perform tilde expansion on their
-    arguments.
-
-z.  Noted in the documentation that `set -a' will cause functions to be
-    exported if they are defined after `set -a' is executed.
-
-aa. When an interactive login shell starts, if $PWD and $HOME refer to the
-    same directory but are not the same string, $PWD is set to $HOME.
-
-bb. Fixed `printf' to handle invalid floating point numbers better.
-
-cc. Temporary files are now created with random filenames, to improve security.
-
-dd. The readline initialization code now binds the custom bash functions and
-    key bindings after the readline defaults are set up.
-
-ee. Fixed the `source' builtin to no longer overwrite a shell function's
-    argument list, even if the sourced file changes the positional parameters.
-
-ff. A bug fix was made in the expansion of `$*' in contexts where it should
-    not be split, like assignment statements.
-
-gg. Fixed a bug in the parameter substring expansion to handle conditional
-    arithmetic expressions ( exp ? val1 : val2 ) without cutting the expression
-    off at the wrong `:'.
-
-hh. The `<>' redirection is no longer subject to the current setting of
-    `noclobber', as POSIX.2 specifies.
-
-ii. Fixed a bug in the conditional command parsing code that caused expressions
-    in parentheses to occasionally be parsed incorrectly.
-
-jj. Fixed a bug in the ((...)) arithmetic command to allow do...done or
-    {...} to follow the )) without an intervening list terminator.
-
-kk. `printf' now treats `\E' the same as `\e' when performing backslash escape
-    expansion for the `%b' format specifier.
-
-ll. When in POSIX mode, the shell no longer searches the current directory for
-    a file to be sourced with `.' or `source' if `.' is not in $PATH.
-
-mm. Interactive comments are no longer turned off when POSIX mode is disabled.
-
-nn. The UID, EUID, HOSTNAME variables are not set if they are in the shell's
-    environment when it starts up.
-
-oo. Fixed a bug in the `command' builtin so the effect of a command like
-    `command exec 4<file' is as if the `command' had been omitted.
-
-pp. ${foo[@]} and ${foo[*]} now work as in ksh93 if `foo' is not an array
-    variable.
-
-qq. ${#foo[X]}, where X is 0, @, or *, now work as in ksh93 if `foo' is not
-    an array variable.
-
-rr. The shell's idea of an absolute pathname now takes into account a
-    possible drive specification on Cygwin and other Windows systems.
-
-ss. Fixed a bug which caused incorrect parsing of some multi-character
-    constructs if they were split across input lines with backslash-newline
-    line continuation.
-
-tt. Fixed a bug that caused restricted shell mode to be set inappropriately
-    when trying to execute a shell script without a leading `#!'.
-
-uu. Shell function definitions no longer require that the body be a group
-    command ( {...} ), as POSIX.2 requires.
-
-vv. The `cd' and `pwd' builtins now process symlinks in pathnames internally
-    and should require many fewer calls to getcwd().
-
-ww. Fixed a bug that caused a pipeline's process group to be set incorrectly
-    if one of the pipeline elements contained a command substitution.
-
-xx. Fixed a bug that caused core dumps when expanding the value of HISTIGNORE.
-
-yy. The output of `set' is now quoted using $'...' so invisible characters are
-    displayed as escape sequences.
-
-zz. Fixed the help text for `unset', since PATH and IFS may both be unset.
-
-aaa. The shell no longer puts directory names into the command hash table.
-
-bbb. Fixed a bug in `read' that caused it to occasionally free memory twice if
-     it was interrupted after reading a large amount of data.
-
-ccc. Assignment statements that attempt to assign values to readonly variables
-     now cause the command to return an error status.
-
-ddd. Fixed a bug that could cause incorrect output if a $(<file) construct was
-     interrupted.
-
-eee. GROUPS and FUNCNAME now return an error status when assignment is
-     attempted, but may be unset (in which case they lose their special
-     properties).  In all respects except unsetting, they are readonly.
-
-fff. The string-to-integer conversion code now ignores trailing whitespace in
-     the string, even if strtol(3) does not.
-
-ggg. The tcsh magic-space function now does a better job of inserting the
-     space close to where the point was before the history expansion, rather
-     than just appending it.
-
-hhh. Fixed a bug which caused a file sourced from an interactive shell to
-     fill up the jobs table if it ran lots of jobs.
-
-iii. Fixed a bug in the parameter pattern substitution code to avoid infinite
-     recursion on zero-length matches.
-
-2.  Changes to Readline
-
-a.  When setting the terminal attributes on systems using `struct termio',
-    readline waits for output to drain before changing the attributes.
-
-b.  A fix was made to the history word tokenization code to avoid attempts to
-    dereference a null pointer.
-
-c.  Readline now defaults rl_terminal_name to $TERM if the calling application
-    has left it unset, and tries to initialize with the resultant value.
-
-d.  Instead of calling (*rl_getc_function)() directly to get input in certain
-    places, readline now calls rl_read_key() consistently.
-
-e.  Fixed a bug in the completion code that allowed a backslash to quote a
-    single quote inside a single-quoted string.
-
-f.  rl_prompt is no longer assigned directly from the argument to readline(),
-    but uses memory allocated by readline.  This allows constant strings to
-    be passed to readline without problems arising when the prompt processing
-    code wants to modify the string.
-
-g.  Fixed a bug that caused non-interactive history searches to return the
-    wrong line when performing multiple searches backward for the same string.
-
-h.  Many variables, function arguments, and function return values are now
-    declared `const' where appropriate, to improve behavior when linking with
-    C++ code.
-
-i.  The control character detection code now works better on systems where
-    `char' is unsigned by default.
-
-j.  The vi-mode numeric argument is now capped at 999999, just like emacs mode.
-
-k.  The Function, CPFunction, CPPFunction, and VFunction typedefs have been
-    replaced with a set of specific prototyped typedefs, though they are
-    still in the readline header files for backwards compatibility.
-
-m.  Nearly all of the (undocumented) internal global variables in the library
-    now have an _rl_ prefix -- there were a number that did not, like
-    screenheight, screenwidth, alphabetic, etc.
-
-n.  The ding() convenience function has been renamed to rl_ding(), though the
-    old function is still defined for backwards compatibility.
-
-o.  The completion convenience functions filename_completion_function,
-    username_completion_function, and completion_matches now have an rl_
-    prefix, though the old names are still defined for backwards compatibility.
-
-p.  The functions shared by readline and bash (linkage is satisfied from bash
-    when compiling with bash, and internally otherwise) now have an sh_ prefix.
-
-q.  Changed the shared library creation procedure on Linux and BSD/OS 4.x so
-    that the `soname' contains only the major version number rather than the
-    major and minor numbers.
-
-r.  Fixed a redisplay bug that occurred when the prompt spanned more than one
-    physical line and contained invisible characters.
-
-3.  New Features in Bash
-
-a.  Added a new `--init-file' invocation argument as a synonym for `--rcfile',
-    per the new GNU coding standards.
-
-b.  The /dev/tcp and /dev/udp redirections now accept service names as well as
-    port numbers.
-
-c.  `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
-
-4.  New Features in Readline
-
-a.  The blink timeout for paren matching is now settable by applications.
-
-b.  _rl_executing_macro has been renamed to rl_executing_macro, which means
-    it's now part of the public interface.
-
-c.  Readline has a new variable, rl_readline_state, which is a bitmap that
-    encapsulates the current state of the library; intended for use by
-    callbacks and hook functions.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.04-release,
-and the previous version, bash-2.04-beta5.
-
-1.  Changes to Bash
-
-a.  Better compile-time and configure-time checks for the necessity of
-    inet_aton().
-
-b.  A bug was fixed in the expansion of "${@:-}" when there are positional
-    parameters.
-
-c.  A typo was fixed in the output of `complete'.
-
-d.  The matches generated for a word by the `-W' argument to complete and
-    compgen are now matched against the word being completed, and only
-    matches are returned as the result.
-
-e.  Some fixes were made for systems which do not restart read(2) when a
-    signal caught by bash is received.
-
-f.  A bug was fixed which caused the umask to be set to 0 when an invalid
-    symbolic mode mask was parsed.
-
-g.  Fixed a bug that could cause a core dump if a SIGCHLD was received while
-    performing an assignment statement using command substitution.
-
-h.  Changed the word splitting function for programmable completion so cases
-    in which the cursor is between words are handled a bit better.
-
-2.  Changes to Readline
-
-a.  rl_funmap_names() is now documented.
-
-3.  New Features in Bash
-
-a.  The LC_NUMERIC variable is now treated specially, and used to set the
-    LC_NUMERIC locale category for number formatting, e.g., when `printf'
-    displays floating-point numbers.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.04-beta5,
-and the previous version, bash-2.04-beta4.
-
-1.  Changes to Bash
-
-a.  A couple of changes were made to the Makefiles for easier building on
-    non-Unix systems.
-
-b.  Fixed a bug where the current prompt would be set to $PS2 at startup.
-
-c.  The shell script that tests an already-installed version was changed to
-    remove the directory it created its test programs in at exit.
-
-d.  Several changes were made to the code that tokenizes an input line for
-    the programmable completion code.  Shell metacharacters will now appear
-    as individual words in the word list passed to the completion functions.
-    Some of the example completion shell functions were changed to understand
-    redirection operators.
-
-e.  A bug was fixed that, under obscure circumstances, could confuse the
-    parser when a shell function was run by the programmable completion code.
-
-f.  A bug was fixed in the ulimit builtin for systems not using getrlimit().
-
-g.  The execution code now propagates the correct exit status back to the rest
-    of the code if the return value of a subshell command was being inverted.
-    Some new test cases for inverting return values with the `!' reserved
-    word have been added.
-
-h.  Negative exponents in the arithmetic evaluation of v**e now return an
-    evaluation error.
-
-i.  A bug that caused bash to check the wrong process in a pipeline for
-    abnormal termination (and consequently resetting the terminal attributes)
-    was fixed.
-
-j.  Fixed a bug that caused $PS2 to be displayed after PROMPT_COMMAND was
-    executed.
-
-2.  Changes to Readline
-
-1.  Fixed a bug in a C preprocessor define that caused the keypad control
-    functions to be compiled out for all platforms except DJGPP.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.04-beta4,
-and the previous version, bash-2.04-beta3.
-
-1.  Changes to Bash
-
-a.  A couple of changes were made to the redirection to attempt to avoid
-    race conditions and malicious file replacement.
-
-2.  A change was made to the string evaluation code (used for command 
-    substitution, `eval', and the `.' builtin) to fix an obscure core
-    dump on alpha machines.
-
-3.  A bug that caused $LINENO to be wrong when executing arithmetic for
-    commands was fixed.
-
-4.  A couple of memory leaks in the programmable completion code were fixed.
-
-5.  A bug that could cause a core dump by freeing memory twice during a call
-    to `eval' if `set -u' had been enabled and an undefined variable was
-    referenced was fixed.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.04-beta3,
-and the previous version, bash-2.04-beta2.
-
-1.  Changes to Bash
-
-a.  Bash should run the appropriate startup files when invoked by ssh2.
-
-b.  Fixed a bug in the parsing of conditional commands that could cause a
-    core dump.
-
-c.  Fixed a bug in parsing job specifications that occasionally caused
-    core dumps when an out-of-range job was referenced.
-
-d.  Fixed the `type' and `command' builtins to do better reporting of
-    commands that are not found in $PATH or the hash table.
-
-e.  Fixed a POSIX.2 compliance problem in the command builtin -- commands
-    are supposed to be reported as full pathnames.
-
-f.  The `echo' builtin now returns failure if a write error occurs.
-
-g.  Fixed a bug which caused the locale to not be reset correctly when
-    LC_ALL was unset.
-
-h.  Changed description of `getopts' in man page and reference manual to make
-    it clear that option characters may be characters other than letters.
-
-i.  If the shell exits while in a function, make sure that any trap on EXIT
-    doesn't think the function is still executing.
-
-j.  Bashbug now tries harder to find a usable editor if $EDITOR is not set,
-    rather than simply defaulting to `emacs'.
-
-k.  Changes to the scripts that guess and canonicalize the system type, from
-    the latest `automake' distribution via Debian.
-
-l.  When using named pipes for process substitution, make sure the file
-    descriptors opened for reading are set to non-blocking mode.
-
-m.  Fixed a bug that caused termination of pipelines that are killed by a
-    signal to not be reported in some cases.
-
-n.  When not in literal-history mode, shell comment lines are not added to
-    the history list.
-
-o.  When running in POSIX.2 mode, bash no longer performs word splitting on
-    the expanded value of the word supplied as the filename argument to
-    redirection operators.
-
-p.  The prompt string decoding code now backslash-quotes only characters that
-    are special within double quotes when expanding the \w and \W escape
-    sequences.
-
-q.  Fixed a bug in the prompt decoding code that could cause a non-interactive
-    shell to seg fault if `\u' was used in PS4 and the shell was in xtrace
-    mode.
-
-r.  Fixed a bug that caused function definitions to be printed with any
-    redirections that should be attached to the entire function before the
-    closing brace.
-
-s.  Changed the tilde expansion code for Cygwin systems to avoid creating
-    pathnames beginning with `//' if $HOME == `/'.
-
-t.  Fixed a couple of autoconf tests to avoid creating files with fixed names
-    in /tmp.
-
-u.  The `trap' and `kill' builtins now know the names of the POSIX.1b real-
-    time signals on systems which support them.
-
-2.  Changes to Readline
-
-a.  Fixed a problem with the single-quote quoting function that could cause
-    buffer overflows.
-
-b.  Fixed a bug that caused incorrect `stat characters' to be printed if
-    the files being completed were in the root directory and visible-stats
-    was enabled.
-
-3.  New Features in Bash
-
-a.  There is a new `rbash.1' manual page, from the Debian release.
-
-b.  The `--enable-usg-echo-default' option to `configure' has been renamed to
-    `--enable-xpg-echo-default'.  The old option is still there for backwards
-    compatibility.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.04-beta2,
-and the previous version, bash-2.04-beta1.
-
-1.  Changes to Bash
-
-a.  Fixed a bug that could cause pipes to be closed inappropriately in
-    some obscure cases.
-
-b.  Fixed a bug that caused creation of the exported environment to clobber
-    the current command string if there were any exported shell functions.
-
-c.  Some changes were made to reduce bash's memory usage.
-
-d.  Fixed a problem with programmable completion and filenames to be
-    completed containing quote characters.
-
-e.  Changed the code the removes named pipes created for the <(...) and >(...)
-    expansions to defer removal until after any current shell function has
-    finished executing.
-
-f.  Fixed a bug in `select' which caused it to not handle the `continue'
-    builtin correctly.
-
-g.  Autoconf tests added for cygwin32 and mingw32.
-
-2.  New Features in Bash
-
-a.  The `--with-bash-malloc' configure option replaces `--with-gnu-malloc'
-    (which is still there for backwards compatibility).
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.04-beta1,
-and the previous version, bash-2.04-alpha1.
-
-1.  Changes to Bash
-
-a.  Fixed a bug in the programmable completion code that occurred when
-    trying to complete command lines containing a `;' or `@'.
-
-b.  The file descriptor from which the shell is reading a script is now
-    moved to a file descriptor above the user-addressible range.
-
-c.  Changes to `printf' so that it can handle integers beginning with 0
-    or 0x as octal and hex, respectively.
-
-d.  Fixes to the programmable completion code so it handles nonsense like
-    `compgen -C xyz' gracefully.
-
-e.  The shell no longer modifies the signal handler for SIGPROF, allowing
-    profiling again on certain systems.
-
-f.  The shell checks for a new window size, if the user has requested it,
-    after a process exits due to a signal.
-
-g.  Fixed a bug with variables with null values in a program's temporary
-    environment and the bash getenv() replacement.
-
-h.  `declare' and the other builtins that take variable assignments as
-    arguments now honor `set -a' and mark modified variables for export.
-
-i.  Some changes were made for --dump-po-strings mode when writing strings
-    with embedded newlines.
-
-j.  The code that caches export strings from the initial environment now
-    duplicates the string rather than just pointing into the environment.
-
-k.  The filename completion quoting code now uses single quotes by default
-    if the filename being completed contains newlines, since \<newline>
-    has a special meaning to the parser.
-
-l.  Bash now uses typedefs bits32_t and u_bits32_t instead of int32_t and
-    u_int32_t, respectively to avoid conflicts on certain Unix versions.
-
-m.  Configuration changes were made for: Rhapsody, Mac OS, FreeBSD-3.x.
-
-n.  Fixed a problem with hostname-to-ip-address translation in the
-    /dev/(tcp|udp)/hostname/port redirection code.
-
-o.  The texinfo manual has been reorganized slightly.
-
-p.  Filename generation (globbing) range comparisons in bracket expressions
-    no longer use strcoll(3) even if it is available, since it has unwanted
-    effects in certain locales.
-
-q.  Fixed a cosmetic problem in the source that caused the shell to not
-    compile if DPAREN_ARITHMETIC was not defined but ARITH_FOR_COMMAND was.
-
-r.  Fixed a bug in the here-document code tripped when the file descriptor
-    opened to the file containing the text of the here document was the
-    same as a redirector specified by the user.
-
-s.  Fixed a bug where the INVERT_RETURN flag was not being set for `pipeline'
-    in `time ! pipeline'.
-
-t.  Fixed a bug with the `wait' builtin which manifested itself when an
-    interrupt was received while the shell was waiting for asynchronous
-    processes in a shell script.
-
-u.  Fixed the DEBUG trap code so that it has the correct value of $?.
-
-v.  Fixed a bug in the parameter pattern substitution code that could cause
-    the shell to attempt to free unallocated memory if the pattern started
-    with `/' and an expansion error occurs.
-
-w.  Fixed a bug in the positional parameter substring code that could
-    cause the shell to loop freeing freed memory.
-
-x.  Fixed a bug in the positional parameter pattern substitution code so
-    that it correctly handles null replacement strings with a pattern
-    string prefixed with `%' or `#'.
-
-y.  The shell no longer attempts to import functions from the environment if
-    started with `-n'.
-
-z.  Fixed a bug that caused `return' in a command substitution executed in
-    a shell function to return from the function in a subshell and continue
-    execution.
-
-aa. `hash -p /pathname/with/slashes name' is no longer allowed when the shell
-    is restricted.
-
-bb. The wait* job control functions now behave better if called when there
-    are no unwaited-for children.
-
-cc. Command substitution no longer unconditionally disables job control in
-    the subshell started to run the command.
-
-dd. A bug was fixed that occasionally caused traps to mess up the parser
-    state.
-
-ee. `bashbug' now honors user headers in the mail message it sends.
-
-ff. A bug was fixed that caused the `:p' history modifier to not print the
-    history expansion if the `histverify' option was set.
-
-2.  Changes to Readline
-
-a.  Fixed a bug in the redisplay code for lines with more than 256 line
-    breaks.
-
-b.  A bug was fixed which caused invisible character markers to not be
-    stripped from the prompt string if the terminal was in no-echo mode.
-
-c.  Readline no longer tries to get the variables it needs for redisplay
-    from the termcap entry if the calling application has specified its
-    own redisplay function.  Readline treats the terminal as `dumb' in
-    this case.
-
-d.  Fixes to the SIGWINCH code so that a multiple-line prompt with escape
-    sequences is redrawn correctly.
-
-3.  New Features in Bash
-
-a.  `bashbug' now accepts `--help' and `--version' options.
-
-b.  There is a new `xpg_echo' option to `shopt' that controls the behavior
-    of echo with respect to backslash-escaped characters at runtime.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.04-alpha1,
-and the previous version, bash-2.04-devel.
-
-1.  Changes to Bash
-
-a.  Fixed a bug that could cause core dumps when performing substring
-    expansion.
-
-b.  Shared object configuration changes for:  Solaris, OSF/1
-
-c.  The POSIX_GLOB_LIBRARY code that uses the POSIX.2 globbing facilities
-    for pathname expansion now understands GLOBIGNORE.
-
-d.  The code that implements `eval' was changed to save the value of the
-    current prompt, so an eval in a shell function called by the programmable
-    completion code will not change the prompt to $PS2.
-
-e.  Restored the undocumented NON_INTERACTIVE_LOGIN_SHELLS #define to
-    config-top.h.  If this is defined, all login shells will read the
-    startup files, not just interactive and non-interactive started with
-    the `--login' option.
-
-f.  Fixed a bug that caused the expansion code to occasionally dump core if
-    IFS contained characters > 128.
-
-g.  Fixed a problem with the grammar so that a newline is not required
-    after the `))' in the new-style arithmetic for statement; a semicolon
-    may be used as expected.
-
-h.  Variable indirection may now reference the shell's special variables.
-
-i.  The $'...' and $"..." constructs are now added to the history correctly
-    if they contain newlines and command-oriented history is enabled.
-
-j.  It is now an error to try to assign a value to a function-local copy
-    of a readonly shell variable (declared with the `local' builtin).
-
-2.  Changes to Readline
-
-a.  The history file code now uses O_BINARY mode when reading and writing
-    the history file on cygwin32.
-
-3.  New Features in Bash
-
-a.  A new programmable completion facility, with two new builtin commands:
-    complete and compgen.
-
-b.  configure has a new option, `--enable-progcomp', to compile in the
-    programmable completion features (enabled by default).
-
-c.  `shopt' has a new option, `progcomp', to enable and disable programmable
-    completion at runtime.
-
-d.  Unsetting HOSTFILE now clears the list of hostnames used for completion.
-
-4.  New Features in Readline
-
-a.  A new variable, rl_gnu_readline_p, always 1.  The intent is that an
-    application can verify whether or not it is linked with the `real'
-    readline library or some substitute.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.04-devel,
-and the previous version, bash-2.03-release.
-
-1.  Changes to Bash
-
-a.  System-specific configuration and source changes for:  Interix, Rhapsody
-
-b.  Fixed a bug in execute_cmd.c that resulted in a compile-time error if
-    JOB_CONTROL was not defined.
-
-c.  An obscure race condition in the trap code was fixed.
-
-d.  The string resulting from $'...' is now requoted to avoid any further
-    expansion.
-
-e.  The $'...' quoting syntax now allows backslash to escape a single quote,
-    for ksh-93 compatibility.
-
-f.  The $"..." quoting syntax now escapes backslashes and double quotes in
-    the translated string when displaying them with the --dump-po-strings
-    option.
-
-g.  `echo -e' no longer converts \' to '.
-
-h.  Fixes were made to the extended globbing code to handle embedded (...)
-    patterns better.
-
-i.  Some improvements were made to the code that unsets `nodelay' mode on
-    the file descriptor from which bash is reading input.
-
-j.  Some changes were made to the replacement termcap library for better
-    operation on MS-DOS.
-
-k.  Some changes were made to the tilde expansion code to handle backslash
-    as a pathname separator on MS-DOS.
-
-l.  The source has been reorganized a little bit -- there is now an `include'
-    subdirectory, and lib/posixheaders has been removed.
-
-m.  Improvements were made to the `read' builtin so that it makes many
-    fewer read(2) system calls.
-
-n.  The expansion of $- will include `c' and `s' when those options are
-    supplied at shell invocation.
-
-o.  Several improvments were made to the completion code:  variable completion
-    now works better when there are unterminated expansions, command
-    completion understands quotes better, and completion now works in certain
-    unclosed $(... constructs.
-
-p.  The arithmetic expansion code was fixed to not need the value of a
-    variable being assigned a value (fixes the "ss=09; let ss=10" bug).
-
-q.  Some changes were made to make exported environment creation faster.
-
-r.  The html documentation will be installed into $(htmldir) if that variable
-    has a value when `make install' is run.
-
-s.  Fixed a bug that would cause the bashrc file to be sourced inappropriately
-    when bash is started by sshd.
-
-t.  The SSH_CLIENT environment variable is no longer auto-exported.
-
-u.  A bug that caused redirections with (...) subshells to be performed in
-    the wrong order was fixed.
-
-v.  A bug that occasionally caused inappropriate expansion of assignment
-    statements in compound array assignments was fixed.
-
-w.  The code that parses the words in a compound array assignment was
-    simplified considerably and should work better now.
-
-x.  Fixes to the non-job-control code in nojobs.c to make it POSIX.2-compliant
-    when a user attempts to retrieve the status of a terminated background
-    process.
-
-y.  Fixes to the `printf' builtin so that it doesn't try to expand all
-    backslash escape sequences in the format string before parsing it for
-    % format specifiers.
-
-2.  Changes to Readline
-
-a.  The history library tries to truncate the history file only if it is a
-    regular file.
-
-b.  A bug that caused _rl_dispatch to address negative array indices on
-    systems with signed chars was fixed.
-
-c.  rl-yank-nth-arg now leaves the history position the same as when it was
-    called.
-
-d.  Changes to the completion code to handle MS-DOS drive-letter:pathname
-    filenames.
-
-e.  Completion is now case-insensitive by default on MS-DOS.
-
-f.  Fixes to the history file manipulation code for MS-DOS.
-
-g.  Readline attempts to bind the arrow keys to appropriate defaults on MS-DOS.
-
-h.  Some fixes were made to the redisplay code for better operation on MS-DOS.
-
-i.  The quoted-insert code will now insert tty special chars like ^C.
-
-j.  A bug was fixed that caused the display code to reference memory before
-    the start of the prompt string.
-
-k.  More support for __EMX__ (OS/2).
-
-l.  A bug was fixed in readline's signal handling that could cause infinite
-    recursion in signal handlers.
-
-m.  A bug was fixed that caused the point to be less than zero when rl_forward
-    was given a very large numeric argument.
-
-n.  The vi-mode code now gets characters via the application-settable value
-    of rl_getc_function rather than calling rl_getc directly.
-
-3.  New Features in Bash
-
-a.  The history builtin has a `-d offset' option to delete the history entry
-    at position `offset'.
-
-b.  The prompt expansion code has two new escape sequences: \j, the number of
-    active jobs; and \l, the basename of the shell's tty device name.
-
-c.  The `bind' builtin has a new `-x' option to bind key sequences to shell
-    commands.
-
-d.  There is a new shell option, no_empty_command_completion, which, when
-    enabled, disables command completion when TAB is typed on an empty line.
-
-e.  The `help' builtin has a `-s' option to just print a builtin's usage
-    synopsys.
-
-f.  There are several new arithmetic operators:  id++, id-- (variable
-    post-increment/decrement), ++id, --id (variabl pre-increment/decrement),
-    expr1 , expr2 (comma operator).
-
-g.  There is a new ksh-93 style arithmetic for command:
-       for ((expr1 ; expr2; expr3 )); do list; done
-
-h.  The `read' builtin has a number of new options:
-       -t timeout      only wait timeout seconds for input
-       -n nchars       only read nchars from input instead of a full line
-       -d delim        read until delim rather than newline
-       -s              don't echo input chars as they are read
-
-i.  The redirection code now handles several filenames specially:
-    /dev/fd/N, /dev/stdin, /dev/stdout, and /dev/stderr, whether or
-    not they are present in the file system.
-
-j.  The redirection code now recognizes pathnames of the form
-    /dev/tcp/host/port and /dev/udp/host/port, and tries to open a socket
-    of the appropriate type to the specified port on the specified host.
-
-k.  The ksh-93 ${!prefix*} expansion, which expands to the names of all
-    shell variables whose names start with prefix, has been implemented.
-
-l.  There is a new dynamic variable, FUNCNAME, which expands to the name of
-    a currently-executing function.  Assignments to FUNCNAME have no effect.
-
-m.  The GROUPS variable is no longer readonly; assignments to it are silently
-    discarded.  This means it can be unset.
-
-4.  New Features in Readline
-
-a.  Parentheses matching is now always compiled into readline, and enabled
-    or disabled when the value of the `blink-matching-paren' variable is
-    changed.
-
-b.  MS-DOS systems now use ~/_inputrc as the last-ditch inputrc filename.
-
-c.  MS-DOS systems now use ~/_history as the default history file.
-
-d.  history-search-{forward,backward} now leave the point at the end of the
-    line when the string to search for is empty, like
-    {reverse,forward}-search-history.
-
-e.  history-search-{forward,backward} now leave the last history line found
-    in the readline buffer if the second or subsequent search fails.
-
-f.  New function for use by applications:  rl_on_new_line_with_prompt, used
-    when an application displays the prompt itself before calling readline().
-
-g.  New variable for use by applications:  rl_already_prompted.  An application
-    that displays the prompt itself before calling readline() must set this to
-    a non-zero value.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.03-release,
-and the previous version, bash-2.03-beta2.
-
-1.  Changes to Bash
-
-a.  A file descriptor leak in the `fc' builtin was fixed.
-
-b.  A bug was fixed in the `read' builtin that caused occasional spurious
-    failures when using `read -e'.
-
-c.  The version code needed to use the value of the cpp variable
-    CONF_MACHTYPE rather than MACHTYPE.
-
-d.  A new test was added to exercise the command printing and copying code.
-
-e.  A bug was fixed that caused `time' to be recognized as a reserved word
-    if it was the first pattern in a `case' statement pattern list.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.03-beta2,
-and the previous version, bash-2.03-beta1.
-
-1.  Changes to Bash
-
-a.  Slight additions to support/shobj-conf, mostly for the benefit of AIX 4.2.
-
-b.  config.{guess,sub} support added for the NEC SX4.
-
-c.  Changed some of the cross-compiling sections of the configure macros in
-    aclocal.m4 so that configure won't abort.
-
-d.  Slight changes to how the HTML versions of the bash and readline manuals
-    are generated.
-
-e.  Fixed conditional command printing to avoid interpreting printf `%'-escapes
-    in arguments to [[.
-
-f.  Don't include the bash malloc on all variants of the alpha processor.
-
-g.  Changes to configure to make --enable-profiling work on Solaris 2.x.
-
-h.  Fixed a bug that manifested itself when shell functions were called
-    between calls to `getopts'.
-
-i.  Fixed pattern substitution so that a bare `#'as a pattern causes the
-    replacement string to be prefixed to the search string, and a bare
-    `%' causes the replacement string to be appended to the search string.
-
-j.  Fixed a bug in the command execution code that caused child processes
-    to occasionally have the wrong value for $!.
-
-2.  Changes to Readline
-
-a.  Added code to the history library to catch history substitutions using
-    `&' without a previous history substitution or search having been
-    performed.
-
-3.  New Features in Bash
-
-4.  New Features in Readline
-
-a.  New bindable variable: `isearch-terminators'.
-
-b.  New bindable function: `forward-backward-delete-char' (unbound by default).
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.03-beta1,
-and the previous version, bash-2.03-alpha.
-    
-1.  Changes to Bash
-
-a.  A change was made to the help text for `{...}' to make it clear that a
-    semicolon is required before the closing brace.
-
-b.  A fix was made to the `test' builtin so that syntax errors cause test
-    to return an exit status > 1.
-
-c.  Globbing is no longer performed on assignment statements that appear as
-    arguments to `assignment builtins' such as `export'.
-
-d.  System-specific configuration changes were made for:  Rhapsody,
-    AIX 4.2/gcc, BSD/OS 4.0.
-
-e.  New loadable builtins: ln, unlink.
-
-f.  Some fixes were made to the globbing code to handle extended glob patterns
-    which immediately follow a `*'.
-
-g.  A fix was made to the command printing code to ensure that redirections
-    following compound commands have a space separating them from the rest
-    of the command.
-
-h.  The pathname canonicalization code was changed to produce fewer leading
-    `//' sequences, since those are interpreted as network file system
-    pathnames on some systems.
-
-i.  A fix was made so that loops containing `eval' commands in commands passed
-    to `bash -c' would not exit prematurely.
-
-j.  Some changes were made to the job reaping code when the shell is not
-    interactive, so the shell will retain exit statuses longer for examination
-    by `wait'.
-
-k.  A fix was made so that `jobs | command' works again.
-
-l.  The erroneous compound array assignment var=((...)) is now a syntax error.
-
-m.  A change was made to the dynamic loading code in `enable' to support
-    Tenon's MachTen.
-
-n.  A fix was made to the globbing code so that extended globbing patterns
-    will correctly match `.' in a bracket expression.
-
-2.  Changes to Readline
-
-a.  A fix was made to the completion code in which a typo caused the wrong
-    value to be passed to the function that computed the longest common
-    prefix of the list of matches.
-
-b.  The completion code now checks the value of rl_filename_completion_desired,
-    which is set by application-supplied completion functions to indicate
-    that filename completion is being performed, to decide whether or not to
-    call an application-supplied `ignore completions' function.
-
-3.  New Features in Bash
-
-a.  A change was made to the startup file code so that any shell begun with
-    the `--login' option, even non-interactive shells, will source the login
-    shell startup files.
-
-4.  New Features in Readline
-
-a.  A new variable, rl_erase_empty_line, which, if set by an application using
-    readline, will cause readline to erase, prompt and all, lines on which the
-    only thing typed was a newline.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.03-alpha,
-and the previous version, bash-2.02.1-release.
-
-1.  Changes to Bash
-
-a.  System-specific configuration changes were made for: Irix 6.x, Unixware 7.
-
-b.  The texi2dvi and texi2html scripts were updated to the latest versions
-    from the net.
-
-c.  The configure tests that determine which native type is 32 bits were
-    changed to not require a compiled program.
-
-d.  Fixed a bug in shell_execve that could cause memory to be freed twice
-    after a failed exec.
-
-e.  The `printf' test uses `diff -a' if it's available to prevent confusion
-    due to the non-ascii output.
-
-f.  Shared object configuration is now performed by a shell script,
-    support/shobj-conf, which generates values to be substituted into
-    makefiles by configure.
-
-g.  Some changes were made to `ulimit' to avoid the use of RLIM_INVALID as a
-    return value.
-
-h.  Changes were made to `ulimit' to work around HPUX 9.x's peculiar
-    handling of RLIMIT_FILESIZE.
-
-i.  Some new loadable builtins were added: id, printenv, sync, whoami, push,
-    mkdir.  `pushd', `popd', and `dirs' can now be built as regular or
-    loadable builtins from the same source file.
-
-j.  Changes were made to `printf' to handle NUL bytes in the expanded format
-    string.
-
-k.  The various `make clean' Makefile targets now descend into lib/sh.
-
-l.  The `type' builtin was changed to use the internal `getopt' so that things
-    like `type -ap' work as expected.
-
-m.  There is a new configuration option, --with-installed-readline, to link
-    bash with a locally-installed version of readline.  Only readline version
-    4.0 and later releases can support this.  Shared and static libraries
-    are supported.  The installed include files are used.
-
-n.  There is a new autoconf macro used to find which basic type is 64 bits.
-
-o.  Dynamic linking and loadable builtins should now work on SCO 3.2v5*,
-    AIX 4.2 with gcc, Unixware 7, and many other systems using gcc, where
-    the `-shared' options works correctly.
-
-p.  A bug was fixed in the bash filename completion code that caused memory to
-    be freed twice if a directory name containing an unset variable was
-    completed and the -u option was set.
-
-q.  The prompt expansion code now quotes the `$' in the `\$' expansion so it
-    is not processed by subsequent parameter expansion.
-
-r.  Fixed a parsing bug that caused a single or double quote after a `$$' to
-    trigger ANSI C expansion or locale translation.
-
-s.  Fixed a bug in the globbing code that caused quoted filenames containing
-    no globbing characters to sometimes be incorrectly expanded.
-
-t.  Changes to the default prompt strings if prompt string decoding is not
-    compiled into the shell.
-
-u.  Added `do', `then', `else', `{', and `(' to the list of keywords that may
-    precede the `time' reserved word.
-
-v.  The shell may now be cross-built for BeOS as well as cygwin32.
-
-w.  The conditional command execution code now treats `=' the same as `=='
-    for deciding when to perform pattern matching.
-
-x.  The `-e' option no longer causes the shell to exit if a command exits
-    with a non-zero status while running the startup files.
-
-y.  The `printf' builtin no longer dumps core if a modifier is supplied in
-    the format string without a conversion character (e.g. `%h').
-
-z.  Array assignments of the form a=(...) no longer show up in the history
-    list.
-
-aa. The parser was fixed to obey the POSIX.2 rules for finding the closing
-    `}' in a ${...} expression.
-
-bb. The history file is now opened with mode 0600 rather than 0666, so bash
-    no longer relies on the user's umask being set appropriately.
-
-cc. Setting LANG no longer causes LC_ALL to be assigned a value; bash now
-    relies on proper behavior from the C library.
-
-dd. Minor changes were made to allow quoted variable expansions using
-    ${...} to be completed correctly if there is no closing `"'.
-
-ee. Changes were made to builtins/Makefile.in so that configuring the shell
-    with `--enable-profiling' works right and builtins/mkbuiltins is
-    generated.
-
-2.  Changes to Readline
-
-a.  The version number is now 4.0.
-
-b.  There is no longer any #ifdef SHELL code in the source files.
-
-c.  Some changes were made to the key binding code to fix memory leaks and
-    better support Win32 systems.
-
-d.  Fixed a silly typo in the paren matching code -- it's microseconds, not
-    milliseconds.
-
-e.  The readline library should be compilable by C++ compilers.
-
-f.  The readline.h public header file now includes function prototypes for
-    all readline functions, and some changes were made to fix errors in the
-    source files uncovered by the use of prototypes.
-
-g.  The maximum numeric argument is now clamped at 1000000.
-
-h.  Fixes to rl_yank_last_arg to make it behave better.
-
-i.  Fixed a bug in the display code that caused core dumps if the prompt
-    string length exceeded 1024 characters.
-
-j.  The menu completion code was fixed to properly insert a single completion
-    if there is only one match.
-
-k.  A bug was fixed that caused the display code to improperly display tabs
-    after newlines.
-
-3.  New Features in Bash
-
-a.  New `shopt' option, `restricted_shell', indicating whether or not the
-    shell was started in restricted mode, for use in startup files.
-
-b.  Filename generation is now performed on the words between ( and ) in
-    array assignments (which it probably should have done all along).
-
-c.  OLDPWD is now auto-exported, as POSIX.2 seems to require.
-
-d.  ENV and BASH_ENV are read-only variables in a restricted shell.
-
-4.  New Features in Readline
-
-a.  Many changes to the signal handling:
-       o Readline now catches SIGQUIT and cleans up the tty before returning;
-       o A new variable, rl_catch_signals, is available to application writers 
-         to indicate to readline whether or not it should install its own
-         signal handlers for SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP,
-         SIGTTIN, and SIGTTOU;
-       o A new variable, rl_catch_sigwinch, is available to application
-         writers to indicate to readline whether or not it should install its
-         own signal handler for SIGWINCH, which will chain to the calling
-         applications's SIGWINCH handler, if one is installed;
-       o There is a new function, rl_free_line_state, for application signal
-         handlers to call to free up the state associated with the current
-         line after receiving a signal;
-       o There is a new function, rl_cleanup_after_signal, to clean up the
-         display and terminal state after receiving a signal;
-       o There is a new function, rl_reset_after_signal, to reinitialize the
-         terminal and display state after an application signal handler
-         returns and readline continues
-
-b.  There is a new function, rl_resize_terminal, to reset readline's idea of
-    the screen size after a SIGWINCH.
-
-c.  New public functions: rl_save_prompt and rl_restore_prompt.  These were
-    previously private functions with a `_' prefix.
-
-d.  New function hook: rl_pre_input_hook, called just before readline starts
-    reading input, after initialization.
-
-e.  New function hook: rl_display_matches_hook, called when readline would
-    display the list of completion matches.  The new function
-    rl_display_match_list is what readline uses internally, and is available
-    for use by application functions called via this hook.
-
-f.  New bindable function, delete-char-or-list, like tcsh.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.02.1-release,
-and the previous version, bash-2.02-release.
-
-1.  Changes to Bash
-
-a.  A bug that caused the bash readline support to not compile unless aliases
-    and csh-style history were configured into the shell was fixed.
-
-b.  Fixed a bug that could cause a core dump when here documents contained
-    more than 1000 characters.
-
-c.  Fixed a bug that caused a CDPATH entry of "" to not be treated the same
-    as the current directory when in POSIX mode.
-
-d.  Fixed an alignment problem with the memory returned by the bash malloc,
-    so returned memory is now 64-bit aligned.
-
-e.  Fixed a bug that caused command substitutions executed within pipelines
-    to put the terminal in the wrong process group.
-
-f.  Fixes to support/config.sub for: alphas, SCO Open Server and Open Desktop,
-    Unixware 2, and Unixware 7.
-
-g.  Fixes to the pattern matching code to make it work correctly for eight-bit
-    characters.
-
-h.  Fixed a problem that occasionally caused the shell to display the wrong
-    value for the new working directory when changing to a directory found
-    in $CDPATH when in physical mode.
-
-i.  Fixed a bug that caused core dumps when using conditional commands in
-    shell functions.
-
-j.  Fixed a bug that caused the printf builtin to loop forever if the format
-    string did not consume any of the arguments.
-
-k.  Fixed a bug in the parameter expansion code that caused "$@" to be
-    incorrectly split if $IFS did not contain a space character.
-
-l.  Fixed a bug that could cause a core dump when completing hostnames if
-    the number of matching hostnames was an exact multiple of 16.
-
-m.  Fixed a bug that caused the shell to fork too early when a command
-    such as `%2 &' was given.
-
-2.  Changes to Readline
-
-a.  Fixed a problem with redisplay that showed up when the prompt string was
-    longer than the screen width and the prompt contained invisible characters.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.02-release,
-and the previous version, bash-2.02-beta2.
-
-1.  Changes to Bash
-
-a.  A bug was fixed that caused the terminal process group to be set
-    incorrectly when performing command substitution of builtins in a
-    pipeline.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.02-beta2,
-and the previous version, bash-2.02-beta1.
-
-1.  Changes to Bash
-
-a.  Attempting to `wait' for stopped jobs now generates a warning message.
-
-b.  Pipelines which exit due to SIGPIPE in non-interactive shells are now
-    not reported if the shell is compiled -DDONT_REPORT_SIGPIPE.
-
-c.  Some changes were made to builtins/psize.sh and support/bashbug.sh to
-    attempt to avoid some /tmp file races and surreptitious file
-    substitutions.
-
-d.  Fixed a bug that caused the shell not to compile if configured with
-    dparen arithmetic but without aliases.
-
-e.  Fixed a bug that caused the input stream to be switched when assigning
-    empty arrays with `bash -c'.
-
-f.  A bug was fixed in the readline expansion glue code that caused bash to
-    dump core when expanding lines with an unclosed single quote.
-
-g.  A fix was made to the `cd' builtin so that using a non-empty directory
-    from $CDPATH results in an absolute pathname of the new current working
-    directory to be displayed after the current directory is changed.
-
-h.  Fixed a bug in the variable assignment code that caused the shell to
-    dump core when referencing an unset variable with `set -u' enabled in
-    an assignment statement preceding a command.
-
-i.  Fixed a bug in the exit trap code that caused reserved words to not be
-    recognized under certain circumstances.
-
-j.  Fixed a bug in the parameter pattern substitution code so that quote
-    removal is performed.
-
-k.  The shell should now configure correctly on Apple Rhapsody systems.
-
-l.  The `kill' builtin now prints a usage message if it is not passed any
-    arguments.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.02-beta1,
-and the previous version, bash-2.02-alpha1.
-
-1.  Changes to Bash
-
-a.  A few compilation bugs were fixed in the new extended globbing code.
-
-b.  Executing arithmetic commands now sets the command name to `((' so
-    error messages look right.
-
-c.  Fixed some build problems with various configuration options.
-
-d.  The `printf' builtin now aborts immediately if an illegal format
-    character is encountered.
-
-e.  The code that creates here-documents now behaves better if the file it's
-    trying to create already exists for some reason.
-
-f.  Fixed a problem with the extended globbing code that made patterns like
-    `x+*' expand incorrectly.
-
-g.  The prompt string expansion code no longer quotes tildes with backslashes.
-
-h.  The bash getcwd() implementation in lib/sh/getcwd.c now behaves better in
-    the presence of lstat(2) failures.
-
-i.  Fixed a bug with strsub() that caused core dumps when executing `fc -s'.
-
-j.  The mail checking code now ensures that it has a valid default mailpath.
-
-k.  A bug was fixed that caused local variables to be unset inappropriately
-    when sourcing a script from within another sourced script.
-
-l.  A bug was fixed in the history saving code so that functions are saved
-    in the history list correctly if `cmdhist' is enabled, but `lithist'
-    is not.
-
-m.  A bug was fixed that caused printf overflows when displaying error
-    messages.
-
-n.  It should be easier to build the loadble builtins in examples/loadables,
-    though some manual editing of the generated Makefile is still required.
-
-o.  The user's primary group is now always ${GROUPS[0]}.
-
-p.  Some updates were made to support/config.guess from the GNU master copy.
-
-q.  Some changes were made to the autoconf support for Solaris 2.6 large
-    files.
-
-r.  The `command' builtins now does the right thing when confstr(3) cannot
-    find a value for _CS_PATH.
-
-s.  Extended globbing expressions like `*.!(c)' are not history expanded if
-    `extglob' is enabled.
-
-t.  Using the `-P' option to `cd' will force the value that is assigned to
-    PWD to not contain any symbolic links.
-
-2.  Changes to Readline
-
-a.  The code that prints completion listings now behaves better if one or
-    more of the filenames contains non-printable characters.
-
-b.  The time delay when showing matching parentheses is now 0.5 seconds.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.02-alpha1,
-and the previous version, bash-2.01.1-release.
-
-1.  Changes to Bash
-
-a.  OS-specific configuration changes for:  BSD/OS 3.x, Minix 2.x,
-    Solaris 2.6, SINIX SVR4.
-
-b.  Changes were made to the generated `info' files so that `install-info'
-    works correctly.
-
-c.  PWD is now auto-exported.
-
-d.  A fix was made to the pipeline code to make sure that the shell forks
-    to execute simple commands consisting solely of assignment statements.
-
-e.  Changes to the test suite for systems with 14-character filenames.
-
-f.  The default sizes of some internal hash tables have been made smaller
-    to reduce the shell's memory footprint.
-
-g.  The `((...))' arithmetic command is now executed directly instead of
-    being translated into `let "..."'.
-
-h.  Fixes were made to the expansion code so that "$*", "$@", "${array[@]}",
-    and "${array[@]}" expand correctly when IFS does not contain a space
-    character, is unset, or is set to NULL.
-
-i.  The indirect expansion code (${!var}) was changed so that the only
-    valid values of `var' are variable names, positional parameters, `#',
-    `@', and `*'.
-
-j.  An arithmetic expression error in a $((...)) expansion now causes a
-    non-interactive shell running in posix mode to exit.
-
-k.  Compound array assignment now splits the words within the parentheses
-    on shell metacharacters like the parser would before expansing them
-    and performing the assignment.  This is for compatibility with ksh-93.
-
-l.  The internal shell backslash-quoting code (used in the output of `set'
-    and completion) now quotes tildes if they appear at the start of the
-    string or after a `=' or `:'.
-
-m.  A couple of bugs with `shopt -o' were fixed.
-
-n.  `bash +o' now displays the same output as `set +o' before starting an
-    interactive shell.
-
-o.  A bug that caused command substitution and the `eval' builtin to
-    occasionally free memory twice when an error was encountered was fixed.
-
-p.  The filename globbing code no longer requires read permission for a
-    directory when the filename to be matched does not contain any globbing
-    characters, as POSIX.2 specifies.
-
-q.  A bug was fixed so that the job containing the last asynchronous
-    process is not removed from the job table until a `wait' is executed
-    for that process or another asynchronous process is started.  This
-    satisfies a POSIX.2 requirement.
-
-r.  A `select' bug was fixed so that a non-numeric user response is treated
-    the same as a numeric response that is out of range.
-
-s.  The shell no longer parses the value of SHELLOPTS from the environment
-    if it is restricted, running setuid, or running in `privileged mode'.
-
-t.  Fixes were made to enable large file support on systems such as
-    Solaris 2.6, where the size of a file may be larger than can be held
-    in an `int'.
-
-u.  The filename hashing code was fixed to not add `./' to the beginning of
-    filenames which already begin with `./'.
-
-v.  The configure script was changed so that the GNU termcap library is not
-    compiled in if `prefer-curses' has been specified.
-
-w.  HISTCONTROL and HISTIGNORE are no longer applied to the second and
-    subsequent lines of a multi-line command.
-
-x.  A fix was made to `disown' so that it does a better job of catching
-    out-of-range jobs.
-
-y.  Non-interactive shells no longer report the status of processes terminated
-    due to SIGINT, even if the standard output is a terminal.
-
-z.  A bug that caused the output of `jobs' to have extra carriage returns
-    was fixed.
-
-aa. A bug that caused PIPESTATUS to not be set when builtins or shell
-    functions were executed in the foreground was fixed.
-
-bb. Bash now attempts to detect when it is being run by sshd, and treats
-    that case identically to being run by rshd.
-
-cc. A bug that caused `set -a' to export SHELLOPTS when one of the shell
-    options was changed was fixed.
-
-dd. The `kill' builtin now disallows empty or missing process id arguments
-    instead of treating them as identical to `0', which means the current
-    process.
-
-ee. `var=value declare -x var' now behaves identically to
-    `var=value export var'.  Similarly for `var=value declare -r var' and
-    `var=value readonly var'.
-
-ff. A few memory leaks were fixed.
-
-gg. `alias' and `unalias' now print error messages when passed an argument
-    that is not an alias for printing or deletion, even when the shell is
-    not interactive, as POSIX.2 specifies.
-
-hh. `alias' and `alias -p' now return a status of 0 when no aliases are
-    defined, as POSIX.2 specifes.
-
-ii. `cd -' now prints the pathname of the new working directory if the shell
-    is interactive.
-
-jj. A fix was made so that the code that binds $PWD now copes with getcwd()
-    returning NULL.
-
-kk. `unset' now checks whether or not a function name it's trying to unset
-    is a valid shell identifier only when the shell is running in posix mode.
-
-ll. A change was made to the code that generates filenames for here documents
-    to make them less prone to name collisions.
-
-mm. The parser was changed so that `time' is recognized as a reserved word
-    only at the beginning of a pipeline.
-
-nn. The pathname canonicalization code was changed so that `//' is converted
-    into `/', but all other pathnames beginning with `//' are left alone, as
-    POSIX.2 specifies.
-
-oo. The `logout' builtin will no longer exit a non-interactive non-login
-    shell.
-
-2.  Changes to Readline
-
-a.  Fixed a problem in the readline test program rltest.c that caused a core
-    dump.
-
-b.  The code that handles parser directives in inputrc files now displays
-    more error messages.
-
-c.  The history expansion code was fixed so that the appearance of the
-    history comment character at the beginning of a word inhibits history
-    expansion for that word and the rest of the input line.
-
-3.  New Features in Bash
-
-a.  A new version of malloc, based on the older GNU malloc, that has many
-    changes, is more page-based, is more conservative with memory usage,
-    and does not `orphan' large blocks when they are freed.
-
-b.  A new version of gmalloc, based on the old GLIBC malloc, with many
-    changes and range checking included by default.
-
-c.  A new implementation of fnmatch(3) that includes full POSIX.2 Basic
-    Regular Expression matching, including character classes, collating
-    symbols, equivalence classes, and support for case-insensitive pattern
-    matching.
-
-d.  ksh-88 egrep-style extended pattern matching ([@+*?!](patlist)) has been
-    implemented, controlled by a new `shopt' option, `extglob'.
-
-e.  There is a new ksh-like `[[' compound command, which implements
-    extended `test' functionality.
-
-f.  There is a new `printf' builtin, implemented according to the POSIX.2
-    specification.
-
-g.  There is a new feature for command substitution: $(< filename) now expands
-    to the contents of `filename', with any trailing newlines removed
-    (equivalent to $(cat filename)).
-
-h.  There are new tilde prefixes which expand to directories from the
-    directory stack.
-
-i.  There is a new `**' arithmetic operator to do exponentiation.
-
-j.  There are new configuration options to control how bash is linked:
-    `--enable-profiling', to allow bash to be profiled with gprof, and
-    `--enable-static-link', to allow bash to be linked statically.
-
-k.  There is a new configuration option, `--enable-cond-command', which
-    controls whether or not the `[[' command is included.  It is on by
-    default.
-
-l.  There is a new configuration option, `--enable-extended-glob', which
-    controls whether or not the ksh extended globbing feature is included.
-    It is enabled by default.
-
-m.  There is a new configuration #define in config.h.top that, when enabled,
-    will cause all login shells to source /etc/profile and one of the user-
-    specific login shell startup files, whether or not the shell is
-    interactive.
-
-n.  There is a new invocation option, `--dump-po-strings', to dump
-    a shell script's translatable strings ($"...") in GNU `po' format.
-
-o.  There is a new `shopt' option, `nocaseglob', to enable case-insensitive
-    pattern matching when globbing filenames and using the `case' construct.
-
-p.  There is a new `shopt' option, `huponexit', which, when enabled, causes
-    the shell to send SIGHUP to all jobs when an interactive login shell
-    exits.
-
-q.  `bind' has a new `-u' option, which takes a readline function name as an
-    argument and unbinds all key sequences bound to that function in a
-    specified keymap.
-
-r.  `disown' now has `-a' and `-r' options, to limit operation to all jobs
-    and running jobs, respectively.
-
-s.  The `shopt' `-p' option now causes output to be displayed in a reusable
-    format.
-
-t.  `test' has a new `-N' option, which returns true if the filename argument
-    has been modified since it was last accessed.
-
-u.  `umask' now has a `-p' option to print output in a reusable format.
-
-v.  A new escape sequence, `\xNNN', has been added to the `echo -e' and $'...'
-    translation code.  It expands to the character whose ascii code is NNN
-    in hexadecimal.
-
-w.  The prompt string expansion code has a new `\r' escape sequence.
-
-x.  The shell may now be cross-compiled for the CYGWIN32 environment on
-    a Unix machine.
-
-4.  New Features in Readline
-
-a.  There is now an option for `iterative' yank-last-arg handline, so a user
-    can keep entering `M-.', yanking the last argument of successive history
-    lines.
-
-b.  New variable, `print-completions-horizontally', which causes completion
-    matches to be displayed across the screen (like `ls -x') rather than up
-    and down the screen (like `ls').
-
-c.  New variable, `completion-ignore-case', which causes filename completion
-    and matching to be performed case-insensitively.
-
-d.  There is a new bindable command, `magic-space', which causes history
-    expansion to be performed on the current readline buffer and a space to
-    be inserted into the result.
-
-e.  There is a new bindable command, `menu-complete', which enables tcsh-like
-    menu completion (successive executions of menu-complete insert a single
-    completion match, cycling through the list of possible completions).
-
-f.  There is a new bindable command, `paste-from-clipboard', for use on Win32
-    systems, to insert the text from the Win32 clipboard into the editing
-    buffer.
-
-g.  The key sequence translation code now understands printf-style backslash
-    escape sequences, including \NNN octal escapes.  These escape sequences
-    may be used in key sequence definitions or macro values.
-
-h.  An `$include' inputrc file parser directive has been added.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.01.1-release,
-and the previous version, bash-2.01-release.
-
-1.  Changes to Bash
-
-a.  The select command was fixed to check the validity of the user's
-    input more strenuously.
-
-b.  A bug was fixed that prevented `time' from timing commands correctly
-    when supplied as an argument to `bash -c'.
-
-c.  A fix was made to the mail checking code to keep from adding the same
-    mail file to the list of files to check multiple times when parsing
-    $MAILPATH.
-
-d.  Fixed an off-by-one error in the tilde expansion library.
-
-e.  When using the compound array assignment syntax, the old value of
-    the array is cleared before assigning the new value.
-
-f.  Fixed a bug that could cause a core dump when a trap handler was reset
-    to the default in the trap command associated with that signal.
-
-g.  Fixed a bug in the locale code that occurred when assigning a value
-    to LC_ALL.
-
-h.  A change was made to the parser so that words of the form xxx=(...)
-    are not considered compound assignment statements unless there are
-    characters before the `='.
-
-i.  A fix was made to the command tracing code to correctly quote each
-    word of output.
-
-j.  Some changes were made to the bash-specific autoconf tests to make them
-    more portable.
-
-k.  Completion of words with globbing characters now correctly quotes the
-    result.
-
-l.  The directory /var/spool/mail is now preferred to /usr/spool/mail when
-    configure is deciding on the default mail directory.
-
-m.  The brace completion code was fixed to not quote the `{' and `}'.
-
-n.  Some fixes were made to make $RANDOM more random in subshells.
-
-o.  System-specific changes were made to configure for: SVR4.2
-
-p.  Changes were made so that completion of words containing globbing chars
-    substitutes the result only if a single filename was matched.
-
-q.  The window size is now recomputed after a job is stopped with SIGTSTP if
-    the user has set `checkwinsize' with `shopt'.
-
-r.  When doing substring expansion, out-of-range substring specifiers now
-    cause nothing to be substituted rather than an expansion error.
-
-s.  A fix was made so that you can no longer trap `SIGEXIT' or `SIGDEBUG' --
-    only `EXIT' and `DEBUG' are accepted.
-
-t.  The display of trapped signals now uses the signal number if signals
-    for which bash does not know the name are trapped.
-
-u.  A fix was made so that `bash -r' does not turn on restricted mode until
-    after the startup files are executed.
-
-v.  A bug was fixed that occasionally caused a core dump when a variable
-    found in the temporary environment of export/declare/readonly had a
-    null value.
-
-w.  A bug that occasionally caused unallocated memory to be passed to free()
-    when doing arithmetic substitution was fixed.
-
-x.  A bug that caused a buffer overrun when expanding a prompt string
-    containing `\w' and ${#PWD} exceeded PATH_MAX was fixed.
-
-y.  A problem with the completion code that occasionally caused it to
-    refer to a character before the beginning of the readline line buffer
-    was fixed.
-
-z.  A bug was fixed so that the `read' builtin restarts reads when
-    interrupted by signals other than SIGINT.
-
-aa. Fixed a bug that caused a command to be freed twice when there was
-    an evaluation error in the `eval' command.
-
-2.  Changes to Readline
-
-a.  Added a missing `extern' to a declaration in readline.h that kept
-    readline from compiling cleanly on some systems.
-
-b.  The history file is now opened with mode 0600 when it is written for
-    better security.
-
-c.  Changes were made to the SIGWINCH handling code so that prompt redisplay
-    is done better.
-
-d.  ^G now interrupts incremental searches correctly.
-
-e.  A bug that caused a core dump when the set of characters to be quoted
-    when completing words was empty was fixed.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.01-release,
-and the previous version, bash-2.01-beta2.
-
-1.  Changes to Bash
-
-a.  The `distclean' target should remove the `printenv' executable if it
-    has been created.
-
-b.  The test suite was changed slightly to ensure that the error messages
-    are printed in English.
-
-c.  A bug that caused the shell to dump core when a filename containing a
-    `/' was passed to `hash' was fixed.
-
-d.  Pathname canonicalization now leaves a leading `//' intact, as POSIX.1
-    requires.
-
-e.  A memory leak when completing commands was fixed.
-
-f.  A memory leak that occurred when checking the hash table for commands
-    with relative paths was fixed.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.01-beta2,
-and the previous version, bash-2.01-beta1.
-
-1.  Changes to Bash
-
-a.  The `ulimit' builtin translates RLIM_INFINITY to the hard limit only if
-    the current (soft) limit is less than or equal to the hard limit.
-
-b.  Fixed a bug that caused the bash emulation of strcasecmp to produce
-    incorrect results.
-
-c.  A bug that caused memory to be freed twice when a trap handler resets
-    the trap more than once was fixed.
-
-d.  A bug that caused machines where sizeof (pointer) > sizeof (int) to
-    fail (and possibly dump core) when trying to unwind-protect a null
-    pointer was fixed.
-
-e.  The startup files should not be run with job control enabled.  This fix
-    allows SIGINT to once again interrupt startup file execution.
-
-f.  Bash should not change the SIGPROF handler if it is set to something
-    other than SIG_DFL.
-
-g.  The completion code that provides bash-specific completions for readline
-    now quotes characters that the readline code would treat as word break
-    characters if they appear in a file name.
-
-h.  The completion code now correctly quotes filenames containing a `!',
-    even if the user attempted to use double quotes when attempting
-    completion.
-
-i.  A bug that caused the shell to dump core when `disown' was called without
-    arguments and there was no current job was fixed.
-
-j.  A construct like $((foo);bar) is now processed as a command substitution
-    rather than as a bad arithmetic substitution.
-
-k.  A couple of bugs that caused `fc' to not obey the `cmdhist' and `lithist'
-    shell options when editing and re-executing a series of commands were
-    fixed.
-
-l.  A fix was made to the grammar -- the list of commands between `do' and
-    `done' in the body of a `for' command should be treated the same as a
-    while loop.
-
-2.  Changes to Readline
-
-a.  A couple of bugs that caused the history search functions to attempt to
-    free a NULL pointer were fixed.
-
-b.  If the C library provides setlocale(3), readline does not need to look
-    at various environment variables to decide whether or not to go into
-    eight-bit mode automatically -- just check whether the current locale
-    is not `C' or `POSIX'.
-
-c.  If the filename completion function finds that a directory was not closed
-    by a previous (interrupted) completion, it closes the directory with
-    closedir().
-
-3.  New Features in Bash
-
-a.  New bindable readline commands:  history-and-alias-expand-line and
-    alias-expand-line.  The code was always in there, there was just no
-    way to execute it.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.01-beta1,
-and the previous version, bash-2.01-alpha1.
-
-1.  Changes to Bash
-
-a.  Fixed a problem that could cause file descriptors used for process
-    substitution to conflict with those used explicitly in redirections.
-
-b.  Made it easier to regenerate configure if the user changes configure.in.
-
-c.  ${GROUPS[0]} should always be the primary group, even on systems without
-    multiple groups.
-
-d.  Spelling correction is no longer enabled by default.
-
-e.  Fixes to quoting problems in `bashbug'.
-
-f.  OS-specific configuration changes were made for: Irix 6.
-
-g.  OS-specific code changes were made for: QNX.
-
-h.  A more meaningful message is now printed when the file in /tmp for a
-    here document cannot be created.
-
-i.  Many changes to the shell's variable initialization code to speed
-    non-interactive startup.
-
-j.  Changes to the non-job-control code so that it does not try to open
-    /dev/tty.
-
-k.  The output of `set' and `export' is once again sorted, as POSIX wants.
-
-l.  Fixed a problem caused by a recursive call reparsing the value of
-    $SHELLOPTS.
-
-m.  The tilde code no longer calls getenv() when it's compiled as part of
-    the shell, which should eliminate problems on systems that cannot
-    redefine getenv(), like the NeXT OS.
-
-n.  Fixed a problem that caused `bash -o' or `bash +o' to not list all
-    the shell options.
-
-o.  Fixed `ulimit' to convert RLIM_INFINITY to the appropriate hard limit
-    only if the hard limit is greater than the current (soft) limit.
-
-p.  Fixed a problem that arose when building bash in a different directory
-    than the source and y.tab.[ch] were remade with something other than
-    bison.  This came up most often on NetBSD.
-
-q.  Fixed a problem with completion -- it thought that `pwd`/[TAB] indicated
-    an unfinished command completion (`/), which generated errors.
-
-r.  The bash special tilde expansions (~-, ~+) are now attempted before
-    calling the standard tilde expansion code, which should eliminate the
-    problems people have been seeing with this on Solaris 2.5.1.
-
-s.  Added support for <stdarg.h> to places where it was missing.
-
-t.  Changed the code that reads the output of a command substitution to not
-    go through stdio.  This reduces the memory requirements and is faster.
-
-u.  A number of changes to speed up export environment creation were made.
-
-v.  A number of memory leaks were fixed as the result of running the test
-    scripts through Purify.
-
-w.  Fixed a bug that caused subshells forked to interpret executable
-    scripts without a leading `#!' to not reinitialize the values of
-    the shell options.
-
-2.  Changes to Readline
-
-a.  History library has less `#ifdef SHELL' code -- abstracted stuff out
-    into application-specific function hooks.
-
-b.  Readline no longer calls getenv() if it's compiled as part of the shell,
-    which should eliminate problems on systems that cannot redefine getenv(),
-    like the NeXT OS.
-
-c.  Fixed translation of ESC when `untranslating' macro values.
-
-d.  The region kill operation now fixes the mark if it ends up beyond the
-    boundaries of the line after the region is deleted.
-
-3.  New Features in Bash
-
-a.  New argument for `configure':  `--with-curses'.  This can be used to
-    override the selection of the termcap library on systems where it is
-    deficient.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.01-alpha1,
-and the previous version, bash-2.0-release.
-
-1.  Changes to Bash
-
-a.  System-specific configuration changes for: FreeBSD, SunOS4, Irix,
-    MachTen, QNX 4.2, Harris Night Hawk, SunOS5.
-
-b.  System-specific code changes were made for: Linux, 4.4 BSD, QNX 4.2,
-    HP-UX, AIX 4.2.
-
-c.  A bug that caused the exec builtin to fail because the full pathname of
-    the command could not be found was fixed.
-
-d.  The code that performs output redirections is now more resistant to
-    race conditions and possible security exploits.
-
-e.  A bug that caused the shell to dump core when performing pattern
-    substitutions on variable values was fixed.
-
-f.  More hosts are now recognized by the auto-configuration mechanism
-    (OpenBSD, QNX, others).
-
-g.  Assignments to read-only variables that attempt to convert them to
-    arrays are now errors.
-
-h.  A bug that caused shell scripts using array assignments in POSIX mode
-    to exit after the assignment was performed was fixed.
-
-i.  The substring expansion code is now more careful about running off the
-    ends of the expanded variable value.
-
-j.  A bug that caused completion to fail if a backquoted command substitution
-    appeared anywhere on the line was fixed.
-
-k.  The `source' builtin no longer turns off history if it has been enabled
-    in a non-interactive shell.
-
-l.  A bug that caused the shell to crash when `disown' was given a pid
-    instead of a job number was fixed.
-
-m.  The `cd' spelling correction code will not try to change to `.' if no
-    directory entries match a single-character argument.
-
-n.  A bad variable name supplied to `declare', `export', or `readonly' no
-    longer causes a non-interactive shell in POSIX mode to exit.
-
-o.  Some fixes were made to the test suite to handle peculiarities of
-    various Unix versions.
-
-p.  The bash completion code now quotes characters that readline would
-    treat as word breaks for completion but are not shell metacharacters.
-
-q.  Bad options supplied at invocation now cause a usage message to be
-    displayed.
-
-r.  Fixes were made to the code that handles DEBUG traps so that the trap
-    string is not freed inappropriately.
-
-s.  Some changes were made to the bash debugger in examples/bashdb -- it
-    should be closer to working now.
-
-t.  A problem that caused the default filename used for mail checking to be
-    wrong was fixed.
-
-u.  A fix was made to the `echo' builtin so that NUL characters printed with
-    `echo -e' do not cause the output to be truncated.
-
-v.  A fix was made to the job control code so that the shell behaves better
-    when monitor mode is enabled in a non-interactive shell.
-
-w.  Bash no longer catches all of the terminating signals in a non-
-    interactive shell until a trap is set on EXIT, which should result in
-    quicker startup.
-
-x.  A fix was made to the command timing code so that `time' can be used in
-    a loop.
-
-y.  A fix was made to the parser so that `((cmd); cmd2)' is now parsed as
-    a nested subshell rather than strictly as an (erroneous) arithmetic
-    command.
-
-z.  A fix was made to the globbing code so that it correctly matches quoted
-    filenames beginning with a `.'.
-
-aa. A bug in `fc' that caused some multi-line commands to not be stored as
-    one command in the history when they were re-executed after editing
-    (with `fc -e') was fixed.
-
-bb. The `ulimit' builtin now attempts to catch some classes of integer
-    overflows.
-
-cc. The command-oriented-history code no longer attempts to add `;'
-    inappropriately when a newline appears while reading a $(...) command
-    substitution.
-
-dd. A bug that caused the shell to dump core when `help --' was executed
-    was fixed.
-
-ee. A bug that caused the shell to crash when an unset variable appeared
-    in the body of a here document after `set -u' had been executed was
-    fixed.
-
-ff. Implicit input redirections from /dev/null for asynchronous commands
-    are now handled better.
-
-gg. A bug that caused the shell to fail to compile when configured with
-    `--disable-readline' was fixed.
-
-hh. The globbing code should now be interruptible.
-
-ii. Bash now notices when the `kill' builtin is used to send SIGCONT to a
-    stopped job and adjusts the data structures accordingly, as if `bg' had
-    been executed instead.
-
-jj. A bug that caused the shell to crash when mixing calls to `getopts'
-    and `shift' on the same set of positional parameters was fixed.
-
-kk. The command printing code now preserves the `-p' flag to `time'.
-
-ll. The command printing code now handles here documents better when there
-    are other redirections associated with the command.
-
-mm. The special glibc environment variable (NNN_GNU_nonoption_argv_flags_)
-    is no longer placed into the environment of executed commands -- users
-    of glibc had too many problems with it.
-
-nn. Reorganized the code that generates signames.h.  The signal_names list
-    is now more complete but may be slightly different (SIGABRT is favored
-    over SIGIOT, for example).  The preferred signal names are those
-    listed in the POSIX.2 standard.
-
-oo. `bashbug' now uses a filename shorter than 14 characters for its
-    temporary file, and asks for confirmation before sending the bug
-    report.
-
-pp. A bug that caused TAB completion in vi editing mode to not be turned
-    off when `set -o posix' was executed or back on when `set +o posix'
-    was executed was fixed.
-
-qq. A bug in the brace expansion code that caused brace expansions appearing
-    in new-style $(...) command substitutions to be inappropriately expanded
-    was fixed.
-
-rr. A bug in the readline hook shell-expand-line that could cause memory to
-    be inappropriately freed was fixed.
-
-ss. A bug that caused some arithmetic expressions containing `&&' and `||'
-    to be parsed with the wrong precedence has been fixed.
-
-tt. References to unbound variables after `set -u' has been executed now
-    cause the shell to exit immediately, as they should.
-
-uu. A bug that caused the shell to exit inappropriately when `set -e' had
-    been executed and a command's return status was being inverted with the
-    `!' reserved word was fixed.
-
-vv. A bug that could occasionally cause the shell to crash with a
-    divide-by-zero error when timing a command was fixed.
-
-ww. A bug that caused parameter pattern substitution to leave stray
-    backslashes in the replacement string when the expression is in
-    double quotes was fixed.
-
-xx. The `break' and `continue' builtins now break out of all loops when an
-    invalid count argument is supplied.
-
-yy. Fixed a bug that caused PATH to be set to the empty string if
-    `command -p' is executed with PATH unset.
-
-zz. Fixed `kill -l signum' to print the signal name without the `SIG' prefix,
-    as POSIX specifies.
-
-aaa. Fixed a bug that caused the shell to crash while setting $SHELLOPTS
-     if there were no shell options set.
-
-bbb. Fixed `export -p' and `readonly -p' so that when the shell is in POSIX
-     mode, their output is as POSIX.2 specifies.
-
-ccc. Fixed a bug in `readonly' so that `readonly -a avar=(...)' actually
-     creates an array variable.
-
-ddd. Fixed a bug that prevented `time' from correctly timing background
-     pipelines.
-
-2.  Changes to Readline
-
-a.  A bug that caused an extra newline to be printed when the cursor was on
-    an otherwise empty line was fixed.
-
-b.  An instance of memory being used after it was freed was corrected.
-
-c.  The redisplay code now works when the prompt is longer than the screen
-    width.
-
-d.  `dump-macros' is now a bindable name, as it should have been all along.
-
-e.  Non-printable characters are now expanded when displaying macros and
-    their values.
-
-f.  The `dump-variables' and `dump-macros' commands now output a leading
-    newline if they're called as the result of a key sequence, rather
-    than directly by an application.
-
-3.  New Features in Bash
-
-a.  There is a new builtin array variable: GROUPS, the set of groups to which
-    the user belongs.  This is used by the test suite.
-
-4.  New Features in Readline
-
-a.  If a key sequence bound to `universal-argument' is read while reading a
-    numeric argument started with `universal-argument', it terminates the
-    argument but is otherwise ignored.  This provides a way to insert multiple
-    instances of a digit string, and is how GNU emacs does it.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.0-release,
-and the previous version, bash-2.0-beta3.
-
-1.  Changes to Bash
-
-a.  Fix to the `getopts' builtin so that it does the right thing when a
-    required option argument is not present.
-
-b.  The completion code now updates the common prefix of matched names
-    after FIGNORE processing is done, since any names that were removed
-    may have changed the common prefix.
-
-c.  Fixed a bug that made messages in MAILPATH entries not work correctly.
-
-d.  Fixed a serious documentation error in the description of the new
-    ${parameter:offset[:length]} expansion.
-
-e.  Fixes to make parameter substring expansion ({$param:offset[:length]})
-    work when within double quotes.
-
-f.  Fixes to make ^A (CTLESC) survive an unquoted expansion of positional
-    parameters.
-
-g.  Corrected a misspelling of `unlimited' in the output of `ulimit'.
-
-h.  Fixed a bug that caused executable scripts without a leading `#!' to
-    occasionally pick up the wrong set of positional parameters.
-
-i.  Linux systems now have a working `ulimit -v', using RLIMIT_AS.
-
-j.  Updated config.guess so that many more machine types are recognized.
-
-k.  Fixed a bug with backslash-quoted slashes in the ${param/pat[/sub]}
-    expansion.
-
-l.  If the shell is named `-su', and `-c command' is supplied, read and
-    execute the login shell startup files even though the shell is not
-    interactive.  This is to support the `-' option to `su'.
-
-m.  Fixed a bug that caused core dumps when the DEBUG trap was ignored
-    with `trap "" DEBUG' and a shell function was subsequently executed.
-
-n.  Fixed a bug that caused core dumps in the read builtin when IFS was
-    set to the null string and the input had leading whitespace.
-
-2.  Changes to Readline
-
-a.  Fixed a bug that caused a numeric argument of 1024 to be ignored when
-    inserting text.
-
-b.  Fixed the display code so that the numeric argument is displayed as it's
-    being entered.
-
-c.  Fixed the numeric argument reading code so that `M-- command' is
-    equivalent to `M--1 command', as the prompt implies.
-
-3.  New Features in Bash
-
-a.  `ulimit' now sets both hard and soft limits and reports the soft limit
-    by default (when neither -H nor -S is specified).  This is compatible
-    with versions of sh and ksh that implement `ulimit'.
-
-b.  Integer constants have been extended to base 64.
-
-4.  New Features in Readline
-
-a.  The `home' and `end' keys are now bound to beginning-of-line and
-    end-of-line, respectively, if the corresponding termcap capabilities
-    are present.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.0-beta3,
-and the previous version, bash-2.0-beta2.
-
-1.  Changes to Bash
-
-a.  System-specific changes for: AIX 4.2, SCO 3.2v[45], HP-UX.
-
-b.  When in POSIX mode, variable assignments preceding a special builtin
-    persist in the shell environment after the builtin completes.
-
-c.  Changed all calls to getwd() to getcwd().  Improved check for systems
-    where the libc getcwd() calls popen(), since that breaks on some
-    systems when job control is being used.
-
-d.  Fixed a bug that caused seg faults when executing scripts with the
-    execute bit set but without a leading `#!'.
-
-e.  The environment passed to executed commands is never sorted.
-
-f.  A bug was fixed in the code that expands ${name[@]} to the number of
-    elements in an array variable.
-
-g.  A bug was fixed in the array compound assignment code ( A=( ... ) ).
-
-h.  Window size changes now correctly propagate down to readline if
-    the shopt `checkwinsize' option is enabled.
-
-i.  A fix was made in the code that expands to the length of a variable
-    value (${#var}).
-
-j.  A fix was made to the command builtin so that it did not turn on the
-    `no fork' flag inappropriately.
-
-k.  A fix was made to make `set -n' work more reliably.
-
-l.  A fix was made to the job control initialization code so that the
-    terminal process group is set to the shell's process group if the
-    shell changes its own process group.
-
-2.  Changes to Readline
-
-a.  System-specific changes for: SCO 3.2v[45].
-
-b.  The behavior of the vi-mode `.' when redoing an `i' command was changed
-    to insert the text previously inserted by the `i' command rather than
-    simply entering insert mode.
-
-3.  New features in Bash
-
-a.  There is a new version of the autoload function package, in
-    examples/functions/autoload.v2, that uses arrays and provides more
-    functionality.
-
-b.  Support for LC_COLLATE and locale-specific sorting of the results of
-    pathname expansion if strcoll() is available.
-
-4.  New Features in Readline
-
-a.  Support for locale-specific sorting of completion possibilities if
-    strcoll() is available.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.0-beta2,
-and the previous version, bash-2.0-beta1.
-
-1.  Changes to Bash
-
-a.  `pushd -' is once again equivalent to `pushd $OLDPWD'.
-
-b.  OS-specific changes for: SCO 3.2v[45].
-
-c.  A change was made to the fix for the recently-reported security hole
-    when reading characters with octal value 255 to make it work better on
-    systems with restartable system calls when not using readline.
-
-d.  Some changes were made to the test suite so that it works if you
-    configure bash with --enable-usg-echo-default.
-
-e.  A fix was made to the parsing of conditional arithmetic expressions.
-
-f.  Illegal arithmetic bases now cause an arithmetic evaluation error rather
-    than being silently reset.
-
-g.  Multiple arithmetic bases now cause an arithmetic evaluation error
-    instead of being ignored.
-
-h.  A fix was made to the evaluation of ${param?word} to conform to POSIX.2.
-
-i.  A bug that sometimes caused array indices to be evaluated twice (which
-    would cause errors when they contained assignment statements) was fixed.
-
-j.  `ulimit' was rewritten to avoid problems with getrlimit(2) returning
-    unsigned values and to simplify the code.
-
-k.  A bug in the command-oriented-history code that caused it to sometimes
-    put semicolons after right parens inappropriately was fixed.
-
-l.  The values inserted into the prompt by the \w and \W escape sequences
-    are now quoted to prevent further expansion.
-
-m.  An interactive shell invoked as `sh' now reads and executes commands
-    from the file named by $ENV when it starts up.  If it's a login shell,
-    it does this after reading /etc/profile and ~/.profile.
-
-n.  The file named by $ENV is never read by non-interactive shells.
-
-2.  Changes to Readline
-
-a.  A few changes were made to hide some macros and functions that should not
-    be public.
-
-b.  An off-by-one error that caused seg faults in the history expansion code
-    was fixed.
-
-3.  New Features in Bash
-
-a.  The ksh-style ((...)) arithmetic command was implemented.  It is exactly
-    identical to let "...".  This is controlled by a new option to configure,
-    `--enable-dparen-arithmetic', which is on by default.
-
-b.  There is a new #define available in config.h.top: SYS_BASH_LOGOUT.  If
-    defined to a filename, bash reads and executes commands from that file
-    when a login shell exits.  It's commented out by default.
-
-c.  `ulimit' has a `-l' option that reports the maximum amount of data that
-    may be locked into memory on 4.4BSD-based systems.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.0-beta1,
-and the previous version, bash-2.0-alpha4.
-
-1.  Changes to Bash
-
-a.  A bug that sometimes caused traps to be ignored on signals the
-    shell treats specially was fixed.
-
-b.  The internationalization code was changed to track the values of
-    LC_* variables and call setlocale() as appropriate.  The TEXTDOMAIN
-    and TEXTDOMAINDIR variables are also tracked; changes cause calls
-    to textdomain() and bindtextdomain(), if available.
-
-c.  A bug was fixed that sometimes caused double-quoted strings to be
-    parsed incorrectly.
-
-d.  Changes were made so that the siglist code compiles correctly on
-    Solaris 2.5.
-
-e.  Added `:' to the set of characters that cause word breaks for the
-    completion code so that pathnames in assignments to $PATH can be
-    completed.
-
-f.  The `select' command was fixed to print $PS3 to stderr.
-
-g.  Fixed an error in the manual page section describing the effect that
-    setting and unsetting GLOBIGNORE has on the setting of the `dotglob'
-    option.
-
-h.  The time conversion code now uses CLK_TCK rather than CLOCKS_PER_SEC
-    on systems without gettimeofday() and resources.
-
-i.  The getopt static variables are now initialized each time a subshell
-    is started, so subshells using `getopts' work right.
-
-j.  A sign-extension bug that caused a possible security hole was fixed.
-
-k.  The parser now reads characters between backquotes within a double-
-    quoted string as a single word, so double quotes in the backquoted
-    string don't terminate the enclosing double-quoted string.
-
-l.  A bug that caused `^O' to work incorrectly when typed as the first
-    thing to an interactive shell was fixed.
-
-m.  A rarely-exercised off-by-one error in the code that quotes variable
-    values was fixed.
-
-n.  Some memory and file descriptor leaks encountered when running a
-    shell script that is executable but does not have a leading `#!'
-    were plugged.
-
-2.  Changes to Readline
-
-a.  A bug that sometimes caused incorrect results when trying to read
-    typeahead on systems without FIONREAD was fixed.
-
-3.  New Features in Bash
-
-a.  The command timing code now uses the value of the TIMEFORMAT variable
-    to format and display timing statistics.
-
-b.  The `time' reserved word now accepts a `-p' option to force the
-    POSIX.2 output format.
-
-c.  There are a couple of new and updated scripts to convert csh startup
-    files to bash format.
-
-d.  There is a new builtin array variable: BASH_VERSINFO.  The various
-    members hold the parts of the version information in BASH_VERSION,
-    plus the value of MACHTYPE.
-
-4.  New Features in Readline
-
-a.  Setting LANG to `en_US.ISO8859-1' now causes readline to enter
-    eight-bit mode.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.0-alpha4,
-and the previous version, bash-2.0-alpha3.
-
-1.  Changes to Bash
-
-a.  There is better detection of rsh connections on Solaris 2.
-
-b.  Assignments to read-only variables preceding a command name are now
-    variable assignment errors.  Variable assignment errors cause
-    non-interactive shells running in posix mode to exit.
-
-c.  The word tokenizer was rewritten to handle nested quotes and pairs
-    ('', "", ``, ${...}, $(...), $[...], $'...', $"...", <(...), >(...))
-    correctly.  Some of the parameter expansion code was updated as a
-    consequence.
-
-d.  A fix was made to `test' when given three arguments so that a binary
-    operator is checked for first, before checking that the first argument
-    is `!'.
-
-e.  2''>/dev/null is no longer equivalent to 2>/dev/null.
-
-f.  Parser error messages were regularized, and in most cases the name of
-    the shell script being read by a non-interactive shell is not printed
-    twice.
-
-g.  A fix was made to the completion code so that it no longer removes the
-    text the user typed in some cases.
-
-h.  The special glibc `getopt' environment variable is no longer put into
-    the environment on machines with small values of ARG_MAX.
-
-i.  The expansion of ${...} now follows the POSIX.2 rules for finding the
-    closing `}'.
-
-j.  The shell no longer displays spurious status messages for background
-    jobs in shell scripts that complete successfully when the script is
-    run from a terminal.
-
-k.  `shopt -o' now correctly updates $SHELLOPTS.
-
-l.  A bug that caused the $PATH searching code to return a non-executable
-    file even when an executable file with the same name appeared later in
-    $PATH was fixed.
-
-m.  The shell now does tilde expansions on unquoted `:~' in assignment
-    statements when not in posix mode.
-
-n.  Variable assignment errors when a command consists only of assignments
-    now cause non-interactive shells to exit when in posix mode.
-
-o.  If the variable in a `for' or `select' command is read-only, or not a
-    legal shell identifier, a variable assignment error occurs.
-
-p.  `test' now handles `-a' and `-o' as binary operators when three arguments
-    are supplied, and correctly parses `( word )' as equivalent to `word'.
-
-q.  `test' was fixed so that file names of the form /dev/fd/NN mean the same
-    thing on all systems, even Linux.
-
-r.  Fixed a bug in the globbing code that caused patterns with multiple
-    consecutive `*'s to not be matched correctly.
-
-s.  Fixed a bug that caused $PS2 to not be printed when an interactive shell
-    not using readline is reading a here document.
-
-t.  Fixed a bug that caused history expansion to be performed inappropriately
-    when a single-quoted string spanned more than one line.
-
-u.  `getopts' now checks that the variable name passed by the user as the
-    second argument is a legal shell identifier and that the variable is
-    not read-only.
-
-v.  Fixed `getopts' to obey POSIX.2 rules for setting $OPTIND when it
-    encounters an error.
-
-w.  Fixed `set' to display variable values in a form that can be re-read.
-
-x.  Fixed a bug in the code that keeps track of whether or not local variables
-    have been declared at the current level of function nesting.
-
-y.  Non-interactive shells in posix mode now exit if the name in a function
-    declaration is not a legal identifier.
-
-z.  The job control code now ignores stopped children when the shell is not
-    interactive.
-
-aa. The `cd' builtin no longer attempts spelling correction on the directory
-    name if the shell is not interactive, regardless of the setting of the
-    `cdspell' option.
-
-bb. Some OS-specific changes were made for SCO 3.2v[45] and AIX 4.2.
-
-cc. `time' now prints its output to stderr, as POSIX.2 specifies.
-
-2.  Fixes to Readline
-
-a.  After printing possible completions, all lines of a multi-line prompt
-    are redisplayed.
-
-b.  Some changes were made to the terminal handling code in rltty.c to
-    work around AIX 4.2 bugs.
-
-3.  New Features in Bash
-
-a.  There is a new loadable builtin: sprintf, with calling syntax
-               sprintf var format [args]
-    This provides an easy way to simulate ksh left- and right-justified
-    variable values.
-
-b.  The expansions of \h and \H in prompt strings were swapped.  \h now
-    expands to the hostname up to the first `.', as in bash-1.14.
-
-4.  New Features in Readline
-
-a.  The bash-1.14 behavior when ^M is typed while doing an incremental
-    search was restored.  ^J may now be used to terminate the search without
-    accepting the line.
-
-b.  There is a new bindable variable: disable-completion.  This inhibits
-    word completion and causes the completion character to be inserted as
-    if it had been bound to self-insert.
-
-------------------------------------------------------------------------------
-This document details the changes between this version, bash-2.0-alpha3,
-and the previous version, bash-2.0-alpha2.
-
-There is now a file `COMPAT' included in the distribution that lists the
-user-visible incompatibilities between 1.14 and 2.0.
-
-1. Changes to Bash
-
-a. Some work was done so that word splitting of the rhs of assignment
-   statements conforms more closely to historical practice.
-
-b. A couple of errant memory frees were fixed.
-
-c. A fix was made to the test builtin so it recognizes `<' and `>' as
-   binary operators.
-
-d. The GNU malloc in lib/malloc/malloc.c now scrambles memory as it's
-   allocated and freed.  This is to catch callers that refer to freed
-   memory or assume something about newly-allocated memory.
-
-e. Fixed a problem with conversion to 12-hour time in the prompt
-   expansion code.
-
-f. Fixed a problem with configure's argument parsing order.  Now you can
-   correctly turn on specific options after using --enable-minimal-config.
-
-g. The configure script now automatically disables the use of GNU malloc
-   on systems where it's appropriate (better than having people read the
-   NOTES file and do it manually).
-
-h. There are new prompt expansions (\v and \V) to insert version information
-   into the prompt strings.
-
-i. The default prompt string now includes the version number.
-
-j. Most of the builtins that take no options were changed to use the
-   internal getopt so they can produce proper error messages for -?
-   and incorrect options.
-
-k. Some system-specific changes were made for SVR4.2 and Solaris 2.5.
-
-l. Bash now uses PATH_MAX instead of MAXPATHLEN and NAME_MAX instead of
-   MAXNAMLEN.
-
-m. A couple of problems caused by uninitialized variables were fixed.
-
-n. There are a number of new loadable builtin examples: logname, basename,
-   dirname, tty, pathchk, tee, head, and rmdir.  All of these conform to
-   POSIX.2.
-
-o. Bash now notices changes in TZ and calls tzset() if present, so
-   changing TZ will alter the time printed by prompt expansions.
-
-p. The source was reorganized a bit so I don't have to wait so long for
-   some files to compile, and to facilitate the creation of a `shell
-   library' at some future point.
-
-q. Bash no longer turns off job control if called as `sh', since the
-   POSIX.2 spec includes job control as a standard feature.
-
-r. `bash -o posix' now works as intended.
-
-s. Fixed a problem with the completion code: when completing a filename
-   that contained globbing characters, if show-all-if-ambiguous was set,
-   the completion code would remove the user's text.
-
-t. Fixed ulimit so that (hopefully) the full range of limits is available
-   on HPUX systems.
-
-u. A new `shopt' option (`hostcomplete') enables and disables hostname
-   completion.
-
-v. The shell no longer attempts to save the history on an abort(),
-   which is usually called by programming_error().
-
-w. The `-s' option to `fc' was changed to echo the command to be executed
-   to stderr instead of stdout.
-
-x. If the editor invoked by `fc -e' exits with a non-zero status, no
-   commands are executed.
-
-y. Fixed a bug that made the shopt `histverify' option work incorrectly.
-
-z. There is a new variable `MACHTYPE' whose value is the GNU-style
-   `cpu-company-system' system description as set by configure.  (The
-   values of MACHTYPE and HOSTTYPE should really be swapped.)
-
-aa. The `ulimit' builtin now allows the maximum virtual memory size to be
-    set via setrlimit(2) if RLIMIT_VMEM is defined.
-
-bb. `bash -nc 'command'' no longer runs `command'.
-
-2. Changes to Readline
-
-a. Fixed a typo in the code that checked for FIONREAD in input.c.
-
-b. Fixed a bug in the code that outputs keybindings, so things like C-\
-   are quoted properly.
-
-c. Fixed a bug in the inputrc file parsing code to handle the problems
-   caused by inputrc files created from the output of `bind -p' in
-   previous versions of bash.  The problem was due to the bug fixed
-   in item b above.
-
-d. Readline no longer turns off the terminal's meta key, and turns it on
-   once the first time it's called.
-
-------------------------------------------------------------------------------
-This file documents the changes between this version, bash-2.0-alpha2,
-and the previous version, bash-2.0-alpha.
-
-1. Changes to Bash
-
-a. The shell no longer thinks directories are executable.
-
-b. `disown' has a new option, `h', which inhibits the resending of SIGHUP
-   but does not remove the job from the jobs table.
-
-c. The varargs functions in error.c now use ANSI-C `stdarg' if available.
-
-d. The build process now treats the `build version' in .build as local to
-   the build directory, so different versions built from the same source
-   tree have different `build versions'.
-
-e. Some problems with the grammar have been fixed. (It used `list' in a few
-   productions where `compound_list' was needed.  A `list' must be terminated
-   with a newline or semicolon; a `compound_list' need not be.)
-
-f. A fix was made to keep `wait' from hanging when waiting for all background
-   jobs.
-
-g. `bash --help' now writes its output to stdout, like the GNU Coding Standards
-   specify, and includes the machine type (the value of MACHTYPE).
-
-h. `bash --version' now prints more information and exits successfully, like
-   the GNU Coding Standards specify.
-
-i. The output of `time' and `times' now prints fractional seconds with three
-   places after the decimal point.
-
-j. A bug that caused process substitutions to screw up the pipeline printed
-   by `jobs' was fixed.
-
-k. Fixes were made to the code that implements $'...' and $"..." so they
-   work as documented.
-
-l. The process substitution code now opens named pipes for reading with
-   O_NONBLOCK to avoid hanging.
-
-m. Fixes were made to the trap code so the shell cleans up correctly if the
-   trap command contains a `return' and we're executing a function or
-   sourcing a script with `.'.
-
-n. Fixes to doc/Makefile.in so that it doesn't try to remake all of the
-   documentation (ps, dvi, etc.) on a `make install'.
-
-o. Fixed an auto-increment error that caused bash -c args to sometimes dump
-   core.
-
-p. Fixed a bug that caused $HISTIGNORE to fail when the history line
-   contained globbing characters.
-
-2. Changes to Readline
-
-a. There is a new string variable, rl_library_version, available for use by
-   applications.  The current value is "2.1".
-
-b. A bug encountered when expand-tilde was enabled and file completion was
-   attempted on a word beginning with `~/' was fixed.
-
-c. A slight change was made to the incremental search termination behavior.
-   ESC still terminates the search, but if input is pending or arrives
-   within 0.1 seconds (on systems with select(2)), it is used as a prefix
-   character.  This is intented to allow users to terminate searches with
-   the arrow keys and get the behavior they expect.
diff --git a/COMPAT~ b/COMPAT~
deleted file mode 100644 (file)
index 6ee2bb3..0000000
--- a/COMPAT~
+++ /dev/null
@@ -1,367 +0,0 @@
-Compatibility with previous versions
-====================================
-
-This document details the incompatibilities between this version of bash,
-bash-4.1, and the previous widely-available versions, bash-2.x (which is
-still the `standard' version for a few Linux distributions) and bash-3.x. 
-These were discovered by users of bash-2.x and 3.x, so this list is not
-comprehensive.  Some of these incompatibilities occur between the current
-version and versions 2.0 and above.
-
-1.  Bash uses a new quoting syntax, $"...", to do locale-specific
-    string translation.  Users who have relied on the (undocumented)
-    behavior of bash-1.14 will have to change their scripts.  For
-    instance, if you are doing something like this to get the value of
-    a variable whose name is the value of a second variable:
-
-       eval var2=$"$var1"
-
-    you will have to change to a different syntax.
-
-    This capability is directly supported by bash-2.0:
-
-       var2=${!var1}
-
-    This alternate syntax will work portably between bash-1.14 and bash-2.0:
-
-       eval var2=\$${var1}
-
-2.  One of the bugs fixed in the YACC grammar tightens up the rules
-    concerning group commands ( {...} ).  The `list' that composes the
-    body of the group command must be terminated by a newline or
-    semicolon.  That's because the braces are reserved words, and are
-    recognized as such only when a reserved word is legal.  This means
-    that while bash-1.14 accepted shell function definitions like this:
-
-       foo() { : }
-
-    bash-2.0 requires this:
-
-       foo() { :; }
-
-    This is also an issue for commands like this:
-
-       mkdir dir || { echo 'could not mkdir' ; exit 1; }
-
-    The syntax required by bash-2.0 is also accepted by bash-1.14.
-
-3.  The options to `bind' have changed to make them more consistent with
-    the rest of the bash builtins.  If you are using `bind -d' to list
-    the readline key bindings in a form that can be re-read, use `bind -p'
-    instead.  If you were using `bind -v' to list the key bindings, use
-    `bind -P' instead.
-
-4.  The `long' invocation options must now be prefixed by `--' instead
-    of `-'.  (The old form is still accepted, for the time being.)
-
-5.  There was a bug in the version of readline distributed with bash-1.14
-    that caused it to write badly-formatted key bindings when using 
-    `bind -d'.  The only key sequences that were affected are C-\ (which
-    should appear as \C-\\ in a key binding) and C-" (which should appear
-    as \C-\").  If these key sequences appear in your inputrc, as, for
-    example,
-
-       "\C-\": self-insert
-
-    they will need to be changed to something like the following:
-
-       "\C-\\": self-insert
-
-6.  A number of people complained about having to use ESC to terminate an
-    incremental search, and asked for an alternate mechanism.  Bash-2.03
-    uses the value of the settable readline variable `isearch-terminators'
-    to decide which characters should terminate an incremental search.  If
-    that variable has not been set, ESC and Control-J will terminate a
-    search.
-
-7.  Some variables have been removed:  MAIL_WARNING, notify, history_control,
-    command_oriented_history, glob_dot_filenames, allow_null_glob_expansion,
-    nolinks, hostname_completion_file, noclobber, no_exit_on_failed_exec, and
-    cdable_vars.  Most of them are now implemented with the new `shopt'
-    builtin; others were already implemented by `set'.  Here is a list of
-    correspondences:
-
-       MAIL_WARNING                    shopt mailwarn
-       notify                          set -o notify
-       history_control                 HISTCONTROL
-       command_oriented_history        shopt cmdhist
-       glob_dot_filenames              shopt dotglob
-       allow_null_glob_expansion       shopt nullglob
-       nolinks                         set -o physical
-       hostname_completion_file        HOSTFILE
-       noclobber                       set -o noclobber
-       no_exit_on_failed_exec          shopt execfail
-       cdable_vars                     shopt cdable_vars
-
-8. `ulimit' now sets both hard and soft limits and reports the soft limit
-    by default (when neither -H nor -S is specified).  This is compatible
-    with versions of sh and ksh that implement `ulimit'.  The bash-1.14
-    behavior of, for example,
-
-               ulimit -c 0
-
-    can be obtained with
-
-               ulimit -S -c 0
-
-    It may be useful to define an alias:
-
-               alias ulimit="ulimit -S"
-
-9.  Bash-2.01 uses a new quoting syntax, $'...' to do ANSI-C string
-    translation.  Backslash-escaped characters in ... are expanded and
-    replaced as specified by the ANSI C standard.
-
-10. The sourcing of startup files has changed somewhat.  This is explained
-    more completely in the INVOCATION section of the manual page.
-
-    A non-interactive shell not named `sh' and not in posix mode reads
-    and executes commands from the file named by $BASH_ENV.  A
-    non-interactive shell started by `su' and not in posix mode will read
-    startup files.  No other non-interactive shells read any startup files.
-
-    An interactive shell started in posix mode reads and executes commands
-    from the file named by $ENV.
-
-11. The <> redirection operator was changed to conform to the POSIX.2 spec.
-    In the absence of any file descriptor specification preceding the `<>',
-    file descriptor 0 is used.  In bash-1.14, this was the behavior only
-    when in POSIX mode.  The bash-1.14 behavior may be obtained with
-
-       <>filename 1>&0
-
-12. The `alias' builtin now checks for invalid options and takes a `-p'
-    option to display output in POSIX mode.  If you have old aliases beginning
-    with `-' or `+', you will have to add the `--' to the alias command
-    that declares them:
-
-       alias -x='chmod a-x' --> alias -- -x='chmod a-x'
-
-13. The behavior of range specificiers within bracket matching expressions
-    in the pattern matcher (e.g., [A-Z]) depends on the current locale,
-    specifically the value of the LC_COLLATE environment variable.  Setting
-    this variable to C or POSIX will result in the traditional ASCII behavior
-    for range comparisons.  If the locale is set to something else, e.g.,
-    en_US (specified by the LANG or LC_ALL variables), collation order is
-    locale-dependent.  For example, the en_US locale sorts the upper and
-    lower case letters like this:
-
-       AaBb...Zz
-
-    so a range specification like [A-Z] will match every letter except `z'.
-    Other locales 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).
-
-    You can find your current locale information by running locale(1):
-
-       caleb.ins.cwru.edu(2)$ locale
-       LANG=en_US
-       LC_CTYPE="en_US"
-       LC_NUMERIC="en_US"
-       LC_TIME="en_US"
-       LC_COLLATE="en_US"
-       LC_MONETARY="en_US"
-       LC_MESSAGES="en_US"
-       LC_ALL=en_US
-
-    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.
-
-14. Bash versions up to 1.14.7 included an undocumented `-l' operator to
-    the `test/[' builtin.  It was a unary operator that expanded to the
-    length of its string argument.  This let you do things like
-
-       test -l $variable -lt 20
-
-    for example.
-
-    This was included for backwards compatibility with old versions of the
-    Bourne shell, which did not provide an easy way to obtain the length of
-    the value of a shell variable.
-
-    This operator is not part of the POSIX standard, because one can (and
-    should) use ${#variable} to get the length of a variable's value.
-    Bash-2.x does not support it.
-
-15. Bash no longer auto-exports the HOME, PATH, SHELL, TERM, HOSTNAME,
-    HOSTTYPE, MACHTYPE, or OSTYPE variables.  If they appear in the initial
-    environment, the export attribute will be set, but if bash provides a
-    default value, they will remain local to the current shell.
-
-16. Bash no longer initializes the FUNCNAME, GROUPS, or DIRSTACK variables
-    to have special behavior if they appear in the initial environment.
-
-17. Bash no longer removes the export attribute from the SSH_CLIENT or
-    SSH2_CLIENT variables, and no longer attempts to discover whether or
-    not it has been invoked by sshd in order to run the startup files.
-
-18. Bash no longer requires that the body of a function be a group command;
-    any compound command is accepted.
-
-19. As of bash-3.0, the pattern substitution operators no longer perform
-    quote removal on the pattern before attempting the match.  This is the
-    way the pattern removal functions behave, and is more consistent.
-
-20. After bash-3.0 was released, I reimplemented tilde expansion, incorporating
-    it into the mainline word expansion code.  This fixes the bug that caused
-    the results of tilde expansion to be re-expanded.  There is one
-    incompatibility:  a ${paramOPword} expansion within double quotes will not
-    perform tilde expansion on WORD.  This is consistent with the other
-    expansions, and what POSIX specifies.
-
-21. A number of variables have the integer attribute by default, so the +=
-    assignment operator returns expected results: RANDOM, LINENO, MAILCHECK,
-    HISTCMD, OPTIND.
-
-22. Bash-3.x is much stricter about $LINENO correctly reflecting the line
-    number in a script; assignments to LINENO have little effect.
-
-23. By default, readline binds the terminal special characters to their
-    readline equivalents.  As of bash-3.1/readline-5.1, this is optional and
-    controlled by the bind-tty-special-chars readline variable.
-
-24. The \W prompt string expansion abbreviates $HOME as `~'.  The previous
-    behavior is available with ${PWD##/*/}.
-
-25. The arithmetic exponentiation operator is right-associative as of bash-3.1.
-
-26. The rules concerning valid alias names are stricter, as per POSIX.2.
-
-27. The Readline key binding functions now obey the convert-meta setting active
-    when the binding takes place, as the dispatch code does when characters
-    are read and processed.
-
-28. The historical behavior of `trap' reverting signal disposition to the
-    original handling in the absence of a valid first argument is implemented
-    only if the first argument is a valid signal number.
-
-29. In versions of bash after 3.1, the ${parameter//pattern/replacement}
-    expansion does not interpret `%' or `#' specially.  Those anchors don't
-    have any real meaning when replacing every match.
-
-30. Beginning with bash-3.1, the combination of posix mode and enabling the
-    `xpg_echo' option causes echo to ignore all options, not looking for `-n'
-
-31. Beginning with bash-3.2, bash follows the Bourne-shell-style (and POSIX-
-    style) rules for parsing the contents of old-style backquoted command
-    substitutions.  Previous versions of bash attempted to recursively parse
-    embedded quoted strings and shell constructs; bash-3.2 uses strict POSIX
-    rules to find the closing backquote and simply passes the contents of the
-    command substitution to a subshell for parsing and execution.
-
-32. Beginning with bash-3.2, bash uses access(2) when executing primaries for
-    the test builtin and the [[ compound command, rather than looking at the
-    file permission bits obtained with stat(2).  This obeys restrictions of
-    the file system (e.g., read-only or noexec mounts) not available via stat.
-
-33. Bash-3.2 adopts the convention used by other string and pattern matching
-    operators for the `[[' compound command, and matches any quoted portion
-    of the right-hand-side argument to the =~ operator as a string rather
-    than a regular expression.
-
-34. Bash-4.0 allows the behavior in the previous item to be modified using
-    the notion of a shell `compatibility level'.  If the compat31 shopt
-    option is set, quoting the pattern has no special effect.
-
-35. Bash-3.2 (patched) and Bash-4.0 fix a bug that leaves the shell in an
-    inconsistent internal state following an assignment error.  One of the
-    changes means that compound commands or { ... } grouping commands are
-    aborted under some circumstances in which they previously were not.
-    This is what Posix specifies.
-
-36. Bash-4.0 now allows process substitution constructs to pass unchanged
-    through brace expansion, so any expansion of the contents will have to be
-    separately specified, and each process subsitution will have to be
-    separately entered.
-
-37. Bash-4.0 now allows SIGCHLD to interrupt the wait builtin, as Posix
-    specifies, so the SIGCHLD trap is no longer always invoked once per
-    exiting child if you are using `wait' to wait for all children.
-
-38. Since bash-4.0 now follows Posix rules for finding the closing delimiter
-    of a $() command substitution, it will not behave as previous versions
-    did, but will catch more syntax and parsing errors before spawning a
-    subshell to evaluate the command substitution.
-
-39. The programmable completion code uses the same set of delimiting characters
-    as readline when breaking the command line into words, rather than the
-    set of shell metacharacters, so programmable completion and readline
-    should be more consistent.
-
-40. When the read builtin times out, it attempts to assign any input read to
-    specified variables, which also causes variables to be set to the empty
-    string if there is not enough input.  Previous versions discarded the
-    characters read.
-
-41. Beginning with bash-4.0, when one of the commands in a pipeline is killed
-    by a SIGINT while executing a command list, the shell acts as if it
-    received the interrupt.  This can be disabled by setting the compat31 or
-    compat32 shell options.
-
-42. Bash-4.0 changes the handling of the set -e option so that the shell exits
-    if a pipeline fails (and not just if the last command in the failing
-    pipeline is a simple command).  This is not as Posix specifies.  There is
-    work underway to update this portion of the standard; the bash-4.0
-    behavior attempts to capture the consensus at the time of release.
-
-43. Bash-4.0 fixes a Posix mode bug that caused the . (source) builtin to
-    search the current directory for its filename argument, even if "." is
-    not in $PATH.  Posix says that the shell shouldn't look in $PWD in this
-    case.
-
-44. Bash-4.1 uses the current locale when comparing strings using the < and
-    > operators to the `[[' command.  This can be reverted to the previous
-    behavior by setting one of the `compatNN' shopt options.
-
-Shell Compatibility Level
-=========================
-
-Bash-3.2 introduced the concept of a `shell compatibility level', specified
-as a set of options to the shopt builtin (compat31, compat32, compat40 at
-this writing).  There is only one current compatibility level -- each
-option is mutually exclusive.  This list does not mention behavior that is
-standard for a particular version (e.g., setting compat32 means that quoting
-the rhs of the regexp matching operator quotes special regexp characters in
-the word, which is default behavior in bash-3.2 and above).
-
-compat31 set
-       - the < and > operators to the [[ command do not consider the current
-         locale when comparing strings
-       - quoting the rhs of the regexp matching operator (=~) has no
-         special effect
-
-compat32 set
-       - the < and > operators to the [[ command do not consider the current
-         locale when comparing strings
-
-compat40 set
-       - the < and > operators to the [[ command do not consider the current
-         locale when comparing strings
-       - interrupting a command list such as "a ; b ; c" causes the execution
-         of the entire list to be aborted
-
--------------------------------------------------------------------------------
-
-Copying and distribution of this file, with or without modification,
-are permitted in any medium without royalty provided the copyright
-notice and this notice are preserved.  This file is offered as-is,
-without any warranty.
diff --git a/CWRU/CWRU.chlog~ b/CWRU/CWRU.chlog~
deleted file mode 100644 (file)
index fe712b2..0000000
+++ /dev/null
@@ -1,9302 +0,0 @@
-                                7/27/2004
-                                ---------
-
-[bash-3.0 released]
-
-                                  7/28
-                                  ----
-array.c
-       - in array_insert(), make sure the value to be added is non-NULL before
-         calling savestring() on it
-
-builtins/reserved.def
-       - fix description of `CDPATH'
-
-lib/readline/display.c
-       - when expanding a prompt that spans multiple lines with embedded
-         newlines, set prompt_physical_chars from the portion after the
-         final newline, not the preceding portion.  Bug reported by
-         "Ralf S. Engelschall" <rse@engelschall.com>
-
-make_cmd.c
-       - explicitly declare `lineno' in function prologue for make_case_command
-
-builtins/evalfile.c
-       - include `trap.h' for declaration for run_return_trap
-
-bashline.c
-       - fix a `return' without a value in enable_hostname_completion
-
-general.c
-       - include test.h for extern declaration for test_eaccess
-
-externs.h
-       - add declaration for zcatfd
-
-tests/{history,histexp}.tests
-       - unset HISTFILESIZE to avoid problems if a value of 0 is inherited
-         from the environment
-
-                                  7/30
-                                  ----
-bashline.c
-       - small changes to glob_expand_word to perform tilde expansion before
-         attempting globbing
-
-builtins/Makefile.in
-       - fix the install-help target to not cd into the `helpfiles'
-         subdirectory, so a value of $INSTALL_DATA containing a relative
-         pathname (e.g., .././support/install.sh) remains valid
-
-                                  7/31
-                                  ----
-subst.c
-       - new function, mbstrlen(s), returns length of a multibyte character
-         string
-
-include/shmbutil.h
-       - new macro, MB_STRLEN(s), calls mbstrlen or STRLEN as appropriate
-
-builtins/trap.def
-       - small change so that a first argument that's a valid signal number
-         (digits only -- no symbolic names) will be treated as a signal and
-         reverted back to the original handling disposition.  Fixes debian
-         complaints
-
-subst.c
-       - call MB_STRLEN instead of STRLEN where appropriate in
-         parameter_brace_expand_length to handle multibyte characters properly
-       - call MB_STRLEN instead of strlen in verify_substring_values so that
-         negative substrings of strings with multibyte chars work properly
-
-                                   8/1
-                                   ---
-jobs.c
-       - describe_pid needs to write to stderr, not stdout (POSIX)
-       - start_job, since it's only used by builtins (fg/bg), needs to write
-         its output to stdout, not stderr (POSIX)
-
-sig.c
-       - add an `orig_flags' member to struct terminating_signal so the
-         original signal handling flags (SA_RESTART, etc.) can be preserved
-         on POSIX systems
-       - make sure to preserve the signal flags state in
-         initialize_terminating_signals and reset them for child processes
-         in reset_terminating_signals
-
-builtins/fc.def
-       - fixed an off-by-one error that caused `fc -l' to list one too many
-         history entries
-       - in posix mode, `fc' should not list any indication as to whether or
-         not history lines have been modified (POSIX)
-       - when in posix mode, the default editor for `fc' should be `ed' (POSIX)
-
-doc/bashref.texi
-       - updated the description of `trap' behavior when given a first
-         argument that is a valid signal number
-       - noted that `fc -l' won't indicate whether a history entry has been
-         modified if the shell is in posix mode
-
-builtins/command.def
-       - fixed bug: `command -v' is supposed to be silent if a command is not
-         found
-
-builtins/hash.def
-       - `hash' should print its `hash table empty' message to stderr
-
-lib/readline/misc.c
-       - back out 7/7 change to _rl_maybe_save_line; it breaks emacs-mode ^P
-
-general.c
-       - changed base_pathname so that it will return reasonable results for
-         non-absolute pathnames -- this is what is intended by all of its
-         callers
-
-arrayfunc.c
-       - fix array_variable_part to return NULL if it finds an invisible
-         variable in the hash table.  Fixes seg fault caused by referring to
-         unset local variable using array notation
-
-{locale,variables}.c
-       - support LC_TIME as a special locale variable so HISTTIMEFORMAT tracks
-         the current locale
-
-                                   8/2
-                                   ---
-variables.c
-       - fixed small memory leak in makunbound() when a local array variable
-         is unset.  Fix from William Park
-
-lib/readline/display.c
-       - fixed a problem when computing the number of invisible characters on
-         the first line of a prompt whose length exceeds the screen width
-         (should only happen when invisible characters occur after the
-         line wrap).  Bug reported by agriffis@gentoo.org
-
-builtins/command.def
-       - `command -V' passes a new flag, CDESC_ABSPATH, which means to convert
-         to an absolute path
-
-builtins/type.def
-       - in posix mode, `type' and `command -v/-V' should not report
-         non-executable files, even if the execution code will attempt to
-         run them.  Other posix shells do this
-
-doc/bashref.texi
-       - add note to POSIX Mode section describing behavior of type and command
-         when finding a non-executable file
-
-execute_cmd.c
-       - force extended_glob to 1 before calling binary_test in
-         execute_cond_node so that the right extended pattern matching gets
-         performed
-
-                                   8/3
-                                   ---
-braces.c
-       - make sure lhs[0] and rhs[0] are cast to `unsigned char' so chars
-         with values > 128 are handled correctly
-
-builtins/printf.def
-       - change bexpand() and printstr() to handle strings with a leading
-         '\0' whose length is non-zero, since that's valid input for the
-         `%b' format specifier
-
-subst.c
-       - fix a couple of instances of find_variable that didn't check the
-         result for an invisible variable
-
-variables.c
-       - BASH_ARGC, BASH_ARGV, BASH_SOURCE, BASH_LINENO no longer created as
-         invisible vars
-
-pcomplete.c
-       - make sure COMP_WORDS is not invisible when bind_comp_words returns
-       - ditto for COMPREPLY in gen_shell_function_matches
-
-                                   8/4
-                                   ---
-braces.c
-       - fix problem where ${ was ignored but did not increment the open
-         brace count.  Bug reported by Tim Waugh <twaugh@redhat.com>
-
-variables.c
-       - if make_local_variable finds a variable in the correct context in
-         the right variable scope, make sure it's not invisible before
-         returning it
-
-                                   8/5
-                                   ---
-builtins/trap.def
-       - fixed usage message to show `action' as not optional, though it
-         actually is when not in posix mode (for a single argument)
-
-                                   8/7
-                                   ---
-configure.in
-       - kfreebsd-gnu has had its sbrk() problems fixed, and no longer needs
-         to be configured --without-gnu-malloc
-
-lib/readline/vi_mode.c
-       - in rl_vi_search, free any saved history line before starting the
-         search, so failure leaves you at that line, not the last line in
-         the history (assuming the current line is not the last history line).
-         Fix from llattanzi@apple.com to replace fix of 7/7
-
-                                   8/9
-                                   ---
-support/Makefile.in
-       - renamed `mostly-clean' target to `mostlyclean'
-
-                                  8/11
-                                  ----
-lib/readline/vi_mode.c
-       - make same change for EOL in multibyte character case of
-         rl_vi_change_char
-
-                                  8/12
-                                  ----
-subst.c
-       - in verify_substring_values, fix off-by-one error checking bounds of
-         `offset', esp. in array values (e.g., getting the highest element
-         of an array)
-
-                                  8/16
-                                  ----
-aclocal.m4
-       - change BASH_CHECK_DEV_FD to make sure that file descriptors > 2 are
-         accessible via /dev/fd, unlike FreeBSD 5.x
-
-lib/sh/strftime.c
-       - make sure `zone' is initialized with gettimeofday before it is used
-       - work around HPUX lack of `altzone' and differing definitions of
-         `timezone'
-
-lib/malloc/malloc.c
-       - internal_memalign and memalign now take a `size_t' as their first
-         argument, which seems to be the prevailing standard
-
-lib/malloc/{malloc.c,shmalloc.h}
-       - change sh_memalign to take a `size_t' as its first argument
-
-builtins/echo.def
-       - if posixly_correct and xpg_echo are both set, don't try to interpret
-         any arguments at all, as POSIX/XOPEN requires (fix inspired by Paul
-         Eggert)
-
-doc/bashref.texi
-       - amend description of bash posix mode to include new echo behavior
-
-builtins/fg_bg.def
-       - allow bg to take multiple job arguments, as posix seems to specify,
-         placing them all in the background, returning the status of the last
-         one as the status of `bg'
-
-lib/readline/vi_mode
-       - fix _rl_vi_change_mbchar_case (multibyte-char version of `~'
-         command) to have the right behavior at EOL -- handle case where vi
-         mode backs up at the end of the line
-
-                                  8/18
-                                  ----
-array.c
-       - check for an empty array in array_rshift before shifting elements
-         and adjusting max_index
-       - check for null array in array_subrange
-
-jobs.c
-       - fix raw_job_exit_status to not ignore exit status of the last
-         process in the pipeline when `set -o pipefail' is enabled
-
-                                  8/19
-                                  ----
-lib/readline/mbutil.c
-       - make sure _rl_find_next_mbchar_internal has a valid multibyte
-         character before it checks whether or not it's a zero-width
-         wide character and adjusts point accordingly
-
-                                  8/24
-                                   ----
-bashline.c
-        - new function, bash_directory_expansion, duplicates the expansions
-          performed on the directory name by rl_filename_completion_function
-        - call bash_directory_expansion in command_word_completion_function
-          if we decide we're doing tilde expansion (and any other
-          canonicalization) on the directory name being completed
-
-                                   8/25
-                                   ----
-configure.in
-        - use new-style AC_CHECK_HEADER to check for sys/ptem.h (which requires
-          sys/stream.h).  The correct checks are in the code, but autoconf
-          complains if sys/stream.h is not included, rather than simply
-          checking for the header's presence
-
-                                  8/26
-                                  ----
-builtins/hash.def
-       - fix a bug that prevented `hash -d' from working right (as soon as
-         hash removed a command from the table, the bug caused it to be added
-         right back)
-
-                                  8/27
-                                  ----
-doc/{bash.1,bashref.texi}
-       - explicitly note that conditional primaries that operate on files
-         operate on the targets of symbolic links rather than the links
-         themselves
-
-                                  8/30
-                                  ----
-lib/readline/display.c
-       - fix multibyte calculation of `physchars' in prompt expansion, to
-         handle double-width multibyte characters correctly
-       - changes to rl_redisplay to handle prompts longer than the screenwidth
-         that might contain double-width multibyte characters.  Fixes from
-         Tomohiro Kubota
-
-                                   9/6
-                                   ---
-subst.c
-       - change word_list_split to avoid really bad behavior caused by calling
-         list_append for each split word -- as the list gets long, you have
-         to traverse it every time.  Keep a pointer to the end of the list and
-         and just tack onto it
-
-                                   9/8
-                                   ---
-lib/readline/complete.c
-       - change fnprint to calculate the displayed width of a filename in
-         the same way as fnwidth
-
-subst.c
-       - in verify_substring_values, when expanding ${array[@]:offset}, make
-         sure negative offsets count from one greater than the array's
-         maximum index so things like ${x[@}: -1} work to give the last element
-         (requires fixing array tests)
-
-builtins/common.c
-       - new error function, sh_wrerror(),  for builtins to call when a write
-         error occurs
-
-builtins/common.h
-       - extern declaration for sh_wrerror()
-
-builtins/cd.def
-       - change builtin_error call to use sh_wrerror()
-
-builtins/echo.def
-       - report write errors with sh_wrerror() instead of just returning
-         failure
-
-builtins/printf.def
-       - change printstr to return failure (-1) or success (0) indication
-         rather than void
-       - report write errors when printstr() fails, return failure
-       - if any of the PF/printf calls fail, report write error and return
-         failure
-
-execute_cmd.c
-       - change execute_in_subshell so the subshell command inherits the
-         command timing flags from the enclosing COMMAND *
-
-                                  9/11
-                                  ----
-[prayers for the victims of 9/11/2001]
-
-lib/sh/strnlen.c
-       - new file, implementation of GNU libc extension function strnlen
-
-lib/sh/Makefile.in, {config.h,configure,Makefile}.in, MANIFEST
-       - changes for strnlen
-
-configure.in
-       - version changed to 3.1-devel
-
-doc/bash.1, lib/readline/doc/rluser.texi
-       - added description of `-o plusdirs' to complete/compgen (thanks,
-         Arnold)
-
-parse.y
-       - new parser_state flag, PST_ASSIGNOK, if set indicates we're parsing
-         arguments to a builtin that accepts assignment statement arguments
-       - turn on PST_ASSIGNOK in read_token_word when appropriate
-       - turn off PST_ASSIGNOK in read_token when appropriate
-       - don't attempt to parse a compound assignment specially unless we're
-         in a position where an assignment statement is acceptable, or
-         PST_ASSIGNOK is set
-
-                                  9/13
-                                  ----
-variables.c
-       - make BASH_ARGC, BASH_ARGV, BASH_LINENO, and BASH_SOURCE
-         non-unsettable, since the shell uses those values internally
-
-expr.c
-       - make exponentiation right-associative, as is apparently correct
-
-                                  9/16
-                                  ----
-arrayfunc.c
-       - make sure convert_var_to_array marks the environment as needing
-         recreation if the converted variable was exported
-
-                                  9/17
-                                  ----
-braces.c
-       - mark ${ as introducing an additional level of braces only if it's
-         not in a quoted string -- quoted strings are handled before brace
-         matching is done
-
-parse.y
-       - fixed an obscure problem in history_delimiting_chars where the `in'
-         in a case statement could have a semicolon added after it, if the
-         `case word' was on a previous line
-
-support/config.guess
-       - support for newest versions of tandem non-stop kernel
-
-lib/readline/display.c
-       - in compute_lcd_of_matches, explicitly cast `text' to `char *' before
-         passing it to rl_filename_dequoting_function
-
-lib/readline/terminal.c
-       - bind the key sequence sent by the keypad `delete' key to delete-char
-         (same as ^D in emacs mode)
-
-builtins/ulimit.def
-       - in print_all_limits, don't print anything if get_limit returns
-         -1/EINVAL, indicating that the kernel doesn't support that particular
-         limit
-       - add -i (max number of pending signals), -q (max size of posix msg
-         queues), -x (max number of file locks) for systems (Linux) that
-         support them
-
-doc/{bash.1,bashref.texi}
-       - fix description of correspondence between FUNCNAME, BASH_LINENO,
-         and BASH_SOURCE indices in description of BASH_LINENO
-
-                                  9/18
-                                  ----
-lib/sh/shquote.c
-       - don't quote CTLESC and CTLNUL with CTLESC in sh_backslash_quote, as
-         long as the resultant string never gets sent to the word expansion
-         functions without going through the shell parser
-
-externs.h
-       - add extern declarations for strnlen and strpbkrk from lib/sh
-
-subst.[ch]
-       - changes to handle case where IFS consists of multibyte characters.
-         Changed: string_extract_verbatim, split_at_delims,
-         string_list_dollar_star, string_list_dollar_at, list_string,
-         get_word_from_string, setifs
-
-                                  9/19
-                                  ----
-mailcheck.c
-       - change file_mod_date_changed to reset the cached mail file data if
-         the file size drops to zero
-
-lib/readline/complete.c
-       - change append_to_match so that a non-zero value for
-         rl_completion_suppress_append will cause no `/' to be appended to a
-         directory name
-
-bashline.c
-       - experimental change to suppress appending a slash for a completed
-         filename that is found in PATH as well as a directory in the current
-         directory under certain circumstances:  a single instance found in
-         $PATH when `.' is not in $PATH, and multiple instances found in the
-         $PATH, even when `.' is in the $PATH
-
-                                  9/24
-                                  ----
-command.h
-       - new word flag: W_ASSIGNRHS, means word is rhs of assignment statement
-       - new word flag: W_NOTILDE, means word is not to be tilde expanded
-       - new word flag (internal): W_ITILDE, means the next character is a
-         tilde that should be expanded
-
-general.c
-       - new set of tilde suffixes for use when parsing the RHS of an
-         assignment statement and =~ should not be subject to tilde expansion
-       - if ASSIGN_P argument to bash_tilde_expand is 2, use tilde prefixes
-         for parsing RHS of assignment statement
-
-general.[ch]
-       - new function bash_tilde_find_word, drop-in replacement for
-         tilde_find_word
-
-subst.c
-       - call bash_tilde_expand with secord argument of 2 when expanding rhs
-         of an assignment statement, so tildes after second and subsequent
-         `=' in an assignment are not expanded
-       - new function, expand_string_assignment, to expand the rhs of an
-         assignment statement
-       - add `~' to EXP_CHAR, the characters that will cause the word
-         expansion functions to be called
-       - move tilde expansion into expand_word_internal instead of many
-         different calls to bash_tilde_expand scattered across different
-         functions.  NOTE:  This means that double quotes surrounding a
-         {paramOPword} expansion will cause tilde expansion to NOT be
-         performed on `word'.  I think this is right, what POSIX specifies,
-         and consistent with the behavior of other characters in the rhs
-
-execute_cmd.c
-       - take out calls to bash_tilde_expand before calling word expansion
-         functions
-
-                                  9/26
-                                  ----
-execute_cmd.c
-       - make sure to call UNBLOCK_CHILD before returning on a pipe creation
-         failure in execute_pipeline
-
-                                  9/27
-                                  ----
-variables.c
-       - change get_bash_command to deal with the_printed_command_except_trap
-         being NULL
-
-execute_cmd.c
-       - fix execute_simple_command to deal with the_printed_command being
-         NULL when assigning to the_printed_command_except_trap -- fixes
-         seg fault in savestring()
-
-parse.y
-       - change the parser so that the closing `)' in a compound variable
-         assignment delimits a token -- ksh93 does it this way
-
-doc/{bash.1,bashref.texi}
-       - change description of tilde expansion to note that expansion is
-         attempted only after the first =~ in an assignment statement
-
-builtins/declare.def
-       - when assigning to an array variable with declare -a x=(...), make
-         sure the last character in the rhs  of the variable assignment is
-         `)', not just that it appears somewhere
-
-                                  9/28
-                                  ----
-command.h
-       - add a `W_NOEXPAND' flag to inhibit all expansion except quote removal
-       - add a `W_COMPASSIGN' flag to denote a word is a compound assignment
-         statement
-
-parse.y
-       - set W_COMPASSIGN on words that appear to be compound assignments
-
-subst.c
-       - pass W_NOXPAND and W_COMPASSIGN through end of expand_word_internal
-
-subst.[ch]
-       - new function, expand_assignment_string_to_string, calls
-         expand_string_assignment and then string_list on the result
-
-variables.c
-       - assign_in_env now calls expand_assignment_string_to_string
-
-                                  9/30
-                                  ----
-builtins/common.c
-       - change get_job_spec so the null job `%' once again means the current
-         job
-
-                                  10/1
-                                  ----
-subst.c
-       - do_assignment_internal now takes a WORD_DESC * as its first
-         argument, and uses its `word' member as the assignment string
-       - change expand_word_list_internal to call do_word_assignment instead
-         of do_assignment, passing it `word' instead of, e.g., `word->word'
-       - change extract_array_assignment_list to just return the passed
-         string minus a trailing `)' if the last character is a right
-         paren
-       - change do_assignment_internal to call extract_array_assignment_list
-
-subst.[ch]
-       - change do_assignment and do_assignment_no_expand to take a `char *'
-         instead of `const char *' first argument; change extern prototypes
-       - new function, do_word_assignment, takes a WORD_DESC * and calls
-         do_assignment_internal on it; add extern declaration with prototype
-
-general.h
-       - new typedef, sh_wassign_func_t, like sh_assign_func_t but takes a
-         WORD_DESC * as its first argument
-
-variables.[ch]
-       - assign_in_env now takes a WORD_DESC * as its first argument
-
-                                  10/2
-                                  ----
-command.h
-       - new word flag, W_ASSNBLTIN, denotes that the word is a builtin
-         command (in a command position) that takes assignment statements
-         as arguments, like `declare'
-       - new word flags, W_ASSIGNARG, denotes that word is an assignment
-         statement given as argument to assignment builtin
-
-execute_cmd.c
-       - set W_ASSNBLTIN flag in fix_assignment_words if necessary (if there
-         are any arguments that are assignment statements)
-       - set W_ASSIGNARG flag in fix_assignment_words if necessary
-
-subst.c
-       - new function, do_compound_assignment, encapsulates the necessary
-         code to perform a compound array assignment (including creation of
-         local variables); called from do_assignment_internal
-       - to fix the double-expansion problem with compound array assignments
-         that are arguments to builtins like `declare', changed
-         shell_expand_word_list to treat those arguments like assignment
-         statements (with proper creation of local variables inside shell
-         functions) and pass the attribute-setting portion of the statement
-         onto the builtin.  This is what ksh93 appears to do, from inspection
-         of the `ksh93 -x' output
-
-execute_cmd.c
-       - fix execute_simple_command:  in case of pipeline or async command,
-         when forking early, set `subshell_environment' so that it can contain
-         both SUBSHELL_PIPE and SUBSHELL_ASYNC -- the two should not be
-         mutually exclusive.  Fixes bug reported by pierre.humblet@ieee.org
-       - remove references to last_pid, old_command_subst_pid; use NO_PID as
-         a sentinel value to decide whether or not a child process has been
-         created and needs to be waited for.  Submitted by
-         pierre.humblet@ieee.org to fix recycling-pid problem on cygwin
-
-doc/{bash.1,bashref.texi}
-       - fixed documentation of `@(pattern)' extended globbing operator --
-         it succeeds if the string matches one of the patterns, not exactly
-         one.  This is what ksh93 does, too
-
-lib/readline/complete.c
-       - fixed rl_menu_complete so that a negative argument cycles backwards
-         through the list
-
-                                  10/3
-                                  ----
-subst.c
-       - use W_COMPASSIGN flag in do_assignment_internal instead of deciding
-         lexically which assignments are compound array assignments
-
-                                  10/6
-                                  ----
-support/shobj-conf
-       - additions for System V.5 from Boyd Gerber <gerberb@zenez.com>
-
-subst.c
-       - in command_substitute, if subshell_environment includes
-         SUBSHELL_ASYNC, call make_child with the `async_p' argument set to
-         non-zero.  This keeps command substitutions for async commands or
-         pipelines from trying to give the terminal back to the shell's
-         pgrp.  make sure to save and restore last_asynchronous_pid.  Fix
-         suggested by <pierre.humblet@ieee.org>
-
-                                  10/7
-                                  ----
-config.h.in
-       - add a placeholder definition for WCONTINUED_BROKEN
-
-                                  10/9
-                                  ----
-aclocal.m4
-       - add BASH_CHECK_WCONTINUED, checks for glibc bug where WCONTINUED is
-         defined but rejected as invalid by waitpid(2)
-
-configure.in
-       - add call to BASH_CHECK_WCONTINUED, defines WCONTINUED_BROKEN
-
-redir.c
-       - experimental change to add_undo_redirect to save manipulations to
-         file descriptors >= SHELL_FD_BASE (10) on the list of redirections
-         to be undone even if `exec' causes the list to be discarded
-
-doc/{bash.1,bashref.texi}
-       - note that redirections using file descriptors > 9 should be used
-         carefully, because they might conflict with file descriptors the
-         shell uses internally
-
-                                  10/11
-                                  -----
-parse.y
-       - fix pipeline_command production to handle case where `pipeline'
-         as `argument' of `!' or `time' is null (e.g., a syntax error not
-         handled by the grammar)
-
-                                  10/13
-                                  -----
-lib/readline/readline.c
-       - new internal variable, _rl_bind_stty_chars; if non-zero, bind the
-         terminal special characters to readline equivalents at startup
-       - change readline_default_bindings() and reset_default_bindings() to
-         understand _rl_bind_stty_chars
-
-lib/readline/rlprivate.h
-       - new extern declaration for _rl_bind_stty_chars
-
-lib/readline/rltty.c
-       - change rl_prep_terminal to add support for _rl_bind_stty_chars
-
-                                  10/15
-                                  -----
-lib/readline/bind.c
-       - new bindable variable, `bind-tty-special-chars', bound to value of
-         _rl_bind_stty_chars
-
-doc/bash.1,lib/readline/doc/{readline.3,rluser.texi}
-       - documented new readline variable `bind-tty-special-chars'
-
-builtins/pushd.def
-       - make the first check for option `--' skip the rest of option
-         checking
-
-                                  10/16
-                                  -----
-lib/readline/shell.c
-       - change sh_set_lines_and_columns to prefer setenv, which has
-         predictable memory allocation behavior, to putenv, which does not
-
-                                  10/19
-                                  -----
-variables.c
-       - change push_exported_var so that a tempenv variable has to have the
-         export attribute set (which they all do -- something to look at) and
-         the `propagate' attribute set to be propagated down to the next
-         scope
-
-execute_cmd.c
-       - change execute_builtin so that if CMD_COMMAND_BUILTIN is set in the
-         passed flags argument, call pop_scope with a value that says the
-         builtin is not special, since `command' means that preceding variable
-         assignments don't persist in the environment.  Fixes problem with
-         variable assignments preceding command preceding special builtin
-         keeping those variable assignments around (when in posix mode)
-
-                                  10/20
-                                  -----
-lib/sh/shquote.c
-       - new function, sh_mkdoublequoted, brackets a given string with
-         double quotes and returns a new string.  Flags argument, if non-
-         zero, means to quote embedded double quotes with backslashes
-
-externs.h
-       - new extern declaration for sh_mkdoublequoted
-
-parse.y
-       - use sh_mkdoublequoted after calling localeexpand()
-
-lib/sh/strtrans.c
-       - change ansicstr to understand that  (flags & 4) != 0 means to remove
-         backslash from unrecognized escape sequences
-
-general.c
-       - fix logic problem in assignment() that caused non-variable-starter
-         characters to be allowed, resulting in things like `1=xxx' creating
-         a variable `1' in the hash table
-
-                                  10/21
-                                  -----
-bashline.c
-       - don't call programmable_completions with an assignment statement
-         argument
-
-                                  10/22
-                                  -----
-lib/readline/rltty.c
-       - in prepare_terminal_settings, turn echoing on (readline_echoing_p)
-         if get_tty_settings fails because the input is not a terminal
-
-                                  10/24
-                                  -----
-lib/readline/util.c
-       - include rlmbutil.h for multibyte definitions
-       - new function, _rl_walphabetic, wide char version of rl_alphabetic
-
-lib/readline/mbutil.c
-       - new function, _rl_char_value(buf, ind), returns value of (possibly
-         multibyte) character at buf[ind]
-
-lib/readline/rlmbutil.h
-       - extern defines for _rl_walphabetic and _rl_char_value for when
-         multibyte chars are not being used
-       - new wrapper definitions for _rl_find_next_mbchar (MB_NEXTCHAR) and
-         _rl_find_prev_mbchar (MB_PREVCHAR) that try to avoid unneeded
-         function calls
-
-lib/readline/text.c
-       - fix rl_foward_word to work with multibyte characters (or in a
-         multibyte locale) using above utility functions
-       - fix rl_backward_word to work with multibyte characters (or in a
-         multibyte locale) using above utility functions
-
-                                  10/26
-                                  -----
-parse.y
-       - fix parse_matched_pair so that it doesn't swallow \<newline> when
-         parsing a $'...' construct (call shell_getc with different arg)
-
-                                  10/28
-                                  -----
-lib/glob/glob.c
-       - after some (compiled-in) threshold, glob_vector will stop using
-         alloca to allocate `struct globval's and will switch to using
-         malloc, with appropriate cleanup before returning
-
-subst.c
-       - don't expand tildes after `=' in expand_word_internal, even if the
-         W_TILDEEXP flag is set, unless it's the first tilde in a word
-         marked W_ASSIGNMENT
-
-                                  10/31
-                                  -----
-lib/readline/text.c
-       - make sure rl_point doesn't go below 0 in rl_delete_horizontal_space
-         (from SUSE, but not sent in)
-
-shell.c
-       - make sure shell_is_restricted skips over a single leading `-' in
-         the shell name (from SUSE, but not sent in)
-
-lib/readline/display.c
-       - disable `fast redisplay' at the end of the line if in a locale that
-         supports multibyte characters (from SUSE, but not sent in)
-
-lib/readline/histexpand.c
-       - fix a problem with finding the delimiter of a `?' substring when
-         compiled for multibyte characters (from SUSE, but not sent in)
-
-                                  11/1
-                                  ----
-lib/readline/display.c
-       - correct some assignments to _rl_last_c_pos:  when in a multibyte
-         locale, it's used as an absolute cursor position; when not using
-         multibyte characters, it's a buffer offset.  I should have caught
-         this when the multibyte character support was donated
-
-                                  11/5
-                                  ----
-general.c
-       - change `assignment()' to accept `+=' assignment operator
-
-arrayfunc.[ch]
-       - bind_array_variable and assign_array_element both take a new `flags'
-         argument
-       - assign_array_var_from_string, assign_array_from_string, and
-         assign_array_var_from_word_list now all take a new `flags' argument
-       - change assign_array_var_from_word_list to understand how to append
-         to an array variable
-       - change assign_array_var_from_string to understand how to append
-         to an array variable.  It does not unset the previous value if
-         appending, allowing both old values to be changed and new ones to
-         be added
-
-subst.h
-       - new flag #defines to use for evaluating assignment statements
-
-{subst,variables}.c, builtins/{declare,read}.def
-       - change callers of assign_array_element and bind_array_variable
-       - change do_compound_assignment to understand assignment flags
-       - change do_assignment_internal to set assignment flags and pass them
-         to underlying functions
-
-pcomplete.c,builtins/{declare,read}.def
-       - fix callers of assign_array_var_from_string, assign_array_var_from_word_list
-
-variables.[ch]
-       - make_variable_value now takes a new `flags' argument
-       - make_variable_value now understands how to append to a particular
-         variable, using the old value
-       - bind_variable_value now takes a new `flags' argument
-       - change make_variable_value to understand ASS_APPEND flag
-       - bind_variable now takes a new `flags' argument
-       - bind_variable_internal now takes a new `flags' argument
-
-arrayfunc.c
-       - change callers of make_variable_value to add flags arg
-
-builtins/declare.def
-       - change callers of bind_variable_value to add flags arg
-
-{execute_cmd,mailcheck,pcomplete,shell,subst,variables}.c,parse.y
-builtins/{cd,command,declare,getopts,read,set,setattr}.def
-       - change callers of bind_variable to add flags arg
-
-variables.c
-       - change callers of bind_variable_internal
-       - change bind_variable_internal to pass assignment flags on to
-         make_variable_value
-       - change assign_in_env to treat `var+=value' like `var=value'
-
-arrayfunc.c
-       - break code that actually constructs the new value and assigns it
-         to a particular array index out into a new functions:
-         bind_array_var_internal.  This fakes out make_variable_value by
-         passing a dummy SHELL_VAR * so it can do proper appending and other
-         += processing
-       - changes to assign_array_var_from_string to accept and process as if
-         they were `standalone' assignment statements array assignment words
-         of the form [ind]+=val
-
-                                  11/7
-                                  ----
-builtins/declare.def
-       - added support for `declare [flags] var+=value'.  `Flags' are applied
-         before the assignment is performed, which has implications for things
-         like `-i' -- if -i is supplied, arithmetic evaluation and increment
-         will be performed
-
-builtins/setattr.def
-       - add support for `+=' assignment for rest of `assignment builtins':
-         export, readonly
-
-                                  11/12
-                                  -----
-lib/readline/display.c
-       - make sure prompt_physical_chars and prompt_invis_chars_first_line
-         are reset to 0 if the prompt string passed to rl_expand_prompt is
-         NULL or empty
-
-                                  11/14
-                                  -----
-{configure,config.h}.in
-       - check for `raise', define HAVE_RAISE if available
-
-lib/intl/dcigettext.c
-       - make sure `raise' is defined if HAVE_RAISE is not before
-         eval-plurah.h is included
-
-lib/malloc/trace.c
-       - put extern declaration for imalloc_fopen inside the MALLOC_TRACE
-         #ifdef
-
-                                  11/16
-                                  -----
-lib/intl/Makefile.in
-       - make sure SHELL is defined to cpp
-
-lib/intl/dcigettext.c
-       - make sure we use getcwd() even if HAVE_GETCWD is not defined after
-         including config.h; if SHELL is defined, #define HAVE_GETCWD
-
-                                  11/18
-                                  -----
-trap.[ch]
-       - new function, int signal_in_progress(int sig), returns TRUE if the
-         trap handler for signal SIG is currently executing
-
-                                  11/19
-                                  -----
-redir.c
-       - slightly change do_redirection_internal to set the close-on-exec
-         flag for file descriptors > 2 used to save file descriptors < 2
-         using explicit redirections (e.g., `exec 3>&1').  This keeps file
-         descriptors pointing to pipes from being left open but doesn't
-         change the shell's file descriptor semantics
-
-                                  11/20
-                                  -----
-doc/{bash.1,bashref.texi}
-       - correct some minor typos, forwarded from doko@debian.org
-
-                                  11/22
-                                  -----
-doc/bash.1,lib/readline/doc/{readline.3,rluser.texi}
-       - documented detail that yank-last-arg and yank-nth-arg use the history
-         arg expansion code (and, as a result, are subject to restrictions
-         of the history-comment character)
-
-                                  11/23
-                                  -----
-execute_cmd.c
-       - changes so that BASH_COMMAND preserves its value into a DEBUG trap:
-         for commands, arithmetic for command expressions, select commands,
-         case commands, (( commands, [[ commands, simple commands
-
-                                  11/24
-                                  -----
-doc/{bash.1,bashref.texi}
-       - changed description of `set' builtin slightly so that it is clear
-         that only variables are displayed in posix mode and that read-only
-         variables can't be reset by simply sourcing the output of `set'
-
-lib/sh/strftime.c
-       - don't try to redefine `inline' if it's already defined
-
-                                  11/26
-                                  -----
-execute_cmd.c
-       - fix execute_function to check funcname_a after function execution,
-         since FUNCNAME can be changed or unset within a function
-
-                                  11/27
-                                  -----
-builtins/evalfile.c
-       - make same changes as 11/26, this time to _evalfile
-
-execute_cmd.c
-       - change execute_function to run the return trap after a function
-         completes execution even if the shell is compiled without DEBUGGER
-         defined
-
-trap.c
-       - change reset_or_restore_signal_handlers so that the RETURN trap is
-         not inherited by command substitution when DEBUGGER is not defined
-
-                                  11/30
-                                  -----
-lib/readline/misc.c
-       - fix memory leaks in _rl_free_history_entry and rl_maybe_replace_line
-         caused by not freeing `timestamp' member of history entry
-       - make sure timestamp is initialized to NULL in rl_maybe_save_line
-
-                                  12/1
-                                  ----
-execute_cmd.c
-       - fix execute_function so a function calling `return' will run the
-         RETURN trap, if one's defined
-
-doc/{bash.1,bashref.texi}
-       - fix description of RETURN trap in various places to indicate that it's
-         only inherited by shell functions if function tracing is on globally
-         or has been enabled for that function
-       - fix documentation to indicate that the DEBUG and RETURN traps are
-         inherited under the same conditions
-
-execute_cmd.c
-       - a function does not inherit the RETURN trap if a DEBUG trap is
-         currently running
-
-                                  12/2
-                                  ----
-lib/glob/xmbsrtowcs.c
-       - change xmbsrtowcs to handle the one case where malloc can fail
-         (though it should not matter) -- don't try to free a null pointer
-
-                                  12/9
-                                  ----
-subst.c
-       - fix get_var_and_type to handle var[@], where `var' is a scalar
-         variable, identically to var -- all calling expansions can now
-         handle var[@] like var.  Bug reported by agriffis@gentoo.org
-
-                                  12/10
-                                  -----
-lib/readline/bind.c
-       - make new-style "\M-x" keybindings obey `convert-meta' settings
-         (bug reported by twaugh@redhat.com)
-
-                                  12/14
-                                  -----
-builtins/set.def
-       - added description of `-' option to help text
-
-builtins/shopt.def
-       - fix bug that caused `gnu_errfmt' to not be compiled in unless
-         READLINE is defined
-
-                                  12/16
-                                  -----
-subst.c
-       - fixed a typo in string_extract_verbatim in first call to MBLEN
-         (used `slen - 1' instead of `slen - i')
-
-                                  12/17
-                                  -----
-subst.c
-       - avoid some calls to strlen if the value is only being used for
-         ADVANCE_CHAR and MB_CUR_MAX == 1 (since ADVANCE_CHAR doesn't need
-         it unless multibyte characters are possible)
-       - change string_extract_verbatim so it takes the length of the string
-         as a parameter, so we don't have to recompute the length of the same
-         string over and over again when doing word splitting (that kills if
-         it's a long string)
-
-                                  12/18
-                                  -----
-subst.c
-       - in string_list_dollar_star, make sure to null-terminate the
-         separator if the character is longer than one byte
-
-                                  12/22
-                                  -----
-doc/{bash.1,bashref.texi}
-       - changed text in quoting section explaining that double quotes do
-         not prevent history expansion from taking place, and that backslashes
-         escaping ! are not removed
-
-                                  12/28
-                                  -----
-shell.c
-       - set gnu_error_format to 1 if running under emacs.  This should allow
-         the emacs `next-error' stuff to work, at least for interactive shells
-
-parse.y
-       - change yy_stream_get to set interrupt_immediately before calling
-         getc_with_restart when the shell is interactive.  This avoids the
-         synchronization problem caused by the call to QUIT in read_a_line,
-         which results in the first character after a SIGINT/^C to be
-         dropped
-
-                                  12/30
-                                  -----
-builtins/mkbuiltins.c
-       - changes to write long documentation to arrays as a single string by
-         default, rather than an array of strings -- enabled by default
-       - new option, -S, to restore old behavior of writing multiple strings
-         for long documentation
-       - changes to avoid filenames written when the separate-filenames option
-         (-H) has been supplied being run through gettext
-
-configure.in
-       - new cofiguration option, --enable-single-help-strings (on by default),
-         causes help text to be stored as a single string (or smaller set than
-         one string per line)
-
-builtins/Makefile.in
-       - pass `-S' to mkbuiltins if single-help-strings is turned off
-
-doc/bashref.texi
-       - documented new `single-help-strings' configure option
-
-                                1/3/2005
-                                --------
-jobs.c
-       - make wait_for return a non-zero status if the job or processed
-         waited for is suspended.  Returns 128 + stop signal.  This fixes
-         the problem with `echo one && sleep 5 && echo two' displaying
-         `two' after the sleep is suspended
-
-                                   1/5
-                                   ---
-print_cmd.c
-       - change indirection_level_string so the code duplicates the first
-         character of $PS4 to indicate the indirection level, rather than
-         the first byte
-
-                                   1/8
-                                   ---
-variables.c
-       - new special variable hook function for COMP_WORDBREAKS; sets
-         rl_completer_word_break_characters back to NULL when the variable
-         is unset
-       - change bind_variable_value to understand dynamic variables with
-         assign_function set, and handle them correctly.  If the variable is
-         being appended to, use make_variable_value to create the new
-         value
-       - change bind_variable_internal to understand dynamic variables with
-         assign_function set, and handle them the same way
-       - RANDOM and LINENO now get the integer attribute, so appending works
-         as expected
-       - ditto for HISTCMD, MAILCHECK, OPTIND
-
-lib/readline/display.c
-       - change _rl_make_prompt_for_search to set prompt_physical_chars
-         appropriately
-       - rl_save_prompt and rl_restore_prompt save and restore
-         prompt_prefix_length
-       - change redraw_prompt to use rl_save_prompt and rl_restore_prompt
-       - change rl_restore_prompt to set the `save' variables back to
-         NULL/0 so code can check whether or not the prompt has been saved
-       - change rl_message and rl_clear_message to save and restore the
-         prompt if the caller has not already done it (using a simple
-         semaphore-like variable)
-       - change rl_message to call expand_prompt, so that local_prompt and
-         local_prompt prefix are set before calling the redisplay functions,
-         in case the prompt is longer than a screenwidth (fixes bug
-         reported to debian by epl@unimelb.edu.au)
-
-lib/readline/doc/rltech.texi
-       - make sure to note that rl_save_prompt should be called before
-         rl_message, and rl_restore_prompt before rl_clear_message
-
-pcomplete.c
-       - make sure to save and restore the parser state around the call to
-         execute_shell_function in gen_shell_function_matches.  Fixes bug
-         reported by a050106.1.keeLae3x@captaincrumb.com (cute)
-
-lib/readline/readline.c
-       - fix _rl_dispatch_subseq in the case where we're recursing back up
-         the chain (r == -2) and we encounter a key shadowed by a keymap,
-         but originally bound to self-insert.  Calling rl_dispatch with
-         ANYOTHERKEY as the first argument will call rl_insert, but with
-         ANYOTHERKEY (256) as the char to insert.  Use the shadow keymap
-         and set things up to dispatch to rl_insert with the shadowed key
-         as the argument.  Fixes the bug reported by Thomas Glanzmann
-         (sithglan@stud.uni-erlangen.de)
-
-                                  1/13
-                                  ----
-command.h
-       - new word flag: W_HASQUOTEDNULL
-
-make_cmd.c
-       - new function to allocate a WORD_DESC * without doing anything with a
-         containing string:  alloc_word_desc
-
-make_cmd.h
-       - extern declaration for alloc_word_desc
-
-dispose_cmd.c
-       - new function to just free a WORD_DESC * without freeing the contained
-         string:  dispose_word_desc
-
-dispose_cmd.h
-       - extern declaration for dispose_word_desc
-
-subst.c
-       - change some places to use alloc_word_desc
-       - make same changes to word_list_quote_removal as were made to
-         word_list_split
-       - set W_HASQUOTEDNULL when a word is created with w->word[0] ==
-         CTLNUL and w->word[1] == '\0'
-
-subst.c
-       - parameter_brace_expand_word now returns a WORD_DESC * -- changed
-         callers to understand
-       - parameter_brace_expand_indir now returns a WORD_DESC * -- changed
-         callers to understand
-       - parameter_brace_expand_rhs now returns a WORD_DESC * -- changed
-         callers to understand
-       - remove W_HASQUOTEDNULL from a word's flags when remove_quoted_nulls
-         is called on the word's enclosed string
-
-                                  1/15
-                                  ----
-subst.c
-       - param_expand now returns a WORD_DESC * -- changed callers to
-         understand
-       - parameter_brace_expand now returns a WORD_DESC * -- changed
-         callers to understand
-       - in expand_word_internal, only call remove_quoted_nulls after a word
-         is returned with W_HASQUOTEDNULL
-       - changes to pass W_HASQUOTEDNULL flag out of expand_word_internal;
-         changed callers to call remove_quoted_nulls only if return value has
-         W_HASQUOTEDNULL set.  This is a mostly-complete fix for the
-         long-standing CTLNUL confusion between a quoted null expansion and
-         the expansion of a variable with a literal '\177' in its value
-       - change string_list_dollar_at to compute the separator character the
-         same way as string_list_dollar_star:  using the already-computed
-         values generated in setifs()
-       - when expanding unquoted $*, if $IFS is empty, check whether or not
-         we're eventually going to split the results (e.g., on the rhs of an
-         assignment statement) and concatenate the positional parameters as
-         if the expansion were within double quotes if we're not going to
-         split
-
-tests/iquote.tests
-       - test cases based on old bug reports about the quoted-null vs. 0177
-         problem the recent code fixes
-
-                                  1/16
-                                  ----
-dispose_cmd.c
-       - set w->word to 0 before putting a WORD_DESC * back in the cache in
-         dispose_word_desc; changed callers to delete those assignments
-
-variables.c
-       - change assign_random and get_random_value so that the random number
-         generator only gets re-seeded once in a subshell environment, and
-         assigning a value to RANDOM counts as seeding the generator.  This
-         makes the sequences a little more predictable
-
-                                  1/20
-                                  ----
-lib/readline/history.c
-       - fix replace_history_entry, remove_history to return NULL if
-         passed index is < 0
-
-                                  1/22
-                                  ----
-lib/sh/netconn.c
-       - fix isnetconn() to understand that getpeername can return ENOTCONN
-         to indicate that an fd is not a socket
-
-configure.in
-       - set BUILD_DIR to contain backslashes to escape any spaces in the
-         directory name -- this is what make will accept in targets and
-         prerequisites, so it's better than trying to use double quotes
-       - set SIZE to the appropriate value if some cross-compiling tool
-         chain is being used; `size' by default (can be overridden by
-         SIZE environment variable)
-
-Makefile.in
-       - use $(SIZE) instead of size; set SIZE from configure
-
-                                  1/31
-                                  ----
-arrayfunc.c
-       - in array_value_internal, return NULL right away if the variable's
-         value is NULL, instead of passing a null string to add_string_to_list
-
-                                   2/1
-                                   ---
-jobs.h
-       - new struct to hold stats and counters for child processes and jobs
-       - change some uses of global and static variables to use members of
-         new struct (struct jobstats)
-
-                                   2/2
-                                   ---
-
-jobs.[ch]
-       - change PRUNNING to PALIVE
-       - new define INVALID_JOB
-       - new macro get_job_by_jid(ind), currently expands to jobs[ind]
-       - new define J_JOBSTATE, operates on a JOB * like JOBSTATE operates on
-         a job index
-       - new function, reset_job_indices, called from delete_job if
-         js.j_lastj or js.j_firstj are removed
-       - change various functions to keep counters and stats in struct jobstats
-
-pcomplete.c, builtins/common.c, builtins/{exit,fg_bg,jobs,kill,wait}.def
-       - change global variables (e.g., job_slots) to struct members
-         (e.g., js.j_jobslots)
-       - use INVALID_JOB define where appropriate
-       - use get_job_by_jid and J_JOBSTATE where appropriate
-
-trap.c
-       - change reset_or_restore_signal_handler to not free the exit trap
-         string if the function pointer is reset_signal, which is used when
-         the trap strings shouldn't be freed, like in command substitution
-
-                                   2/4
-                                   ---
-jobs.c
-       - new function, realloc_jobs_list, copies jobs array to newly-allocated
-         memory shrinking (or growing) size to have next multiple of JOB_SLOTS
-         greater than js.j_njobs
-       - change compact_jobs_list to just call reap_dead_jobs and then
-         realloc_jobs_list, simplifying it considerably
-       - discard_pipeline now returns `int':  the number of processes freed
-       - slightly changed the logic deciding whether or not to call
-         compact_jobs_list:  now non-interactive shells will compact the
-         list if it reaches MAX_JOBS_IN_ARRAY in size
-
-parse.y
-       - move test for backslash-newline after pop_string in shell_getc so
-         that things like
-
-               ((echo 5) \
-                (echo 6))
-
-         work right
-
-                                   2/8
-                                   ---
-jobs.h
-       - new structs for holding status of exited background processes, as
-         POSIX specifies
-       - new job flag: J_ASYNC
-
-jobs.c
-       - new functions to manipulate struct holding status of exited
-         background processes
-       - new members in struct jobstats to hold pointer to last created job
-         and last created asynchronous job
-       - initialize js.c_childmax in initialize_job_control
-       - if the `async' arg to stop_pipeline is non-null, set the J_ASYNC
-         flag in the job struct
-       - set js.j_last_made_job and js.j_last_asynchronous_job in
-         stop_pipeline
-       - new function: find_last_proc, returns the PROCESS * to the last proc
-         in a job's pipeline
-       - changed find_last_pid to call find_last_proc
-       - change delete_job to call bgp_add on the last proc of the job being
-         deleted
-       - change delete_all_jobs and wait_for_background_pids to call bgp_clear
-
-                                   2/9
-                                   ---
-jobs.c
-       - change wait_for_single_pid to look for pid in bgpids.list (using
-         bgp_search()) if find_pipeline returns NULL
-
-                                  2/10
-                                  ----
-support/shobj-conf
-       - change the solaris-gcc stanza so that it auto-selects the appropriate
-         options for ld depending on which `ld' gcc says it's going to run
-
-                                  2/11
-                                  ----
-jobs.h
-       - add support for PS_RECYCLED as a process state, add PRECYCLED macro
-         to test it.  Change PALIVE and PRUNNING macros to not count processes
-         in PS_RECYCLED state
-
-execute_cmd.c
-       - restore use of last_pid as sentinel value; use NO_PID as sentinel
-         only if RECYCLES_PIDS is defined
-
-jobs.c
-       - change find_job to return a pointer to the PROCESS the desired pid
-         belongs to, analogous to find_pipeline returning pointer to JOB
-       - change find_job callers to add extra argument
-       - change running_only arguments to find_pipeline and find_job to
-         alive_only, since we don't want recycled pids returned here and it
-         better describes the result
-       - new function find_process, calls find_pipeline and searches the
-         returned pipeline for the PROCESS * describing the desired pid
-       - in make_child, if fork() returns the same pid as the value of
-         last_asynchronous_pid when RECYCLES_PIDS is defined, avoid pid
-         aliasing by resetting last_asynchronous_pid to 1
-       - use PRUNNING instead of child->running, since we, for the most
-         part, don't want to consider recycled pids (e.g., in make_child())
-       - call find_process instead of find_pipeline in waitchld()
-       - use PEXITED(p) instead of testing p->running == PS_DONE
-       - in make_child, call bgp_delete to remove a just-created pid from the
-         last of saved pid statuses
-       - in add_process, check whether or not pid being added is already in
-         the_pipeline or the jobs list (using find_process) and mark it as
-         recycled if so
-       - This set of fixes mostly came from Pierre Humblet
-         <pierre.humblet@ieee.org> to fix pid aliasing and reuse problems on
-         cygwin
-
-variables.c
-       - set $_ from the environment if we get it there, set to $0 by
-         default if not in env
-
-doc/{bashref.texi,bash.1}
-       - a couple of clarifying changes to the description of $_ based on
-         comments from Glenn Morris <gmorris+mail@ast.cam.ac.uk>
-
-                                  2/15
-                                  ----
-shell.c
-       - use strstr instead of strmatch when checking whether $EMACS contains
-         `term' -- simpler and faster
-
-                                  2/18
-                                  ----
-builtins/cd.def
-       - implement posix requirement that `pwd -P' set $PWD to a directory
-         name containing no symlinks
-       - add new function, setpwd(), just sets (and changes exported value)
-         of PWD
-
-doc/bashref.texi
-       - add note to posix mode section about pwd -P setting $PWD
-
-doc{bash.1,bashref.texi}
-       - added note that BASH_ARGC and BASH_ARGV are only set in extended
-         debug mode
-       - expand description of extdebug option to include everything changed
-         by extended debug mode
-
-                                  2/19
-                                  ----
-pathexp.h
-       - new flag macro, FNMATCH_IGNCASE, evaluates to FNM_CASEFOLD if the
-         match_ignore_case variable is non-zero
-
-execute_cmd.c
-       - new variable, match_ignore_case
-       - change call to strmatch() in execute_case_command so it includes
-         FNMATCH_IGNCASE
-
-test.c
-       - change call to strmatch() in patcomp() so that pattern matching
-         calls for [[ ... ]] obey the match_ignore_case variable
-
-lib/sh/shmatch.c
-       - if match_ignore_case is set, enable REG_ICASE in the regexp match
-         flags
-
-builtins/shopt.def
-       - new settable option, `nocasematch', controls the match_ignore_case
-         variable.  Currently alters pattern matching for case and [[ ... ]]
-         commands (==, !=, and =~ operators)
-
-doc/{bashref.texi,bash.1}
-       - updated descriptions of [[ and case to include reference to
-         nocasematch option
-
-                                  2/22
-                                  ----
-builtins/mkbuiltins.c
-       - add `times' to the list of posix special builtins
-
-                                  2/23
-                                  ----
-builtins/cd.def
-       - posix mode no longer turns on effect of -P option on $PWD if a
-         directory is chosen from CDPATH
-
-doc/bashref.texi
-       - clarified that in posix mode, reserved words are not alias expanded
-         only in a reserved word context
-       - removed item about cd, $CDPATH, and -P from posix mode section
-
-                                  2/24
-                                  ----
-builtins/reserved.def
-       - minor cleanups to the description of `if'
-
-                                   3/2
-                                   ---
-subst.c
-       - change list_string and get_word_from_string to explicitly treat an
-         IFS character that is not space, tab, or newline *and any adjacent
-         IFS white space* as a single delimiter, as SUSv3/XPG6 says
-
-builtins/read.def
-       - check whether or not the number of fields is exactly the same as
-         the number of variables instead of just assigning the rest of the
-         line (minus any trailing IFS white space) to the last variable.
-         This parses a field and checks whether or not it consumes all of
-         the input (including any trailing field delimiters), falling back
-         to the previous behavior if it does not.  This is what POSIX.2
-         specifies, I believe (and the consensus of the austin-group list).
-         This requires a few tests in read.tests to be changed: backslashes
-         escaping IFS whitespace characters at the end of input cause the
-         whitespace characters to be preserved in the value assigned to the
-         variable, and the trailing non-whitespace field delimiter issue
-
-                                   3/7
-                                   ---
-configure.in
-       - add -D_POSIX_SOURCE to the LOCAL_CFLAGS for Interix
-
-                                   3/8
-                                   ---
-bashline.c
-       - make bash_directory_expansion a void function, since it doesn't have
-         any return value
-
-                                   3/9
-                                   ---
-builtins/read.def
-       - when testing for a pipe, use `fd' instead of hard-coding 0, since we
-         can read from other file descriptors now
-
-lib/sh/zread.c
-       - in zsyncfd, only set lind and lused to 0 if the lseek succeeds.
-         If the lseek fails, we might steal input from other programs, but
-         a failed lseek won't cause us to erroneously discard input
-
-                                  3/11
-                                  ----
-builtins/evalstring.c
-       - don't allow parse_and_execute to short-circuit and call exec() if
-         the command's return value is being inverted
-
-                                  3/15
-                                  ----
-builtins/printf.def
-       - new macro PC to call putchar and increment number of chars printed -
-         fixes bug in computation of value for %n format char
-       - `tw' is now a global var so printstr can modify it using PC()
-       - convert PF macro to use asprintf into a local buffer
-         Preparation for printf -v var
-       - add code to add the text printed to a `variable buffer' if -v option
-         supplied.  The buffer grows as needed
-       - printf now takes a `-v var' option to put the output into the variable
-         VAR rather than sending it to stdout.  It does not:
-               print partial output on error (e.g., format string error)
-               handle NULs in the variable value, as usual
-
-                                  3/16
-                                  ----
-parse.y
-       - fix bug in prompt string decoding that caused a core dump when PS1
-         contained \W and PWD was unset (null pointer deref)
-
-builtins/printf.def
-       - changed -v var behavior so it stores partial output into the named
-         variable upon an error
-
-                                  3/24
-                                  ----
-lib/readline/bind.c
-       - bool_to_int now takes a `const char *' argument
-
-support/{printenv,recho,zecho}.c
-       - include config.h
-       - include "bashansi.h" for appropriate extern function declarations
-
-configure.in
-       - on MacOS X 10.4, compensate for loader not allowing static library
-         to override existing system dynamic library when compiling -dynamic
-         (affects readline and history libraries); so use absolute pathname
-         instead of -lreadline as library name
-
-lib/glob/{glob,sm_loop,smatch}.c
-       - make sure to cast arguments to (char *)  or (unsigned char *) as
-         appropriate to avoid gcc4 warnings
-
-lib/glob/smatch.c
-       - collsym (single-byte version) now takes a (CHAR *) first argument to
-         match callers; cast argument to strncmp appropriately
-
-lib/sh/snprintf.c
-       - fix ldfallback and dfallback to handle width and precision specs in
-         the format passed to sprintf()
-       - fix STAR_ARGS macro to deal with negative field widths and precisions
-
-                                  3/25
-                                  ----
-builtins/printf.def
-       - since a negative precision in a "x.x[fFgGeE]" format specifier should
-         be allowed but treated as if the precision were missing, let it
-         through
-
-lib/sh/snprintf.c
-       - fix * code to deal with a negative precision by treating it as if
-         the `.' and any digit string in the precision had not been specified
-       - fix format parsing code to deal with a negative inline precision,
-         e.g., "%4.-4f" by treating it as if the `'. and any digit string in
-         the precision had not been specified
-       - a `+' in a format specifier should only act as a flag if it comes
-         before a `.' (otherwise it is ignored)
-
-lib/readline/vi_mode.c
-       - new function, rl_vi_rubout, to rl_rubout as rl_vi_delete is to
-         rl_delete; saves deleted text for possible reinsertion as with any
-         vi-mode `text modification' command (fixes problem with `X' reported
-         by beat.wieland@gmx.ch)
-
-lib/readline/vi_keymap.c
-       - bind `X' in vi command mode to rl_vi_rubout
-
-lib/readline/funmap.c
-       - add a bindable `vi-rubout' command, runs rl_vi_rubout
-
-lib/readline/text.c
-       - rewrote internals of _rl_rubout_char to make structure cleaner
-
-lib/readline/{complete,text}.c
-       - changed code to remove #ifdef HANDLE_MULTIBYTE where possible
-
-                                  3/28
-                                  ----
-lib/readline/examples/rl.c
-       - include <sys/stat.h> instead of posixstat.h if READLINE_LIBRARY not
-         defined
-
-subst.c
-       - fix mbstrlen to treat invalid multibyte sequences as sequences of
-         single-byte characters
-
-                                   4/8
-                                   ---
-configure.in
-       - default SIZE to `:' if cross-compiling and an appropriate size for
-         the target is not found
-
-                                  4/11
-                                  ----
-subst.c
-       - change match_upattern and match_wpattern to check whether or not the
-         supplied pattern matches anywhere in the supplied string, prefixing
-         and appending the pattern with `*' if necessary.  If it doesn't we
-         can short-circuit immediately rather than waste time doing up to
-         N-1 unsuccessful calls to strmatch/wcsmatch (which kills for long
-         strings, even if the pattern is short)
-
-                                  4/12
-                                  ----
-configure.in
-       - make sure the special case for MacOS X 10.4 only kicks in if the
-         `--with-installed-readline' option isn't supplied
-
-lib/readline/{callback,readline,signals}.c
-       - make sure rl_prep_term_function and rl_deprep_term_function aren't
-         dereferenced if NULL (as the documentation says)
-
-builtins/mkbuiltins.c
-       - don't bother with the special HAVE_BCOPY code; just use straight
-         assignments
-
-builtins/ulimit.def
-       - use _POSIX_PIPE_BUF in pipesize() if it's defined and PIPE_BUF is
-         not
-
-                                  4/13
-                                  ----
-execute_cmd.c
-       - add cm_function_def to the list of control structures for which
-         child processes are forked when pipes come in or out
-
-                                  4/14
-                                  ----
-builtins/read.def
-       - make sure the ^As added for internal quoting are not counted as
-         characters read when -n is supplied
-
-                                  4/20
-                                  ----
-redir.c
-       - fix redir_open so that the repeat open on failure that AFS support
-         adds restores the correct value of errno for any error message
-
-                                  4/26
-                                  ----
-
-Makefile.in
-       - make sure mksignames and mksyntax are invoked with the $(EXEEXT)
-         extension
-
-                                  4/28
-                                  ----
-lib/readline/readline.h
-       - new state variable: RL_STATE_CALLBACK, means readline is using the
-         callback interface
-
-lib/readline/callback.c
-       - set RL_STATE_CALLBACK in rl_callback_handler_install, unset in
-         rl_callback_handler_remove
-
-                                  4/29
-                                  ----
-config-top.h
-       - DONT_REPORT_SIGPIPE is now on by default, since it apparently
-         interferes with scripts
-
-configure.in
-       - arrange things so PGRP_PIPE is defined on Linux-2.4+ and version 3
-         kernels (ones that apparently schedule children to run before their
-         parent)
-
-                                  4/30
-                                  ----
-builtins/caller.def
-       - add call to no_options, so it can handle `--' option
-
-doc/{bash.1,bashref.texi}
-       - note explicitly that test, :, true, and false don't understand --
-         as meaning the end of options
-
-                                   5/7
-                                   ---
-support/shobj-conf
-       - darwin 8 needs the same LDFLAGS setting as darwin 7
-
-parse.y
-       - in save_parser_state, make sure we cast the return value from
-         xmalloc() to the right type
-       - remove casts to (char *) in calls to yyerror()
-
-lib/readline/signals.c
-       - make SIGQUIT and SIGALRM code conditional on their definition
-       - use raise() to send a signal if we don't have kill()
-
-lib/readline/display.c
-       - some MS-DOS and MINGW changes from the cygwin and mingw folks
-
-config.h.in
-       - add HAVE_PWD_H for <pwd.h>
-       - add HAVE_FCNTL, HAVE_KILL for respective system calls
-       - add HAVE_GETPW{ENT,NAM,UID} for passwd functions
-
-configure.in
-       - add check for <pwd.h>
-       - add checks for fcntl, kill system calls
-       - add checks for getpw{ent,nam,uid} C library functions
-       - pass a flag indicating we're cross compiling through to
-         CFLAGS_FOR_BUILD in Makefile.in
-
-lib/readline/complete.c
-       - guard inclusion of <pwd.h> with HAVE_PWD_H
-       - don't provide a missing declaration for getpwent if we don't have it
-       - guard calls to {get,end}pwent with HAVE_GETPWENT
-
-lib/readline/shell.c
-       - guard inclusion of <pwd.h> with HAVE_PWD_H
-       - guard inclusion of <fcntl.h> with HAVE_FCNTL_H
-       - don't provide a missing declaration for getpwuid if we don't have it
-       - guard calls to getpwuid with HAVE_GETPWUID
-       - don't bother with body of sh_unset_nodelay_mode if we don't have
-         fcntl
-
-lib/tilde/tilde.c
-       - guard inclusion of <pwd.h> with HAVE_PWD_H
-       - guard calls to getpw{nam,uid} with HAVE_GETPW{NAM,UID}
-       - guard calls to {get,end}pwent with HAVE_GETPWENT
-
-Makefile.in,builtins/Makefile.in
-       - @CROSS_COMPILE@ is substituted into CFLAGS_FOR_BUILD (equal to
-         -DCROSS_COMPILING if bash is being cross-compiled)
-
-                                   5/9
-                                   ---
-aclocal.m4
-       - print version as `0.0' in RL_LIB_READLINE_VERSION if the
-         `rl_gnu_readline_p' variable isn't 1 (accept no imitations)
-
-                                  5/11
-                                  ----
-lib/readline/rlprivate.h
-       - definition of a readline `search context', to be use for incremental
-         search initially and other types of search later.  Original from
-         Bob Rossi as part of work on incremental searching problems when
-         using callback interface
-
-lib/readline/isearch.c
-       - functions to allocate and free search contexts
-       - function to take a search context and a character just read and
-         `dispatch' on it:  change search parameters, add to search string,
-         search further, etc.
-       - isearch is now completely context-driven:  a search context is
-         allocated and passed to the rest of the functions
-
-                                  5/12
-                                  ----
-lib/readline/isearch.c
-       - an additional `isearch cleanup' function that can be called from
-         the callback interface functions when the search is to be terminated
-       - an additional `isearch callback' function that can be called from
-         rl_callback_read_char when input is available
-       - short-circuit from rl_search_history after initialization if
-         the callback interface is being used
-
-lib/readline/callback.c
-       - in rl_callback_read_char(), if RL_STATE_ISEARCH is set, call
-         _rl_isearch_callback to read the character and dispatch on it.
-         If RL_STATE_ISEARCH is unset when that call returns, and there is
-         input pending, call rl_callback_read_char() again so we don't
-         have to wait for new input to pick it up
-
-support/shobj-conf,configure.in
-       - add support for dragonfly bsd, the same as freebsd
-
-                                5/13-5/15
-                                ---------
-lib/readline/callback.c
-       - support for readline functions to `register' a function that will
-         be called when more input is available, with a generic data
-         structure to encapsulate the arguments and parameters.  Primarily
-         intended for functions that read a single additional character,
-         like quoted-insert
-       - support for callback code reading numeric arguments in a loop,
-         using readline state and an auxiliary variable
-       - support for callback code performing non-incremental searches using
-         the same search context struct as the isearch code
-
-lib/readline/{callback,display}.c
-       - if a callback function sets `_rl_redisplay_wanted', the redisplay
-         function will be called as soon as it returns
-
-lib/readline/input.c
-       - changes to _rl_read_mbchar to handle reading the null multibyte
-         character and translating it into '\0'
-
-lib/readline/misc.c
-       - break rl_digit_loop() into component functions that can be called
-         individually from the callback code more easily
-       - share some of the functions with rl_digit_loop1() in vi_mode.c
-
-lib/readline/readline.h
-       - change the version #defines to reflect readline 5.1
-
-lib/readline/search.c
-       - break code into smaller functions that can be composed to work with
-         the callback code more easily
-
-lib/readline/text.c
-       - in rl_quoted_insert(), don't mess around with the tty signals if
-         running in `callback mode'
-
-lib/readline/vi_mode.c
-       - changed set-mark, goto-mark, change-char, and char-search to work
-         when called by callback functions
-
-                                  5/17
-                                  ----
-
-lib/readline/rlprivate.h
-       - new struct declaration for a `reading key sequence' context
-
-lib/readline/readline.c
-       - new variable, _rl_dispatching_keymap, keeps track of which keymap
-         we are currently searching
-       - functions to allocate and deallocate contexts for reading multi-char
-         key sequences
-
-                                  5/18
-                                  ----
-lib/readline/rlprivate.h
-       - new struct defining a context for multiple-key key sequences (the
-         base case is escape-prefixed commands)
-
-lib/readline/readline.c
-       - change structure of _rl_dispatch_subseq to allow for callback code
-         to use it - rudimentary support for supporting the existing
-         recursion using a stack of contexts, each with a reference to the
-         previous
-       - fix so that ^G works when in callback mode
-
-lib/readline/callback.c
-       - call the appropriate multiple-key sequence callback if the state is
-         set
-
-                                  5/19
-                                  ----
-lib/readline/readline.c
-       - broke code from _readline_internal_char after call to rl_dispatch
-         out into separate function:  _rl_internal_char_cleanup, callable by
-         other parts of the code
-       - change _rl_internal_char_cleanup to unset _rl_want_redisplay after
-         it calls (*rl_redisplay_func)
-
-lib/readline/callback.c
-       - call _rl_internal_char_cleanup from rl_callback_read_char when
-         appropriate
-
-                                  5/24
-                                  ----
-lib/readline/callback.c
-       - use _rl_dispatch_callback and a chain of _rl_keyseq_contexts to
-         simulate the recursion used to decode multicharacter key sequences
-         (even things like ESC- as meta-prefix)
-       - call setjmp in rl_callback_read_char to give things like rl_abort
-         a place to jump, since the saved location in readline() will not
-         be valid
-       - keep calling _rl_dispatch_callback from rl_callback_read_char while
-         we are still decoding a multi-key key sequence
-       - keep calling readline_internal_char from rl_callback_read_char while
-         we are reading characters from a macro
-
-lib/readline/macro.c
-       - use a slightly different strategy upon encountering the end of a macro
-         when using the callback interface:  when the last character of a
-         macro is read, and we are reading a command, pop the macro off the    
-         stack immediately so the loop in rl_callback_read_char terminates
-         when it should
-
-lib/readline/readline.c
-       - if longjmp() is called and we end up at the saved location while
-         using the callback interface, just return -- don't go back into a
-         blocking read
-       - new function to dispose a chain of rl_keyseq_cxts
-       - only read new input in _rl_dispatch_callback if the KSEQ_DISPATCHED
-         flag is not set in the current keyseq context -- if it is, we are
-         traversing the chain back up and should use what we already saved
-       - use -3 as a magic value from _rl_dispatch_subseq to indicate that
-         we're allocating a new context and moving downward in the chain
-         (a special return value for the benefit of _rl_dispatch_callback)
-
-lib/readline/rlprivate.h
-       - new extern declaration for _rl_keyseq_chain_dispose
-
-                                   6/1
-                                   ---
-builtins/read.def
-       - fixed a bug that occurred when reading a set number of chars and
-         the nth char is a backslash (read one too many).  Bug reported by
-         Chris Morgan <chmorgan@gmail.com>
-
-execute_cmd.c
-       - fix execute_builtin so the `unset' builtin also operates on the
-         temporary environment in POSIX mode (as well as source and eval),
-         so that unsetting variables in the temporary environment doesn't
-         leave them set when unset completes.  Report by Eric Blake
-         <ebb9@byu.net>
-
-array.c
-       - fix from William Park for array_rshift when shifting right on an
-         empty array -- corrects calculation of array->max_index
-
-builtins/exec.def
-       - if an exec fails and the execfail option is set, don't call
-         restart_job_control unless the shell is interactive or job_control
-         is set
-
-jobs.c
-       - add a run-time check for WCONTINUED being defined in header files
-         but rejected with EINVAL by waitpid().  Fix from Maciej Rozycki
-         <macro@linux-mips.org>
-
-                                  6/20
-                                  ----
-bashhist.c
-       - make sure calls to sv_histchars are protected by #ifdef BANG_HISTORY
-       - ditto for calls to history_expand_line_internal
-
-                                  6/23
-                                  ----
-doc/bashref.texi
-       - remove extra blank lines in @menu constructs
-
-variables.c
-       - assign export_env to environ (extern char **) every time it changes
-         (mostly in add_to_export_env define), so maybe getenv will work on
-         systems that don't allow it to be replaced
-
-                                  6/29
-                                  ----
-bashline.c
-       - in bash_directory_completion_hook, be careful about not turning `/'
-         into `//' and `//' into `///' for benefit of those systems that treat
-         `//' as some sort of `network root'.  Fix from Eric Blake
-         <ebb9@byu.net>
-
-lib/readline/complete.c
-       - in to_print, do the right thing after stripping the trailing slash
-         from full_pathname: // doesn't turn into /, and /// doesn't become
-         //.  Fix from Eric Blake <ebb9@byu.net>
-
-                                  6/30
-                                  ----
-lib/malloc/trace.c
-       - include <unistd.h> if it's available for a definition of size_t
-
-jobs.c
-       - in wait_for, if a child process is marked as running but waitpid()
-         returns -1/ECHILD (e.g., when the bash process is being traced by
-         strace), make sure to increment c_reaped when marking the child as
-         dead
-       - in without_job_control, make sure to close the pgrp pipe after
-         calling start_pipeline
-
-                                   7/1
-                                   ---
-Makefile.in
-       - only remove pathnames.h when the other files created by running
-         configure are removed (e.g., Makefile).  Fix from William Park
-
-lib/sh/shquote.c
-       - since backslash-newline disappears when within double quotes, don't
-         add a backslash in front of a newline in sh_double_quote.  Problem
-         reported by William Park
-
-jobs.c
-       - in notify_of_job_status, don't print status messages about
-         terminated background processes unless job control is active
-
-bashhist.c
-       - new variable, hist_last_line_pushed, set to 0 in really_add_history
-         (used by `history -s' code)
-
-bashhist.h
-       - new extern declaration for history -s
-
-builtins/history.def
-       - don't remove last history entry in push_history if it was added by
-         a call to push_history -- use hist_last_line_pushed as a sentinel
-         and set it after adding history entry.  This allows multiple
-         calls to history -s to work right:  adding all lines to the history
-         rather than deleting all but the last.  Bug reported by Matthias
-         Schniedermeyer <ms@citd.de>
-       - pay attention to hist_last_line_pushed in expand_and_print_history()
-         so we don't delete an entry pushed by history -s
-
-                                   7/4
-                                   ---
-print_cmd.c
-       - fix print_arith_for_command to not print so many blanks between
-         expressions in ((...))
-
-command.h
-       - new word flag: W_DQUOTE.  Means word should be treated as if double
-         quoted
-
-make_cmd.c
-       - add W_DQUOTE to word flags in make_arith_for_expr
-
-parse.y
-       - add W_DQUOTE to word flags for (( ... )) arithmetic commands
-
-subst.c
-       - don't perform tilde expansion on a word with W_DQUOTE flag set
-       - don't perform process substitution on a word with W_DQUOTE flag set
-
-arrayfunc.c
-       - expand an array index within [...] the same way as an arithmetic
-         expansion between (( ... ))
-
-lib/readline/input.c
-       - use getch() instead of read() on mingw
-
-lib/readline/readline.c
-       - add a few key bindings for the arrow keys on mingw
-
-lib/readline/rldefs.h
-       - if on mingw, define NO_TTY_DRIVER
-
-lib/readline/rltty.c
-       - compile in the stub functions for _rl_{disable,restore}_tty_signals
-         if on mingw
-       - compile in stub function for rl_restart_output on mingw
-       - make sure enough functions and macros are defined to compile if
-         NO_TTY_DRIVER is defined (lightly tested - builds on MacOS X, at
-         least)
-
-                                   7/7
-                                   ---
-command.h
-       - add a `flags' member to the PATTERN_LIST structure
-
-make_cmd.c
-       - intialize the `flags' member of a PATTERN_LIST when it's created
-
-builtins/psize.c
-       - protect extern declaration of errno with usual #ifdef errno
-
-configure.in, variables.c
-       - changes for QNX 6.x
-
-                                   7/9
-                                   ---
-parse.y
-       - fix parse_matched_pair to handle single and double quoted strings
-         inside old-style command substitution (``) since they can each
-         quote the ` and embedded $-expansions.  Report by Eric Blake
-         <ebb9@byu.net>
-
-{configure,Makefile}.in
-       - TILDE_LIB is now substituted into Makefile by configure
-
-configure.in
-       - if configuring --with-installed-readline on cygwin, set TILDE_LIB
-         to the empty string to avoid multiply-defined symbols.  Cygwin
-         doesn't allow undefined symbols in dynamic libraries.  Report by
-         Eric Blake <ebb9@byu.net>
-
-                                  7/11
-                                  ----
-input.c
-       - in duplicate_buffered_stream, don't call free_buffered_stream if the
-         two buffered streams share the same b_buffer object (e.g., if they
-         had already been duplicated with a previous call).  Fixes Debian bug
-         reported by eero17@bigfoot.com
-
-                                  7/12
-                                  ----
-shell.c
-       - make set_shell_name more resistant to a NULL argument
-       - in bind_args, use < instead of != when counting the arguments and
-         making the arg list
-       - in main(), make sure arg_index is not initialized to a value greater
-         than argc
-
-                                  7/14
-                                  ----
-lib/readline/display.c
-       - in expand_prompt, don't set the location of the last invisible
-         char if the sequence is zero length  (\[\])
-
-                                  7/15
-                                  ----
-doc/{bash.1,bashref.texi}
-       - document that the shell uses $TMPDIR when creating temporary files
-
-                                  7/20
-                                  ----
-[bash-3.1-alpha1 frozen]
-
-                                  7/29
-                                  ----
-builtins/evalstring.c
-       - make sure that parse_and_execute saves and restores the value of
-         loop_level, so loops in sourced scripts and eval'd strings don't
-         mess up the shell's parser state
-
-bashline.c
-       - change command_subst_completion_function to suppress appending
-         any character to a unique completion, instead of a space, unless
-         the last word in the quoted command substitution completes to a
-         directory name.  In that case we append the expected slash
-
-                                   8/1
-                                   ---
-builtins/printf.def
-       - make sure variables are initialized if their values are tested later
-
-[bash-3.1-alpha1 updated and re-frozen]
-
-                                   8/2
-                                   ---
-variables.c
-       - make sure to call stifle_history with an `int' instead of an intmax_t.
-         Sometimes it makes a difference
-
-                                   8/3
-                                   ---
-[bash-3.1-alpha1 released]
-
-support/mksignames.c
-       - add `SIGSTKFLT' (RHE3)
-       - add `SIGXRES' (Solaris 9)
-
-                                   8/4
-                                   ---
-builtins/ulimit.def
-       - fix typo to make `x' the right option for locks
-       - add new options to short help synopsis
-
-variables.c
-       - use get_variable_value instead of direct reference to value_cell
-         in make_variable_value when appending to the current value, so
-         references to array variables without subscripts will be equivalent
-         to element 0
-
-lib/readline/text.c
-       - rewrote rl_change_case to correctly change the case of multibyte
-         characters where appropriate
-
-                                   8/5
-                                   ---
-configure.in
-       - remove call to obsolete macro AC_ACVERSION
-       - remove special calls to AC_CYGWIN and AC_MINGW32; AC_CANONICAL_HOST
-         takes care of those cases
-
-general.h
-       - include `chartypes.h' for definition of ISALPHA
-       - fix definitions of ABSPATH and RELPATH for cygwin
-       - fix definition of ISDIRSEP for cygwin to allow backslash as a
-         directory name separator
-
-                                   8/9
-                                   ---
-builtins/setattr.def
-       - when setting a variable from the temporary environment in
-         set_var_attribute  (e.g., `LC_ALL=C export LC_ALL'), make sure to
-         call stupidly_hack_special_variables after binding the variable in
-         the current context
-
-builtins/printf.def
-       - make sure to call stupidly_hack_special_variables if using `printf -v'
-         to put formatted output in a shell variable
-
-                                  8/11
-                                  ----
-support/shobj-conf
-       - new variable: SHLIB_LIBPREF, prefix for shared library name (defaults
-         to `lib'
-       - new variable: SHLIB_DLLVERSION, used on Cygwin to set the library
-         version number
-       - new variable: SHLIB_DOT, separator character between library name and
-         suffix and version information (defaults to `.')
-       - new stanza for cygwin to generate windows-compatible dll
-
-                                  8/14
-                                  ----
-variables.c
-       - new special variable function for Cygwin, so the export environment
-         is remade when HOME is changed.  The environment is the only way to
-         get information from the shell to cygwin dlls, for instanace, when
-         bash is compiled to use an already-installed libreadline
-
-variables.h
-       - new extern declaration for sv_home
-
-                                  8/15
-                                  ----
-lib/readline/display.c
-       - call init_line_structures from rl_redisplay if vis_lbreaks == 0
-         to avoid consequences of a poorly-timed SIGWINCH
-
-                                  8/16
-                                  ----
-subst.c
-       - fix logic for performing tilde expansion when in posix mode (don't
-         rely on W_TILDEEXP flag always being set, because it won't be when
-         expanding the RHS of assignment statement).  Use W_TILDEEXP only
-         when deciding to expand a word marked as W_ASSIGNMENT that doesn't
-         precede a command name
-
-                                  8/17
-                                  ----
-execute_cmd.c
-       - in execute_function, when subshell == 1, don't short-cut by using
-         the command contained in the group command -- if you do, any
-         redirections attached to the group command (function) don't get
-         executed
-
-general.h
-       - new #define, FS_READABLE, indicates file is readable by current
-         user
-
-findcmd.c
-       - rewrote file_status to use S_xxx POSIX file mode bits and to add
-         support for FS_READABLE (affects ./source and searching $PATH for
-         scripts whose names are supplied as arguments on the command line)
-       - change find_path_file to look for readable files -- source requires
-         it
-       - change find_in_path_element to do the right thing when FS_READABLE
-         is supplied as a flag
-
-doc/bashref.texi
-       - remove note about posix non-compliance in `.': we now require and
-         look for readable files when searching $PATH
-
-                                  8/20
-                                  ----
-subst.c
-       - fix setifs to handle case where passed variable is non-zero but
-         v->value == 0 (as in an unset local variable); treat IFS as unset
-         in this case
-
-jobs.c
-       - in kill_pid, if asked to killpg a process or pgrp whose pgrp is
-         recorded as the same as the shell's, just call killpg and let the
-         chips fall where they may -- there may be other processes in that
-         pgrp that are not children of the shell, so killing each process
-         in the pipeline will not do a complete job, and killpg'ing each
-         such process will send too many signals in the majority of cases
-
-builtins/cd.def
-       - in posix mode, pwd needs to check that the value it prints and `.'
-         are the same file
-
-builtins/read.def
-       - if reading input from stdin in a non-interactive shell and calling
-         `read', call sync_buffered_stream to seek backward in the input
-         stream if necessary (XXX - should we do this for all shell builtins?)
-
-                                  8/23
-                                  ----
-builtins/cd.def
-       - in posix mode, if canonicalization of the absolute pathname fails
-         because the path length exceeds PATH_MAX, but the length of the passed
-         (non-absolute) pathname does not, attempt the chdir, just as when
-         not in posix mode
-
-builtins/type.def
-       - don't have describe_command call sh_makepath if the full path found
-         is already an absolute pathname (sh_makepath will stick $PWD onto the
-         front of it)
-
-                                  8/24
-                                  ----
-
-jobs.c
-       - in posix mode, don't have start_job print out and indication of
-         whether the job started by `bg' is the current or previous job
-       - change start_job to return success if a job to be resumed in the
-         background is already running.  This means that bg won't fail when
-         asked to bg a background job, as SUSv3/XPG6 requires
-       - new function, init_job_stats, to zero out the global jobstats struct
-
-{jobs,nojobs}.c
-       - change kill_pid to handle pids < -1 by killing process groups
-
-jobs.h
-       - extern declaration for init_job_stats
-
-lib/readline/history.c
-       - check whether or not the history list is null in remove_history
-
-builtins/history.def
-       - delete_last_history is no longer static so fc builtin can use it
-
-builtins/fc.def
-       - use free_history_entry in fc_replhist instead of freeing struct
-         members individually
-       - call delete_last_history from fc_replhist instead of using inline
-         code
-       - if editing (-l not specified), make sure the fc command that caused
-         the editing is removed from the history list, as POSIX specifies
-
-builtins/kill.def
-       - just call kill_pid with any pid argument and let it handle pids < -1
-         This is the only way to let kill_pid know whether a negative pid or
-         a job spec was supplied as an argument to kill
-
-builtins/fg_bg.def
-       - force fg_bg to return EXECUTION_SUCCESS explicitly if called by bg
-         and start_job returns successfully
-       - bg now returns success only if all the specified jobs were resumed
-         successfully
-
-execute_cmd.c
-       - call init_job_stats from initialize_subshell to zero out the global
-         job stats structure
-
-                                  8/25
-                                  ----
-bashline.c
-       - change vi_edit_and_execute_command to just call vi when in posix
-         mode, instead of checking $FCEDIT and $EDITOR
-
-lib/readline/search.c
-       - if in vi_mode, call rl_free_undo_list in make_history_line_current
-         to dispose of undo list accumulated while reading the search string
-         (if this isn't done, since vi mode leaves the current history
-         position at the entry which matched the search, the call to
-         rl_revert_line in rl_internal_teardown will mangle the matched
-         history entry using a bogus rl_undo_list)
-       - call rl_free_undo_list after reading a non-incremental search string
-         into rl_line_buffer -- that undo list should be discarded
-
-lib/readline/rlprivate.h
-       - add UNDO_LIST * member to search context struct
-
-lib/readline/isearch.c
-       - initialize UNDO_LIST *save_undo_list member of search context struct
-
-                                  8/27
-                                  ----
-lib/readline/bind.c
-       - change rl_parse_and_bind to strip whitespace from the end of a
-         variable value assignment before calling rl_variable_bind
-
-doc/bash.1,lib/readline/doc/{rluser.texi,readline.3}
-       - clarified the language concerning parsing values for boolean
-         variables in assignment statements
-
-                                  8/28
-                                  ----
-lib/sh/pathphys.c
-       - fix small memory leak in sh_realpath reported by Eric Blake
-
-                                  8/31
-                                  ----
-doc/bashref.texi
-       - add additional notes to posix mode section
-
-                                   9/3
-                                   ---
-parse.y
-       - if $'...' occurs within a ${...} parameter expansion within
-         double quotes, don't single-quote the expanded result -- the double
-         quotes will cause it to be expanded incorrectly
-
-                                   9/4
-                                   ---
-builtins/fc.def
-       - if STRICT_POSIX is defined, the posix mode default for the editor to
-         use is $FCEDIT, then ed
-
-shell.c
-       - if STRICT_POSIX is defined, initialize `posixly_correct' to 1
-
-config.h.in
-       - add #undef STRICT_POSIX
-
-                                   9/5
-                                   ---
-configure.in
-       - add new option argument, --enable-strict-posix-default, configures
-         bash to be posix-conformant (including defaulting echo to posix
-         conformance) by default
-
-builtins/echo.def
-       - if STRICT_POSIX is defined, default echo to xpg-style
-
-doc/bashref.texi
-       - describe the --enable-strict-posix-default option to configure
-
-                                  9/10
-                                  ----
-builtins/mkbuiltins.c
-       - change to not generate N_(""), because the translated empty string is
-         special to GNU gettext
-
-                                  9/13
-                                  ----
-lib/readline/complete.c
-       - a negative value for rl_completion_query_items means to not ask
-
-lib/readline/doc/{{rltech,rluser}.texi,readline.3}
-       - documented new semantics for rl_completion_query_items/
-         completion-query-items
-
-                                  9/14
-                                  ----
-bashline.c
-       - bind M-TAB in emacs mode to dynamic-complete-history even if the
-         current binding is `tab-insert' (which is what it is by default),
-         not just if it's unbound
-
-                                  9/15
-                                  ----
-eval.c
-       - call QUIT before calling dispose_command on current_command after
-         the  `exec_done' label.  If we dispose current_command first, the
-         longjmp might restore the value of current_command after we've
-         disposed it, and the subsequent call to dispose_command from the
-         DISCARD case will free memory twice
-
-                                  9/16
-                                  ----
-lib/sh/strto[iu]max.c
-       - make sure the function being declared is not a cpp define before
-         defining it -- should fix problems on HP-UX
-
-                                  9/19
-                                  ----
-Makefile.in
-       - make sure the binaries for the tests are at the front of $PATH
-
-                                  9/22
-                                  ----
-parse.y
-       - new flag for parse_matched_pair: P_COMMAND, indicating that the
-         text being parsed is a command (`...`, $(...))
-       - change calls to parse_matched_pair to include P_COMMAND where
-         appropriate
-       - if P_COMMAND flag is set and the text is unquoted, check for comments
-         and don't try to parse embedded quoted strings if in a comment (still
-         not exactly right yet)
-
-                                  9/24
-                                  ----
-builtins/history.def
-       - if running history -n, don't count these new lines as history lines
-         for the current session if the `histappend' shell option is set.
-         If we're just appending to the history file, the issue that caused
-         history_lines_this_session to be recalculated doesn't apply -- the
-         history file won't be missing any entries
-
-lib/readline/isearch.c
-       - fix C-w handler for isearch string reader to handle multibyte chars
-
-lib/readline/rlmbutil.h
-       - new defines for _rl_to_wupper and _rl_to_wlower
-
-lib/readline/text.c
-       - use _rl_to_wupper and _rl_to_wlower as appropriate
-
-                                  9/26
-                                  ----
-execute_cmd.c
-       - in shell_execve, if the exec fails due to E2BIG or ENOMEM, just print
-         the appropriate error message instead of checking out any interpreter
-         specified with #!
-
-                                  9/30
-                                  ----
-bashhist.c
-       - make $HISTCMD available anytime remember_on_history is non-zero,      
-         which indicates that we're saving commands to the history, and
-         let it evaluate to 1 if we're not
-
-                                  10/4
-                                  ----
-lib/sh/snprintf.c
-       - in floating(), make sure d != 0 before calling chkinfnan -- gcc on the
-         version of Solaris 9 I have translates 0 to -inf on the call
-
-[bash-3.1-beta1 frozen]
-
-                                  10/6
-                                  ----
-jobs.c
-       - set the_pipeline to NULL right away in cleanup_the_pipeline, and
-         dispose a copy of the pointer so we don't mess with the_pipeline
-         while we're in the process of destroying it
-       - block and unblock SIGCHLD around manipulating the_pipeline in
-         cleanup_the_pipeline  
-
-                                  10/7
-                                  ----
-[bash-3.1-beta1 released]
-
-lib/readline/isearch.c
-       - when switching directions, make sure we turn off the SF_REVERSE
-         flag in the search context's flags word if we're going from reverse
-         to forward i-search
-
-lib/readline/bind.c
-       - new function, rl_variable_value, returns a string representing a
-         bindable readline variable's value
-       - new auxiliary function, _rl_get_string_variable_value, encapsulates
-         everything needed to get a bindable string variable's value
-       - rewrote rl_variable_dumper to use _rl_get_string_variable_value
-
-lib/readline/readline.h
-       - new extern declaration for rl_variable_value
-
-lib/readline/doc/rltech.texi
-       - documented rl_variable_value
-
-bashline.c
-       - in command_word_completion_function, if readline sets
-         rl_completion_found_quote, but doesn't set rl_completion_quote_character,
-         we have an embedded quoted string or backslash-escaped character in
-         the passed text.  We need to dequote that before calling
-         filename_completion_function.  So far, this is in place only for
-         absolute program names (those containing a `/')
-       - in command_word_completion_function, use rl_variable_value to decide
-         whether or not we should ignore case, and use strncasecmp instead of
-         strncmp where appropriate
-
-                                  10/11
-                                  -----
-builtins/fc.def
-       - fixed a typo when using POSIX_FC_EDIT_COMMAND
-
-redir.h
-       - new flag values for redirections: RX_INTERNAL and RX_USER (currently
-         unused)
-
-redir.c
-       - add_undo_redirect and add_undo_close_redirect now set RX_INTERNAL
-         flag when making new redirects
-       - in do_redirection_internal, only set file descriptors > 2 to CLEXEC
-         if they're marked as RX_INTERNAL
-
-                                  10/12
-                                  -----
-jobs.c
-       - in wait_for_single_pid, if in posix mode, remove the waited-for pid
-         from the list of background pids, forgetting it entirely.  POSIX
-         conformance tests test for this.
-
-lib/readline/{readline.h,vi_mode.c}
-       - new state flag, RL_STATE_VICMDONCE, set after entering vi command
-         mode the first time; reset on each call to readline()
-
-                                  10/13
-                                  -----
-lib/readline/undo.c
-       - in rl_revert_line, make sure that revert-line in vi mode leaves
-         rl_point set to 0 no matter the state of the line buffer
-
-lib/readline/vi_mode.c
-       - when entering vi_command mode for the first time, free any existing
-         undo list so the previous insertions won't be undone by the `U'
-         command.  This is how POSIX.2 says `U' should work (and the test
-         suite tests for it)
-
-lib/readline/bind.c
-       - change rl_parse_and_bind so only `set' commands involving boolean
-         readline variables have trailing whitespace stripped from the value
-         string
-
-                                  10/16
-                                  -----
-lib/glob/sm_loop.c
-       - fix patscan() to correctly scan backslash-escaped characters
-
-                                  10/18
-                                  -----
-lib/sh/{winsize.c,Makefile.in},{jobs,nojobs}.c,Makefile.in,externs.h
-       - moved get_new_window_size from jobs.c/nojobs.c to new file,
-         lib/sh/winsize.c, made function global
-
-{jobs,nojobs,sig}.c,{jobs,sig}.h
-       - moved SIGWINCH handling code to sig.c rather than duplicate it in
-         jobs.c and nojobs.c
-       - call set_sigwinch_handler from sig.c code rather than job control
-         signal initialization
-
-sig.[ch]
-       - new variable, sigwinch_received, acts like interrupt_state for
-         SIGWINCH, set by sigwinch_sighandler.  sigwinch_sighandler no longer
-         calls get_new_window_size
-
-parse.y
-       - add call to get_new_window_size if sigwinch_received at top of
-         shell_getc
-
-                                  10/19
-                                  -----
-lib/malloc/malloc.c
-       - to avoid orphaning memory on free if the right bucket is busy, use a
-         new function xplit(mem, bucket) to split the block into two or more
-         smaller ones and add those to the right bucket (appropriately marking
-         it as busy)
-       - audit bsplit(), bcoalesce(), and xsplit() for proper use of busy[],
-         since they're dealing with two separate buckets
-
-                                  10/22
-                                  -----
-subst.c
-       - new flag for string_extract: EX_REQMATCH, means to return an error
-         if a matching/closing character is not found before EOS
-       - new static flag variables: extract_string_error and extract_string_fatal
-       - change expand_word_internal to check for new error returns from
-         string_extract and return errors if appropriate
-
-                                  10/23
-                                  -----
-builtins/cd.def
-       - make sure we free TDIR in change_to_directory after calling
-         set_working_directory (which allocates new memory) and other places
-         we short-circuit and return
-
-                                  10/24
-                                  -----
-subst.c
-       - modified fix from 10/22 to allow bare ` to pass through (for
-         some backwards compatibility and more correctness)
-
-                                  10/27
-                                  -----
-conftypes.h
-       - make MacOS X use the RHAPSODY code that gets HOSTTYPE, et al.
-         at build rather than configure time, to support universal binaries
-         (fix from llattanzi@apple.com)
-
-                                  10/30
-                                  -----
-builtins/evalstring.c
-       - make sure we don't turn on CMD_NO_FORK in parse_and_execute if
-         we're running a trap command on signal receipt or exit
-
-execute_cmd.c
-       - in shell_execve, improve the error message a little bit if the
-         interpreter name in a #! exec header ends with a ^M (as in a DOS-
-         format file)
-
-                                  11/1
-                                  ----
-lib/readline/vi_mode.c
-       - fix vi-mode `r' command to leave the cursor in the right place
-
-[bash-3.1-rc1 frozen]
-
-                                  11/5
-                                  ----
-execute_cmd.c
-       - make sure a DEBUG trap doesn't overwrite a command string passed to
-         make_child in execute_simple_command
-
-bashline.c
-       - rearrange some code in bash_quote_filename so filenames with leading
-         tildes containing spaces aren't tilde-expanded before being
-         returned to the caller
-
-                                  11/6
-                                  ----
-lib/readline/display.c
-       - when deciding where to move the cursor in rl_redisplay and needing
-         to move the cursor back after moving it vertically and compensate
-         for invisible characters in the prompt string, make sure that
-         _rl_last_c_pos is treated as an absolute cursor position in a
-         multibyte locale and the wrap offset (number of invisible characters)
-         is added explicitly when deciding how many characters to backspace
-
-                                  11/10
-                                  -----
-lib/readline/terminal.c
-       - _rl_set_screen_size now interprets a lines or columns argument < 0
-         as an indication not to change the current value
-
-                                  11/11
-                                  -----
-
-lib/readline/terminal.c
-       - new function, rl_reset_screen_size, calls _rl_get_screen_size to
-         reset readline's idea of the terminal size
-       - don't call _rl_get_screen_size in _rl_init_terminal_io if both        
-         _rl_screenheight and _rl_screenwidth are > 0
-       - don't initialize _rl_screenheight and _rl_screenwidth to 0 in
-         _rl_init_terminal_io; let caller take care of it
-       - set _rl_screenheight and _rl_screenwidth to 0 before calling
-         _rl_init_terminal_io
-
-lib/readline/readline.h
-       - new extern declaration for rl_reset_screen_size
-
-lib/readline/doc/rltech.texi
-       - documented rl_reset_screen_size
-
-variables.c
-       - if readline is being used, compile in a special var function for
-         assignments to LINES and COLUMNS that calls rl_set_screen_size or
-         rl_reset_screen_size as appropriate.  Only do this in posix mode
-         and only when STRICT_POSIX is defined at compile time
-       - new semaphore variable, winsize_assignment, set while doing an
-         assignment to LINES or COLUMNS
-       - new variable, winsize_assigned, says LINES or COLUMNS was assigned
-         to or found in the environment
-       - if in the middle of an assignment to LINES or COLUMNS, make
-         sh_set_lines_and_columns a no-op
-
-lib/sh/winsize.c
-       - get_new_window_size now takes two int * arguments, to return the
-         screen dimensions
-
-externs.h
-       - change extern declaration for get_new_window_size
-
-{jobs,nojobs}.c, parse.y
-       - change callers of get_new_window_size
-
-                                  11/12
-                                  -----
-lib/readline/terminal.c
-       - new variable, rl_prefer_env_winsize, gives LINES and COLUMNS
-         precedence over values from the kernel when computing window size
-
-lib/readline/readline.h
-       - extern declaration for rl_prefer_env_winsize
-
-lib/readline/doc/rltech.texi
-       - document rl_prefer_env_winsize
-
-                                  11/13
-                                  -----
-lib/readline/rltty.c
-       - change rl_prep_terminal to make sure we set and reset the tty
-         special characters in the vi insertion keymap if in vi mode.  This
-         matters if we get accept-line for the previous line while in vi
-         command mode
-
-                                  11/14
-                                  -----
-builtins/pushd.def
-       - make sure any call to cd_builtin includes a leading `--' from the
-         argument list (or constructs one)
-
-                                  11/16
-                                  -----
-pcomplete.c
-       - fix small memory leak in gen_wordlist_matches
-
-[bash-3.1-rc2 frozen]
-
-                                  11/21
-                                  -----
-[bash-3.1-rc2 released]
-
-                                  11/23
-                                  -----
-lib/readline/display.c
-       - changes to rl_redisplay to compensate for update_line updating
-         _rl_last_c_pos without taking invisible characters in the line into
-         account.  Important in multibyte locales where _rl_last_c_pos is an
-         absolute cursor position
-       - changes to _rl_move_cursor_relative to account for _rl_last_c_pos
-         being an absolute cursor position in a multibyte character locale
-       - rewrote _rl_move_cursor_relative to make it a little simpler
-
-                                  11/29
-                                  -----
-lib/readline/display.c
-       - changes to rl_redisplay and update_line for update_line to communicate
-         upward that it took the number of invisible characters on the current
-         line into account when modifying _rl_last_c_pos
-       - in update_line, adjust _rl_last_c_pos by wrap_offset before calling
-         _rl_move_cursor_relative, so we pass correct information about the
-         true cursor position
-
-                                  12/1
-                                  ----
-configure.in
-       - changed release status to `release'
-
-[bash-3.1 frozen]
-
-                                  12/8
-                                  ----
-[bash-3.1 released]
-
-                                  12/9
-                                  ----
-doc/{bash.1,version.texi},lib/readline/doc/version.texi
-       - remove `beta1' from man page footer and texinfo documents
-
-variables.c
-       - make sure winsize_assignment is protected by #ifdef READLINE, so
-         minimal shell will compile
-
-builtins/read.def
-       - make sure error cases free memory and run any unwind-protects to
-         avoid memory leaks
-
-                                  12/10
-                                  -----
-execute_cmd.c
-       - change execute_command_internal to set $PIPESTATUS for ((...)) and
-         [[ ... ]] commands
-
-doc/{bash.1,bashref.texi,version.texi}
-       - add documentation for ulimit -[iqx] and bump revision date
-
-                                  12/12
-                                  -----
-parse.y
-       - make sure parse_compound_assignment saves and restores the
-         PST_ASSIGNOK parser state flag around its calls to read_token.
-         Fixes bug reported by Mike Frysinger
-
-                                  12/13
-                                  -----
-parse.y
-       - change parse_compound_assignment to save and restore the value of
-         last_read_token.  Not sure why it was set unconditionally in the
-         first place after parsing the complete compound assignment
-
-                                  12/14
-                                  -----
-lib/readline/text.c
-       - don't use return value of rl_kill_text (which always succeeds and
-         returns the number of characters killed) in rl_delete as an indication
-         of success or failure
-       - ditto for return value of rl_delete_text
-
-lib/readline/readline.c
-       - don't return the value of the called readline function as the return
-         value from _rl_dispatch_subseq; -1 means something different to the
-         callers (return 0 all the time to indicate that a readline function
-         was found and dispatched).  Fix from Andreas Schwab for <DEL><DEL>
-         bug in callback interface first reported by Mike Frysinger
-
-execute_cmd.c
-       - fixed a typo in execute_case_command
-
-                                  12/15
-                                  -----
-aclocal.m4
-       - add check for wctype() to BASH_CHECK_MULTIBYTE, define HAVE_WCTYPE
-
-config.h.in
-       - add HAVE_WCTYPE #define
-
-config-bot.h
-       - add HAVE_WCTYPE to the set of checks for HANDLE_MULTIBYTE.  This
-         should catch the deficient NetBSD multibyte support
-
-                                  12/16
-                                  -----
-parse.y
-       - use CTLESC instead of literal '\001' when decode_prompt_string
-         prefixes RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE
-
-                                  12/20
-                                  -----
-lib/readline/display.c
-       - don't treat RL_PROMPT_START_IGNORE specially inside a sequence of
-         ignored characters
-       - keep track of the start of the current sequence of ignored
-         characters; make sure that an empty sequence of such characters
-         really is an empty sequence, not one that happens to end with '\001'
-         (RL_PROMPT_START_IGNORE)
-
-                                  12/21
-                                  -----
-subst.c
-       - change expand_word_internal to process rest of `tilde-word' as a
-         regular part of the word if tilde expansion leaves the tilde-word
-         unchanged.  This means that ~$USER expands to ~chet, which seems
-         more intuitive, and is effectively what bash-3.0 did
-
-                                  12/23
-                                  -----
-subst.c
-       - when making a local array variable in do_compound_assignment, make
-         sure that we don't use a variable of the same name from a previous
-         context
-
-doc/bash.1
-       - documented expansions for word and patterns in case statement
-
-builtins/ulimit.def,doc/{bashref.texi,bash.1}
-       - added new -e and -r (nice and rtprio) options to ulimit; documented
-         them
-
-                                  12/26
-                                  -----
-variables.c
-       - use `hmax' instead of `num' in sv_histsize to avoid integer overflow
-         problems with intmax_t
-
-builtins/read.def
-       - add unwind-protect to restore rl_attempted_completion_function in
-         case of a timeout
-
-{bashline,variables}.c
-       - move initialization of HISTSIZE from initialization path to
-         load_history, so it can be overridden by a value assigned in a
-         startup file
-
-lib/readline/misc.c
-       - add a missing `return r' so that rl_digit_loop returns a meaningful
-         value
-
-lib/readline/{bind,callback,display,isearch,rltty,search,text,vi_mode}.c
-       - minor cleanups to satisfy compiler warnings, mostly removing unused
-         variables
-
-                                  12/27
-                                  -----
-support/Makefile.in
-       - add LIBS_FOR_BUILD support; defaults to ${LIBS}
-
-Makefile.in
-       - add LIBS_FOR_BUILD with no default value; use when linking programs
-         using CC_FOR_BUILD (e.g., bashversion)
-
-                                  12/28
-                                  -----
-lib/readline/bind.c
-       - fix rl_translate_keyseq bad translation of \M-\C-x sequences
-
-execute_cmd.c
-       - in execute_arith_command, if the expression expands to more than one
-         word, make sure we join the words into a single string and pass the
-         entire thing to evalexp()
-
-expr.c
-       - new functions: _is_arithop(c), returns true if C is a valid single-
-         character arithmetic operator; _is_multiop(c), returns true if C is
-         a token corresponding to a valid multi-character arithmetic operator
-       - if we encounter a character that isn't a valid arithmetic
-         operator, throw an error.  Try to be intelligent about what type of
-         error message to print
-
-subst.c
-       - new function, expand_arith_string, calls expand_string_if_necessary;
-         used where an arithmetic expression needs to be expanded
-
-subst.h
-       - new extern declaration for expand_arith_string
-
-arrayfunc.c
-       - in array_expand_index, call expand_arith_string to expand the
-         subscript in a fashion consistent with other arithmetic expressions
-
-subst.c
-       - fix parameter_brace_patsub so that we don't try to anchor the pattern
-         at the beginning or end of the string if we're doing global
-         replacement -- that combination doesn't doesn't make sense, and
-         the changed behavior is compatible with ksh93
-
-doc/{bash.1,bashref.texi}
-       - changed description of pattern substitution to match the new
-         semantics
-
-tests/new-exp.tests
-       - change tests to remove all ${pat//#rep} and ${pat//%rep}
-         expansions, since they don't mean the same thing anymore
-
-                                  12/29
-                                  -----
-support/signames.c
-       - new file, initialize_signames() function from old mksignames.c.  This
-         file builds the signal_names array
-
-support/mksignames.c
-       - strip out initialize_signames(), move to signames.c.  This file only
-         writes signames.h
-       - set up to only write a stub signames.h if CROSS_COMPILING is defined,
-         with extern declaration for initialize_signames
-       - if not cross compiling, #define initialize_signames to nothing
-
-Makefile.in
-       - mksignames is now linked from mksignames.o and buildsignames.o
-       - add rules to build signames.o, assuming we're building it as part
-         of the shell (cross-compiling)
-
-trap.c
-       - call initialize_signames from initialize_traps
-
-configure.in
-       - set SIGNAMES_O to nothing (normal) or signames.o (cross-compiling),
-         substitute into Makefile
-       - don't set SIGNAMES_H if cross-compiling any more
-
-                                  12/30
-                                  -----
-command.h
-       - new word flag: W_NOPROCSUB, inhibits process substitution on a word
-
-subst.c
-       - change expand_word_internal to suppress process substitution if the
-         word has the W_NOPROCSUB flag
-
-shell.c
-       - --wordexp turns on W_NOPROCSUB in addition to W_NOCOMSUB
-
-subst.c
-       - change string_list_dollar_at and string_list_dollar_star so that
-         MB_CUR_MAX is used to size an array only when using gcc, since gcc
-         can handle non-constant array sizes using a mechanism like alloca.
-         Other compilers, e.g. Sun's compiler, do not implement that
-         extension
-
-                                  12/31
-                                  -----
-builtins/mkbuiltins.c
-       - when cross-compiling, don't include <config.h>, since it's for the
-         target rather than the host system.  Instead, choose a reasonable
-         set of default #defines based on a minimal POSIX system
-
-jobs.c
-       - change find_process to handle a NULL return value from find_pipeline
-       - return immediately from delete_job if jobs[index] is already NULL or
-         if it has a null pipeline associated with it
-       - in delete_job, if find_last_proc returns NULL, don't try to call
-         bgp_delete
-
-                                1/7/2006
-                                --------
-doc/bash.1
-       - patch from Tim Waugh to replace some literal single quotes with
-         \(aq, the groff special character for it
-
-jobs.c
-       - in realloc_jobs_list, make sure to zero out slots after j_lastj
-         in the new list
-
-                                   1/9
-                                   ---
-support/mksignames.c
-       - make sure to include <signal.h> to get right value of NSIG from
-         (usually) <sys/signal.h>
-
-                                  1/10
-                                  ----
-parse.y
-       - when calling parse_matched_pair on a $(...) command substitution,
-         don't pass the P_DQUOTE flag so that single quotes don't get
-         stripped from $'...' inside the command substitution.  Bug report
-         and fix from Mike Stroyan <mike.stroyan@hp.com>
-
-jobs.c
-       - start maintaining true count of living children in js.c_living
-       - call reset_current in realloc_jobs_list, since old values for current
-         and previous job are most likely incorrect
-       - don't allocate a new list in realloc_jobs_list if the old size and
-         new size are the same; just compact the existing list
-       - make sure realloc_jobs_list updates value of js.j_njobs
-       - add some more itrace messages about non-null jobs after j_lastj in
-         jobs array
-
-                                  1/11
-                                  ----
-bashjmp.h
-       - new value for second argument to longjmp: SIGEXIT.  Reserved for
-         future use
-
-                                  1/12
-                                  ----
-jobs.c
-       - add logic to make_child to figure out when pids wrap around
-       - turn second argument to delete_job into flags word, added flag to
-         prevent adding proc to bgpids list
-
-                                  1/13
-                                  ----
-lib/readline/vi_mode.c
-       - move code that moves forward a character out of rl_vi_append_mode
-         into a separate function, _rl_vi_append_forward
-       - change _rl_vi_append_mode to save `a' as the last command, so it
-         can be redone properly
-       - new function _rl_vi_backup, moves point back a character taking
-         multibyte locales into account
-       - change rl_vi_redo to handle redoing an `a' command specially --
-         it should be redone like `i' but after moving forward a character
-       - change rl_vi_redo to use _rl_vi_backup to move point backward
-         after redoing `i' or `a'
-
-jobs.c
-       - new function, delete_old_job (pid), checks whether or not PID is in
-         a job in the jobs list.  If so, and the job is dead, it just removes
-         the job from the list.  If so, and the job is not dead, it zeros
-         the pid in the appropriate PROCESS so pid aliasing doesn't occur
-       - make_child calls delete_old_job to potentially remove an already-used
-         instance of the pid just forked from the jobs list if pids have
-         wrapped around.  Finally fixes the bug reported by Tim Waugh
-         <twaugh@redhat.com>
-
-trap.c
-       - new define, GETORIGSIG(sig), gets the original handling for SIG and
-         sets SIG_HARD_IGNORE if that handler is SIG_IGN
-       - call GETORIGSIG from initialize_traps, get_original_signal, and
-         set_signal
-
-jobs.c
-       - in wait_for, if the original SIGINT handler is SIG_IGN, don't set
-         the handler to wait_sigint_handler.  This keeps scripts started in
-         the background (and ignoring SIGINT) from dying due to SIGINT while
-         they're waiting for a child to exit.  Bug reported by Ingemar
-         Nilsson <init@kth.se>
-
-lib/readline/vi_mode.c
-       - don't save text to buffer unless undo pointer points to a record of
-         type UNDO_INSERT; zero it out instead.  This fixes bug reported by
-         Craig Turner <craig@synect.com> with redoing `ctd[ESC]' (empty
-         insert after change to)
-
-shell.c
-       - change set_shell_name so invocations like "-/bin/bash" are marked as
-         login shells
-
-doc/bash.1
-       - add note about destroying functions with `unset -f' to the section
-         on shell functions
-
-lib/readline/terminal.c
-       - if readline hasn't been initialized (_rl_term_autowrap == -1, the
-         value it's now initialized with), call _rl_init_terminal_io from
-         _rl_set_screen_size before deciding whether or not to decrement
-         _rl_screenwidth.  Fixes bug from Mike Frysinger <vapier@gentoo.org>
-
-                                  1/14
-                                  ----
-lib/readline/input.c
-       - allow rl_set_keyboard_input_timeout to set the timeout to 0, for
-         applications that want to use select() like a poll without any
-         waiting
-
-lib/readline/doc/rltech.texi
-       - documented valid values for timeout in rl_set_keyboard_input_timeout
-
-jobs.c
-       - in stop_pipeline, don't have the parent shell call give_terminal_to
-         if subshell_environment contains SUBSHELL_ASYNC (no background
-         process should ever give the terminal to anything other than
-         shell_pgrp)
-       - in make_child, don't give the terminal away if subshell_environment
-         contains SUBSHELL_ASYNC
-
-                                  1/15
-                                  ----
-subst.c
-       - in parameter_brace_expand, if extracting ${#varname}, only allow
-         `}' to end the expansion, since none of the other expansions are
-         valid.  Fixes Debian bug reported by Jan Nordhorlz <jckn@gmx.net>
-
-                                  1/17
-                                  ----
-parse.y
-       - in parse_matched_pair, protect all character tests with the MBTEST
-         macro
-       - in parse_dparen, take out extra make_word after call to alloc_word_desc
-         (mem leak)
-
-                                  1/18
-                                  ----
-parse.y
-       - in parse_matched_pair, add P_ALLOWESC to flags passed to recursive
-         parse_matched_pair call when encountering a single or double quote
-         inside a ``-style command substitution
-
-execute_cmd.c
-       - add call to QUIT at beginning of execute_command_internal; better
-         responsiveness to SIGINT
-
-                                  1/21
-                                  ----
-lib/readline/bind.c
-       - change rl_invoking_keyseqs_in_map to honor the setting of
-         convert-meta when listing key bindings, since if convert-meta is off,
-         using '\M-' as the prefix for bindings in, for instance,
-         emacs-escape-keymap, is wrong.  This affects `bind -p' output
-       - change rl_untranslate_keyseq to add '\e' instead of '\C-[' for
-         ESC
-
-execute_cmd.c
-       - add call to QUIT at end of execute_command
-
-                                  1/23
-                                  ----
-lib/readline/display.c
-       - changed two places in update_line where a check of whether the cursor
-         is before the last invisible character in the prompt string to
-         differentiate between the multibyte character case (where
-         _rl_last_c_pos is a physical cursor position) and the single-byte
-         case (where it is a buffer index).  This prevents many unnecessary
-         \r-redraw the line sequences.  Reported by Dan Jacobson.
-
-                                  1/24
-                                  ----
-quit.h
-       - wrap QUIT macro in do...while(0) like other compound statement
-         macros
-       - CHECK_TERMSIG define (placeholder for now); future use will be to
-         handle any received signals that should  cause the shell to
-         terminate (e.g., SIGHUP)
-
-{input,jobs,nojobs}.c
-       - add calls to CHECK_TERMSIG where appropriate (reading input and
-         waiting for children)
-       - include quit.h if necessary
-
-                                  1/25
-                                  ----
-parse.y
-       - undo change that makes `)' in a compound assignment delimit a token.
-         It messes up arithmetic expressions in assignments to `let', among
-         other things
-
-sig.h,{jobs,nojobs,sig,trap}.c,builtins/trap.def
-       - rename termination_unwind_protect to termsig_sighandler
-
-sig.c
-       - split termsig_sighandler into two functions: termsig_sighandler, which
-         runs as a signal handler and sets a flag noting that a terminating
-         signal was received, and termsig_handler, which runs when it is `safe'
-         to handle the signal and exit
-       - new terminate_immediately variable, similar to interrupt_immediately
-       - termsig_sighandler calls termsig_handler immediately if
-         terminate_immediately is non-zero
-
-quit.h
-       - change CHECK_TERMSIG macro to check terminating_signal and call
-         termsig_handler if it's non-zero
-       - add same check of terminating_signal and call to termsig_handler to
-         QUIT macro
-
-{jobs,nojobs}.c
-       - change call to termsig_sighandler to call termsig_handler directly,
-         as was intended
-
-parse.y,builtins/read.def
-       - set terminate_immediately to non-zero value when reading interactive
-         input, as is done with interrupt_immediately
-
-                                  1/26
-                                  ----
-doc/{bash.1,bashref.texi}
-       - reworded the POSIX standard references to remove mention of POSIX.2
-         or 1003.2 -- it's all the 1003.1 standard now.  Recommended by
-         Arnold Robbins
-
-                                  1/27
-                                  ----
-lib/readline/complete.c
-       - move call to filename dequoting function into
-         rl_filename_completion_function; call only if directory completion
-         hook isn't set.  This means that directory-completion-hook now needs
-         to dequote the directory name.  We don't want to dequote the directory
-         name before calling the directory-completion-hook.  Bug reported by
-         Andrew Parker <andrewparker@bigfoot.com>
-
-bashline.c
-       - add necessary directory name dequoting to bash_directory_expansion
-         and bash_directory_completion_hook
-
-lib/readline/doc/rltech.texi
-       - add note to description of rl_directory_completion_hook that it
-         needs to dequote the directory name even if no other expansions are
-         performed
-
-                                  1/28
-                                  ----
-braces.c
-       - make sure that we skip over braces that don't start a valid matched
-         brace expansion construct in brace_expand -- there might be a valid
-         brace expansion after the unmatched `{' later in the string
-       - brace_gobbler now checks that when looking for a `}' to end a brace
-         expansion word, there is an unquoted `,' or `..' that's not inside
-         another pair of braces.  Fixes the a{b{c,d}e}f problem reported by
-         Tim Waugh
-
-builtins/declare.def
-       - when not in posix mode, and operating on shell functions, typeset
-         and declare do not require their variable operands to be valid
-         shell identifiers.  The other `attribute' builtins work this way.
-         Fixes inconsistency reported by Mike Frysinger <vapier@gentoo.org>
-
-{configure,config.h}.in
-       - add test for setregid, define HAVE_SETREGID and HAVE_DECL_SETREGID
-         as appropriate
-       - add test for eaccess, define HAVE_EACCESS if found
-
-lib/sh/eaccess.c
-       - new file, with sh_stat and sh_eaccess functions, moved from test.c
-       - renamed old sh_eaccess as sh_stataccess, since it uses the stat(2)
-         information to determine file accessibility
-       - new function, sh_euidaccess, to call when uid != euid or gid != egid;
-         temporarily swaps uid/euid and gid/egid around call to access
-       - rewrote sh_eaccess to call eaccess, access, sh_euidaccess or
-         sh_stataccess as appropriate.  access(2) will take into account
-         things like ACLs, read-only file systems, file flags, and so on.
-
-lib/sh/Makefile.in,Makefile.in
-       - add necessary entries for eaccess.[co]
-
-test.c
-       - change calls to test_stat to call sh_stat
-
-{test,general}.c
-       - change calls to test_eaccess to call sh_eaccess
-
-externs.h
-       - new extern declaration for sh_eaccess
-
-test.[ch]
-       - remove test_stat and test_eaccess
-
-                                  1/29
-                                  ----
-braces.c
-       - make change from 1/28 dependant on CSH_BRACE_COMPAT not being
-         defined (since old bash behavior is what csh does, defining
-         CSH_BRACE_COMPAT will produce old bash behavior)
-
-                                  1/30
-                                  ----
-bashline.c
-       - last argument of bash_default_completion is now a flags word:
-         DEFCOMP_CMDPOS (in command position) is only current value
-       - attempt_shell_completion now computes flags before calling
-         bash_default_completion
-       - if no_empty_command_completion is set, bash does not attempt command
-         word completion even if not at the beginning of the line, as long
-         as the word to be completed is empty and start == end (catches
-         beginning of line and all whitespace preceding point)
-
-                                   2/4
-                                   ---
-lib/readline/display.c
-       - change _rl_make_prompt_for_search to use rl_prompt and append the
-         search character to it, so the call to expand_prompt in rl_message
-         will process the non-printing characters correctly.  Bug reported
-         by Mike Stroyan <mike.stroyan@hp.com>
-
-                                   2/5
-                                   ---
-lib/readline/display.c
-       - fix off-by-one error when comparing against PROMPT_ENDING_INDEX,
-         which caused a prompt with invisible characters to be redrawn one
-         extra time in a multibyte locale.  Change from <= to < fixes
-         multibyte locale, but I added 1 to single-byte definition of
-         PROMPT_ENDING_INDEX (worth checking) to compensate.  Bug reported
-         by Egmont Koblinger <egmont@uhulinux.hu>
-
-                                   2/8
-                                   ---
-lib/readline/terminal.c
-       - call _emx_get_screensize with wr, wc like ioctl code for consistency
-       - new function, _win_get_screensize, gets screen dimensions using
-         standard Windows API for mingw32 (code from Denis Pilat)
-       - call _win_get_screensize from _rl_get_screen_size on mingw32
-
-lib/readline/rlconf.h
-       - define SYS_INPUTRC (/etc/inputrc) as system-wide default inputrc
-         filename
-
-support/shobj-conf
-       - changes to make loadable builtins work on MacOS X 10.[34]
-
-builtins/pushd.def
-       - changes to make it work as a loadable builtin compiled with gcc4
-
-                                   2/9
-                                   ---
-lib/readline/bind.c
-       - add SYS_INPUTRC as last-ditch default (if DEFAULT_INPUTRC does not
-         exist or can't be read) in rl_read_init_file
-
-lib/readline/doc/rluser.texi
-       - add description of /etc/inputrc as ultimate default startup file
-
-                                  2/10
-                                  ----
-lib/readline/bind.c
-       - fix problem with rl_function_of_keyseq that returns a non-keymap
-         bound to a portion of the passed key sequence without processing
-         the entire thing.  We can bind maps with existing non-map
-         functions using the ANYOTHERKEY binding code.
-
-variables.c
-       - shells running in posix mode do not set $HOME, as POSIX apparently
-         requires
-
-                                  2/15
-                                  ----
-braces.c
-       - mkseq() now takes the increment as an argument; changed callers
-
-                                  2/16
-                                  ----
-builtins/hash.def
-       - print `hash table empty' message to stdout instead of stderr
-
-                                  2/17
-                                  ----
-lib/readline/readline.c
-       - when resetting rl_prompt in rl_set_prompt, make sure rl_display_prompt
-         is set when the function returns
-
-                                  2/18
-                                  ----
-lib/readline/display.c
-       - further fixes to _rl_make_prompt_for_search from Eric Blake to deal
-         with multiple calls to expand_prompt
-
-                                  2/21
-                                  ----
-builtins/hash.def
-       - don't print `hash table empty' message in posix mode
-
-                                  2/27
-                                  ----
-lib/glob/sm_loop.c
-       - change extmatch() to turn off FNM_PERIOD in flags passed to recursive
-         calls to gmatch() when calling it with a substring after the start
-         of the string it receives.  Changed `+', `*', `?, `@', and `!' cases
-         to do the right thing.  Fixes bug reported by Benoit Vila
-         <bvila@free.fr>
-
-braces.c
-       - add QUIT; statements to mkseq to make large sequence generation
-         interruptible
-
-                                  2/28
-                                  ----
-lib/glob/glob.c
-       - initialize nalloca in glob_vector
-
-                                   3/1
-                                   ---
-lib/glob/glob.c
-       - in glob_vector, when freeing up the linked list after some error,
-         make sure to set `tmplink' to 0 if `firstlink' is set to 0, else we
-         get multiple-free errors
-
-                                   3/5
-                                   ---
-trap.c
-       - inheritance of the DEBUG, RETURN, and ERR traps is now dependent
-         only on the `functrace' and `errtrace' shell options, as the
-         documentation says, rather than on whether or not the shell is in
-         debugging mode.  Reported by Philip Susi <psusi@cfl.rr.com>
-
-parse.y
-       - in parse_matched_pair, don't recursively parse ${...} or other
-         ${...} constructs inside ``
-       - in parse_matched_pair, remove special code that recursively parses
-         quoted strings inside `` constructs.  For Bourne shell compatibility
-
-                                   3/6
-                                   ---
-builtins/pushd.def
-       - let get_directory_stack take take an `int flags' argument and convert
-         $HOME to ~ if flags&1 is non-zero
-
-builtins/common.h
-       - change extern declaration for get_directory_stack
-
-variables.c
-       - call get_directory_stack with an arg of 0 to inhibit converting
-         $HOME to  ~ in the result.  Fixes cd ${DIRSTACK[1]} problem
-         reported by Len Lattanzi <llattanzi@apple.com> (cd fails because
-         the tildes won't be expanded after variable expansion)
-
-jobs.c
-       - changed hangup_all_jobs slightly so stopped jobs marked J_NOHUP
-         won't get a SIGCONT
-
-general.c
-       - changed check_binary_file() to check for a NUL byte instead of a
-         non-printable character.  Might at some point want to check
-         entire (possibly multibyte) characters instead of just bytes.  Hint
-         from ksh via David Korn
-
-                                   3/7
-                                   ---
-builtins/reserved.def
-       - changed runs of spaces to tabs in variables help text to make
-         indentation better when displayed
-
-builtins/mkbuiltins.c
-       - changes to avoid the annoying extra space that keeps gettext from
-         being passed an empty string
-
-                                   3/9
-                                   ---
-lib/glob/glob.c
-       - make sure globbing is interrupted if the shell receives a terminating
-         signal
-
-                                  3/14
-                                  ----
-lib/readline/search.c
-       - call rl_message with format argument of "%" in _rl_nsearch_init
-         to avoid `%' characters in the prompt string from being interpreted
-         as format specifiers to vsnprintf/vsprintf
-
-                                  3/19
-                                  ----
-parse.y, eval.c, input.h
-       - change execute_prompt_command to execute_variable_command; takes the
-         variable name as a new second argument
-
-                                  3/25
-                                  ----
-bashline.c
-       - command_word_completion_function keeps track of when it's searching
-         $PATH and doesn't return directory names as matches in that case.
-         Problem reported by Pascal Terjan <pterjan@mandriva.com>
-       - command_word_completion_function returns what it's passed as a
-         possible match if it's the name of a directory in the current
-         directory (only non-absolute pathnames are so tested).
-
-                                  3/27
-                                  ----
-subst.c
-       - expand_arith_string takes a new argument: quoted.  Either 0 (outside
-         subst.c) or Q_DOUBLE_QUOTES (substitution functions); changed callers
-
-subst.h
-       - changed extern declaration for expand_arith_string
-
-arrayfunc.c
-       - changed call to expand_arith_string in array_expand_index
-
-                                  3/31
-                                  ----
-lib/readline/histfile.c
-       - change read_history_range to allow windows-like \r\n line endings
-
-execute_cmd.c
-       - add new variable, line_number_for_err_trap, currently set but not
-         used
-
-                                   4/2
-                                   ---
-lib/sh/strtrans.c
-       - add code to echo -e and echo with xpg_echo enabled to require
-         a leading 0 to specify octal constants
-
-                                   4/3
-                                   ---
-subst.c
-       - slight change to wcsdup() replacement: use memcpy instead of wcscpy
-
-parse.y
-       - before turning on W_COMPASSIGN, make sure the final character in the
-         token is a `(' (avoids problems with things like a=(4*3)/2)
-
-                                   4/4
-                                   ---
-lib/sh/snprintf.c
-       - in number() and lnumber(), turn off PF_ZEROPAD if explicit precision
-         supplied in format
-       - change number() and lnumber() to correctly implement zero-padding
-         specified by a non-zero `.precision' part of the format
-
-subst.c
-       - new flag for extract_delimited_string: EX_COMMAND.  For $(...), so
-         we can do things like skip over delimiters in comments.  Added to
-         appropriate callers
-       - changes to extract_delimited_string to skip over shell comments when
-         extracting a command for $(...) (EX_COMMAND is contained in the
-         flags argument)
-
-                                   4/5
-                                   ---
-subst.c
-       - first argument to skip_single_quoted is now a const char *
-       - new function, chk_arithsub, checks for valid arithmetic expressions
-         by balancing parentheses.  Fix based on a patch from Len Lattanzi
-
-                                   4/6
-                                   ---
-{configure,config.h}.in
-       - add separate test for isnan in libc, instead of piggybacking on
-         isinf-in-libc test
-
-lib/sh/snprintf.c
-       - separate the isnan replacement function so it's guarded by its own
-         HAVE_ISNAN_IN_LIBC define
-
-lib/sh/wcsdup.c
-       - new file, contains replacement wcsdup library function from subst.c
-         with change back to using wcscpy
-
-Makefile.in,lib/sh/Makefile.in
-       - make sure wcsdup.c is compiled and linked in
-
-subst.c
-       - wcsdup now found in libsh; removed static definition
-
-                                  4/10
-                                  ----
-lib/readline/callback.c
-       - loop over body of rl_callback_read_char as long as there is additional
-         input rather than just calling readline_internal_char, which does
-         not handle multi-character key sequences or escape-prefixed chars
-
-lib/readline/macro.c
-       - make sure we turn off RL_STATE_MACROINPUT when the macro stack is
-         empty if we are reading additional input with RL_STATE_MOREINPUT
-
-support/shobj-conf
-       - Mac OS X no longer likes the `-bundle' option to gcc when creating a
-         dynamic shared library
-
-                                  4/11
-                                  ----
-lib/tilde/tilde.c
-       - don't try to dereference user_entry if HAVE_GETPWENT isn't defined
-
-lib/readline/input.c
-       - make sure chars_avail is not used without being assigned a value in
-         rl_gather_tyi
-       - use _kbhit() to check for available input on Windows consoles, in
-         rl_gather_tyi and _rl_input_available
-
-                                  4/21
-                                  ----
-lib/readline/display.c
-       - calculate (in expand_prompt) and keep track of length of local_prompt
-         in local_prompt_len; use where appropriate
-       - when using o_pos to check whether or not we need to adjust
-         _rl_last_c_pos after calling update_line, assume that it's correct
-         (a buffer index in non-multibyte locales and a cursor position in
-         multibyte locales) and adjust with wrap_offset as appropriate
-       - in update_line, set cpos_adjusted to 1 after calling
-         _rl_move_cursor_relative to move to the end of the displayed prompt
-         string
-       - in _rl_move_cursor_relative, check that the multibyte display
-         position is after the last invisible character in the prompt string
-         before offsetting it by the number of invisible characters in the
-         prompt (woff)
-
-                                  4/26
-                                  ----
-lib/readline/doc/{rluser.texi,readline.3}
-       - make sure to note that key bindings don't allow any whitespace
-         between the key name or sequence to be bound and the colon
-
-                                  4/28
-                                  ----
-lib/readline/display.c
-       - in update_line, make sure we compare _rl_last_c_pos as strictly less
-         than PROMPT_ENDING_INDEX, since it's 0-based, to avoid multiple
-         prompt redraws
-
-                                   5/4
-                                   ---
-parse.y
-       - in decode_prompt_string, only prefix the expansion of \[ or \]
-         with CTLESC if the corresponding readline escape character is
-         CTLESC (coincidentally the same as \[) or CTLNUL.  Bug report sent
-         by Mike Frysinger <vapier@gentoo.org> prompted the discovery
-
-aclocal.m4
-       - slight change to test for /dev/fd to compensate for a linux
-         failing; suggested by Mike Frysinger <vapier@gentoo.org>
-
-                                   5/9
-                                   ---
-arrayfunc.c
-       - broke assign_array_var_from_string into two functions:
-         expand_compound_array_assignment and assign_compound_array_list;
-         assign_array_var_from_string just calls those functions now
-
-arrayfunc.h
-       - new extern declarations for expand_compound_array_assignment and
-         assign_compound_array_list
-
-subst.c
-       - in do_compound_assignment, call expand_compound_array_assignment
-         before creating the local variable so a previous inherited
-         value can be used when expanding the rhs of the compound assignment
-         statement
-
-                                  5/11
-                                  ----
-doc/{bash.1,bashref.texi}
-       - clarifed `trap' description to make it clear that trapped signals
-         that are not set to SIG_IGN are reset when a subshell is created
-
-                                  5/18
-                                  ----
-locale.c
-       - change reset_locale_vars to call setlocale (LC_ALL, "") if LANG
-         is unset or NULL
-       - if LANG is unset or NULL, reset the export environment before
-         calling setlocale in reset_locale_vars, and trust that it will
-         change the environment setlocale() inspects
-
-                                  5/21
-                                  ----
-lib/readline/history.c
-       - new function, HIST_ENTRY *alloc_history_entry (char *string, char *ts);
-         creates a new history entry with text STRING and timestamp TS (both
-         of which may be NULL)
-       - new function, HIST_ENTRY *copy_history_entry (HIST_ENTRY *hist),
-         which copies the line and timestamp entries to new memory but just
-         copies the data member, since that's an opaque pointer
-       - new function, void replace_history_data (int which, histdata_t *old, histdata_t *new)
-         which replaces the `data' member of specified history entries with
-         NEW, as long as it is OLD.  WHICH says which history entries to
-         modify
-       - add calls to replace_history_data in rl_free_undo_list and
-         rl_do_undo
-
-lib/readline/undo.c
-       - new function, alloc_undo_entry (enum undo_code what, int start, int end, char *text)
-         takes care of allocating and populating a struct for an individual
-         undo list entry
-       - new function: _rl_copy_undo_entry(UNDO_LIST *entry)
-       - new function: _rl_copy_undo_list(UNDO_LIST *head)
-
-lib/readline/rlprivate.h
-       - new extern declarations for _rl_copy_undo_{entry,list}
-
-execute_cmd.c
-       - change execute_cond_node so that quoting the rhs of the =~
-         operator forces string matching, like the == and != operators
-
-                                  5/23
-                                  ----
-redir.c
-       - add_undo_redirect now takes as an additional argument the type of
-         redirection we're trying to undo
-       - don't add a "preservation" redirection for fds > SHELL_FD_BASE if
-         the redirection is closing the fd
-
-                                  5/24
-                                  ----
-subst.c
-       - make sure that parameter_brace_substring leaves this_command_name
-         set to either NULL or its previous value after setting it so that
-         arithmetic evaluation errors while expanding substring values
-         contain meaningful information
-
-                                   6/9
-                                   ---
-execute_cmd.c
-       - make sure that SUBSHELL_ASYNC and SUBSHELL_PIPE are set as flag bits
-         in subshell_environment, rather than setting only a single value
-       - change execute_subshell_builtin_or_function to give the `return'
-         builtin a place to longjmp to when executed in a subshell or pipeline
-         (mostly as the last command in a pipeline).  Bug reported by
-         Oleg Verych <olecom@gmail.com>
-       - in execute_simple_command, make sure to call execute_disk_command
-         with the_printed_command_except_trap to keep DEBUG trap command
-         strings from overwriting the command strings associated with jobs
-         and printed in job control messages.  Bug reported by Daniel Kahn
-         Gillmor <dkg-debian.org@fifthhorseman.net>
-
-[bash-3.2-alpha frozen]
-
-                                  6/22
-                                  ----
-syntax.h
-       - add new CBLANK (for [:blank:] class) flag value for syntax table and
-         shellblank(c) character test macro
-
-mksyntax.c
-       - add support for setting CBLANK flag in the syntax table depending on
-         whether or not isblank(x) returns true for character x
-
-locale.c
-       - change locale_setblanks to set or unset CBLANK flag for each
-         character when locale changes
-
-parse.y
-       - change call to whitespace(c) in lexical analyzer (read_token()) to
-         call shellblank(c) instead, so locale-specific blank characters are
-         treated as white space.  Fixes bug reported by Serge van deb Boom
-         <svdb+bug-bash@stack.nl>
-
-print_cmd.c
-       - when printing redirections, add a space between <, >, and <> and the
-         following word, to avoid conflicts with process substitution.  Bug
-         reported by Ittay Dror <ittyad@qlusters.com>
-
-                                  6/26
-                                  ----
-configure.in
-       - set CROSS_COMPILE to the empty string by default, so we don't inherit
-         a random value from the environment.   Bug reported by
-         Lee Revell <rlrevell@joe-job.com>
-
-                                  6/29
-                                  ----
-lib/glob/xmbsrtowcs.c
-       - make sure destp is non-null before assigning a 0 to *destp in
-         xdupmbstowcs.  Fix from Louiwa Salem <loulwas@us.ibm.com>
-
-execute_cmd.c
-       - fix execute_in_subshell to make sure asynchronous isn't set to 0
-         before subshell_environment is set appropriately and
-         setup_async_signals is run.  Based on report by Louiwa Salem
-         <loulwas@us.ibm.com>
-
-lib/readline/bind.c
-       - in rl_generic_bind(), make sure that the keys array is freed before
-         an error return.  Fix from Louiwa Salem <loulwas@us.ibm.com>
-
-                                   7/1
-                                   ---
-builtins/read.def
-       - make sure all editing code is protected with #ifdef READLINE, esp.
-         unwind-protect that restores the default completion function
-
-lib/readline/display.c
-       - make sure to set local_prompt_len in rl_message() [in bash-3.2-alpha]
-
-                                   7/5
-                                   ---
-builtins/printf.def
-       - add more of echo's write error handling to printf.  Suggested by
-         martin.wilck@fujitsu-siemens.com
-
-                                   7/7
-                                   ---
-lib/readline/display.c
-       - save and restore local_prompt_len in rl_{save,restore}_prompt
-         [in bash-3.2-alpha]
-
-                                   7/8
-                                   ---
-[bash-3.2-alpha released]
-
-                                   7/9
-                                   ---
-lib/readline/display.c
-       - make sure that _rl_move_cursor_relative sets cpos_adjusted when it
-         offsets `dpos' by wrap_offset in a multi-byte locale.  Bug reported
-         by Andreas Schwab and Egmont Koblinger
-
-subst.c
-       - make sure that the call to mbstowcs in string_extract_verbatim is
-         passed a string with enough space for the closing NUL.  Reported
-         by Andreas Schwab
-
-                                  7/18
-                                  ----
-lib/readline/{display,terminal}.c
-       - remove #ifdefs for HACK_TERMCAP_MOTION so we can use
-         _rl_term_forward_char in the redisplay code unconditionally
-
-lib/readline/rlprivate.h
-       - new extern declaration for _rl_term_forward_char
-
-lib/readline/display.c
-       - in _rl_move_cursor_relative, use `dpos' instead of `new' when
-         deciding whether or not a CR is faster than moving the cursor from
-         its current position
-       - in _rl_move_cursor_relative, we can use _rl_term_forward_char to
-         move the cursor forward in a multibyte locale, if it's available.
-         Since that function doesn't have a handle on where the cursor is in
-         the display buffer, it has to output a cr and print all the data.
-         Fixes rest of problem reported by Egmont Koblinger
-       - change variable denoting the position of the cursor in the line buffer
-         from c_pos (variable local to rl_redisplay) to cpos_buffer_position
-         (variable local to file) for future use by other functions
-
-                                  7/25
-                                  ----
-lib/malloc/{stats,table}.h
-       - include <string.h> for prototypes for memset, strlen
-
-lib/termcap/{termcap,tparam}.c
-       - include <string.h> and provide macro replacement for bcopy if
-         necessary
-
-                                  7/27
-                                  ----
-lib/readline/histexpand.c
-       - add support for `<<<' here-string redirection operator to
-         history_tokenize_word.  Bug reported by agriffis@gentoo.org
-
-externs.h      
-       - don't add prototype for strerror() if HAVE_STRERROR defined
-
-                                  7/29
-                                  ----
-subst.c
-       - in list_string, use `string' instead of `s' -- s is not initialized
-
-                                   8/9
-                                   ---
-subst.c
-       - fix parameter_brace_expand to set W_HASQUOTEDNULL in the WORD_DESC it
-         returns if the result of parameter_brace_substring is a quoted null
-         ("\177").  Fixes bug reported by Igor Peshansky <pechtcha@cs.nyu.edu>
-
-                                  8/16
-                                  ----
-lib/readline/readline.h
-       - new #define, READERR, intended to be used to denote read/input errors
-
-lib/readline/input.c
-       - in rl_getc, if read() returns an error other than EINTR (after the
-         EWOULDBLOCK/EAGAIN cases are handled), return READERR rather than
-         converting return value to EOF if readline is reading a top-level
-         command (RL_STATE_READCMD)
-
-lib/readline/readline.c
-       - if rl_read_key returns READERR to readline_internal_char[loop],
-         abort as if it had read EOF on an empty line, without any conversion
-         to newline, which would cause a partial line to be executed.  This
-         fixes the bug reported by Mathieu Bonnet <mathieu.bonnet@nalkym.org>
-
-aclocal.m4
-       - when testing for validity of /dev/fd/3, use /dev/null instead of
-         standard input, since the standard input fails with linux and `su'.
-         Bug reported by Greg Shafer <gschafer@zip.com.au>
-
-                                  8/17
-                                  ----
-Makefile.in
-       - switch the TAGS and tags targets so TAGS is the output of `etags' and
-         tags is the output of `ctags'.  Suggested by Masatake YAMATO
-
-                                  8/25
-                                  ----
-execute_cmd.c
-       - change code to match documentation: set BASH_COMMAND (which takes its
-         value from the_printed_command_except_trap) only when not running a
-         trap.  Rocky says the debugger is ok with this, and this is what his
-         original diffs did
-
-                                  8/29
-                                  ----
-variables.c
-       - change set_if_not to create shell_variables if it is NULL, since
-         -o invocation options can cause variables to be set before the
-         environment is scanned
-
-[bash-3.2-beta frozen]
-
-                                   9/5
-                                   ---
-[bash-3.2-beta released]
-
-                                   9/8
-                                   ---
-variables.c
-       - change dispose_used_env_vars to call maybe_make_export_env
-         immediately if we're disposing a temporary environment, since
-         `environ' points to the export environment and getenv() will use
-         that on systems that don't allow getenv() to be replaced.  This
-         could cause the temporary environment to affect the shell.  Bug
-         reported by Vasco Pedro <vp@di.uevora.pt>
-
-builtins/echo.def,doc/{bash.1,bashref.texi}
-       - clarify that `echo -e' and echo when the `xpg_echo' shell option is
-         enabled require the \0 to precede any octal constant to be expanded.
-         Reported by Vasco Pedro <vp@di.uevora.pt>
-
-                                  9/12
-                                  ----
-builtins/printf.def
-       - make sure `%q' format specifier outputs '' for empty string arguments
-         Bug reported by Egmont Koblinger <egmont@uhulinux.hu>
-
-make_cmd.c
-       - change make_here_document to echo lines in here-doc if set -v has
-         been executed.  Reported by Eduardo Ochs <eduardoochs@gmail.com>
-
-aclocal.m4
-       - change BASH_CHECK_MULTIBYTE:
-               o replace check for wctomb with check for wcrtomb
-               o add checks for wcscoll, iswctype, iswupper, iswlower,
-                 towupper, towlower
-               o add call to AC_FUNC_MBRTOWC to check for mbrtowc and mbstate_t
-                 define HAVE_MBSTATE_T manually
-               o add checks for wchar_t, wctype_t, wint_t
-
-config.h.in
-       - add defines for wcscoll, iswctype, iswupper, iswlower, towupper,
-         towlower functions
-       - replace define for wctomb with one for wcrtomb
-       - add defines for wchar_t, wint_t, wctype_t types
-
-config-bot.h, lib/readline/rlmbutil.h
-       - add check for HAVE_LOCALE_H before defining HANDLE_MULTIBYTE
-       - add checks for: ISWCTYPE, ISWLOWER, ISWUPPER, TOWLOWER, TOWUPPER
-       - add checks for: WCTYPE_T, WCHAR_T, WCTYPE_T
-
-                                  9/13
-                                  ----
-lib/readline/display.c
-       - when displaying prompts longer than the screenwidth in rl_redisplay,
-         and looking for the index of the last character whose buffer index
-         is <= the screen width to set up the inv_lbreaks array, make sure to
-         catch the case where the index == the screen width (an off-by-one
-         error occurs otherwise with prompts one character longer than the
-         screen width).  Bug reported by Alexey Toptygin <alexeyt@freeshell.org>
-
-configure.in
-       - change DEBUGGER_START_FILE to start with ${ac_default_prefix}/share,
-         like bashdb installs itself.  Reported by Nick Brown
-         <nickbroon@blueyonder.co.uk>
-
-                                  9/14
-                                  ----
-lib/readline/display.c
-       - make multibyte code that computes the buffer indices of line breaks
-         for a multi-line prompt dependent on MB_CUR_MAX, so we don't take
-         the function call hit unless we're in a locale that can have
-         multibyte characters
-
-                                  9/19
-                                  ----
-subst.c
-       - make dequote_list extern so other parts of the shell can use it
-
-subst.h
-       - extern declaration for dequote_list
-
-builtins/read.def
-       - call dequote_list before assigning words read to array variable if
-         we saw an escape character.  Old code left spurious CTLESCs in the
-         string after processing backslashes.  Bug reported by Daniel Dawson
-         <ddawson@icehouse.net>
-
-                                  9/21
-                                  ----
-[bash-3.2 frozen]
-
-                                  10/9
-                                  ----
-support/shobj-coonf
-       - change -fpic to -fPIC for FreeBSD systems (needed for SPARC at least)
-
-                                  10/11
-                                  -----
-[bash-3.2 released]
-
-                                  10/12
-                                  -----
-parse.y
-       - change parse_matched_pair to make sure `` command substitution does
-         not check for shell comments while parsing.  Bug reported against
-         bash-3.2 by Greg Schaefer <gschafer@zip.com.au>
-
-                                  10/14
-                                  -----
-parse.y
-       - add new parser_state flag: PST_REGEXP; means we are parsing a
-         regular expression following the =~ conditional operator
-       - cond_node sets PST_REGEXP after reading the `=~' operator     
-       - change read_token to call read_token_word immediately if the
-         PST_REGEXP bit is set in parser_state
-       - change read_token_word to skip over `(' and `|' if PST_REGEXP is
-         set, since those characters are legitimate regexp chars (but still
-         parse matched pairs of parens)
-
-                                  10/16
-                                  -----
-builtins/ulimit.def
-       - add -e and -r to $SHORT_DOC usage string
-
-po/ru.po
-       - fix encoding; Russian text in the file is actually encoded in KOI8-R
-
-                                  10/23
-                                  -----
-shell.c
-       - make sure that the call to move_to_high_fd in open_shell_script
-         passes 1 for the  `check_new' parameter so open high file descriptors
-         don't get closed and reused.  Bug reported by Mike Stroyan
-         <mike.stroyan@hp.com>
-
-doc/bashref.texi
-       - fixes for typos and misspellings sent in by Brian Gough
-
-                                  10/24
-                                  -----
-support/shobj-conf
-       - make netbsd shared library creation like openbsd's until I hear
-         differently (called using `gcc -shared')
-
-                                  10/26
-                                  -----
-subst.c
-       - fix bug in parameter_brace_patsub so if the first character of the
-         expanded pattern is a `/', it is not taken as a global replacement
-         specifier.  Bug reported on forums.nekochan.net 
-
-                                  10/27
-                                  -----
-builtins/printf.def
-       - if we need an extern declaration for asprintf, make sure we include
-         stdarg.h or varargs.h, whichever is appropriate
-       - if we do not have asprintf, add an extern declaration using
-         stdarg format.  This fixes the bugs with %G on IRIX reported by
-         Matthew Woehlke <mwoehlke@tibco.com> and Stuart Shelton
-         <srcshelton@gmail.com>
-
-
-lib/sh/snprintf.c
-       - add note to not call log_10 with 0 argument -- we don't want to do
-         what real log10 does (-infinity/raise divide-by-zero exception)
-       - make sure numtoa (used by dtoa) takes the precision into account
-         when computing the fractional part with an argument of `0.0'
-       - make sure `g' and `G' formats don't print radix char if there are
-         no characters to be printed after it (change to floating())
-       - change callers of log_10 (exponent, 'g' and 'G' cases in
-         vsnprintf_internal) to not call it with 0 for argument.  This fixes
-         the hang reported on IRIX by Matthew Woehlke <mwoehlke@tibco.com>
-         and Stuart Shelton <mwoehlke@tibco.com>
-
-                                  10/28
-                                  -----
-builtins/{caller,pushd}.def
-       - changed longdoc strings in loadable builtin section to be single
-         strings, as put in the build directory builtins.c file, to aid
-         translators
-
-                                  11/1
-                                  ----
-execute_cmd.c
-       - reset subshell_environment to 0 after make_child() call in
-         execute_null_command.  Fix provided by Roy Marples
-         <uberlord@gentoo.org>
-
-                                  11/7
-                                  ----
-lib/tilde/tilde.c
-lib/readline/{util,undo,callback,input,isearch,kill}.c
-       - make sure that memory allocated with xmalloc is freed with xfree
-
-                                  11/9
-                                  ----
-lib/readline/display.c
-       - make sure that _rl_redisplay_after_sigwinch clears the last displayed
-         line instead of the current line (instead of assuming that the
-         cursor is on the last line).  Fixes bug reported by Egmont
-         Koblinger <egmont@uhulinux.hu>
-
-                                  11/10
-                                  -----
-lib/readline/display.c
-       - make sure that _rl_col_width is never called with MB_CUR_MAX == 1,
-         since it doesn't count invisible characters and they are not
-         compensated for.  Added a warning in _rl_col_width if called when
-         MB_CUR_MAX == 1.  Bug reported and solution suggested by Eric
-         Blake <ebb9@byu.net>
-
-                                  11/11
-                                  -----
-lib/readline/display.c
-       - make sure _rl_wrapped_line is initialized to inv_lbsize int chars.
-         inv_lbsize and vis_lbsize are the same at that point, but it makes
-         the intent clearer.  Fix from jan.kratochvil@redhat.com.
-       - in rl_redisplay, make sure we call memset on _rl_wrapped_line with
-         its full initialized size: inv_lbsize*sizeof(int).  Fix from
-         jan.kratochvil@redhat.com.
-       - wrap the invisible and visible line variables and _rl_wrapped_line
-         into line_state structures, which can be swapped more efficiently.
-         Have to watch the wrapped_line field, since there's now one for
-         each struct.  Changes from jan.kratochvil@redhat.com.
-
-lib/readline/complete.c
-       - in stat_char, check for `//server' on cygwin and return `/', since
-         it will always behave as a directory.  Fix from Eric Blake
-
-lib/readline/histfile.c
-       - Cygwin's mmap() works in recent versions, so don't #undef HAVE_MMAP.
-         Recommendation from Eric Blake
-
-lib/readline/rlwinsize.h
-       - make sure tcflow() is defined on SCO Unix.  Fix from William Bader
-
-aclocal.m4
-       - add check for localeconv to AM_INTL_SUBDIR macro
-
-config.h.in
-       - add HAVE_LOCALECONV
-
-lib/sh/snprintf.c
-       - add check for HAVE_LOCALECONV for GETLOCALEDATA macro
-
-general.[ch]
-       - first argument to legal_number is now `const char *'
-
-                                  11/14
-                                  -----
-lib/readline/{readline,rlprivate}.h
-       - move rl_display_prompt declaration from rlprivate.h to readline.h
-
-lib/readline/util.h
-       - new function: rl_free(void *mem), for use by users of readline dlls
-         on Windows
-
-lib/readline/readline.h
-       - new extern declaration for rl_free
-
-lib/readline/doc/rltech.texi
-       - document rl_free and rl_display_prompt for use by application writers
-
-                                  11/15
-                                  -----
-aclocal.m4
-       - change tests for /dev/fd and /dev/stdin to use constructs of the form
-         (exec test ... ) instead of test ... to avoid bash's /dev/fd and
-         /dev/stdin emulation
-
-                                  11/16
-                                  -----
-jobs.c
-       - in delete_job, reset_current was being called before the job slot
-         was cleared -- moved after job_slots[job] was set to NULL.  Fixes
-         bug reported by Dan Jacobson <jidanni@jidanni.org>
-
-                                  11/19
-                                  -----
-findcmd.c
-       - when the checkhash option is set, fix the check for the hashed
-         pathname being an existing executable file.  Old code required a
-         hash table deletion and re-addition.  Bug reported by Linda
-         Walsh <bash@tlinx.org>
-
-                                  11/21
-                                  -----
-subst.c
-       - in pos_params, handle case of `start' == 0 by making the list of
-         positional parameters begin with $0
-       - in parameter_brace_substring, increment `len' if start == 0, sicne
-         we will be adding $0 to the beginning of the list when we process it
-
-doc/{bash.1,bashref.texi}
-       - document new behavior of `0' offset when using substring expansion
-         with the positional parameters
-
-support/shobj-conf
-       - changes to shared object creation for loadable builtins on Mac OS X
-         10.4 to use libtool instead of ld by specifying -dynamiclib
-         argument and changing options to be appropriate for libtool.  This
-         winds up creating a dynamic shared library instead of an executable
-
-                                  11/24
-                                  -----
-{jobs,nojobs}.c
-        - don't set last_asynchronous_pid to the child's pid in the child
-          for asynchronous jobs (for compatibility -- all other posix shells
-          seem to do it this way).  This means that (echo $! )& echo $! should
-          display two different pids.  Fix from discussion on the
-          austin-group-l list
-
-builtins/mkbuiltins.c
-       - change builtins.c file generation so short doc strings are marked for
-         gettext and available for subsequent translation.  Suggestion by
-         Benno Schulenberg <bensberg@justemail.net>
-
-builtins/{bind,cd,hash,inlib,printf,pushd,test,times,ulimit}.def
-lib/malloc/malloc.c
-{shell,subst}.c
-       - fix a few strings that were not marked as translatable.  Fix from
-         Benno Schulenberg <bensberg@justemail.net>
-
-lib/readline/misc.c
-       - new function, _rl_revert_all_lines(void).  Goes through history,
-         reverting all entries to their initial state by undoing any undo
-         lists.
-
-lib/readline/rlprivate.h
-       - extern declaration for _rl_revert_all_lines
-
-rldefs.h
-       - add #undef HAVE_STRCOLL if STRCOLL_BROKEN is defined, prep to move
-         from config.h.in.  Problem reported by Valerly Ushakov
-         <uwe@ptc.spbu.ru>
-
-                                  11/25
-                                  -----
-lib/readline/readline.c
-       - call _rl_revert_all_lines from readline_internal_teardown if the
-         variable _rl_revert_all_at_newline is non-zero
-       - declare _rl_revert_all_lines initially 0
-
-                                  11/27
-                                  -----
-doc/{bash.1,bashref.texi}
-       - make sure to be explicit that `typeset +r' cannot remove the readonly
-         attribute from a variable
-
-                                  11/28
-                                  -----
-lib/sh/zmapfd.c
-       - new file, implements zmapfd(), which takes a file and returns its
-         contents in a string
-
-externs.h
-       - extern declaration for zmapfd
-
-                                  11/29
-                                  -----
-builtins/evalfile.c
-       - in _evalfile, use zmapfd to read the contents of the file into a
-         string, rather than using the size reported by stat and reading that
-         many characters, if the file is not a regular file (for things like
-         named pipes, stat reports the size as 0)
-
-                                  12/3
-                                  ----
-lib/sh/snprintf.c
-       - make sure number() sets the FL_UNSIGNED flag for %x and %X, so
-         fmtulong treats them as unsigned numbers.  Fixes bug reported by
-         James Botte <James.M.Botte@lowes.com>
-
-                                  12/13
-                                  -----
-lib/readline/util.c
-       - new function, _rl_ttymsg, for internal warning messages -- does
-         redisplay after printing message
-       - new function, _rl_errmsg, for internal warning/error messages --
-         does not do redisplay after printing message
-
-lib/readline/rlprivate.h
-       - new extern declaration for _rl_ttymsg, _rl_errmsg
-
-lib/readline/{bind,callback,complete,display,rltty}.c
-       - use _rl_ttymsg/_rl_errmsg instead of direct writes to stderr
-
-lib/sh/tmpfile.c
-       - in get_tmpdir(), make sure that $TMPDIR names a writable directory;
-         otherwise skip it.  This catches names longer than PATH_MAX, but in
-         case it doesn't test that the length does not exceed PATH_MAX.  Fixes
-         heap overrun bug reported by Eric Blake <ebb9@byu.net>
-
-                                  12/16
-                                  -----
-builtin/{set,declare,shopt,trap,wait,bind,complete,enable,fc,history,read,setattr}.def
-doc/{bash.1,bashref.texi}
-       - improvements and clarifications to the help text associated with
-         several builtins, in some cases bringing them into line with the
-         man page text.  From Benno Schulenberg <bensberg@justemail.net>
-
-doc/{bash.1,bashref.texi}
-       - add `E' and `T' to the synopsis of the set builtin.
-         From Benno Schulenberg <bensberg@justemail.net>
-
-builtins/{break,exit,fg_bg,hash,jobs,type,ulimit}.def
-builtins/{common,evalfile}.c
-{error,expr,jobs,mksyntax,nojobs,shell,subst,version,siglist}.c
-       - add gettextizing marks to untranslated strings
-         From Benno Schulenberg <bensberg@justemail.net>
-
-                                  12/19
-                                  -----
-builtins/common.c
-       - change display_signal_list (used by `trap -l' and `kill -l') to use
-         five columns instead of 4 to display signal names
-
-builtins/help.def
-       - use the true terminal width instead of assuming 80 when displaying
-         help topics, leaving two characters of whitespace between horizontal
-         descriptions instead of 1
-       - change to print in columns with entries sorted down rather than across
-         (that is, like `ls' rather than `ls -x').  Change inspired by Benno 
-         Schulenberg <bensberg@justemail.net>
-
-jobs.h
-       - give values to the JOB_STATE enumerations so they can be used as
-         bitmasks, too
-
-                                  12/22
-                                  -----
-doc/{bash.1,bashref.texi}
-       - change description of `set' to make it clearer that you can use
-         `+' to turn off options
-       - clarify in the description of word splitting that sequences of
-         IFS whitespace at the beginning or end of the string are ignored
-
-                                  12/26
-                                  -----
-doc/bashref.texi
-       - move `shopt' builtin to its own section; change internal references
-         from `Bash Builtins' to the new shopt builtin
-       - new section for builtins that modify shell behavior in `Shell
-         Builtin Commands'; move set and shopt to new section.  Changes
-         inspired by Benno Schulenberg <bensberg@justemail.net>
-
-{redir,subst}.c
-       - add MT_USETMPDIR flag to calls to sh_mktmpfd and sh_mktmpname.  Bug
-         reported by Eric Blake <ebb9@byu.net>
-
-{configure,Makefile}.in
-       - changes so that the pathname for DEBUGGER_START_FILE is substituted
-         into pathnames.h at make time (allowing more flexibility in setting
-         `prefix' or `datadir') instead of at configure time.  Suggested by
-         Nick Brown <nickbroon@blueyonder.co.uk>
-
-shell.c
-       - declaration for  have_devfd; initialized from HAVE_DEV_FD
-       - declaration for check_jobs_at_exit; initialized to 0
-       - declaration for autocd; initialized to 0
-
-variables.c
-       - new dynamic variable, BASHPID, always set from return value from
-         getpid() (changes even when $$ doesn't change).  Idea from Bruce
-         Korb <bruce.corb@3pardata.com>
-
-builtins/exit.def
-       - if check_jobs_at_exit is non-zero, list jobs if there are any stopped
-         or running background jobs; don't exit shell if any running jobs
-
-execute_cmd.c
-       - in execute_simple_command, if the first word of a simple command is
-         a directory name (after looking for builtins, so `.' isn't caught)
-         that isn't found in $PATH, and `autocd' is non-zero, prefix a "cd"
-         to the command words
-
-builtins/shopt.def
-       - new `checkjobs' option, changes value of check_jobs_at_exit
-       - new `autocd' option, changes value of autocd
-
-pcomplete.c
-       - add COMP_TYPE, set to rl_completion_type, to list of variables set
-         by bind_compfunc_variables and unset by unbind_compfunc_variables
-
-doc/{bash.1,bashref.texi}
-       - document BASHPID
-       - document new shopt `checkjobs' option
-       - document new shopt `autocd' option
-       - document COMP_TYPE completion variable
-
-                                  12/29
-                                  -----
-aclocal.m4
-       - in BASH_SYS_SIGLIST, check HAVE_DECL_SYS_SIGLIST instead of the
-         obsolete and no-longer-supported SYS_SIGLIST_DECLARED
-
-                                  12/30
-                                  -----
-lib/readline/vi_mode.c
-       - add ` (backquote) to the list of vi motion characters
-       - in rl_vi_delete_to, rl_vi_change_to, and rl_vi_yank_to, don't delete
-         character under the cursor if the motion command moves the cursor
-         backward, so add F and T to the commands that don't cause the
-         mark to be adjusted
-       - add ` to the characters that don't cause the mark to be adjusted
-         when used as a motion command, since it's defined to behave that way
-       - when a motion character that may adjust the mark moves point
-         backward, don't adjust the mark so the character under the cursor
-         isn't deleted
-
-lib/readline/complete.c
-       - add variable rl_sort_completion_matches; allows application to
-         inhibit match list sorting
-       - add variable rl_completion_invoking_key; allows applications to
-         discover the key that invoked rl_complete or rl_menu_complete
-
-lib/readline/readline.h
-       - extern declarations for rl_completion_invoking_key and
-         rl_sort_completion_matches
-
-lib/readline/doc/rltech.texi
-       - documented rl_completion_invoking_key and rl_sort_completion_matches
-
-pcomplete.c
-       - export variable COMP_KEY to completion functions; initialized from
-         rl_completion_invoking_key; unset along with rest of completion
-         variables
-
-doc/{bash.1,bashref.texi},lib/readline/doc/rluser.texi
-       - document COMP_KEY
-
-[many files]
-       - changes to make variables and function parameters `const' for better
-         text sharing.  Changes originally from Andreas Mohr
-         <andi@rhlx01.fht-esslingen.de>
-
-                                1/4/2007
-                                --------
-lib/intl/Makefile.in
-       - use cmp before copying libgnuintl.h to libintl.h -- maybe save a few
-         rebuilds
-
-lib/builtins/Makefile
-       - fixes to build LIBINTL_H if necessary, dependency on this for
-         mkbuiltins.o prevented `make -j 6' from working correctly
-
-                                   1/8
-                                   ---
-subst.c
-       - new function, fifos_pending(), returns the count of FIFOs in
-         fifo_list (process substitution)
-
-subst.h
-       - extern declaration for fifos_pending()
-
-execute_cmd.c
-       - in execute_simple_command, if CMD_NO_FORK is set before we call
-         execute_disk_command, make sure there are no FIFOs in the expanded
-         words (from process substitution) and turn off CMD_NO_FORK if there
-         are, so they can get unlinked when the command finishes
-
-                                  1/10
-                                  ----
-subst.c
-       - read_comsub now takes a flags parameter and returns appropriate W_*
-         flags in it
-       - command_substitute now returns a WORD_DESC *, with the string it used
-         to return as the `word' and `flags' filled in appropriately
-
-subst.h
-       - changed extern declaration for command_substitute
-
-{pcomplete,subst}.c
-       - changed callers of command_substitute appropriately
-
-subst.c
-       - string_extract_verbatim now takes an additional int flags argument;
-         changed callers
-
-                                  1/11
-                                  ----
-support/texi2html
-       - fix problem that caused index links to not be generated if the first
-         index node had a name different than the node name
-
-doc/bashref.texi
-       - encapsulated all indexes into a single `Indexes' appendix; works
-         around bug fixed in texi2html
-
-                                  1/12
-                                  ----
-subst.c
-       - add call to sv_histtimefmt in initialize_variables so HISTTIMEFORMAT
-         from the environment is honored.  Fix from Ark Submedes (heh)
-         <archimerged@gmail.com>
-
-lib/readline/histfile.c
-       - make sure that the first character following the history comment
-         character at the beginning of a line is a digit before interpreting
-         it as a timestamp for the previous line
-
-doc/{bash.1,bashref.texi},lib/readline/doc/hsuser.texi
-       - added detail to make it clear exactly how history timestamps are
-         saved to and read from the history file
-
-subst.c
-       - change quote_escapes to add CTLESC before spaces if IFS is null,
-         just in case we have to split on literal spaces later on (e.g., in
-         case of unquoted $@).  Corresponding changes to dequote_escapes.
-         Fixes a couple of problems reported by Brett Stahlman
-         <brettstahlman@comcast.net>
-
-                                  1/14
-                                  ----
-subst.c
-       - make same change to read_comsub to add CTLESC before ' ' if $IFS is
-         null, since we will split on literal spaces later
-
-                                  1/15
-                                  ----
-array.c
-       - new function, array_quote_escapes (ARRAY *a), calls quote_escapes
-         on each element of the array in the same way array_quote calls
-         quote_string
-       - call array_quote_escapes if match is not quoted in array_patsub
-       - array_slice is now used, so remove the #ifdef INCLUDE_UNUSED define
-       - change structure of array_subrange to call array_slice to create a
-         new array with the desired subset of elements, then call array_quote
-         or array_quote_escapes as necessary, like array_patsub.  Convert to
-         a string by calling array_to_string on the sliced-out array
-
-array.h
-       - new extern declaration for array_quote_escapes
-
-subst.c
-       - since array_patsub now calls quote_escapes as necessary, callers
-         don't need to call it after array_patsub returns.  Fixes first bug
-         reported by Brett Stahlman <brettstahlman@comcast.net>
-       - since array_subrange now calls quote_escapes as necessary, callers
-         don't need to call it after array_patsub returns.  Same fix as
-         for array_patsub
-
-                                  1/31
-                                  ----
-configure.in
-       - add -DSOLARIS to LOCAL_CFLAGS for solaris x
-
-config-bot.h
-       - don't #undef HAVE_GETCWD if GETCWD_BROKEN and SOLARIS are both
-         defined.  Solaris's loopback mount implementation breaks some of the
-         file system assumptions the replacement getcwd uses.
-
-builtins/common.c
-       - if GETCWD_BROKEN is defined, call getcwd with PATH_MAX for the size
-         argument, so it will allocate a buffer for the current working dir
-         with that size, instead of one that's `big enough'
-
-config.h.in
-       - add #undef PRI_MACROS_BROKEN for AIX 4.3.3
-
-pathexp.h
-       - new flag value for quote_string_for_globbing: QGLOB_REGEXP (quoting
-         an ERE for matching as a string)
-
-pathexp.c
-        - change quote_string_for_globbing to understand QGLOB_REGEXP
-
-execute_cmd.c
-       - change execute_cond_node to pass 2 (regexp match), 1 (shell pattern
-         match), or 0 (no matching) to cond_expand_word
-
-subst.c
-       - change cond_expand_word to translate SPECIAL==2 into passing
-         QGLOB_REGEXP to quote_string_for_globbing
-
-locale.c
-       - by default, if all else fails, set shell's idea of locale to ""
-         instead of its idea of `default_locale' -- the library functions
-         behave better with that value
-
-                                   2/2
-                                   ---
-builtins/printf.def
-       - if PRI_MACROS_BROKEN is defined, #undef PRIdMAX (AIX 4.3.3 broken)
-
-                                   2/3
-                                   ---
-Makefile.in,{builtins,doc}/Makefile.in,lib/*/Makefile.in
-       - add assignment for datarootdir as per GNU coding standards
-
-Makefile.in,builtins/Makefile.in,lib/intl/Makefile.in,po/Makefile.in.in
-       - use @localedir@ instead of $(datadir)/locale in assignment
-
-                                  2/13
-                                  ----
-jobs.c
-       - fix compact_jobs_list to not return js.j_lastj, since that is in use
-         and should not be overwritten.  Fix from Len Lattanzi
-         <llattanzi@apple.com>
-
-                                  2/16
-                                  ----
-lib/readline/text.c
-       - change rl_forward_char to allow moving to the end of the line when
-         using the arrow keys in vi insertion mode, rather than having the
-         behavior identical between vi command and insertion modes.  Change
-         suggested by Hugh Sasse <hgs@dmu.ac.uk>
-
-                                  2/19
-                                  ----
-CWRU/audit-patch
-       - patch from Steve Grubb of RedHat <sgrubb@redhat.com> to make bash
-         audit root's behavior by logging commands using his audit
-         framework.  Enabled if the shell's name is `aubash'.
-
-                                   3/8
-                                   ---
-jobs.c
-       - use WSTATUS (p->status) instead of bare p->status.  Fix from
-         Jim Brown <jim.brown@rsmas.miami.edu>
-
-                                   3/9
-                                   ---
-lib/readline/{complete,input,isearch,misc,readline,text,vi_mode}.c
-       - make sure cases where rl_read_key returns -1 (usually due to EIO
-         because the controlling tty has gone away) are handled correctly.
-         Prompted by report from Thomas Loeber <ifp@loeber1.de>
-
-                                  3/10
-                                  ----
-sig.c
-       - new function, top_level_cleanup, callable from contexts where some
-         cleanup needs to be performed before a non-fatal call to
-         jump_to_top_level
-
-sig.h
-       - new extern declaration for top_level_cleanup
-
-builtins/common.c
-       - add calls to top_level_cleanup before calls to jump_to_top_level
-         in a builtin command context (no_args(), get_numeric_arg()).  Fixes
-         bug reported by Ian Watson
-
-lib/readline/display.c
-       - in _rl_move_cursor_relative, use `new' when comparing against
-         the last invisible character in the prompt, since they both denote
-         buffer indices when in a multibyte locale, whereas `dpos' is a
-         display position
-
-                                  3/13
-                                  ----
-lib/readline/complete.c
-       - set rl_completion_append_character to the default (' ') in
-         set_completion_defaults().  Fixes bug reported by David Emerson
-         <demerson3x@angelbase.com>
-
-                                  3/23
-                                  ----
-builtins/evalfile.c
-       - make sure read() returns a value >= 0 before using it as an index
-         into string[]
-       - use a variable of type `ssize_t' for return value from read()
-       - only try to read the entire contents of a regular file in one shot
-         if the file size is less than SSIZE_MAX.  These fix problems
-         reported by hooanon05@yahoo.co.jp.
-
-include/typemax.h
-       - define SSIZE_MAX as 32767 if it's not defined
-
-lib/readline/display.c
-       - in rl_redisplay() and update_line(), if redrawing the prompt because
-         it contains invisible characters, make sure we redraw the character
-         indicating a modified history line and take it into account when
-         computing _rl_last_c_pos
-       - in update_line, if deleting characters and redrawing the new text,
-         make sure we adjust _rl_last_c_pos by wrap_offset in a multibyte
-         locale if the text we're drawing starts before or at the last
-         invisible character in the prompt string.  Fixes bug reported on
-         bug-readline by J Pelkey <pelkeyj@gmail.com>
-
-parse.y
-       - when adding at CTLESC character to the current token, do not
-         escape it with CTLESC if pass_next_character indicates that the
-         CTLESC was escaped by a backslash.  Fixes bug reported by
-         Paul Bagshaw <paul.bagshaw@orange-ftgroup.com>.
-
-                                  3/25
-                                  ----
-lib/readline/text.c
-       - in rl_forward_char, short-circuit the loop if in emacs mode and
-         rl_point == rl_end.  Fixes problem with multibyte locales
-         reported by Len Lattanzi <llattanzi@apple.com>
-
-                                  3/29
-                                  ----
-command.h
-       - new flag for subshell_environment: SUBSHELL_PROCSUB, for process
-         substitution
-
-subst.c
-       - add SUBSHELL_PROCSUB to subshell_environment in process_substitute
-
-                                  3/30
-                                  ----
-doc/Makefile.in
-       - fix installation of bash.info to understand that it is in the build
-         directory, not the source directory
-
-mailcheck.c
-       - new function, init_mail_dates, calls remember_mail_dates only if
-         there are no mailboxes in `mailfiles'
-       - new function, init_mail_file, initializes a FILEINFO, using the
-         last time mail was checked as the mtime and atime (or the time the
-         shell was started if last_time_mail_checked is uninitialized)
-       - call init_mail_file instead of update_mail_file in add_mail_file,
-         called from remember_mail_dates (which is supposed to initialize
-         the list of mail files)
-       - new convenience functions, alloc_mail_file and dispose_mail_file to
-         allocate and free FILEINFO structs
-
-mailcheck.h
-       - extern declaration for init_mail_dates
-
-shell.c
-       - call init_mail_dates instead of remember_mail_dates
-
-                                   4/4
-                                   ---
-builtins/read.def
-       - changes to print $PS2 when a line is continued with a backslash in
-         an interactive shell.  This is as POSIX requires
-
-                                   4/5
-                                   ---
-subst.c
-       - make sure quote_escapes is only ever called when the word to be
-         escaped is not marked as double-quoted -- cleaner, and allows us
-         to make certain assumptions
-
-                                   4/6
-                                   ---
-subst.c
-       - change all EX_* defines to begin with SX_
-       - new flag, SX_NOCTLESC, obeyed by string_extract_verbatim, tells it
-         to not obey CTLESC quoting
-       - change quote_escapes to not quote CTLESC with CTLESC if one of the
-         chars in $IFS is CTLESC, since the return value from quote_string
-         will be passed to word splitting and filename generation
-       - change read_comsub to do the same thing for unquoted command
-         substitutions
-       - change list_string to pass SX_NOCTLESC if CTLESC is one of the
-         chars in $IFS, so it will split on CTLESC instead of using it as a
-         quote character
-
-                                   4/7
-                                   ---
-subst.c
-       - slight change to string_extract_verbatim to allow CTLESC to quote
-         CTLNUL even if SX_NOCTLESC is set in the flags passed, to protect
-         the CTLNULs from future calls to remove_quoted_nulls.  Only
-         matters when $IFS contains CTLESC
-       - changes to cope with $IFS containing CTLNUL in the same way as the
-         CTLESC changes
-
-builtins/read.def
-       - changes to cope with $IFS containing CTLNUL in the same way as the
-         CTLESC changes
-
-                                  4/16
-                                  ----
-lib/sh/strftime.c
-       - a couple of fixes to the `%z' code
-
-eval.c
-       - add an fflush after printing the auto-logout message
-
-                                  4/24
-                                  ----
-subst.c
-       - add call to top_level_cleanup in exp_jump_to_top_level to get things
-         like unwind-protects and the loop levels cleaned up
-
-{arrayfunc,expr,variables}.c
-       - add calls to top_level_cleanup before jump_to_top_level() 
-
-                                  4/27
-                                  ----
-builtins/complete.def
-       - make sure the `command' argument to the -C option is printed with
-         single quotes, since multi-word commands will require them.  Bug
-         reported by martin@snowplow.org
-
-execute_cmd.c
-       - change execute_builtin_or_function and execute_subshell_builtin_or_function
-         to call fflush(stdout) after the builtin or function returns, to
-         make sure that all output  is flushed before the call returns.  It
-         matters on cygwin.  Fix suggested by Eric Blake <ebb9@byu.net>
-
-redir.c
-       - in do_redirection_internal, if the file descriptor being acted upon
-         is the same one used by the stdout stream, call fflush(stdout) to
-         make sure all output is flushed before changing the underlying fd
-         out from underneath stdio.  Fix suggested by Eric Blake <ebb9@byu.net>
-
-
-                                  4/30
-                                  ----
-
-builtins/common.c
-       - new function, sh_chkwrite(int), fflushes stdout and checks for error;
-         printing an error message and returning a new exit status if there's
-         an error on stdout.  Takes exit status as argument; returns new exit
-         status (EXECUTION_FAILURE if write error)
-
-builtins/common.h
-       - new extern declaration for sh_chkwrite
-
-builtins/{alias,cd,complete,echo,fc,history,pushd,shopt,times,trap,type,ulimit,umask}.def
-       - change to use sh_chkwrite to report write errors
-
-builtins/fc.def
-       - if an error occurs while writing commands from the history to a file
-         to be executed, report a write error and return failure without
-         attempting to execute any commands
-
-                                   5/1
-                                   ---
-builtins/{bind,declare,set,setattr}.def
-       - change to use sh_chkwrite to report write errors
-
-                                   5/2
-                                   ---
-lib/readline/input.c
-       - fix off-by-one errors in _rl_get_char (pop_index) and rl_stuff_char
-         (push_index) that caused the 511th character in the buffer to be
-         discarded.  Fixes bug reported by Tom Bjorkholm <tom.bjorkholm@ericsson.com>
-
-                                   5/8
-                                   ---
-subst.c
-       - fix parameter_brace_remove_pattern to pass getpattern() newly-allocated
-         memory.  If word expansions (particularly brace expansions) are
-         required, the expansion code will free the string passed to
-         expand_word_internal, and we don't want to free unallocated memory
-         (patstr++) or have duplicate frees (patstr).  Fixes bug reported on
-         Red Hat bugzilla
-
-                                   5/9
-                                   ---
-lib/readline/signals.c
-       - fix bug in rl_set_signals that caught SIGINT twice and didn't catch
-         SIGTERM.  Bug reported by Ed Kwan <ed.kwan@onstor.com>
-
-                                  5/18
-                                  ----
-jobs.c
-       - change compact_jobs_list to return 1 if js.j_lastj == 0 and there is
-         a job in jobs[0]; compact_jobs_list should never return an index
-         already occupied
-       - change reset_job_indices to avoid infinite looping when js.j_firstj
-         == 0 or js.j_firstj == js.j_jobslots upon function entry.  Fixes
-         bug reported by osicka@post.cz
-
-                                  5/20
-                                  ----
-
-execute_cmd.c
-       - new variable, executing_builtin, keeps track of number of "levels"
-         of builtins being executed; incremented by execute_builtin; saved
-         and restored by execute_simple_command
-
-subst.c
-       - new variable, assigning_in_environment, set and unset around calls
-         to assign_in_env by the expansion code
-
-variables.c
-       - use executing_builtin and assigning_in_environment to decide whether
-         or not to look into temporary_env when calling find_variable_internal.
-         Fixes problem reported by Kevin Quinn <kevquinn@gentoo.org>
-
-                                  5/22
-                                  ----
-redir.c
-       - change add_undo_redirect to differentiate between file descriptors
-         greater than SHELL_FD_BASE (currently 10) used internally to save
-         others and then being the targets of user redirection and fds that
-         are just the target of user redirections.  The former need to have
-         an `exec undo' redirect added to undo it in case exec throws away
-         redirections; the latter does not.  We use the close-on-exec flag
-         for this:  if it's set, we assume that the file descriptor is being
-         used internally to save another.  Fixes problem reported by Ian
-         Jackson <ian@davenant.greenend.org.uk>
-
-shell.c
-       - new function, init_interactive_script(), does interactive initialization
-         for a script run with `bash -i script' -- does everything the same
-         as init_interactive except set `interactive == 1', which causes the
-         shell to read from the standard input, after calling
-         init_noninteractive
-       - call init_interactive_script if a script is run as `bash -i script'.
-         Fixes problem reported by Joseph Michaud <jmichaud@sgi.com>
-
-                                  5/24
-                                  ----
-builtins/printf.def
-       - change vbadd to only call FASTCOPY if the passed buffer length is
-         > 1
-       - if the `-v' option is supplied and `vbuf' is already non-null from a
-         previous `printf -v var' call, set vbuf[0]=0 explicitly instead of
-         relying on vbadd to do it -- vbadd may not be called.
-       - fix PRETURN macro to set vbuf[0] == 0 if vbuf is not freed.  These
-         should fix problem reported by Elmar Stellnberger <estellnb@yahoo.de>
-
-lib/readline/display.c
-        - fix update_line to deal with the case where col_lendiff > 0 (meaning
-          the new string takes up more screen real estate than the old) but
-          lendiff < 0 (meaning that it takes fewer bytes to do so).  This can
-          happen when a multibyte prompt string is replaced with a longer one
-          containing only single-byte characters (e.g., when doing a reverse
-          i-search).  Fixes gentoo bug reported by Peter Volkov
-          <torre_cremata@mail.ru>
-
-builtins/read.def
-       - make sure we only print $PS2 if the standard input is a terminal
-       - new function, read_mbchar, to read a multibyte character so we
-         can make sure we read entire multibyte chars when `read -n' is
-         used, rather than bytes.  Only called when -n is supplied.
-         Fixes problem reported by Stanislav Brabec <sbrabec@suse.cz>
-
-                                  5/25
-                                  ----
-externs.h
-       - new #defines for third argument to named_function_string:
-         FUNC_MULTILINE (don't suppress newlines) and FUNC_EXTERNAL (convert
-         to external display form)
-
-subst.h
-       - new extern declaration for remove_quoted_escapes
-
-subst.c
-       - remove_quoted_escapes is now global
-
-print_cmd.c
-       - in named_function_string, if FUNC_EXTERNAL is in the flags argument,
-         call remove_quoted_escapes to convert from internal to external form.
-         Fixes bug reported by Bo Andresen <bo.andresen@zlin.dk>
-
-variables.c,builtins/{declare,setattr,type}.def
-       - use FUNC_MULTILINE in calls to named_function_string as appropriate
-       - add FUNC_EXTERNAL to calls to named_function_string as appropriate
-
-                                  5/27
-                                  ----
-{make_cmd,variables}.c
-       - changes to enable the shell to compile when debugger support is
-         configured out (function_def hash table and access functions).  Fixes
-         bug reported by Horst Wente <horst.wente@acm.org>
-
-builtins/help.def
-       - fix bug in `help' two-column printing to avoid referencing
-         shell_builtins[num_shell_builtins]
-
-error.c
-       - in get_name_for_error, use dollar_vars[0] if the name returned from
-         looking in $BASH_SOURCE[0] is the empty string as well as if it's
-         null
-
-                                  5/31
-                                  ----
-arrayfunc.c
-       - change array_value_internal to set *RTYPE to 1 if the reference is
-         array[*] and 2 if the reference is array[@]
-
-subst.c
-       - in parameter_brace_expand_word, set the flags returned by the word
-         desc to include W_HASQUOTEDNULL if array_value returns QUOTED_NULL
-         for an array reference like x[*] and the word is quoted.  Fixes bug
-         reported by Christophe Martin <schplurtz@free.fr>
-
-                                   6/1
-                                   ---
-jobs.c
-       - several changes to preserve errno if tcgetpgrp/tcgetattr/tcsetattr
-         fail, for subsequent error messages
-       - change initialize_job_control to turn off job control if the terminal
-         pgrp == -1 or is not equal to shell_pgrp (with an error message)
-       - in initialize_job_control, if the shell has been forced interactive
-         with -i, make sure stderr is hooked to a tty before using it as
-         the controlling terminal.  If it's not, try to open /dev/tty and
-         assign it to shell_tty.  Fixes problems reported by Derek Fawcus
-         <dfawcus@cisco.com>
-
-                                  6/13
-                                  ----
-support/shobj-conf
-       - changes to support shared object and shared library creation on AIX
-         5.x and later versions.  From Niklas Edmundsson <nikke@acc.umu.se>
-
-                                  6/17
-                                  ----
-builtins/mkbuiltins.c
-       - new array of builtins, posix_builtins, containing builtins listed
-         as special to the command search order by POSIX
-       - add POSIX_BUILTIN to the builtin flags if the builtin name is one
-         that's special to the posix command search order
-
-builtins.h
-       - new define, POSIX_BUILTIN, means that a builtin is special to the
-         posix command search order
-
-                                  6/22
-                                  ----
-lib/readline/display.c
-       - new macro, WRAP_OFFSET, intended to replace W_OFFSET.  Takes prompt
-         strings longer than one physical line with invisible characters on
-         the second line into account when calculating the number of
-         invisible characters on the current screen line
-       - use WRAP_OFFSET where appropriate (update_line, _rl_move_cursor_relative)
-       - change update_line to deal with adjusting _rl_last_c_pos in a
-         multibyte environment when the prompt has invisible chars on the
-         second line and redisplay has output the invisible characters
-       - change _rl_move_cursor_relative to adjust _rl_last_c_pos in a
-         multibyte environment when the prompt has invisible chars on the
-         second line and the redisplay draws the invisible character.  Fixes
-         redisplay bug reported by Andreas Schwab <schwab@suse.de>
-
-
-                                  7/11
-                                  ----
-
-lib/readline/rltty.c
-       - enable flush-output code for systems other than AIX 4.1.  Problem
-         reported by Jan Kratochvil <jan.kratochvil@redhat.com>
-
-                                  7/12
-                                  ----
-lib/readline/display.c
-       - set prompt_invis_chars_first_line from the portion of the prompt
-         following the final newline, instead of from the prefix.  Fixes
-         bug reported on the Ubuntu bug list by dAniel hAhler
-         <ubuntu@thequod.de>
-
-                                  7/13
-                                  ----
-variables.c
-       - use native __QNX__ and __QNXNTO__ cpp defines instead of qnx and
-         qnx6, respectively.  Patch from Sean Boudreau <seanb@qnx.com>
-
-lib/sh/getcwd.c
-       - #undef HAVE_LSTAT on qnx, so it uses stat instead.  Patch from
-         Sean Boudreau <seanb@qnx.com>
-
-                                  7/21
-                                  ----
-builtins/common.c
-       - change sh_invalidnum to be a little smarter about octal and hex
-         numbers and change the message appropriately.  Bug originally
-         reported on coreutils list by Jürgen Niinre <Jyrgen.Niinre@emt.ee>
-
-                                  7/26
-                                  ----
-test.c
-       - make sure the string passed to test_unop has only a single character
-         following the `-'.  Fixes bug reported by Michael A. Smith
-         <michael@smith-li.com>
-
-parse.y
-       - better input validation: make sure a word looks like a conditional
-         unary operator (-X) before calling test_unop
-
-                                  7/28
-                                  ----
-trap.c
-       - in trap_handler, if it's called directly from the signal handler
-         (e.g., SIGINT sighandler, set by set_sigint_handler), but the
-         trap disposition has been reset to the default between the
-         assignment and receipt of the signal, check that the signal is
-         trapped and issue a warning if the shell was compiled with
-         debugging enabled.  Fixes bug reported by Fergus Henderson
-         <fergus@google.com>
-
-                                   8/1
-                                   ---
-lib/readline/{util,histexpand}.c
-       - fixes for small memory leaks from Michael Snyder <msnyder@sonic.net>
-
-                                  8/18
-                                  ----
-Makefile.in
-       - add dependency on builtins/builtext.h to nojobs.o list.  Fixes
-         `make -j 5' issue reported by Chris MacGregor <chris@bouncingdog.com>
-
-examples/loadables/Makefile.in
-       - add @LDFLAGS@ to SHOBJ_LDFLAGS assignment -- experimental.  Suggested
-         by Mike Frysinger <vapier@gentoo.org>
-
-examples/loadables/{basename,cut,dirname,finfo,head,ln,logname,mkdir,pathchk,print,printenv,push,realpath,rmdir,sleep,tee,truefalse,tty,uname,unlink,whoami}.c
-       - fix up some includes.  Fix from Mike Frysinger <vapier@gentoo.org>
-
-                                  8/21
-                                  ----
-histexpand.c
-       - fix another memory leak in history_find_word.  Bug report originally
-         from Michael Snyder <msnyder@sonic.net>; test case suggested by Jim
-         Blandy <jimb@codesourcery.com>
-
-                                  8/26
-                                  ----
-subst.c
-       - change to do_assignment_internal to make an assignment to a variable
-         with the `noassign' internal attribute not a variable assignment
-         error.
-       - fix do_assignment_internal so assignment to a `noassign' variable
-         does not cause it to suddenly become visible if it's currently
-         invisible
-
-                                   9/3
-                                   ---
-stringlib.c
-       - change strsub to check whether or not temp is non-null before
-         trying to null-terminate it.  Also make sure temp is allocated
-         even if the pattern and replacement strings are empty, and set
-         to a copy of string (like ${foo//})
-         Bug report from Timo Lindfors <timo.lindfors@iki.fi>
-
-                                  9/10
-                                  ----
-{config.h,Makefile,configure}.in,aclocal.m4
-       - new tests for fpurge and __fpurge
-
-lib/sh/fpurge.c, externs.h
-       - new file, fpurge(3) implementation with external decl in externs.h
-
-builtins/common.c
-       - add call to fpurge(stdout) to sh_chkwrite
-
-{redir,execute_cmd}.c
-       - add call to fpurge(stdout) after fflush(stdout) before changing
-         stdout file descriptor and after a builtin or function executes
-
-                                  9/12
-                                  ----
-expr.c
-       - make sure noeval is set to 0 when a longjmp occurs, since it will
-         not be reset otherwise, and it can be set to 1 while processing
-         a {pre,post}-increment or {pre,post}-decrement token
-       - set noeval to 0 at the beginning of evalexp, since it's never
-         called recursively
-
-                                  9/14
-                                  ----
-config-top.h
-       - new builder-modifiable define:  DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS
-         Turning it on will cause errors from EPIPE to not be reported by
-         the normal shell write error message mechanism
-
-builtins/common.c
-       - if DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS is defined, don't print an
-         error message from sh_wrerror if errno == EPIPE.  Suggestion from
-         Petr Sumbera <petr.sumbera@sun.com>
-
-                                  9/19
-                                  ----
-{jobs,nojobs}.c,jobs.h
-       - add code to retry fork() after EAGAIN, with a progressively longer
-         sleep between attempts, up to FORKSLEEP_MAX (16) seconds.  Suggested
-         by Martin Koeppe <mkoeppe@gmx.de>
-
-                                  9/21
-                                  ----
-version.c
-       - change copyright year to 2007
-
-                                  9/25
-                                  ----
-pathexp.c
-       - change quote_string_for_globbing to add a backslash in front of a
-         backslash appearing in the pathname string, since the globbing
-         code will interpret backslashes as quoting characters internally.
-         Bug reported by <herbert@gondor.apana.org.au> on the debian list
-         (443685)
-
-                                  10/8
-                                  ----
-lib/readline/display.c
-       - in update_line, make sure _rl_last_c_pos is > 0 before setting
-         cpos_adjusted (or we actually moved the cursor to column 0 in
-         _rl_move_cursor_relative).  Fixes redisplay bug with prompt with
-         only invisible characters reported by dAniel hAhler
-         <ubuntu@thequod.de>
-
-                                  10/10
-                                  -----
-lib/readline/display.c
-       - in rl_redisplay, when calculating the new physical cursor position
-         in a multibyte locale (`tx'), do not call rl_backspace if tx ends
-         up < 0.  Rest of fix for bug reported by dAniel hAhler
-         <ubuntu@thequod.de>
-
-                                  10/12
-                                  -----
-lib/sh/getcwd.c
-       - fix memory overwrite problem that's possible if buf is NULL and
-         passed size is greater than the pathname length.  Reported by
-         Ian Campbell <ian.campbell@xensource.com>
-
-builtins/ulimit.def
-       - change the multiplier for the -c and -f options (`blocks') to 512,
-         the traditional value (and the one POSIX specifies).  Bug reported
-         by Pete Graner <pgraner@redhat.com>
-
-braces.c
-       - pass process substitution through unchanged the same as command
-         substitution.  Prompted by suggestion from Stephane Chazelas
-         <stephane_chazelas@yahoo.fr>
-
-lib/readline/input.c
-       - in rl_unget_char, fix off-by-one error when resetting pop_index if
-         it's < 0.  Bug reported by Uwe Doering <gemini@geminix.org>
-
-builtins/type.def
-       - change exit status of `type' to not successful if any of the
-         requested commands are not found.  Reported by Stephane Chazleas
-         <stephane_chazelas@yahoo.fr>
-
-pcomplete.c
-       - change command_line_to_word_list to use rl_completer_word_break_characters
-         instead of the shell metacharacters to split words, so programmable
-         completion does the same thing readline does internally.  Reported
-         by Vasily Tarasov <vtaras@sw.ru>
-
-                                  10/16
-                                  -----
-bashline.c
-       - When completing a command name beginning with a tilde and containing
-         escaped specical characters, dequote the filename before prefixing
-         it to the matches, so the escapes are not quoted again.  Reported
-         by neil@s-z.org
-
-                                  10/17
-                                  -----
-expr.c
-       - in readtok(), don't reset lasttp if we've consumed the whitespace
-         at the end of the expression string.  Fixes error message problem
-         reported by <anmaster@tele2.se>
-
-                                  11/1
-                                  ----
-builtins/printf.def
-       - change asciicode() to return intmax_t; add multibyte character
-         support instead of assuming ASCII (depending on behavior of system
-         multibyte support functions).  Fixes bug reported by Rich
-         Felker <dalias@aerifal.cx>
-
-                                  11/5
-                                  ----
-execute_cmd.c
-       - if redirections attached to a compound command fail, make sure to
-         set last_command_exit_value when returning EXECUTION_FAILURE.
-         Fixes bug reported separately by Andreas Schwab <schwab@suse.de>
-         and Paul Eggert <eggert@cs.ucla.edu>
-
-                                  11/9
-                                  ----
-builtins/read.def
-       - make sure the return value from get_word_from_string is freed if
-         non-null.  Fixes memory leak bug reported by Lars Ellenberg
-         <lars.ellenberg@linbit.com>
-
-                                  11/10
-                                  -----
-variables.c
-       - use getpid() as value of seeded_subshell to avoid problems with
-         random number generator not getting re-seeded correctly when
-         subshells are created.  Fix from Tomas Janousek <tjanouse@redhat.com>
-
-lib/readline/display.c
-       - in update_line(), when outputting characters at the end of the line,
-         e.g., when displaying the prompt string, adjust _rl_last_c_pos by
-         wrap_offset if the text we're drawing begins before the last
-         invisible character in the line.  Similar to fix from 5/24.  Fixes
-         bug reported by Miroslav Lichvar <mlichvar@redhat.com>
-
-                                  11/14
-                                  -----
-subst.c
-       - fix $[ expansion case to deal with extract_arithmetic_subst
-         returning NULL (if the `]' is missing) and return the construct
-         unchanged in that case.  Fixes tab completion bug reported by
-         Heikki Hokkanen <hoxu@users.sf.net> (debian bug 451263)
-
-lib/readline/mbutil.c
-       - fix _rl_find_next_mbchar_internal to deal with invalid multibyte
-         character sequences when finding non-zero-length chars.  Fixes
-         bug reported by Morita Sho <morita-pub-en-debian@inz.sakura.ne.jp>
-
-                                  11/15
-                                  -----
-variables.c
-       - add new function `seedrand' to seed the bash random number
-         generator from more random data.  Suggestion from Steve Grubb
-         <sgrubb@redhat.com>
-       - replace the rng in brand() with a slightly better one from FreeBSD
-         (filtered through Mac OS X 10.5).  Replacement suggested by
-         Steve Grubb <sgrubb@redhat.com>
-
-                                  11/21
-                                  -----
-configure.in
-       - darwin 9 also requires linking against libreadline.a and
-         libhistory.a because of Apple's questionable decision to ship a
-         libreadline "replacement" that doesn't provide all functions
-
-doc/{bash.1,bashref.texi}
-       - slight change to the text describing the effect of set -e when
-         in a || or && list
-
-                                  12/5
-                                  ----
-jobs.c
-       - fix raw_job_exit_status to correct mixing of int/WAIT values (need
-         to return a WAIT)
-       - arrange so that children run as part of command substitutions also
-         set the SIGINT handler to wait_sigint_handler, since they effectively
-         don't do job control
-       - in wait_for, if a child run as part of a command substitution exits
-         due to SIGINT, resend the SIGINT to the waiting shell with kill(2).
-         This makes sure the exit status propagates 
-
-doc/{bash.1,bashref.texi}
-       - tighten up the language describing when bash tries to see if its
-         stdin is a socket, so it can run the startup files.  Suggested by
-         Vincent Lefevre <vincent@vinc17.org>
-
-eval.c
-       - in the DISCARD case of a longjmp to top_level, make sure
-         last_command_exit_value is set to EXECUTION_FAILURE if it's 0,
-         but leave existing non-zero values alone
-
-subst.c
-       - in command_substitute, don't reset pipeline_pgrp in the child
-         process -- this means that second and subsequent children spawned by
-         this comsub shell get put into the wrong process group, not the
-         shell's.  Fix for bug reported by Ingo Molnar <mingo@elte.hu>
-
-                                  12/6
-                                  ----
-support/shobj-conf
-       - make sure the cases for darwin8.x (Mac OS X 10.4.x) are extended to
-         darwin9.x (Mac OS X 10.5.x).  Fixes problem originally reported
-         against readline-5.2 by schneecrash@gmail.com
-
-                                  12/8
-                                  ----
-subst.c
-       - make sure to add the results of (successful) tilde expansion as a
-         quoted string, to inhibit pathname expansion and word splitting.
-         From recent Austin Group interpretation.
-
-include/shtty.h, lib/sh/shtty.c
-       - add ttfd_onechar, ttfd_noecho, ttfd_eightbit, ttfd_nocanon, and
-         ttfd_cbreak to set tty attributes associated with a particular
-         file descriptor (which is presumed to point to a terminal).  Support
-         for fix for bug reported by b_bashbug@thebellsplace.com
-
-lib/readline/display.c
-       - make sure we only use rl_invis_chars_first_line when the number of
-         physical characters exceeds the screen width, since that's the
-         only time expand_prompt sets it to a valid value
-
-                                  12/12
-                                  -----
-builtins/set.def
-       - change set_minus_o_option to return EX_USAGE if an invalid option
-         name is supplied.  All callers can handle it.
-       - change set_builtin to return what set_minus_o_option returns if it's
-         not EXECUTION_SUCCESS.  This allows EX_USAGE errors to abort a
-         shell running in posix mode
-
-                                  12/14
-                                  -----
-builtins/read.def
-       - generalize the calls to the tty attribute functions to maintain a
-         local copy of the terminal attributes and use the fd supplied as
-         the argument to the -u option (default 0).  Fix for bug reported
-         by b_bashbug@thebellsplace.com
-
-doc/bashref.texi, lib/readline/doc/{history,rlman,rluser,rluserman}.texi
-       - Slight changes to conform to the latest FSF documentation standards.
-         Patch from Karl Berry <karl@freefriends.org>
-
-                                  12/20
-                                  -----
-execute_cmd.c
-       - after calling clear_unwind_protect_list, make sure we reset
-         parse_and_execute_level to 0, since there's nothing left to
-         restore it if top_level_cleanup tests it.  Fixes bug reported
-         by Len Lattanzi <llattanzi@apple.com>
-
-                                  12/31
-                                  -----
-lib/sh/getcwd.c
-       - new function, _path_checkino, checks whether the inode corresponding
-         to the path constructed from the first two arguments is the same as
-         the inode number passed as the third argument
-       - if BROKEN_DIRENT_D_INO is defined, meaning the d_ino/d_fileno
-         member of struct dirent doesn't contain valid values, use
-         _path_checkino instead of directly comparing against d_fileno.
-         Fixes Interix problem reported by Michael Haubenwallner
-         <haubi@gentoo.org>
-
-                                1/7/2008
-                                --------
-array.c
-       - fix array_subrange to separate elements in returned string with
-         first char of $IFS if QUOTED is non-zero, since this indicates
-         the caller used ${array[@]:foo}.  Fixes bug reported by Lea
-         Wiemann <lewiemann@gmail.com>
-
-                                   1/8
-                                   ---
-subst.c
-       - new function returning a string containing the first character of
-         $IFS: char *ifs_firstchar(int *)
-
-subst.h
-       - extern declaration for ifs_firstchar()
-
-array.c
-       - call ifs_firstchar() to get first character of $IFS when needed
-         (array_subrange() and array_patsub())
-
-                                  1/11
-                                  ----
-lib/readline/display.c
-       - use sentinel variable set at end of init_line_structures to decide
-         whether to call it from rl_redisplay, since early SIGWINCH on
-         Mac OS X that hits during this function can cause _rl_wrapped_line
-         to be referenced before initialization.  Fix for bug reported by
-         Len Lattanzi <llattanzi@apple.com>
-
-subst.[ch]
-       - skip_to_delim is now compiled into the shell all the time, not just
-         when readline is linked in
-
-subst.c
-       - use skip_to_delim to find the `/' denoting the end of a pattern
-         in pattern substitution, since it knows more shell syntax than
-         quoted_strchr and understands multibyte characters.  Fixes bug
-         reported by Dmitry V Golovashkin <Dmitry.Golovashkin@sas.com>
-
-                                  1/15
-                                  ----
-subst.c
-       - add `flags' argument to skip_to_delim telling it whether or not to
-         set no_longjmp_on_fatal_error; set this flag when calling from the
-         readline completion code
-
-subst.h        
-       - update extern declaration for skip_to_delim
-
-                                  1/17
-                                  ----
-subst.c
-       - expand_prompt_string takes a third argument: the initial flags for
-         the WORD
-
-subst.h
-       - change extern declaration for expand_prompt_string to add third arg
-
-bashline.c
-       - pass W_NOCOMSUB as third argment to expand_prompt_string when
-         calling from bash_directory_completion_hook, since we don't want
-         to do command substitution from the completion code
-
-parse.y
-       - change call to expand_prompt_string
-
-                                  1/18
-                                  ----
-doc/Makefile.in
-       - added an `install_builtins' rule to install the builtins.1 man page,
-         preprocessing it with sed to force `.so man1/bash.1', which some
-         versions of man require.  Suggestion from Peter Breitenlohner
-         <peb@mppmu.mpg.de>
-       - new target `install_everything' that will install normal documentation
-         and builtins man page
-       - changed uninstall target to remove bash_builtins page from man
-         directory
-
-lib/readline/vi_mode.c
-       - new function, rl_vi_insert_mode, which calls rl_vi_start_inserting
-         to make sure the value of `last command to repeat' is set correctly.
-         Fix from Thomas Janousek <tjanouse@redhat.com>
-       - add support for redoing inserts made with the `I' command.  Fix
-         from Thomas Janousek <tjanouse@redhat.com>
-       - add support for redoing inserts made with the `A' command
-
-lib/readline/readline.h
-       - new extern declaration for rl_vi_insert_mode
-
-lib/readline/{misc,readline,vi_mode,vi_keymap}.c
-       - change calls to rl_vi_insertion_mode to rl_vi_insert_mode
-
-                                  1/19
-                                  ----
-builtins/read.def
-       - change timeout behavior when not reading from a tty device to save
-         any partial input in the variable list, but still return failure.
-         This also causes variables specified as arguments to read to be
-         set to null when there is no input available.  Fix inspired by
-         Brian Craft <bcboy@thecraftstudio.com>
-
-                                  1/21
-                                  ----
-builtins/fc.def
-       - change computation of last_hist to use remember_on_history instead
-         of a hard-coded `1'.  This keeps fc -l -1 in PROMPT_COMMAND from
-         looking too far back
-
-                                  1/25
-                                  ----
-lib/readline/complete.c
-       - fix fnwidth to use string[pos] instead of *string when testing the
-         current character for a control character or rubout
-
-                                   2/2
-                                   ---
-general.c
-       - change posix_initialize to turn off source/. searching $PWD when
-         the file sourced is not found in $PATH.  Fixes bug reported by
-         Paolo Bonzini <bonzini@gnu.org> and Eric Blake <ebb9@byu.net>
-
-                                   2/9
-                                   ---
-builtins/*.def
-       - changes to text and formatting suggested by Jan Schampera
-         <jan.schampera@web.de>
-
-                                  2/16
-                                  ----
-bashline.c
-       - change command_word_completion_function to use the word completion
-         found by readline, which matters only when ignoring case is on
-         and the completion found in the file system differs in case from
-         the text the user typed (this is what readline does for normal
-         filename completion).  Fixes issue reported by Jian Wang
-         <jwang@a10networks.com.cn>.
-
-                                  2/18
-                                  ----
-builtins/source.def
-       - if the filename passed as an argument contains a `/', don't search
-         $PATH.  Not sure why it wasn't like this before
-
-                                  2/21
-                                  ----
-lib/readline/terminal.c
-       - change rl_crlf so that the MINT system on ATARI systems adds a
-         carriage return before the \n
-
-                                  2/22
-                                  ----
-doc/{bash.1,bashref.texi}
-       - added text to the EXIT STATUS section noting that exit statuses
-         fall between 0 and 255, inclusive
-
-support/mkversion.sh
-       - output a #define for DEFAULT_COMPAT_LEVEL (${major}${minor}; e.g. 32)
-         to version.h
-
-version.c
-       - int variable, shell_compatibility_level, set to DEFAULT_COMPAT_LEVEL
-         by default
-
-builtins/shopt.def
-       - new shopt variable, compat31, sets shell_compatibility_level to 31
-         (or back to default if unset)
-
-execute_cmd.c
-       - in execute_cond_node, restore bash-3.1 behavior of quoted rhs of
-         regexp matches if shell_compatibility_level == 31
-
-                                  2/28
-                                  ----
-lib/readline/rltty.c
-       - set readline_echoing_p = 1 if tcgetattr fails and sets errno to
-         EINVAL, as Linux does when the fd is a pipe.  Reported by Mike
-         Frysinger <vapier@gentoo.org>
-
-                                   3/6
-                                   ---
-{MANIFEST,Makefile.in},lib/sh/{casemod,uconvert,ufuncs}.c
-       - new library sources from bash-4.0-devel tree
-
-lib/sh/spell.c
-       - moved cdspell() here from builtins/cd.def, renamed dirspell()
-
-externs.h
-       - new declarations for extern functions from new library files
-       - new extern declaration for lib/sh/spell.c:dirspell()
-
-builtins/cd.def
-       - call extern library function dirspell(); remove static cdspell()
-
-builtins/read.def
-       - when read times out, make sure input_string is null-terminated before
-         assigning any partial input read to the named variables
-
-                                  3/10
-                                  ----
-lib/glob/xmbsrtowcs.c
-       - cut the number of memory allocations in xdupmbstowcs by not keeping
-         track of the indices if the caller hasn't asked for it
-
-                                  3/17
-                                  ----
-builtins/fc.def
-       - make sure the adjustment to i in fc_gethnum uses the same formula
-         fc_builtin uses to calculate last_hist
-       - make sure that every time fc_gethnum is called, the fc command last
-         in the history list has not yet been deleted, since fc_gethnum
-         assumes that it has not.  Fix from John Haxby <john.haxby@oracle.com>
-
-lib/readline/complete.c
-       - new private library function, _rl_reset_completion_state(), used to
-         reset any completion state internal to the library when a signal
-         is received
-       - call _rl_reset_completion_state() before returning from
-         rl_complete_internal
-
-lib/readline/rlprivate.h
-       - new extern declaration for _rl_reset_completion_state
-
-lib/readline/signals.c
-       - call _rl_reset_completion_state from rl_signal_handler on SIGINT.
-         This fixes one of the problems identified by Mika Fischer
-         <mf+ubuntu@zoopnet.de>
-
-pcomplete.c
-       - programmable_completions now saves pointer to the compspec it's
-         working with in new global variable CURCS
-       - new function, pcomp_set_readline_variables, that sets or unsets
-         readline variables based on a passed flags value (COPT_FILENAMES,
-         etc.)
-       - new function, pcomp_set_compspec_options, to set or unset bits in
-         the options word of a passed compspec (default CURCS)
-       - only call bash_dequote_filename (via rl_filename_dequoting_function)
-         from pcomp_filename_completion_function if the readline state
-         word indicates word completion is in progress
-
-pcomplete.h
-       - new extern declaration for curcs
-       - new extern declaration for pcomp_set_readline_variables
-       - new extern declaration for pcomp_set_compspec_options
-
-bashline.c
-       - fix bash_dequote_filename to implement shell quoting conventions:
-               1. Inhibit backslash stripping within single quotes
-               2. Inhibit backslash stripping within double quotes only if
-                  the following character is one of the special ones
-       - call pcomp_set_readline_variables from attempt_shell_completion
-         instead of doing the equivalent inline
-
-                                  3/18
-                                  ----
-bracecomp.c
-       - make sure we sort array of matches in byte order (using strcmp). so
-         the brace calculations work correctly even when the locale orders
-         characters like aAbBcC...zZ.  Fixes bug reported by Torsten Nahm
-         <torstennahm@torstennahm.de>
-
-                                  3/20
-                                  ----
-lib/readline/{rltty,signals}.c
-       - move block_sigint and release_sigint from rltty.c to signals.c; add
-         _rl_ prefix to make them public to the library; change callers.
-         From Jan Kratochvil <jan.kratochvil@redhat.com>
-
-lib/readline/rlprivate.h
-       - new extern declarations for _rl_block_sigint and _rl_release_sigint
-
-lib/readline/display.c
-       - add calls to _rl_block_sigint and _rl_release_sigint to rl_redisplay,
-         since it maniupluates global data structures.  Fix from Jan
-         Kratochvil <jan.kratochvil@redhat.com>
-
-builtins/printf.def
-       - change calls to asprintf and manually adding to vbuf to use calls
-         to vsnprintf against vbuf directly -- if the number of characters
-         to be written overflows the buffer, realloc the buffer and use
-         vsnprintf again.  This should reduce the memory used by printf.
-         Idea from Yuya Katayama <yuya999@gmail.com>
-
-lib/readline/doc/rltech.texi
-       - documented rest of readline's state flags, including RL_STATE_CALLBACK
-       - documented rl_save_state and rl_restore_state
-
-                                  3/27
-                                  ----
-lib/readline/{rlprivate.h,{display,readline,rltty,terminal,text}.c}
-       - rename readline_echoing_p to _rl_echoing_p for namespace consistency
-
-lib/readline/{rlprivate.h,{callback,readline,util}.c}
-       - rename readline_top_level to _rl_top_level for namespace consistency
-
-builtins/ulimit.def
-       - new -b (socket buffer size) and -T (number of threads) options
-
-array.c
-       - fix bug in calculation of the array element assignment string length:
-         use length of `is' instead of `indstr'.  Reported as ubuntu bug
-         #202885 by John McCabe-Dansted
-
-builtins/setattr.def
-       - new function, show_all_var_attributes, displays attributes and
-         values for all shell variables (or shell functions) in a reusable
-         format
-
-builtins/common.h
-       - new extern declaration for show_all_var_attributes
-
-builtins/declare.def
-       - change `declare -p' to print out all variable attributes and values,
-         and `declare -fp' to print out all function attributes and
-         definitions.  Inspired by request from John Love-Jensen
-         <eljay@adobe.com>
-
-doc/{bash.1,bashref.texi}
-       - document new -b and -T options to ulimit
-       - tighten up language describing AND and OR lists
-       - add description of new behavior of `declare -p'
-
-                                  3/28
-                                  ----
-pcomplete.c
-       - rename curcs -> pcomp_curcs
-       - new global completion variable, pcomp_curcmd, the current command
-         name being completed
-
-builtins/complete.def
-       - new builtin, compopt, allows completion options for command names
-         supplied as arguments or the current completion being executed to
-         be modified.  Suggested by Mika Fischer <mf+ubuntu@zoopnet.de>
-
-                                  3/30
-                                  ----
-doc/{bash.1,bashref.texi},lib/readline/doc/rluser.texi
-       - document new compopt builtin
-
-                                   4/5
-                                   ---
-support/shobj-conf
-       - change solaris10 stanza to use -fPIC to fix 64-bit sparc_v9/solaris10
-         compilations.  Fix from Fabian Groffen <grobian@gentoo.org>
-
-builtins/read.def
-       - added `-i text' option, inserts `text' into line if using readline.
-         Suggested by many, used some ideas from Kevin Pulo <kevin@pulo.com.au>
-
-doc/{bash.1,bashref.texi}
-       - document new `-i text' option to read builtin
-
-                                   4/7
-                                   ---
-lib/readline/bind.c
-       - new settable variable, `history-size', sets the max number of
-         entries in the history list
-
-doc/bash.1,lib/readline/doc/{rluser.texi,readline.3}
-       - document new `history-size' settable readline variable
-
-                                   4/8
-                                   ---
-builtins/complete.def
-       - change build_actions calling sequence to take a struct with `other'
-         (non-action) flag arguments (-p, -r)
-       - add support for `-E' option to build_actions and complete builtin --
-         modifies or displays (internal) `_EmptycmD_' completion spec
-
-bashline.c
-       - change attempt_shell_completion to try programmable completion on an
-         `empty' command line and return the results
-
-doc/bash.1,lib/readline/doc/rluser.texi
-       - documented new `-E' option to `complete'
-
-                                   4/9
-                                   ---
-bashhist.c
-       - new variable, `enable_history_list', used to reflect setting of
-         `-o history' option
-       - change bash_history_{enable,disable,reinit} to set enable_history_list
-         as well as remember_on_history
-
-builtins/set.def
-       - use `enable_history_list' instead of `remember_on_history' to keep
-         value of `-o history' option
-
-builtins/evalstring.c
-       - instead of unwind-protecting remember_on_history, use a function to
-         restore it to the value of `enable_history_list' after
-         parse_and_execute runs the commands in the string.  This allows
-         history to be turned off in a startup file, for instance.  Problem
-         reported by Dan Jacobson <jidanni@jidanni.org>
-
-                                  4/11
-                                  ----
-bashline.c
-       - limited support for completing command words with globbing characters
-         (only a single match completed on TAB, absolute or relative
-         pathnames supported, no $PATH searching, some support for displaying
-         possible matches, can be used with menu completion).
-         Suggested by Harald Koenig <h.koenig@science-computing.de>
-
-print_cmd.c
-       - change redirection printing to output r_err_and_out as `&>file',
-         since the man page says that's the preferred form
-
-                                  4/12
-                                  ----
-builtins/*.def
-       - change long doc so the first line is a short description
-       - add `Exit Status:' section to each longdoc describing exit values
-
-builtins/help.def
-       - new `-d' option to print short description of each utility
-       - new `-m' option to print description of each builtin in a
-         pseudo-manpage format (inspired by ksh93)
-
-doc/{bash.1,bashref.texi}
-       - document new `-d' and `-m' options to `help'
-
-builtins/mapfile.def
-       - new builtin, `mapfile', imported from bash-4.0-devel branch
-
-tests/{mapfile.{data,right,tests},run-mapfile}
-       - tests for `mapfile' builtin
-
-doc/{bash.1,bashref.texi}
-       - added description of `mapfile' builtin
-
-MANIFEST,Makefile.in,builtins/Makefile.in
-       - added entries for mapfile source files
-
-arrayfunc.[ch]
-       - new function, bind_array_element, to support mapfile builtin
-
-                                  4/20
-                                  ----
-expr.c
-       - fix operator precendence in expcond():  term after the `:' is
-         a conditional-expression, not a logical-OR-expression (using C
-         terminology).  Bug reported by <archimerged@gmail.com>
-
-                                  4/22
-                                  ----
-bashintl.h
-       - new P_ define for using ngettext to decide on plural forms
-         (currently unused)
-
-                                  4/25
-                                  ----
-execute_cmd.c
-       - in execute_disk_command, if the command is not found, search for
-         a shell function named `command_not_found_handle' and call it
-         with the words in the command as arguments.  Inspired by Debian
-         feature.
-
-doc/{bash.1,bashref.texi}
-       - document new command_not_found_handle behavior in COMMAND EXECUTION
-         section
-
-configure.in
-       - change default version to bash-4.0-devel
-
-                                  4/28
-                                  ----
-variables.c
-       - change push_func_var and push_exported_var to call
-         stupidly_hack_special_variables if the temporary variable is going
-         to be disposed.  This undoes any internal changes caused by a local
-         variable assignment in the environment or in a shell function.  Bug
-         reported by Morita Sho <morita-pub-en-debian@inz.sakura.ne.jp> in
-         http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=478096
-
-                                   5/3
-                                   ---
-builtins/fc.def
-       - fixed a problem caused by change of 1/21 to use remember_on_history,
-         since it's turned off by parse_and_execute(), but can cause the
-         last command in history to be deleted and leave last_hist pointing
-         beyond the end of the history list.  edit_and_execute_command can
-         do this.
-
-bashline.c
-       - new define, RL_BOOLEAN_VAR_VALUE, to take a readline boolean variable
-         and get its value as 0 or 1 (consider making readline global)
-       - put tty back into canonical mode before calling parse_and_execute in
-         edit_and_execute_command and then back into raw mode after it
-         returns.  Fixes problem identified by <koersen@gmail.com>.
-
-                                   5/4
-                                   ---
-lib/glob/glob.c
-       - code to support `globstar' option: GX_GLOBSTAR and two internal
-         flags.  Changes to skipname, glob_vector, mbskipname, glob_filename.
-         New function finddirs().
-
-lib/glob/glob.h
-       - new defines to support globstar code
-
-builtins/shopt.def
-       - new shell option, `globstar', enables special handling of `**' in
-         glob patterns -- matches all directories recursively
-
-pathexp.h
-       - extern declaration for glob_star
-
-pathexp.c
-       - break inline code out of quote_globbing_chars into a separate
-         function to decide whether a character is a globbing char:
-         glob_char_p
-       - change shell_glob_filename to call glob_filename with the
-         GX_GLOBSTAR flag if glob_star is set
-
-doc/{bash.1,bashref.texi}
-       - document new `globstar' shell option
-
-arrayfunc.c
-       - new function, broken out of quote_array_assignment_chars:
-         quote_assign; extended from old code to make sure that globbing
-         chars and chars in $IFS are quoted when displaying assignment
-         statements, especially in compound array assignments
-
-                                   5/5
-                                   ---
-bashline.c
-       - new variable, dircomplete_spelling, controls spelling correction
-         of directory names when doing filename completion
-       - change bash_directory_completion_hook to incorporate spelling
-         correction if initial canonicalization of directory name fails
-
-builtins/shopt.def
-       - new shell option, `dirspell', enables and disables spelling
-         correction of directory names during word completion
-
-builtins/read.def
-       - support for fractional timeout values (ival.uval); uses uconvert
-         and falarm/setitimer
-
-config.h.in
-       - new `HAVE_SETITIMER' define
-
-configure.in
-       - look for setitimer(2), define HAVE_SETITIMER if found
-
-doc/{bash.1,bashref.texi}
-       - document new `dirspell' shopt option
-       - document new fractional values to `read -t timeout'
-
-                                   5/6
-                                   ---
-assoc.[ch]
-       - new files, basic support for associative array implementation
-
-general.h
-       - new extern declarations for sh_openpipe, sh_closepipe, trim_pathname
-
-general.c
-        - new functions: sh_openpipe to create a pipe and move the file
-          descriptors to a high range; sh_closepipe, to close pipe fds and
-          clean up, and trim_pathname, to replace portions of a pathname
-          with `...' (for prompting)
-
-jobs.c
-       - don't set last_asynchronous_pid in child shell (messes up $!, among
-         other things)
-
-parse.y,parser.h
-       - moved definitions of parser flags to parser.h
-
-array.c
-       - imported array_modcase (case-changing operations on arrays) from
-         4.0-devel branch
-
-array.h
-       - new extern declaration for array_modcase
-
-lib/readline/complete.c
-       - new variable, rl_menu_completion_entry_function, generator for
-         rl_menu_complete
-       - new menu completion `browsing' implementation, with several
-         improvements over the old code.  Inspired by Sami
-
-lib/readline/readline.h
-       - extern declaration for rl_menu_completion_entry_function
-
-                                   5/8
-                                   ---
-lib/readline/complete.c
-       - add support for a third argument to fnprint and print_filename,
-         which supports replacing a specified portion of the pathnames
-         printed when displaying possible completions with a `...' (or
-         `___', if the prefix would be confused with a portion of the
-         filename)
-       - new variable, _rl_completion_prefix_display_length, sets the
-         number of characters in a common prefix to be replaced with an
-         ellipsis when displaying possible completions
-       - add support to _rl_display_match_list to find the length of the
-         common prefix of all items being displayed, and passing that
-         value to print_filename for possible replacement with an ellipsis
-         if that length is longer than _rl_completion_prefix_display_length
-
-lib/readline/bind.c
-       - add support for retrieving value of history-size variable to
-         _rl_get_string_variable_value
-       - new bindable variable, completion-prefix-display-length.  When
-         displaying possible completions, matches with a common prefix
-         longer than this value have the common prefix replaced with an
-         ellipsis
-       - support for retrieving value of completion-prefix-display-length
-         variable to _rl_get_string_variable_value
-       - new bindable variable, revert-all-at-newline:  if enabled, causes
-         all changes in history lines to be undone before readline returns
-         after processing a newline
-
-doc/bash.1,lib/readline/doc/{readline.3,rluser.texi}
-       - document new `completion-prefix-display-length' variable
-       - document new `revert-all-at-newline' variable
-
-execute_cmd.c
-       - change execute_builtin to not inherit the `-e' flag into commands
-         executed by the `command' or `source/.' builtins if we are supposed
-         to be ignoring the return value.  This is like `eval'.  Fixes bug
-         reported by Hiroshi Fujishima <hirobo@tonteki.org>
-
-                                  5/10
-                                  ----
-variables.c
-       - when reading the initial environment, don't create variables with
-         names that are not valid shell identifiers.  Fixes bug reported by
-         Stephane Chazleas <stephane_chazelas@yahoo.fr>
-
-                                  5/13
-                                  ----
-subst.c
-       - fix string_quote_removal to gracefully handle the case where a
-         backslash is the final character in the string (leaves the backslash
-         in place).  Fixes bug reported by Ian Robertson
-         <iroberts@u.washington.edu>
-
-                                  5/16
-                                  ----
-support/checkbashisms
-       - Perl script that purports to check for bash-specific features in a
-         shell script.  Lifted from Debian via ubuntu
-
-                                  5/20
-                                  ----
-lib/readline/display.c
-       - in update_line, when deciding whether or not to adjust _rl_last_c_pos
-         in a multibyte environment after printing the last line of a multiline
-         prompt with invisible characters on the first and last lines, use
-         the number of inivisible chars on the first line in the calculation
-         deciding whether or not we're past the last invisible character and
-         need to adjust the cursor position.  Old code used the number of
-         invisible chars on the last prompt line.  Fixes bug reported by
-         stuff@slinkp.com.
-       - in update_line, when fixing _rl_last_c_pos after drawing the first
-         line of the prompt, use the number of invisible chars on the first
-         line as the offset, instead of the total number of invisible chars
-       - use prompt_multibyte_characters, the number of multibyte chars in
-         the prompt string, to short-circuit some relatively expensive
-         multibyte text processing in rl_redisplay
-
-                                  5/21
-                                  ----
-variables.c
-       - new function, reinit_special_variables(), a hook for special
-         vars that need their hook functions called when they're unset as
-         a result of the shell reinitializing itself to run a script
-
-shell.c
-       - shell_reinitialize now calls reinit_special_variables
-       - shell_reinitialize now calls bashline_reset
-
-variables.h
-       - new extern declaration for reinit_special_variables
-
-bashline.c
-       - new function, bashline_reset(), called when the shell reinitializes
-         in shell_reinitialize.  Right now, just resets
-         bash_readline_initialized to 0.
-
-bashline.h
-       - new extern declaration for bashline_reset()
-
-                                  5/23
-                                  ----
-bashhist.c
-       - new function, bash_clear_history, clears the history and resets any
-         associated internal bash state
-
-bashhist.h
-       - extern declaration for bash_clear_history
-
-builtins/history.def
-       - call bash_clear_history instead of clear_history for `history -c'.
-         Fixes part of problem reported by Scott McDermott
-         <scott.m.mcdermott@gmail.com>
-       - decrement history_lines_this_session in delete_histent, called for
-         `history -d'
-
-builtins/history.def,bashhist.[ch]
-       - move delete_histent() to bashhist.c; rename to bash_delete_histent
-       - move delete_last_history() to bashhist.c; rename to
-         bash_delete_last_history()
-
-                                  5/25
-                                  ----
-braces.c
-       - add another parameter to mkseq(), the number of digits to put into
-         each member of a numeric sequence (width), changes to determine
-         any zero-padding go into expand_seqterm
-       - changes to expand_seqterm to allow user-specified increments
-
-bashline.[ch],shell.c,sig.c
-       - switched names of bashline_reinitialize and bashline_reset to better
-         reflect their functions
-       - when searching $PATH for directories to use for command completion,
-         make sure to free `current_path' before going out of scope
-       - new bindable function `dabbrev-expand', which is more or less
-         menu completion using dynamic history completion as the generator
-       - changes to bash_execute_unix_command to set variables for the
-         executed command like programmable completion: READLINE_LINE
-         (rl_line_buffer) and READLINE_POINT (rl_point)
-       - change to bash_execute_unix_command to allow the executed command
-         to change the readline line buffer by modifying the value of
-         READLINE_LINE and to change rl_point by modifying the value of
-         READLINE_POINT
-
-common.h
-       - new SEVAL_ defines for later parse_string changes from 4.0-devel
-         branch
-
-command.h
-       - new defines for new &>> r_append_err_and_out redirection
-
-builtins/evalstring.c
-       - new function, parse_string, parses a command from a passed string
-         and returns the number of characters consumed.  For satisfying
-         Posix rules when parsing command substitutions, from bash-4.0-devel
-         branch
-       - split out common prolog code from parse_string and
-         parse_and_execute into a separate function called from both
-
-parse.y
-       - small changes to add symbols needed for parse_string
-       - parser change to add `|&' as synonym for `2>&1 |'; translation is
-         performed at parse time so |& never shows up in output of
-         print_command, for instance.  Picked up from zsh, merged in from
-         bash-4.0-devel branch
-
-parse.y,{redir,copy_cmd,dispose_cmd,make_cmd,print_cmd}.c
-       - implement new &>> r_append_err_and_out (like >>foo 2>&1); merged
-         in from bash-4.0-devel branch
-
-doc/{bash.1,bashref.texi},lib/readline/doc/rluser.texi
-       - document new optional increment in brace expansion
-       - document new zero-padded fixed-width integer brace expansion
-       - document new `dabbrev-expand' bindable readline command
-       - document new effects of `bind -x' setting and reading the values of
-         READLINE_LINE and READLINE_POINT
-       - document new |& synonym for `2>&1 |' pipeline operator
-
-                                  5/26
-                                  ----
-parse.y        - recognize new ;& and ;;& case action list terminator tokens and
-         implement them in the grammar, setting CASEPAT_FALLTHROUGH and
-         CASEPAT_TESTNEXT flags as appropriate
-
-print_cmd.c
-       - print new ;& and ;;& case clause action list terminators as
-         appropriate
-
-execute_cmd.c
-       - implement new case clause action list terminators:
-               ;& - fall through to actions associated with next pattern list
-               ;;& - fall through to tests in next pattern list
-
-doc/{bash.1,bashref.texi}
-       - document new ;& and ;;& case clause action list terminators
-
-                                  5/28
-                                  ----
-jobs.c
-       - change waitchld so it treats SIGCHLD like SIGINT if `wait' is being
-         executed, and allows wait to jump out before running any trap set
-         on SIGCHLD.  Fixes debian bug #483016 reported by Miroslav Rudisin
-         <miero@atrey.karlin.mff.cuni.cz>
-       - run_sigchld_trap is no longer static, so the trap code in trap.c
-         can call it
-       - change run_sigchld_trap to call set_impossible_sigchld_trap instead
-         of just using a call to restore_default_signal
-
-jobs.h
-       - new extern declaration for run_sigchld_trap
-
-trap.c
-       - fix run_pending_traps to run a SIGCHLD trap if the trap handler isn't
-         set to IMPOSSIBLE_TRAP_HANDLER
-       - in trap_handler, don't reset the SIGCHLD trap handler to trap_handler
-         if MUST_REINSTALL_SIGHANDLERS is defined
-       - new function, set_impossible_sigchld_handler, sets the trap string
-         associated with SIGCHLD to IMPOSSIBLE_TRAP_HANDLER; used as a sentinel
-         by run_sigchld_trap and maybe_set_sigchld_handler
-       - change maybe_set_sigchld_handler to set the SIGCHLD trap string only
-         if the current value is IMPOSSIBLE_TRAP_HANDLER.  This ensures that
-         any traps on SIGCHLD set in a SIGCHLD handler will persist.  Fixes
-         debian bug #483016 reported by Miroslav Rudisin
-         <miero@atrey.karlin.mff.cuni.cz>
-
-trap.h
-       - new extern declaration for set_impossible_sigchld_trap
-
-                                  5/31
-                                  ----
-parse.y
-       - new function: parse_comsub(), parses $(...) by parsing command
-         between parens and making sure the next token is `)'.  From
-         the bash-4.0-devel branch
-       - new function: xparse_dolparen, helper function for parsing
-         command substitutions in $(...).  Called from subst.c to extract
-         a command substitution during word expansion.  From bash-4.0-devel
-         branch
-       - new function: rewind_input_stream().  Rewinds bash_input.location.string
-         back to where it was before the shell parsed a $() command
-         substitution.  From bash-4.0-devel branch
-       - changes to parse_matched_pair to combine most of the flag variables
-         (was_dollar, in_comment, and so on) into a local flags word
-
-                                   6/2
-                                   ---
-parse.y
-       - call trim_pathname, which retains only the last $PROMPT_DIRTRIM
-         directories and replaces the intervening characters with `...',
-         when expanding \w and \W
-
-doc/{bash.1,bashref.texi}
-       - document the effect of setting PROMPT_DIRTRIM
-
-                                   6/3
-                                   ---
-builtins/ulimit.def
-       - make the multiplier (block size) for -c and -f 512 bytes only if in
-         Posix mode and 1024 bytes otherwise (as in previous versions).  Uses
-         POSIXBLK and BLOCK_SIZE defines to parameterize size based on value
-         of posixly_correct
-
-doc/bashref.texi
-       - document this addition to posix mode
-
-builtins/common.c
-       - change get_numeric_arg to have a calling sequence and return value
-         more closely mimicking general.c:legal_number(), with the addition
-         of a flags word
-       - add extra value for `fatal' argument to get_numeric_arg to force it
-         to return failure to the caller rather than longjmping
-
-builtins/common.h
-       - change prototype declaration for get_numeric_arg
-
-builtins/{break,shift}.def
-       - change calls to get_numeric_arg to deal with new semantics and calling
-         sequence
-
-builtins/history.def
-       - display_history now returns an int
-       - change calling sequence for get_numeric_arg in display_history
-       - display_history now returns failure to the caller if get_numeric_arg
-         detects an invalid number, rather than jumping back to the top level
-       - use value returned by display_history as return status of history
-         builtin, filtered through sh_chkwrite
-       - history no longer aborts compound commands on invalid arguments.
-         fixes problem reported by Chu Li <chul@cn.fujitsu.com>
-
-{braces,subst}.c
-      - extract_command_subst now takes a third flags argument; passed flags
-       are ORd into flags passed to other functions; changed callers
-
-subst.h
-       - move SX_* defines here from subst.c so parse.y:xparse_dolparen can
-         see them and behave appropriately
-       - extract_command_subst now takes a third flags argument; change
-         prototype
-
-subst.c
-       - change extract_command_subst to call xparse_dolparen when extracting
-         a $() construct
-       - change calls to extract_delimited_string to extract_command_subst
-         as appropriate
-       - if command_substitute returns a NULL word desc, don't call
-         dispose_word_desc on it
-
-parse.y
-       - change xparse_dolparen to use the SX_* flags now in subst.h
-
-                                  6/16
-                                  ----
-subst.c
-       - in quote_list, set W_HASQUOTEDNULL flag in the word if quote_string
-         turns "" into CTLNUL
-       - in dequote_list, turn off W_HASQUOTEDNULL flag in the word if
-         dequote_string turns CTLNUL into ""
-       - new function, string_list_pos_params, encapsulates everything
-         needed to turn the positional parameters or an array indexed with
-         '@' or '*' into a string, including taking care of quoting and
-         using the first char of $IFS, when used in another expansion like
-         pattern removal or pattern substitution
-       - change list_remove_pattern, pos_params, pos_params_pat_subst to
-         call string_list_pos_params.  Fixes problems reported by
-         Stephane Chazelas <stephane_chazelas@yahoo.fr>
-
-                                  6/22
-                                  ----
-variables.h
-       - include assoc.h for associative arrays
-       - defines for case-modifying expansions and associative array variables
-       - sh_var_assign_func_t functions now take an extra char * parameter
-
-                                  6/25
-                                  ----
-variables.c
-       - change declarations and definitions of sh_var_assign_func_t functions
-         to add the extra char * parameter: null_assign, null_array_assign,
-         assign_seconds, assign_random, assign_lineno, assign_subshell,
-         assign_dirstack
-       - change calls to var->assign_func to add extra char * argument
-       - broke part of body of dispose_variable out into a new function,
-         dispose_variable_value, which knows how to free all kinds of shell
-         variable data
-       - changes to deal with variables with the internal `nofree' attribute
-
-arrayfunc.c
-       - change calls to var->assign_func to add extra char * argument
-       - bind_array_var_internal now takes an extra `char *key' argument
-       - additions for associative array implementation; from bash-4.0-devel
-         tree
-
-arrayfunc.[ch],subst.c
-       - expand_compound_array_assignment now takes the variable as the first
-         argument (SHELL_VAR *); changed function definition and callers
-
-builtins/set.def
-       - changes to handle associative arrays in `unset'
-
-{execute_cmd,command}.h
-       - definitions for coproc implementation; from bash-4.0-devel tree
-
-variables.c
-       - new functions for associative arrays: make_new_assoc_variable,
-         make_local_assoc_variable
-
-                                  6/26
-                                  ----
-variables.c
-       - more infrastructure for associative arrays; from bash-4.0-devel tree
-       - infrastructure for handling assignments to variables with
-         case-modifying attributes; from bash-4.0-devel tree
-
-config.h.in
-       - add #defines controlling case-modifying variable attributes and word
-         expansions
-
-configure.in
-       - add enable options for case-modifying variable attributes and word
-         expansions (--enable-casemod-attributes and --enable-casemod-expansions,
-         respectively); from bash-4.0-devel tree
-
-execute_cmd.c
-       - add code to fix_assignment_words to handle assignment statements to
-         "assignment builtins" that seem to be associative arrays.  Imperfect
-
-subst.c
-       - array_remove_pattern now takes a SHELL_VAR * as its first argument
-         instead of an ARRAY *; from the bash-4.0-devel tree
-       - changes to array_length_reference for associative arrays; from the
-         bash-4.0-devel tree
-       - changes to get_var_and_type for associative arrays; from the
-         bash-4.0-devel tree
-       - changes to parameter_brace_substring for associative arrays; from the
-         bash-4.0-devel tree
-       - changes to param_expand for associative arrays; from the
-         bash-4.0-devel tree
-
-builtins/declare.def
-       - changes for associative arrays: new `-A' option, changes to make
-         local and global associative array variables; from the bash-4.0-devel
-         tree
-
-                                  6/27
-                                  ----
-execute_cmd.c
-       - in execute_command_internal, when short-circuiting execution
-         because `breaking' or `continuing' is non-zero, preserve the exit
-         status by returning `last_command_exit_value' instead of an
-         unconditional EXECUTION_SUCCESS.  Fixes bug reported by Roman
-         Rakus <rrakus@redhat.com>
-
-                                  6/28
-                                  ----
-variables.c
-       - fix get_var_and_type to appropriately handle references like
-         ${varname[0]}, where `varname' is a scalar variable
-
-make_cmd.[ch],parse.y
-       - make_here_document now takes a second argument: the current line
-         number; changed caller (gather_here_documents)
-
-builtins/setattr.def
-       - added support for associative arrays and the `-A' variable attribute
-         option; from the bash-4.0-devel tree
-
-subst.c
-       - change code that transforms `declare -A xxx=(yyy)' to perform the
-         internal `declare -A xxx' before doing the variable assignment,
-         because associative arrays have to be declared before being assigned
-         to as such; uses new function make_internal_declare
-
-                                  6/30
-                                  ----
-subst.[ch]
-       - dequote_escapes is now external; add declaration in subst.h
-       - remove_quoted_nulls is now external; add declaration in subst.h
-
-array.[ch]
-       - new functions for completeness:  array_dequote, array_dequote_escapes,
-         array_remove_quoted_nulls
-       - array_subrange now calls array_remove_quoted_nulls for "${array[*]}".
-         Fixes bug reported by Vitor De Araujo <ux386@yahoo.com.br>
-       - array_patsub now calls array_remove_quoted_nulls for "${array[*]}"
-       - array_modcase now calls array_remove_quoted_nulls for "${array[*]}"
-       - array_patsub now handles the mflags&MATCH_QUOTED case appropriately
-         (that implies "${array[@]}")
-
-subst.c
-       - new functions for case-modifying word expansion suppport:
-         pos_params_casemod, parameter_brace_casemod; from bash-4.0-devel branch
-
-assoc.c
-       - new functions for completeness: assoc_remove_quoted_nulls
-       - assoc_patsub now calls assoc_remove_quoted_nulls for "${assoc[*]}"
-       - assoc_modcase now calls assoc_remove_quoted_nulls for "${array[*]}"
-       - assoc_patsub now handles the mflags&MATCH_QUOTED case appropriately
-         (that implies "${assoc[@]}")
-
-                                   7/1
-                                   ---
-assoc.[ch]
-       - new function, assoc_subrange: takes a hash table, converts it to a
-         word list, and performs the subrange and indexing on that list
-       - new functions for completeness: assoc_dequote, assoc_dequote_escapes
-
-subst.c
-       - verify_substring_values now takes the variable SHELL_VAR * as its
-         new first argument; changed callers
-       - change verify_substring_values to handle associative arrays using the
-         number of elements as the upper bound
-       - brought in code to do case-modifying word expansions from
-         bash-4.0-devel branch, conditional on CASEMOD_EXPANSIONS
-
-input.c
-       - if the read(2) in getc_with_restart returns -1/EAGAIN, turn off
-         non-blocking mode on the file descriptor and try again.  Fixes
-         problem reported by Glynn Clements <glynn@clements.plus.com>
-
-                                   7/2
-                                   ---
-doc/{bash.1,bashref.texi}
-       - documented new case-modifying word expansions
-
-make_cmd.c
-       - change make_here_document to display a warning message including the
-         start line of a here document if it ends up delimited by EOF.
-         Addresses issue raised by Richard Neill <rn214@hermes.cam.ac.uk>
-
-subst.c
-       - in do_assignment_internal, make sure the `invisible' attribute is
-         unset before returning success
-
-                                   7/3
-                                   ---
-config-top.h
-       - add `CASEMOD_CAPCASE' define to include or exclude the ~[~] word
-         expansion and the `capcase' variable attribute (declare -c)
-
-builtins/declare.def
-       - add support for manipulating the case-modifying attributes (new
-         declare -clu); from bash-4.0-devel branch
-
-builtins/setattr.def
-       - add support for reporting case-modifying attributes (-clu attributes);
-         from bash-4.0-devel branch
-
-doc/{bash.1,bashref.texi}
-       - specify that the read builtin timing out results in a return value
-         greater than 128
-       - document new `-l' and `-u' options to declare/typeset/local.  Leave
-         `-c' undocumented for now
-
-                                   7/4
-                                   ---
-make_cmd.[ch]
-       - make_coproc_command: construct a coproc; from bash-4.0-devel tree
-
-dispose_cmd.c
-       - dispose coproc command; from bash-4.0-devel tree
-
-copy_cmd.c
-       - copy a coproc command; from bash-4.0-devel tree
-
-print_cmd.c
-       - print a coproc command; from bash-4.0-devel tree
-
-shell.c
-       - dispoe the current coproc on shell exit; from bash-4.0-devel tree
-
-redir.c
-       - when closing redirects as part of user redirections, check whether
-         or not active coprocess fds are being closed and close the coproc
-         if so; from bash-4.0-devel tree
-
-config.h.in
-       - add define for COPROCESS_SUPPORT to include coprocesses
-
-configure.in
-       - add support for configuring coprocesses into and out of the build
-
-jobs.c
-       - in waitchld, check whether or not a coproc processs has exited;
-         from the bash-4.0-devel tree
-
-                                   7/5
-                                   ---
-doc/bashref.texi
-       - document new --enable-coprocesses option that includes coprocess
-         support
-
-execute_cmd.c
-       - add functions for coprocess support, including execute_coproc and
-         code to call it when command->type == cm_coproc; from
-         bash-4.0-devel tree
-
-lib/sh/fdprintf.c
-       - new library function fdprintf(int fd, const char *format, ...);
-         printf to a file descriptor
-
-{configure,config.h}.in
-       - support for detecting fdprintf and compiling in replacement
-
-Makefile.in,lib/sh/Makefile.in
-       - add rules to include fdprintf.o
-
-doc/{bash.1,bashref.texi}
-       - documented coprocesses and `coproc' reserved word
-
-                                   7/7
-                                   ---
-subst.c
-       - fix array_length_reference to use MB_STRLEN instead of STRLEN, so
-         multibyte characters in array values are computed correctly.  Fixes
-         bug reported by Wang Xin <wxinee@gmail.com>
-
-                                  7/10
-                                  ----
-jobs.c
-       - new function, maybe_give_terminal_to (old, new, flags), sets the
-         terminal pgrp to NEW if and only if it's currently set to OLD
-       - call maybe_give_terminal_to when the parent sets the terminal pgrp
-         to the pipeline pgrp in stop_pipeline, so we don't give the
-         terminal to the new job's pgrp unless it's currently owned by the
-         shell.  Fixes race condition described by Joe Peterson
-         <joe@skyrush.com>, where parent bash may change tty pgrp after a
-         grandchild (interactive bash child of su) has changed it to
-         something else.  The call to maybe_give_terminal_to makes explicit
-         a previously-implicit assumption
-
-aclocal.m4
-       - remove dependency on writable /tmp by creating directories in
-         build directory
-
-shell.c
-       - make changes to how bash sets no_line_editing and running_under_emacs
-         to deal with various emacs terminal emulators; use better check
-         for `eterm', since bash sends $PWD to eterm with control sequences
-         that confuse other programs.  Problem reported by Micah Cowan
-         <micah@cowan.name>
-
-
-                                  7/12
-                                  ----
-print_cmd.c
-       - break code that prints here-documents into two functions:
-         print_heredoc_header, which prints the operator and delimiter, and
-         print_heredoc_body, which prints the body text and closing delimiter
-       - change print_redirection to call print_heredoc_{header,body}
-       - sentinel variable, printing_connection, used when printing a command
-         of type `connection' (|, &&, ||, etc.)
-       - change print_redirection_list to save any here documents it finds
-         while printing a connection and save them in `deferred_heredocs'
-       - new function, print_deferred_heredocs, called from print_redirection
-         in the cm_connection case, calls print_heredoc_header for all the
-         here documents, then prints the operator (|, &&, ||, etc.), then
-         the here-document body.  This preserves syntactic correctness; the
-         old code printed the control operator after the body of the here
-         document.  Fixes bug reported by <buport@figpost.com>
-
-                                  7/16
-                                  ----
-locale.c
-       - in set_locale_var, print a warning message if setlocale() fails any
-         time it's called -- required some code restructuring
-
-                                  7/19
-                                  ----
-support/shobj-conf
-       - support for mingw32, contributed by Carlo Bramix
-         <carlo.bramix@libero.it>
-
-                                  7/23
-                                  ----
-execute_cmd.c
-       - added support (currently unused) to manage a list of coprocs
-
-                                  7/25
-                                  ----
-bashline.c
-       - add extern declarations for literal_history and force_append_history
-
-builtins/shopt.def
-       - include "bashhist.h" instead of having extern declarations for the
-         appropriate history variables
-
-parser.h
-       - new parser_state value: PST_HEREDOC, set when reading body of here-
-         document in parse.y:read_secondary_line
-
-parse.y
-       - set PST_HEREDOC bit in parser_state when reading a secondary line
-         for the body of a here-document
-       - change read_secondary_line to save lines in the body of a here-
-         document in the shell history list if remember_on_history is
-         set.  Fixes bug reported by Gene Golub <gene_golub@hotmail.com>
-
-                                   8/4
-                                   ---
-configure.in
-       - changed to 4.0-alpha
-
-lib/readline/readline.h
-       - changed constants to reflect readline-6.0 version
-
-                                  8/11
-                                  ----
-lib/readline/signals.c
-       - make sure we don't use SIGWINCH without checking whether or not it's
-         defined.  Fix from Pedro Alves <pedro@codesourcery.com>
-
-                                  8/12
-                                  ----
-
-COPYING
-       - updated to GPLv3; edits in every file with a copyright or license
-         declaration to update to gpl3
-
-version.c
-       - update extended version info to latest gnu standard
-
-                                  8/17
-                                  ----
-subst.c
-       - change exp_jump_to_top_level to only call top_level_cleanup if
-         parse_and_execute_level is 0.  If it's not, the longjmp to
-         parse_and_execute will run the unwind-protect stack.  Fixes bug
-         most recently reported by Roman Rakus <rrakus@redhat.com>
-
-                                  8/18
-                                  ----
-support/config.{guess,sub}
-       - updated to newer versions from autoconf-2.62 distribution
-
-                                  8/20
-                                  ----
-subst.c
-       - fixed parameter_brace_substring to differentiate between indexed and
-         associative arrays when computing second offset, instead of
-         assuming indexed array
-
-                                  8/21
-                                  ----
-support/xcase.c
-       - simple program to convert input from lower to uppercase and vice
-         versa.  Now used by coproc test suite, since `tr -u' is not
-         portable.
-
-                                  8/22
-                                  ----
-doc/bash.1
-       - fixed description of the bindable edit-and-execute commands to note
-         they check $VISUAL first, instead of $FCEDIT.  Fixed bug reported
-         by
-
-[bash-4.0-alpha frozen]
-
-                                  8/28
-                                  ----
-[bash-4.0-alpha released]
-
-                                   9/1
-                                   ---
-builtins/evalstring.c
-       - fixed typo in parse_string (ostring used uninitialized).  Bug
-         reported by Andreas Schwab <schwab@suse.de>
-
-subst.c
-       - fix return value of parameter_brace_expand to set the
-         W_HASQUOTEDNULL flag in the returned WORD_DESC * if the return value
-         from parameter_brace_remove_pattern is a quoted null string.  Fixes
-         bug reported by Andreas Schwab <schwab@suse.de>
-       - set the W_HASQUOTEDNULL flag in the return value from
-         parameter_brace_expand if the return value from parameter_brace_patsub
-         is a quoted null string
-
-                                   9/6
-                                   ---
-builtins/read.def
-       - change read -t 0 to return success if there is input available to be
-         read -- allows scripts to poll for input.  Uses input_avail libsh
-         function
-
-                                   9/9
-                                   ---
-externs.h
-       - fix extern fpurge declaration -- use HAVE_DECL_FPURGE instead of
-         NEED_FPURGE_DECL, since the former is set by `configure'
-
-jobs.h
-       - add extern declaration for close_pgrp_pipe
-       - add a new job state JNONE (-1) to the enum
-
-jobs.c
-       - include execute_cmd.h for extern declarations for coproc functions
-
-subst.c
-       - include builtins/builtext.h for extern declarations for functions
-         implementing builtins (e.g., declare_builtin)
-
-arrayfunc.c
-       - include "pathexp.h" for extern declaration for glob_char_p
-
-braces.c
-       - add extern declaration for `asprintf'
-
-lib/readline/rlprivate.h
-       - add extern declarations for _rl_trace, _rl_tropen
-
-lib/sh/zgetline.c
-       - add extern declarations for zread, zreadc
-
-lib/sh/mktime.c
-       - include "bashansi.h" for string function declarations
-
-builtins/common.h
-       - add extern declaration for parse_string
-
-trap.c
-       - include jobs.h for extern declaration for run_sigchld_trap
-
-general.c
-       - fix call to strtoimax in legal_number; if ep == string when function
-         returns, the number was not converted, even if errno is not set.
-         Fix from Paul Jarc <prj@case.edu>
-
-                                  9/11
-                                  ----
-[prayers for the victims of 9/11/2001]
-
-builtins/return.def
-       - call no_options, as Posix requires.  This also has the effect of
-         disallowing negative return values unless they're prefixed by `--'
-
-                                  9/13
-                                  ----
-builtins/bind.def
-       - add an error message when bind is used without line editing active,
-         instead of just returning an error status
-
-variables.c
-       - make sure make_local_variable never creates visible variables with
-         a value, whether or not a variable with the same name existed in a
-         previous context.  This is consistent with ksh93.  Fix from
-         <neil@s-z.org>
-
-                                  9/16
-                                  ----
-execute_cmd.c
-       - add call to CHECK_TERMSIG in shell_execve after the call to execve
-         returns.  Recommended by Roman Rakus <rrakus@redhat.com>
-       - add QUIT check in execute_connection after executing first command
-         in a `&' connection
-
-                                  9/22
-                                  ----
-execute_cmd.c
-       - new semaphore variable, executing_list, incremented every time a
-         list (command1;command2 or command1 || command2 or command1 &&
-         command2) is executed; used as sentinel for rest of shell
-
-sig.c,builtins/evalstring.c
-       - set executing_list to 0 when throwing execution back to top level;
-         make sure to unwind-protect it in appropriate places
-
-jobs.c
-       - if a pipeline is killed by SIGINT while executing a list (when
-         executing_list is non-zero), make sure the shell acts as if an
-         interrupt occurred.  The behavior is dependent on the shell
-         compatibility level being > 32 (bash-4.0 and above)
-
-                                  9/23
-                                  ----
-redir.c
-       - don't bother reporting an error with a file descriptor, even if
-         the errno is EBADF, if the redirection error (e.g., NOCLOBBER)
-         can't have anything to do with the fd.  Fixes bug reported by
-         "David A. Harding" <dave@dtrt.org>, debian bug #499633.
-
-                                  9/24
-                                  ----
-builtins/declare.def
-       - make `declare [option] var' (and the `typeset' equivalent) create
-         invisible variables, instead of assigning the null string to a
-         visible variable.  Fixes bug reported by Bernd Eggink <monoped@sudrala.de>
-
-                                  9/25
-                                  ----
-builtins/common.[ch]
-       - new function, builtin_warning(), like builtin_error but for warning
-         messages
-
-builtins/bind.def
-       - experimental: print a warning, but go on, if line editing not active
-         when bind is invoked.  Suggested by Rocky Bernstein
-         <rocky.bernstein@gmail.com>
-
-                                  10/3
-                                  ----
-test.c
-       - use same_file instead of directly comparing st_dev and st_ino when
-         comparing files in filecomp().  From mingw32 patches submitted
-         by Hector Chu <hkcc2@cantab.net>
-
-                                  10/4
-                                  ----
-
-redir.c
-       - in redirection_error(), use `error' instead of errno when comparing
-         against EBADF.  From mingw32 patches submitted by Hector Chu
-         <hkcc2@cantab.net>
-
-shell.c
-       - in unset_bash_input(), reset bash_input.type to st_none after
-         closing the default buffered fd.  From mingw32 patches submitted
-         by Hector Chu <hkcc2@cantab.net>
-
-builtins/cd.def
-       - ignore CDPATH when in privileged mode.  Suggested by Paul Jarc
-         <prj@po.cwru.edu>
-
-variables.c
-       - change sv_globignore to only act if privileged mode is not enabled.
-         Suggested by Paul Jarc <prj@po.cwru.edu>
-
-doc/bash.1,bashref.texi
-       - document new treatment of CDPATH and GLOBIGNORE when privileged
-         mode is enabled
-
-builtins/read.def
-       - change prompt printing to occur after terminal is set to no-echo
-         mode.  Based on suggestion from Stephane Chazelas
-         <stephane_chazelas@yahoo.fr>
-
-lib/readline/signals.c
-       - new variables to keep track of special characters corresponding to
-         SIGINT, SIGQUIT, and SIGTSTP
-       - new variable to keep track of whether tty is echoing control
-         characters corresponding to SIGINT, SIGQUIT, and SIGTSTP
-       - new function, _rl_echo_signal_char(int sig) to display the tty
-         special char generating SIGINT, SIGQUIT, or SIGTSTP.  Based on
-         idea and code from Joe Peterson <joe@skyrush.com>
-       - call rl_echo_signal_char in rl_signal_handler: if the terminal
-         settings indicate it, readline will echo characters that generate
-         keyboard signals
-
-lib/readline/rltty.c
-       - set _rl_intr_char, _rl_quit_char, and _rl_susp_char to special
-         characters that generate signals from keyboard
-       - set _rl_echoctl if ECHOCTL tty flag is set
-
-lib/readline/rlprivate.h
-       - extern declarations for _rl_intr_char, _rl_quit_char, and
-         _rl_susp_char
-       - extern declaration for _rl_echoctl
-
-lib/readline/readline.h
-       - extern declaration for rl_echo_signal_char()
-
-lib/readline/doc/rltech.texi
-       - document rl_echo_signal_handler(): available for applications
-         that install their own signal handlers
-
-                                  10/5
-                                  ----
-execute_cmd.c
-       - fix errexit logic to not cause the shell to exit when a command in
-         a pipeline fails.  Fixes bug reported by Marcin Owsiany
-         <marcin@owsiany.pl>
-
-                                  10/14
-                                  -----
-builtins/evalstring.c
-       - don't short-circuit execution in parse_and_execute if we want to
-         run an exit trap.  Fixes bug reported by Steffen Kiess
-         <s-kiess@web.de>
-
-                                  10/18
-                                  -----
-parse.y
-       - fix error production to only call YYACCEPT if the shell is currently
-         interactive and not in parse_and_execute (so parser errors in
-         things like eval will correctly set $?).  Fixes bug reported by
-         marco-oweber@gmx.de
-
-execute_cmd.c
-       - make sure variable name errors in execute_for_command and non-
-         identifier function names in execute_intern_function set the
-         return status to EX_BADUSAGE (2), not EX_USAGE (258)
-
-parser.h
-       - new parser state, PST_REPARSE
-
-parse.y
-       - turn PST_REPARSE on in parse_string_to_word_list
-       - in parse_matched_pair, if parsing a single-quoted string and
-         PST_REPARSE is set, don't requote CTLESC or CTLNUL.  Fixes bug with
-         compound array assignment using $'\x7f' reported by Antonio Macchi
-         <antonio_macchi@alice.it>
-
-                                  10/23
-                                  -----
-configure.in
-       - define LOCAL_LDFLAGS as `-z interpose' on Solaris 8, 9, and 10 to
-         allow the bash malloc to interpose the libc malloc when called by
-         library functions pre-bound to the libc malloc.  Suggested by
-         Serge Dussud <Serge.Dussud@Sun.COM>
-
-                                  10/26
-                                  -----
-doc/bash.1
-       - add single-sentence descriptions to rest of parameter expansions.
-         Suggested by Ken Irving <fnkci@uaf.edu>
-
-                                  10/27
-                                  -----
-subst.c
-       - rearrange code in skip_to_delims to allow quote characters and other
-         shell expansion characters to be delimiters
-       - add new flags value for inverting search: skip to the next character
-         NOT in the set of delimiters passed as an argument
-
-subst.h
-       - define for new SD_INVERT flag value for skip_to_delims
-
-                                  10/28
-                                  -----
-bashline.c
-       - new bindable functions: shell-forward-word and shell-backward-word.
-         Like forward-word and backward-word, but understand shell quoting
-         and use shell metacharacters and whitespace as delimiters.
-         Suggested by Andre Majorel <amajorel@teaser.fr>
-       - new bindable functions: shell-kill-word and shell-backward-kill-word.
-         Like kill-word and backward-kill-word, but understand shell quoting
-         and  use shell metacharacters and whitespace as delimiters.
-         Suggested by Andre Majorel <amajorel@teaser.fr>
-
-doc/bash.1,lib/readline/doc/rluser.texi
-       - documented shell-forward-word and shell-backward-word
-       - documented shell-kill-word and shell-backward-kill-word
-
-                                  11/1
-                                  ----
-redir.c
-       - add extra argument to add_undo_redirect: fdbase.  FD used to save
-         a file descriptor must be > fdbase if fdbase >= SHELL_FD_BASE.  A
-         value of -1 for fdbase means to just use SHELL_FD_BASE.  Fixes bug
-         with 0<&10 reported by Clark Jian Wang <dearvoid@gmail.com>
-
-                                  11/5
-                                  ----
-unwind_prot.c
-       - new function: have_unwind_protects(); returns 1 if unwind_protect_list
-         is not empty
-
-unwind_prot.h
-       - extern declaration for have_unwind_protects
-
-builtins/evalstring.c
-       - in parse_and_execute_cleanup, make sure that we don't call
-         run_unwind_frame and expect it to decrement parse_and_execute_level
-         if there's no unwind_protect_list, since there's a while loop in
-         throw_to_top_level that calls parse_and_execute_cleanup as long as
-         parse_and_execute_level is non-zero
-
-                                  11/9
-                                  ----
-variables.c
-       - fix the assign function for COMP_WORDBREAKS to allocate new memory
-         to store as the variable's value, to avoid freeing memory twice
-         if the variable is unset after rl_completer_word_break_characters
-         is freed and reallocated.  Fix from Mike Stroyan <mike@stroyan.net
-
-                                  11/11
-                                  -----
-bashline.c
-       - new function to reset the value of rl_completer_word_break_characters
-         while honoring setting of `hostcomplete': reset_completer_word_break_chars.
-
-bashline.h
-       - new extern declaration for reset_completer_word_break_chars.
-
-variables.c
-       - call reset_completer_word_break_chars in sv_comp_wordbreaks when the
-         variable is unset
-
-[bash-4.0-beta frozen]
-
-                                  11/16
-                                  -----
-subst.c
-       - call set_pipestatus_from_exit in exp_jump_to_top_level so that
-         failed expansions that set $? will set $PIPESTATUS.  Fixes bug
-         reported by Eric Blake <ebb9@byu.net>
-
-                                  11/20
-                                  -----
-general.c
-       - new 'file_exists(fn)' primitive; just calls stat(2)
-
-general.h
-       - new extern declaration for file_exists
-
-bashline.c
-       - add `~' to rl_filename_quote_characters so make_quoted_replacement
-         will call bash_quote_filename for words containing `~'.  Then
-         bash_quote_filename can make choices based on that
-       - change quote_word_break_chars to backslash-quote the tilde in a
-         filename with a leading tilde that exists in the current directory,
-         since we want to inhibit tilde expansion in this case
-
-execute_cmd.c
-       - call file_isdir from shell_execve instead of stat(2) directly
-
-bashhist.c
-       - use file_exists and file_isdir primitives instead of calling stat
-
-                                  11/21
-                                  -----
-redir.c
-       - When undoing saving of non-standard file descriptors (>=3) using
-         file descriptors >= SHELL_FD_BASE, we set the saving fd to be
-         close-on-exec and use a flag (RX_SAVCLEXEC) to decide how to set
-         close-on-exec when the fd is restored.  Set flag in add_undo_redirect,
-         check in do_redirection_internal.  Fixes problem reported by Andreas
-         Schwab <schwab@suse.de>
-
-                                  11/26
-                                  -----
-subst.c
-       - fix param_expand to have expansions of $@ and $* exit the shell if
-         there are no positional parameters and `set -u' is enabled.  Fixes
-         bug reported by Dan Jacobson <jidanni@jidanni.org>
-
-                                  11/27
-                                  -----
-lib/readline/display.c
-       - fix update_line to not call space_to_eol if current cursor position
-         (_rl_last_c_pos) indicates that we're already at end of line.
-         Partial fix for bug reported by Mike Frysinger <vapier@gentoo.org>
-       - in update_line, don't call insert_some_chars if that will start
-         before the last invisible character in the prompt string and not
-         draw the entire prompt string.  More of the partial fix for bug
-         reported by Mike Frysinger <vapier@gentoo.org>
-       - fix update_line to adjust _rl_last_c_pos by wrap_offset when adding
-         characters beginning before the last invisible character in the
-         prompt.  New code is same as previously existed in a different code
-         path.  Rest of fix for bug from Mike Frysinger <vapier@gentoo.org>
-       - fix assignment of newline breaks (inv_lbreaks) to correctly account
-         for prompts longer than two screen lines containing invisible
-         characters.  The assumption is that part of the invisible characters
-         are on the first line (prompt_invis_chars_first_line) and the
-         remainder are on the last (wrap_offset - prompt_invis_chars_first_line).
-         Fix is in rl_redisplay.  part of fix for bug reported by
-         "Wesley J. Landaker" <wjl@icecavern.net> in
-         http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=265182
-         [TENTATIVE]
-       - fix _rl_move_cursor_relative to correctly offset `dpos' by `woff'
-         when there are invisible characters on lines after the second by
-         using (_rl_screenwidth*_rl_last_v_pos) when seeing whether or not
-         we just wrote some invisible characters.  Rest of fix for bug
-         reported in http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=265182
-         [TENTATIVE]
-
-                                  12/11
-                                  -----
-sig.c
-       - reset the execution context before running the exit trap in
-         termsig_handler
-
-general.c
-       - set and unset terminate_immediately like interrupt_immediately in
-         bash_tilde_expand
-
-builtins/read.def
-       - change terminate_immediately to a counter instead of a flag, as
-         interrupt_immediately is used
-
-lib/readline/display.c
-       - slight change to fix from 11/27 to deal with prompts longer than a
-         screen line where the invisible characters all appear after the
-         line wrap.  Fixes bug reported by Andreas Schwab <schwab@suse.de>
-
-builtins/{echo,printf}.def
-       - increment terminate_immediately at entry; decrement before returning.
-         Fix for bug reported by Ralf.Wildenhues@gmx.de
-
-                                  12/16
-                                  -----
-subst.c
-       - fix off-by-one error in /dev/fd version of add_fifo_list; make
-         sure we add to totfds when it is == fd, not just when fd > totfds.
-         Fixes bug reported by marciso@gmail.com
-
-[bash-4.0-beta2 frozen]
-
-                                  12/29
-                                  -----
-doc/{bash.1,bashref.texi}
-       - document more clearly that when not in Posix mode, command
-         substitution does not inherit the -e option.  From bug report from
-         Freddy Vulto <fvulto@gmail.com>
-
-{execute_cmd,sig,builtins/evalstring}.c
-       - sentinel variable to keep track of whether or not we're supposed to
-         ignore the failure status of a command executed in a command
-         substitution even if the `-e' option is set: comsub_ignore_return
-       - increment and decrement comsub_ignore_return in execute_simple_command
-         before calling expand_words
-       - in parse_and_execute, if comsub_ignore_return is non-zero and the
-         SUBSHELL_COMSUB bit is set in subshell_environment, enable the
-         CMD_IGNORE_RETURN flag in every command executed from the passed
-         string.  Fixes problem reported by Freddy Vulto <fvulto@gmail.com>
-       - make sure to reset comsub_ignore_return every time we throw to the
-         top level, like executing_list flag
-
-                                1/2/2009
-                                --------
-parse.y
-       - fix to rewind_input_stream to handle case of $(...) command
-         substitution followed by a quoted literal newline.  Report and fix
-         from Andreas Schwab <schwab@suse.de>
-
-                                   1/7
-                                   ---
-
-subst.c
-       - fix match_wpattern and match_upattern to prefix a `*' to the
-         pattern even if it starts with a `*(' (if extglob is enabled)
-         before checking whether or not it can match anywhere in the
-         string.  Fixes bug reported by os@sernet.de.
-
-[bash-4.0-rc1 frozen]
-
-                                   1/9
-                                   ---
-locale.c
-       - since setlocale() doesn't set errno to anything meaningful,
-         don't include the strerror() result in the error message if
-         it fails
-       - make sure the error messages printed when setlocale fails are
-         localizable
-
-                                  1/11
-                                  ----
-lib/readline/histexpand.c
-       - make sure that every time history_no_expand_chars is tested, we
-         also call the history_inhibit_expansion_function if it's set.
-         Fixes bug reported by Yang Zhang <yanghatespam@gmail.com>
-
-                                  1/12
-                                  ----
-trap.c
-       - make sure to call parse_and_execute with the SEVAL_RESETLINE bit
-         set in the flags so it will reset the line number when running
-         the trap commands.  Partial fix for bug reported by
-         peter360@fastmail.us
-
-                                  1/14
-                                  ----
-builtins/reserved.def
-       - document `coproc' so it can be used with `help' builtin.  Pointed
-         out by Pierre Gaston <pgas@freeshell.org>
-
-lib/sh/casemod.c
-       - added two new flags: CASE_UPFIRST and CASE_LOWFIRST to casemod
-         the first character of the passed string and pass the rest
-         through unchanged.  Fixes bug reported by Jan Schampera
-         <jan.schampera@web.de>
-
-externs.h
-       - new defines for CASE_UPFIRST and CASE_LOWFIRST
-
-subst.c
-       - use CASE_UPFIRST for ^ and CASE_LOWFIRST for , casemod operators
-
-builtins/mapfile.def
-       - call zreset() before calling first zgetline(), to clean out any
-         remaining data in local buffer used by zreadc.  Fixes bug
-         reported by Pierre Gaston <pierre.gaston@gmail.com>
-
-                                  1/15
-                                  ----
-lib/sh/zread.c
-       - renamed zreadintr to zreadretry -- not perfect, but better
-       - new functions: zreadintr, which just calls read so it can be
-         interruptible, and zreadcintr, which is like zreadc but uses
-         zreadintr to fill the buffer
-
-lib/sh/zgetline.c
-       - in zgetline, when zread/zreadc return <= 0, make sure line is
-         non-null before assigning to line[nr]
-
-builtins/mapfile.def
-       - return an error right away if the supplied array variable name
-         refers to a readonly or noassign array
-       - set interrupt_immediately so calls to zgetline can be
-         interrupted.  Fixes bug reported by Pierre Gaston
-         <pierre.gaston@gmail.com>
-       - if interactive, pass the SEVAL_INTERACT and SEVAL_NOHIST flags
-         to parse_and_execute when calling callbacks.  Fixes bug reported
-         by Pierre Gaston <pierre.gaston@gmail.com>
-       - add `readarray' as a synonym for mapfile
-
-doc/{bash.1,bashref.texi}
-       - document behavior of mapfile builtin adding index of array element
-         to be assigned as additional argument to callback string.  Reported
-         by Pierre Gaston <pierre.gaston@gmail.com>
-       - document readarray as synonym for mapfile
-
-builtins/common.c
-       - new error function, sh_ttyerror(set), prints an error message having
-         to do with setting or getting terminal attributes
-
-builtins/read.def
-       - print error message if read fails to set terminal attributes
-
-                                  1/16
-                                  ----
-execute_cmd.c
-       - new function, coproc_reap, calls coproc_dispose if sh_coproc is
-         marked as COPROC_DEAD
-       - new function, cpl_reap, disposes coprocs marked as COPROC_DEAD
-         from coproc list
-       - change coproc_pidchk to just mark the coproc as dead instead of
-         calling coproc_dispose, so we don't call unsafe functions from
-         a signal handler.  Fixes bug reported by Andreas Schwab
-         <schwab@suse.de>
-
-execute_cmd.h
-       - new extern declaration for coproc_reap
-
-command.h
-       - new flags for c_flags member of a struct coproc
-
-{jobs,nojobs}.c
-       - add call to coproc_reap in cleanup_dead_jobs, which will do the
-         right queueing or blocking of SIGCHLD
-
-trap.c
-       - modify change from 1/12 to not reset the line number when running
-         the DEBUG and RETURN traps
-
-                                  1/18
-                                  ----
-lib/sh/casemod.c
-       - change default operations to work on entire passed string instead
-         of breaking into words at non-alpha-numerics.  Use new
-         CASE_USEWORDS flag to enable by-word behavior.  Fixes bug reported
-         by Jan Schampera <jan.schampera@web.de>
-
-builtins/printf.def
-       - in vbprintf, bracket each call to vsnprintf (which uses the args
-         passed to vbprintf) with SH_VA_START and va_end, so we can
-         reninitialize the argument list for each call.  This is actually
-         what the C standard requires.  Fixes bug that caused printf -b
-         to `ignore' first % format specifier if it came first in the
-         string.  Reported by David Leverton <levertond@googlemail.com>
-
-builtins/mapfile.def
-       - start the line count at 1, since it doesn't get incremented before
-         (or after) reading the first line, so things like
-         `mapfile -n 5 -c 1 -C 'echo foo' array < file' work right and call
-         the callback after the first line is read.  Fixes bug reported by
-         Pierre Gaston <pierre.gaston@gmail.com>
-
-                                  1/22
-                                  ----
-lib/readline/complete.c
-       - set _rl_interrupt_immediately non-zero before reading from the file
-         system or calling an application-defined completion function
-
-lib/readline/signals.c
-       - renamed rl_signal_handler to _rl_handle_signal; new version of
-         rl_signal_handler that just calls _rl_handle_signal (for now)
-       - new function _rl_signal_handler that calls _rl_handle_signal without
-         any checking
-
-lib/readline/rlprivate.h
-       - new extern declaration for _rl_signal_handler
-       - new define, RL_CHECK_SIGNALS, checks whether or not _rl_caught_signal
-         is set and calls _rl_signal_handler if so
-
-lib/readline/{bind,input,readline}.c
-       - add RL_CHECK_SIGNALS in appropriate places
-
-lib/readline/signals.c
-       - change rl_signal_handler to set a flag and return rather than
-         run through the entire signal handling process.  If
-         _rl_interrupt_immediately is set, call the signal handling code
-         right away instead of setting the flag.  Initial fix for crash
-         bug reported by Roman Rakus <rrakus@redhat.com>
-
-aclocal.m4
-       - new macro, BASH_TYPE_SIG_ATOMIC_T, tests for sig_atomic_t in
-         <signal.h>, defines as int if not defined
-
-configure.in
-       - call BASH_TYPE_SIG_ATOMIC_T
-       - call AC_C_VOLATILE
-
-config.h.in
-       - empty define for sig_atomic_t
-       - empty define for volatile
-
-                                  1/27
-                                  ----
-subst.c
-       - audit calls to add_character and change to add_ifs_character (which
-         quotes characters in $IFS).  Affects primarily `:', `=', and `~'.
-         Fixes bug reported by Jan Schampera <jan.schampera@web.de>; fix
-         suggested by Stephane Chazelas <stephane_chazelas@yahoo.fr>
-
-                                   2/1
-                                   ---
-configure.in
-       - call AC_C_RESTRICT
-
-config.h.in
-       - add empty defintion for `restrict'
-
-pcomplete.c
-       - use unwind_protects around call to execute_shell_function in
-         gen_shell_function_matches to prevent data corruption if
-         throw_to_top_level is called.  Bug report and fix from
-         werner@suse.de.
-
-execute_cmd.c
-       - don't clamp CPU usage at 100% in print_formatted_time.  Bug reported
-         by Linda Walsh <bash@tlinx.org>
-
-                                   2/5
-                                   ---
-locale.c
-       - in set_locale_var, set errno to 0 before calling setlocale(), and
-         print strerror (errno) if setlocale fails and errno ends up non-zero
-
-                                   2/6
-                                   ---
-configure.in
-       - backed out of solaris change from 10/23/2008 (adding `-z interpose'
-         to LDFLAGS) due to solaris updates to fix a linker problem.
-         Updatted by Serge Dussud <Serge.Dussud@Sun.COM>
-
-                                  2/12
-                                  ----
-execute_cmd.c
-       - change execute_connection so failure of a pipeline will cause the
-         shell to exit if -e is on.  From discussion on austin-group
-         mailing list
-       - change execute_command_internal so failure of a user-specified
-         subshell will cause the shell to exit if -e is on.  From discussion
-         on austin-group mailing list
-
-                                  2/13
-                                  ----
-doc/{bash.1,bashref.texi}
-       - clarified description of set -e option to accurately reflect current
-         implementation
-
-                                  2/19
-                                  ----
-print_cmd.c
-       - fix print_deferred_heredocs to not print a space if the separator
-         string is null
-       - change print_deferred_heredocs to set `was_heredoc' after printing
-         something
-       - change connection printing code to only print the `;' separator
-         if we haven't just printed a here-document
-       - change connection printing code to print any deferred here
-         documents after the rhs of the connection.  Fixes bug reported by
-         Bo Andresen <bo.andresen@zlin.dk>
-
-[bash-4.0 frozen]
-
-                                  2/20
-                                  ----
-
-[bash-4.0 released]
-
-                                  2/22
-                                  ----
-
-parse.y
-       - fix parse_comsub to not test a character for being a possible shell
-         metacharacter if LEX_PASSNEXT flag is set.  Fixes bug reported by
-         Mike Frysinger <vapier@gentoo.org>
-
-pcomplete.c
-       - add call to save_parser_state (accidentally dropped from patch) to
-         gen_shell_function_matches.  Fixes bug with bash_completion and
-         file/directory completion reported by phil@Arcturus.universe
-
-Makefile.in
-       - fix assignment to LDFLAGS_FOR_BUILD to match those in subdir
-         Makefiles.  Fixes bug reported by Mike Frysinger <vapier@gentoo.org>
-
-builtins/mapfile.def
-       - make sure the callback quantum (-c option argument) is > 0.  Fixes
-         bug reported by Stephane Chazleas <stephane_chazelas@yahoo.fr>
-
-                                  2/23
-                                  ----
-parse.y
-       - fix save_token_state and restore_token_state to save and restore
-         current_token.  Fixes bug reported by Bernd Eggink
-         <monoped@sudrala.de>
-
-builtins/exit.def
-       - check jobs[i] before checking whether or not it's running when
-         the checkjobs option is set and we're looking for running jobs
-         at exit.  Fixes bug reported by Mike Frysinger <vapier@gentoo.org>
-
-                                  2/24
-                                  ----
-siglist.c
-       - include bashintl.h for definition of _.  Fixes bug reported by
-         Greg Wooledge <wooledg@eeg.ccf.org>
-
-                                  2/25
-                                  ----
-subst.c
-       - new function, skip_matched_pair.  Similar to skip_to_delim and
-         the extract_XXX family
-       - move skipsubscript here from arrayfunc.c; re-implement in terms of
-         skip_matched_pair.  Fixes bugs reported by <anmaster@tele2.se>
-
-arrayfunc.c
-       - remove skipsubscript; moved to subst.c
-
-parse.y
-       - change reset_parser to set current_token to '\n'.  Rest of fix for
-         bug reported by Bernd Eggink <monoped@sudrala.de>; earlier fix on
-         2/23
-
-                                  2/26
-                                  ----
-builtins/declare.def
-       - when given something like array[x]=y (which sets making_array_special
-         to 1), don't convert an associative array to an indexed array (line
-         493).  Part of fix for bug reported by Pierre Gaston
-         <pierre.gaston@gmail.com>
-       - if offset == 0, indicating that we do not have a valid assignment,
-         make sure any `name' containing a `[' is a valid array reference
-         before trying to go on.  Not doing this leads to creating crazy
-         variables like `name[foo[bar]=bax'.  Rest of fix for bug reported
-         by Pierre Gaston <pierre.gaston@gmail.com>
-
-assoc.c
-       - change assoc_to_assign to single-quote the array keys if `quoted' is
-         non-zero.  Makes things easier to read with weird characters in the
-         key
-
-parse.y
-       - fix parse_comsub to not set LEX_HEREDELIM when it sees "<<<".  Fixes
-         bug reported by Mike Frysinger <vapier@gentoo.org>
-
-                                  2/27
-                                  ----
-parse.y
-       - fix report_syntax_error to set last_command_exit_value to
-         EX_BADUSAGE (2) instead of EX_USAGE (258), since there's nothing
-         that will translate that to something < 128 before reading the
-         next command.  Partial fix for bug reported by Mike Frysinger
-         <vapier@gentoo.org>
-
-sig.c
-       - fix sigint_sighandler to set last_command_exit_value to sig+128
-         before calling throw_to_top_level.  Rest of fix for bug reported
-         by Mike Frysinger <vapier@gentoo.org>
-
-jobs.c
-       - if fork() fails, set last_command_exit_value to 126 before calling
-         throw_to_top_level
-
-execute_cmd.c
-       - defer calling unlink_fifo_list in parent branch of
-         execute_disk_command if we're executing in a shell function
-       - change execute_function to call unlink_fifo_list before returning
-         if it's the top-level function
-
-                                   3/2
-                                   ---
-builtins/read.def
-       - if read times out, make sure we remove the top element from the
-         unwind-protect stack (the free of input_string) and run the rest,
-         to reset the tty and readline and alarm states.  Then we jump to
-         assigning the variables to any partial input.  Fixes bug reported
-         by Christopher F. A. Johnson <cfajohnson@gmail.com>
-
-                                   3/3
-                                   ---
-parse.y
-       - break comment checking code into a common COMMENT_BEGIN define so
-         we can use it in multiple places in parse_comsub
-       - in parse_comsub, don't alter the LEX_RESWDOK flag if we read a
-         `#' and we're checking comments, even though `#' isn't a `shell break'
-         character.  Fixes bug reported by Mike Frysinger  <vapier@gentoo.org>
-
-braces.c
-       - in expand_seqterm, decrease the total length of the rhs by the length
-         of any (optional) increment, so we don't end up with unwanted zero
-         padding because the rhs length is wrong.  Fixes bug reported by
-         Carl Albing <albing@comcast.net>
-
-                                   3/4
-                                   ---
-doc/{bash.1,bashref.texi}
-       - changes to clean up some of the language describing the effects of
-         terminal process groups on the ability to read from and write to
-         the terminal
-
-                                   3/5
-                                   ---
-support/shobj-conf
-       - add host_vendor to string tested in switch to handle things like
-         gentoo/freebsd
-       - beginning with version 7, FreeBSD no longer has /usr/bin/objformat
-         or a.out binaries and libraries.  It's always ELF.  Fix from
-         Timothy Redaelli <drizzt@gentoo.org>
-
-parse.y
-       - in parse_comsub, allow comments if we are ready to read a
-         reserved word (tflags & LEX_RESWDOK), haven't read anything from
-         one yet (lex_rwlen == 0) and the current character is a '#'
-
-                                   3/6
-                                   ---
-parse.y
-       - new lex flag for parse_comsub: LEX_INWORD.  Turn it off when
-         we see a shell break character; turn it on or keep it on when
-         not a break character.  Keep track of word length (reset to 0
-         when we turn on LEX_INWORD when it was off).
-       - don't use COMMENT_BEGIN in parse_comsub any more; test
-         whether or not LEX_INWORD is set and lex_wlen == 0 in addition
-         to tests for LEX_RESWDOK and lex_rwlen.  Comments are valid
-         when at the start of a word
-       - move LEX_PASSNEXT code to the top of parse_comsub, so the rest
-         of the function doesn't have to check for the flag at different
-         places
-
-                                   3/7
-                                   ---
-parse.y
-       - in parse_comsub, when looking for a reserved word (LEX_RESWDOK
-         non-zero), and in a case statement, we can see either an esac
-         or a pattern list.  We handle an esac separately.  We should
-         turn off LEX_RESWDOK if we see anything but a newline, since
-         we'll be reading a pattern list.  Other part of fix for bug
-         reported by Mike Frysinger <vapier@gentoo.org> (rest of fix
-         on 3/3)
-
-                                  3/10
-                                  ----
-{.,lib/readline}/doc/fdl.texi
-       - updated to FDL version 1.3
-
-                                  3/11
-                                  ----
-parse.y
-       - when using the |& construct with a simple command preceding it, add
-         the implicit redirection to the simple command's redirection list,
-         since the redirections associated with the command struct are never
-         executed.  Fixes bug reported by Matt Zyzik <Matt@ice.filescope.com>
-
-                                  3/14
-                                  ----
-execute_cmd.c
-       - in execute_case_command, if ;& is used with no following pattern
-         list, make sure we don't reference a NULL pointer.  Bug report and
-         fix from Clark Jian Wang <dearvoid@gmail.com>
-
-parse.y
-       - make parser_state global, so other files can use it
-       - command_word_acceptable now returns non-zero if PST_REDIRLIST bit
-         set in parser_state, so we accept assignment statements and
-         perform alias expansion.  Fix for bug reported by Vincent
-         Lefevre <vincent@vinc17.org> (2/24/2009)
-
-parser.h
-       - add PST_REDIRLIST flag, notes that parser is currently parsing a
-         redirection list preceding a simple command
-
-make_cmd.c
-       - make_simple_command now turns on PST_REDIRLIST in parser_state when
-         creating a new simple command
-       - make_simple_command turns off PST_REDIRLIST in parser_state if it
-         adds a non-redirection to the command it's building
-       - clean_simple_command turns off PST_REDIRLIST to make sure it's off
-
-subst.c
-       - new flag for param_expand: PF_IGNUNBOUND, means to not exit if the
-         variable is unbound even if `set -u' is enabled
-       - change param_expand to not call err_unboundvar if the `pflags'
-         argument has the PF_IGNUNBOUND bit set
-       - parameter_brace_expand_word now takes an extra `pflags' argument to
-         pass down to param_expand; changed callers
-       - changed call to parameter_brace_expand_word in parameter_brace_expand
-         to add PF_IGNUNBOUND flag so ${@:-foo} doesn't cause the shell to
-         exit (but ${@} does) when there are no positional parameters.  Fixes  
-         Debian bug 519165 from Dan Jacobson <jidanni@jidanni.org>
-
-parse.y
-       - add code to parse_comsub to allow here-documents within command
-         substitutions to be delimited by the closing right paren, with the
-         usual warning about here documents delimited by EOF on execution.
-         Fixes regression from bash-3.2 noted in Red Hat bugzilla 485664 by
-         Ralf Corsepius
-
-                                  3/15
-                                  ----
-subst.c
-       - string_list_dollar_at now checks for Q_PATQUOTE, which getpattern()
-         uses to denote Q_DOUBLE_QUOTES (?).  Fixes a=abcd echo "${a#$*}"
-         when IFS= and args are `a b' as noted by Stephane Chazleas
-         <stephane_chazelas@yahoo.fr>
-       - param_expand now checks for Q_PATQUOTE and treats it identically
-         to Q_DOUBLE_QUOTES when expanding $*
-       - expand_word_unsplit now sets W_NOSPLIT in the flags of the word it
-         passes to expand_word_internal if $IFS is NULL
-       - expand_word_leave_quoted now sets expand_no_split_dollar_star and
-         the W_NOSPLIT bit in the word flags before calling
-         expand_word_internal if $IFS is NULL, just like expand_word_unsplit.
-         It is now virtually identical to expand_word_unsplit.  Rest of fix for
-         problems reported by Stephane Chazleas <stephane_chazelas@yahoo.fr>
-
-                                  3/20
-                                  ----
-trap.c
-       - in _run_trap_internal, don't pass SEVAL_RESETLINE as flag to
-         parse_and_execute if running the ERR trap (further modification
-         of change from 1/12)
-
-execute_cmd.c
-       - in execute_simple_command, set line_number to line_number_for_err_trap
-         before calling run_error_trap.  Part of fix for bug reported by
-         Brian J. Murrell <brian@interlinx.bc.ca>
-       - change other places calling run_error_trap() to set and use
-         line_number_for_err_trap
-
-                                  3/21
-                                  ----
-builtins/fc.def
-       - Even though command substitution through parse_and_execute turns 
-         off remember_on_history, command substitution in a shell when
-         set -o history has been enabled (interactive or not) should use it
-         in the last_hist calculation as if it were on.  Same calculation
-         in fc_gethnum and fc_builtin.  Fixes bug reported by
-         Ian Kelling <smallnow@gmail.com> 
-
-sig.c
-       - change termsig_sighandler to terminate immediately if it gets called
-         twice with the same signal before termsig_handler gets called.  This
-         fixes the `looping on SIGSEGV' phenomenon reported by Linux users.
-
-parse.y
-       - in read_secondary_line, don't try to add NULL lines to the history
-         list.  Report and patch from Lubomir Rintel <lkundrak@v3.sk>
-
-                                  3/22
-                                  ----
-sig.c
-       - Augment change from 3/21 with explicit check for signals we *don't*
-         want this to happen for.  Patch from Lubomir Rintel <lkundrak@v3.sk>
-
-                                  3/28
-                                  ----
-array.c
-       - in array_reference, return NULL immediately if the desired index
-         is larger than the maximum
-       - add cache of last array referenced and last array element referenced;
-         use in array_reference to optimize case of sequential access;
-         invalidated where necessary in other functions
-       - array_rshift needs to set max_index to 0 if the array was empty
-         before shifting in the new element 0
-       - array_shift needs to use element_index(a->head->prev) to set the
-         max_index, not a simple decrement, to deal with sparse arrays
-
-                                   4/1
-                                   ---
-bashline.c
-       - in bash_dequote_filename, return right away after copying the
-         backslash if the last character in the string to be expanded
-         is a backslash.  The old code copied an extra NUL and overwrote
-         the bounds checking.  Fixes bug reported by Shawn Starr
-         https://bugzilla.redhat.com/show_bug.cgi?id=488649
-
-                                   4/3
-                                   ---
-subst.c
-       - in pat_subst.c, make sure to copy one character from the input
-         string in the case of a null pattern match, since we substitute
-         on the null match and then increment past the current character.
-         Not doing this means that each character of the original string
-         is replaced because of the null matches.  Fixes debian bug
-         reported bhy Louis-David Mitterrand <ldm@apartia.fr>
-         http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=522160
-
-lib/sh/winsize.c
-       - incorporate contents of readline/rlwinsize.h to get all the various
-         system dependencies right when trying to find TIOCGWINSZ.  Fixes
-         bug reported by Dan Price <dp@eng.sun.com>
-
-                                   4/6
-                                   ---
-doc/{bash.1,bashref.texi}
-       - fix description of conditional `>' and `<' to remove statement that
-         the comparison pays attention to the current locale -- it has
-         always used strcmp
-
-lib/glob/glob.c
-       - fixed a bug in glob_filename that caused glob_dir_to_array to be
-         called to prepend a (globbed) directory name onto the results from
-         glob_vector, which, if we were globbing `**', glob_vector has
-         already done.  Effect is to have the directory name(s) on there
-         twice.  Fixes "dir*/**" bug reported by Matt Zyzik
-         <Matt@ice.filescope.com>
-
-                                   4/8
-                                   ---
-doc/{bash.1,bashref.texi}
-       - fix short syntax summary of for command to reflect full bash
-         syntax (which is a superset of Posix syntax).  Fixes bug reported
-         by Reuben Thomas <rrt@sc3d.org>
-
-                                  4/10
-                                  ----
-{expr,subst}.c
-       - make sure last_command_exit_value is set to EXECUTION_FAILURE
-         before calling err_unboundvar, in case set -e is enabled and
-         the shell exits from there.  Fixes bug reported by Freddy
-         Vulto <fvulto@gmail.com> and Piotr Zielinski
-         <piotr.zielinski@gmail.com>
-
-                                  4/11
-                                  ----
-jobs.c
-       - in restore_pipeline, don't call discard_pipeline with a NULL
-         argument
-
-trap.c
-       - in run_debug_trap, make sure to save and restore the pipeline,
-         pipeline_pgrp, and state of the pipeline around running the debug
-         trap, then remove any job created by running the debug trap from
-         the jobs table when it completes.  Fixes for two bugs reported
-         by lex@upc.ua
-
-                                  4/12
-                                  ----
-lib/readline/signals.c
-       - new functions to block and release SIGWINCH like the SIGINT blocking
-         and releasing functions
-
-lib/readline/rlprivate.h
-       - new extern declarations for _rl_block_sigwinch and _rl_release_sigwinch
-
-lib/readline/display.c
-       - block SIGWINCH during redisplay like SIGINT.  Should fix bug reported
-         by Nicolai Lissner <nlissne@linux01.org>
-
-                                  4/13
-                                  ----
-lib/readline/readline.h
-       - new readline state variable: RL_STATE_REDISPLAYING
-
-lib/readline/display.c
-       - in rl_redisplay, don't block SIGWINCH during redisplay; just set
-         the REDISPLAYING state
-
-lib/readline/terminal.c
-       - in rl_resize_terminal, don't call rl_redisplay_after_sigwinch() if
-         we're already in the middle of redisplay (RL_STATE_REDISPLAYING).
-         Fix for bug reported by Nicolai Lissner <nlissne@linux01.org>
-
-                                  4/15
-                                  ----
-parse.y
-       - fix parse_comsub to add check for \n when seeing whether the current
-         character can change to a state where a reserved word is legal,
-         since it is not a shell meta character.  Fixes bug reported by
-         Bernd Eggink <monoped@sudrala.de>.
-
-                                  4/17
-                                  ----
-jobs.c
-       - new functions to save and restore the pgrp_pipe (since there's only
-         one): save_pgrp_pipe and restore_pgrp_pipe
-
-trap.c
-       - run_debug_trap now saves and restores the pgrp_pipe before and
-         after calling the debug trap
-       - run_debug_trap now makes sure the terminal is owned by the pipeline
-         pgrp after the debug trap runs.  Rest of fix for bug reported by
-         Oleksly Melnyk <o.melnyk@upc.ua> (lex@upc.ca)
-
-                                  4/19
-                                  ----
-include/posixselect.h
-       - new include file, encapsulates select(2) includes and defines for
-         bash and readline.  Inspired by patch from Mike Frysinger
-         <vapier@gentoo.org>
-
-lib/sh/input_avail.c
-        - include "posixselect.h"
-
-lib/readline/{input,parens}.c
-       - include "posixselect.h" instead of using inline includes
-       - use new USEC_TO_TIMEVAL define to make sure that values for timeouts
-         greater than one second are handled properly
-
-lib/sh/fpurge.c
-       - updated implementation, taken from gnulib
-
-                                  4/21
-                                  ----
-lib/glob/glob.c
-       - in finddirs, don't try to free a return value of glob_error_return
-         from glob_vector.  Bug and fix from werner@suse.de
-
-lib/readline/signals.c
-       - in rl_echo_signal_char, check that SIGQUIT and SIGTSTP are defined
-         before trying to use them.  Bug report and fix from Volker Grabsch
-         <vog@notjusthosting.com>
-
-                                  4/24
-                                  ----
-aclocal.m4
-       - add conditional inclusion of <stdint.h> to BASH_CHECK_TYPE
-
-bashtypes.h,lib/sh/strto[iu]max.c
-       - include <stdint.h> if present for any existing declaration of
-         intmax_t and uintmax_t.  Fixes Interix problem reported by
-         Markus Duft <mduft@gentoo.org>
-
-lib/sh/strindex.c,externs.h,builtins/common.h
-       - renamed strindex to strcasestr to agree with other implementations
-         (e.g., BSD, MacOS X, gnulib); changed callers
-
-lib/sh/{strindex.c,Makefile.in},Makefile.in
-       - renamed strindex.c to strcasestr.c
-
-configure.in
-       - add strcasestr to call to AC_REPLACE_FUNCS, take advantage of
-         existing libc implementations
-
-config.h.in
-       - add define for HAVE_STRCASESTR
-
-lib/sh/mbscmp.c
-       - fix mbscmp to return correct values when the strings do not contain
-         valid multibyte characters.  Ideas from gnulib
-
-xstrchr.c
-       - only compare current character against C if mblength == 1
-
-{shell,variables}.c
-       - changed some xstrchr calls back to strchr when the arguments cannot
-         contain multibyte characters
-
-lib/sh/{xstrchr.c,Makefile.in},Makefile.in
-       - renamed xstrchr to mbschr; renamed file to mbschr.c
-
-aclocal.m4
-       - change BASH_CHECK_MULTIBYTE to use AC_REPLACE_FUNCS(mbschr)
-
-externs.h
-       - extern declarations for mbscmp and mbschr, conditional on the usual
-         HAVE_MBSCMP and HAVE_MBSCHR defines
-
-general.h,{alias,arrayfunc,bashline,general,execute_cmd,subst}.c
-       - changed calls to xstrchr to mbschr
-
-doc/bash.1
-       - use `pathname expansion' consistently, not `filename expansion' or
-         `filename generation'
-
-doc/bashref.texi
-       - use the phrase `filename expansion' consistently (since this is
-         what the Gnu people prefer) instead of `pathname expansion' or
-         `filename generation'
-
-aclocal.m4,config.h.in
-       - check for mbscasecmp in BASH_CHECK_MULTIBYTE, define HAVE_MBSCASECMP
-         if found
-
-lib/sh/{mbscasecmp.c,Makefile.in}
-       - new file, case-insensitive multibyte string comparison
-
-externs.h
-       - extern declaration for mbscasecmp
-
-                                  4/25
-                                  ----
-lib/readline/display.c
-       - in _rl_move_cursor_relative, don't adjust dpos by woff if it's
-         already less than woff (don't want it less than 0)
-       - in _rl_move_cursor_relative, short-circuit right away if the cursor
-         is at columns 0 and `new' is 0 (doesn't matter if it's a multibyte
-         locale or not, or whether there are invisible chars in the prompt)
-       - in _rl_move_cursor_relative, go ahead and adjust dpos if
-         prompt_physical_chars >= _rl_screenwidth (previous check was just > )
-         Fixes bug reported by Andreas Schwab <schwab@linux-m68k.org>
-
-                                  4/28
-                                  ----
-lib/glob/glob.c
-       - in glob_vector, don't add an empty pathname ("") if we're adding the
-         currect directory to the dirlist and GX_NULLDIR is set -- we can just
-         ignore it, since the passed directory name (".") was created by
-         the caller.  Fixes bug reported by Matt Zyzik <matt.zyzik@nyu.edu>
-
-                                   5/5
-                                   ---
-subst.c
-       - make expansion of $@ and $* when set -u is in effect and there are
-         no positional parameters be a non-fatal error.  This is the
-         consensus of the austin group, though it is not historical practice.
-         Message from Geoff Clare <20090505091501.GA10097@squonk.masqnet> of
-         5 May 2009 and http://austingroupbugs.net/view.php?id=155
-
-
-                                  5/20
-                                  ----
-lib/glob/glob.c
-       - tentative fix to glob_filename to compensate for glob_vector putting
-         null pathname at front of result vector when dflags&GX_NULLDIR.
-         Current fix manually removes empty string element from front of
-         result vector; a better fix would be to use a flag so glob_vector
-         doesn't add it at all.  Augments patch from 4/28, which appears to
-         have broken some things.  Fixes bug reported by Matt Zyzik
-         <matt.zyzik@nyu.edu>
-
-                                  5/22
-                                  ----
-
-lib/glob/glob.c
-       - better fix for glob_filename; supersedes patch of 5/20.  Now the
-         code does not set GX_ADDCURDIR if directory_len == 0 and the
-         function has not been called recursively ((flags & GX_ALLDIRS) == 0).
-         Better fix for bug reported by Matt Zyzik <matt.zyzik@nyu.edu>
-
-Makefile.in
-       - fix build race condition that occurs in some makes caused by
-         libreadline.a and libhistory.a containing some of the same files
-         (e.g., xmalloc.o) and conflicting when trying to build both at
-         the same time.  Reported by Mike Frysinger <vapier@gentoo.org>
-
-                                  5/25
-                                  ----
-lib/readline/vi_mode.c
-       - fix _rl_vi_initialize_line so that the loop counter is not
-         unsigned (it doesn't matter, but it eliminates a compiler warning).
-         Bug reported by Dave Caroline <dave.thearchivist@gmail.com>
-
-                                  5/26
-                                  ----
-doc/{bash.1,bashref.texi}
-       - add text to the description of array variables making it clear
-         that an array variable is not considered set until a subscript
-         has been assigned a value
-
-                                  5/29
-                                  ----
-lib/readline/text.c
-       - fix rl_change_case to handle case where mbrtowc doesn't find a
-         valid multibyte character
-
-lib/readline/vi_mode.c
-       - fix _rl_vi_change_mbchar_case to handle case where mbrtowc doesn't
-         find a valid multibyte character
-
-lib/sh/casemod.c
-       - fix sh_modcase to handle case where mbrtowc doesn't find a valid
-         multibyte character
-
-lib/readline/mbutil.c
-       - fix _rl_find_next_mbchar_internal to not call mbrtowc at the end of
-         the string, since implementations return different values -- just
-         break the loop immediately
-
-lib/readline/display.c
-       - fix rl_redisplay to make same sort of cursor position adjustments
-         based on multibyte locale and _rl_last_c_pos when performing
-         horizontal scrolling rather than line wrapping.  Probably still
-         more to do.  Fixes bug reported by jim@jim.sh
-
-                                   6/5
-                                   ---
-doc/{bash.1,bashref.texi}
-       - added some more explanation of the inheritance of the ERR trap at
-         the suggestion of Thomas Pospisek <tpo@sourcepole.ch>
-
-findcmd.c
-       - use eaccess(2) if available in file_status to take other file
-         access mechanisms such as ACLs into account.  Patch supplied
-         by werner@suse.de
-
-                                  6/12
-                                  ----
-xmalloc.c
-       - also calculate lowest brk() value the first time xmalloc/xrealloc
-         (and their sh_ counterparts) are called
-       - error messages consolidated into a single function (allocerr/
-         sh_allocerr) to avoid string duplication
-
-                                  6/16
-                                  ----
-variables.c
-       - changes to allow variables.c to be compiled if ALIAS is not defined.
-         Bug and fix from John Gatewood Ham <uraphalinuxserver@gmail.com>
-
-lib/sh/getcwd.c
-       - fix so systems defining BROKEN_DIRENT_D_INO have the necessary
-         defines.  Fix from Jay Krell <jay.krell@cornell.edu>
-
-configure.in
-       - add -D_ALL_SOURCE to interix CFLAGS for struct timezone definition.
-         Bug and fix from John Gatewood Ham <uraphalinuxserver@gmail.com>
-
-                                  6/29
-                                  ----
-variables.c
-       - change initialize_shell_variables to add environment variables with
-         invalid names to the variables hash table, but marking them as
-         invisible and imported
-       - new function, export_environment_candidate.  Used when creating the
-         export environment for commands to include variables with invalid
-         names inherited from the initial environment.  Apparently this
-         behavior is widespread
-       - change make_var_export_array to use export_environment_candidate
-         rather than visible_and_exported to test variables for inclusion
-         in the export environment
-
-                                   7/1
-                                   ---
-builtins/read.def
-       - fix a memory leak where the number of fields is not the same as
-         the number of variables passed to `read'.  Bug report from
-         werner@suse.de
-
-builtins/command.def
-       - move section of code that sets PATH from -p option before the
-         verbose-handling section, so command -v and command -V honor
-         the PATH set by command -p.  Bug report and fix from
-         ohki@gssm.otsuka.tsukuba.ac.jp
-
-                                   7/9
-                                   ---
-subst.c
-       - change brace_expand_word_list to defer brace expansion on compound
-         array assignments that are arguments to builtins like `declare',
-         deferring the expansion until the assignment statement is processed.
-         Fixes inconsistency reported by agriffis@n01se.net
-
-                                  7/16
-                                  ----
-bashline.c
-       - fix bash_execute_unix_command to set rl_point correctly based on
-         READLINE_POINT.  The old method of using save_point will not
-         work because maybe_make_readline_line will change rl_point.  Bug
-         reported by Henning Bekel <h.bekel@googlemail.com>
-
-trap.c
-       - fix _run_trap_internal and run_pending_traps to save and restore
-         value of subst_assign_varlist so the dispose_words on it doesn't
-         leave dangling pointers after the trap handler runs.  Fixes bug
-         reported by Marc Herbert <marc.herbert@gmail.com>
-
-                                  7/22
-                                  ----
-subst.c
-       - fix off-by-one error in pos_params when computing positional
-         parameters beginning with index 0.  Bug and fix from Isaac Good
-         <isaacgood@gmail.com>
-
-                                  7/24
-                                  ----
-lib/readline/display.c
-       - add code to _rl_move_cursor_relative and _rl_col_width to short-
-         circuit a few special cases: prompt string and prompt string plus
-         line contents, both starting from 0.  Saves a bunch of calls to
-         multibyte character functions using already-computed information.
-         As a side effect, fixes bug reported by Lasse Karkkainen
-         <tronic+8qug@trn.iki.fi>
-
-subst.c
-       - fixed a problem in split_at_delims that could leave *cwp set to -1
-         if the line ends in IFS whitespace and SENTINEL is one of those
-         whitespace characters.  Fixes problem with setting COMP_CWORD for
-         programmable completion reported by Ville Skytta <ville.skytta@iki.fi>
-
-bashline.c
-       - change bash_execute_unix_command to clear the current line (if the
-         terminal supplies the "ce" attribute) instead of moving to a new
-         line.  Inspired by report from Henning Bekel <h.bekel@googlemail.com>
-
-builtins/printf.def
-       - changes to allow printf -v var to assign to array indices, the way
-         the read builtin can.  Suggested by Christopher F. A. Johnson
-         <cfajohnson@gmail.com>
-
-lib/readline/complete.c
-       - fix rl_old_menu_complete and rl_menu_complete to appropriately set
-         and unset RL_STATE_COMPLETING while generating the list of matches.
-         Fixes debian bug #538013 reported by Jerome Reybert
-         <jreybert@gmail.com>
-
-                                  7/25
-                                  ----
-execute_cmd.c
-       - change execute_builtin to temporarily turn off and restore the ERR
-         trap for the eval/source/command builtins in the same way as we
-         temporarily disable and restore the setting of the -e option.
-         Fixes bug reported by Henning Garus <henning.garus@googlemail.com>
-
-                                  7/27
-                                  ----
-shell.c
-       - add fflush(stdout) and fflush(stderr) to exit_shell before closing
-         any file descriptors at exit time (e.g., coproc pipes)
-
-                                  7/30
-                                  ----
-lib/readline/complete.c
-       - new function rl_backward_menu_complete, just passes negative count
-         argument to rl_menu_complete
-       - change rl_menu_complete to act appropriately if rl_last_command is
-         rl_backward_menu_complete, so we can cycle forward and backward
-         through the list of completions
-
-lib/readline/doc/{readline.3,rluser.texi},doc/bash.1
-       - document new "menu-complete-backward" bindable readline function.
-         Suggested by Jason Spiro <jasonspiro04@gmail.com>
-
-lib/readline/vi_keymap.c
-       - add binding of C-n to menu-complete and C-p to menu-complete-backward
-         in vi-insert keymap, as suggested by Jason Spiro
-         <jasonspiro04@gmail.com>
-
-pcomplete.c
-       - fixed a bug in programmable_completions: the options it returned from
-         the compspec it found were set before generating the completions,
-         which meant that any changes made by "compopt" were overridden and
-         only in effect for the duration of the executing shell function
-         rather than the entire completion.  Fixes bug reported by Ville
-         Skytta <ville.skytta@iki.fi>
-
-                                  7/31
-                                  ----
-lib/readline/keymaps.c
-       - fixed memory leak in rl_discard_keymap by freeing storage associated
-         with hierarchical keymaps
-       - new convenience function, rl_free_keymap, that calls rl_discard_keymap
-         and frees the keymap passed as an argument
-
-lib/readline/util.c
-       - new bindable keymap function, _rl_null_function, to be used internally
-
-lib/readline/rlprivate.h
-       - extern declaration for _rl_null_function
-
-lib/readline/bind.c
-       - fix rl_generic_bind in the case where we are trying to override a
-         keymap with a null function (e.g., when trying to unbind it).  We
-         can't use a NULL function pointer in ANYOTHERKEY since that's
-         indistinguishable from the keymap not having been overridden at all.
-         We use  _rl_null_function instead, which simply does nothing.  We
-         could add an rl_ding to it later.  Fixes problem with hitting ESC
-         repeatedly while in vi command mode reported by James Rowell
-         <jrjimmy801-misc1@yahoo.com>
-
-builtins/bind.def
-       - call rl_bind_keyseq instead of rl_set_key for -r option
-
-lib/readline/readline.c
-       - Set vi_movement_keymap[ESC] to _rl_null_function after binding the
-         arrow keys in bind_arrow_keys() to allow vi-mode users to hit ESC
-         multiple times in vi command mode while still allowing the arrow
-         keys to work
-
-                                   8/2
-                                   ---
-bashline.c
-       - fix clear_hostname_list by setting hostname_list_initialized to 0
-         after freeing all list members.  Fixes bug reported by Freddy
-         Vulto <fvulto@gmail.com>
-
-lib/readline/display.c
-       - in update_line, if we copy data from one line to another because we
-         are wrapping a multibyte character from, say, the first line to the
-         second, we need to update OMAX and the line indices to account for
-         the moved data.  Bug report and fix from Martin Hamrle
-         <martin.hamrle@gmail.com>
-
-                                   8/3
-                                   ---
-pcomplete.h
-       - defines for EMPTYCMD ("_EmptycmD_") and DEFAULTCMD ("_DefaultCmD_")
-
-builtins/complete.def
-       - change compopt_builtin to make -E work on the "empty" command
-         completion
-       - fix print_compitem and print_compopts to replace EMPTYCMD with -E
-       - added -D (default) option to complete/compgen/compopt.  No supporting
-         code yet
-
-doc/bash.1,lib/readline/doc/rluser.texi
-       - document new -D, -E options to compopt
-       - document new -D option to complete/compgen
-
-shell.h
-       - new define, EX_WEXPCOMSUB, value of 125
-       - new define, EX_RETRYFAIL, value of 124 (for programmable completion)
-
-subst.c
-       - use EX_WEXPCOMSUB instead of literal 125 as exit status when a shell
-         invoked to run wordexp(3) with the -n option supplied attempts a
-         command substitution
-
-pcomplete.c
-       - new define, PCOMP_RETRYFAIL, used to indicate a "failure, retry with
-         next completion" status to the programmable completion code
-
-                                   8/4
-                                   ---
-pcomplete.c
-       - changed gen_shell_function_matches to take an extra parameter
-         indicating whether the specified shell function was not found or
-         returned the special "fail/retry" status, and, if it was either,
-         to not bother returning any matches list
-       - changed gen_compspec_completions to take an extra parameter to pass
-         through the "found" status from gen_shell_function_completions
-       - new function gen_progcomp_completions to take care of searching for
-         and evaluating a compspec for a particular word, saving its status,
-         and returning to its caller (programmable_completions) whether or
-         not to retry completion.  This function also checks whether a
-         retry changed the compspec associated with a command and short-
-         circuits the retry if it has not
-       - changed programmable_completions to try default completion (if set)
-         if a specific completion was not found for a command
-       - changed programmable_completions to implement "fail/retry" semantics
-         for a shell function that returns 124 and changes the compspec
-         associated with the command.  All based on proposal and changes from
-         Behdad Esfahbod (Red Hat bugzilla 475229)
-
-doc/bash.1,lib/readline/doc/rluser.texi
-       - documented new dynamic programmable completion functionality
-
-                                   8/5
-                                   ---
-stringlib.c
-       - first argument to substring() is now `const char *'
-
-externs.h
-       - changed extern declaration for substring()
-
-subst.c
-       - skipsubscript now takes a third FLAGS argument, passes to
-         skip_matched_pair
-       - skip_matched_pair now interprets flags&1 to mean not to parse
-         matched pairs of quotes, backquotes, or shell word expansion
-         constructs
-
-{subst,general,expr}.c
-       - changed skipsubscript() callers
-
-assoc.c
-       - changed assoc_to_assign to double-quote the key if it contains any
-         shell metacharacters
-
-arrayfunc.c
-       - use skipsubscript in quote_assign rather than quote any glob
-         characters in the subscript of an array assignment
-       - in assign_compound_array_list, call skipsubscript with a flags
-         argument of 1 if assigning an associative array to avoid trying
-         to re-parse quoted strings
-
-redir.c
-       - set expanding_redir before expanding body of here documents and
-         here strings to avoid looking for variables in temporary env
-
-                                   8/7
-                                   ---
-lib/readline/readline.c
-       - in _rl_dispatch_callback, return value of -3 means that we have
-         added to a key sequence, but there are previous matches in the
-         sequence.  Don't call _rl_subseq_result if we get a -3 from a
-         previous context in the chain; just go back up the chain.  Report
-         and fix from <freehaha@gmail.com>
-
-bashline.c
-       - fixes to history_completion_generator and bash_dabbrev_expand to
-         make dabbrev-expand inhibit suppressing of appending space char
-         to matches.  Have to do it with the generator too because
-         rl_menu_complete turns off suppressing the appended space in
-         set_completion_defaults().  Suggestion from Dan Nicolaescu
-         <dann@ics.uci.edu>
-       - suppress completion match sorting in bash_dabbrev_expand by
-         setting rl_sort_completion_matches = 0.  Suggestion from Dan
-         Nicolaescu <dann@ics.uci.edu>
-       - don't qsort history match list in build_history_completion_array
-         if dabbrev_expand_active == 1
-       - start the loop in build_history_completion_array that gathers words
-         from history for possible completions from the end of the list
-         rather than the beginning.  It doesn't matter where you start if
-         the results are sorted, and dabbrev-expand is supposed to offer
-         the most recent completions first
-
-                                  8/12
-                                  ----
-execute_cmd.c
-       - change to execute_command_internal to make [[ ... ]] conditional
-         command subject to settings of `set -e' and the ERR trap
-
-                                  8/14
-                                  ----
-execute_cmd.c
-       - change to execute_command_internal to make (( ... )) arithmetic
-         command subject to settings of `set -e' and the ERR trap
-
-lib/readline/text.c
-       - new bindable function, rl_skip_csi_sequence, reads the characters
-         that make up a control sequence as defined by ECMA-48.  Sequences
-         are introduced by the Control Sequence Indicator (CSI) and
-         contain a defined set of characters.  Insert, End, Page Up and so
-         on are CSI sequences.  Report and code from Andy Koppe
-         <andy.koppe@gmail.com>
-
-lib/readline/readline.h
-       - extern declaration for rl_skip_csi_sequence
-
-lib/readline/funmap.c
-       - new bindable command "skip-csi-sequence", runs rl_skip_csi_sequence
-
-doc/bash.1,lib/readline/doc/{readline.3,rluser.texi}
-       - documented new bindable command "skip-csi-sequence", unbound by
-         default
-
-builtins/evalfile.c
-       - fix _evalfile to remove embedded null bytes from the file read
-         into the string.  Report and proposed fix from Roman Rakus
-         <rrakus@redhat.com>
-
-{configure,config.h}.in
-       - check for syslog(3), define HAVE_SYSLOG
-       - check for syslog.h, define HAVE_SYSLOG_H
-
-config-top.h
-       - new define SYSLOG_HISTORY, disabled by default
-
-config-bot.h
-       - if HAVE_SYSLOG or HAVE_SYSLOG_H are not defined, undef SYSLOG_HISTORY
-
-bashhist.c
-       - if SYSLOG_HISTORY is defined, call bash_syslog_history with the
-         line added to the history in bash_add_history.
-       - new function, bash_syslog_history(line), sends line to syslog at
-         user.info.  The line is truncated to send no more than 600
-         (SYSLOG_MAXLEN) bytes to syslog. Feature requested by many, and
-         required by some national laws
-
-sig.c
-       - in termsig_handler, resend SIGHUP to children if subshell_environment
-         indicates we're a shell performing command or process substitution
-
-jobs.c
-       - add CHECK_TERMSIG calls to wait_for in addition to the ones in
-         waitchld()
-
-builtins/shopt.def
-       - new functions set_bashopts, parse_bashopts, and initialize_bashopts
-         to manage new environment variable $BASHOPTS, like $SHELLOPTS but
-         for shopt options
-       - change toggle_shopts to call set_bashopts after setting options, so
-         $BASHOPTS reflects new values
-
-shell.c
-       - call initialize_bashopts after calling initialize_shell_options at
-         shell startup
-
-configure.in
-       - new configure `enable' option --enable-exended-glob-default, to
-         set the initial default value of the `extglob' shell option
-
-config.h
-       - new define, EXTGLOB_DEFAULT, controlled by the `extended-glob-default'
-         configure option
-
-pathexp.c
-        - initialize extended_glob variable to EXTGLOB_DEFAULT
-
-doc/{bash.1,bashref.texi}
-       - document new $BASHOPTS variable and its behavior
-
-doc/bashref.texi
-       - document new --enable-extended-glob-default configure option
-
-                                  8/16
-                                  ----
-print_cmd.c
-       - new variables: xtrace_fd and xtrace_fp, the file descriptor and
-         FILE * to which we send `set -x' tracing output.  If fd == -1
-         then fp == STDERR, the default mode
-       - new function xtrace_init, sets xtrace_fd == -1 and xtrace_fp = stderr
-       - new function xtrace_set (fd, fp), sets xtrace_fd and xtrace_fp
-         to the arguments
-       - new function xtrace_reset, handles closing old xtrace fd/fp and
-         moving them back to -1/stderr
-       - new function xtrace_fdchck, calls xtrace_reset if the fd passed as
-         an argument is xtrace_fd
-       - change xtrace functions to fprintf to xtrace_fp instead of stderr
-
-shell.c
-       - call xtrace_init() very early in main()
-
-variables.c
-       - new special variable, BASH_XTRACEFD, holds file descriptor used for
-         set -x trace output.  Inspired by suggestion from Bruce Korb
-         <bruce.korb@gmail.com>
-
-doc/{bash.1,bashref.texi}
-       - added description of new BASH_XTRACEFD variable
-
-redir.c
-       - add calls to xtrace_fdchk to the redirections that close file
-         descriptors, so we notice if we close BASH_XTRACEFD and compensate
-         accordingly (same places that call coproc_fdchk())
-
-                                  8/18
-                                  ----
-lib/readline/text.c
-       - change to _rl_replace_text to add error checks: start must be <=
-         end, and we don't call rl_insert_text if passed the empty string
-
-config.h.in
-       - add define for HAVE_ICONV, already found by intl autoconf macros
-       - add define for HAVE_LOCALE_CHARSET
-
-aclocal.m4
-       - add check for locale_charset() to BASH_CHECK_MULTIBYTE
-
-lib/sh/fnxform.c
-       - new file with two public function: fnx_tofs and fnx_fromfs.
-         Primarily intended for use on MacOS X, they use iconv to convert
-         between whatever the current locale encoding is and "UTF-8-MAC",
-         a special encoding on OS X in which all characters are
-         decomposed unicode, as the HFS+ filesystem stores them.  These
-         functions return a pointer to a local buffer, allocated once and
-         resized as necessary, to avoid too many allocations; callers
-         should not free the return value, since it may be the string
-         passed
-
-Makefile.in
-       - make sure LIBICONV is set by autoconf (@LIBICONV@) and added to
-         list of link libraries
-
-externs.h
-       - new extern declarations for fnx_fromfs and fnx_tofs
-
-lib/glob/glob.c
-       - convert the filename read using readdir() in glob_vector() using
-         fnx_fromfs and use that value in the call to strmatch.  This
-         ensures that we're using the precomposed Unicode value of the
-         filename rather than the native decomposed form.  Original bug
-         report from Len Lattanzi <llatanzi@apple.com>; fix inspired by
-         Guillaume Outters <guillaume.outters@free.fr>
-
-                                  8/19
-                                  ----
-lib/readline/complete.c
-       - new completion hook: rl_filename_rewrite_hook, can rewrite or modify
-         filenames read from the filesystem before they are compared to the
-         word to be completed
-
-lib/readline/readline.h
-       - extern declaration for rl_filename_rewrite_hook
-
-lib/readline/doc/rltech.texi
-       - document rl_filename_rewrite_hook
-
-bashline.c
-       - new function, bash_filename_rewrite_hook, assigned to
-         rl_filename_rewrite_hook.  Calls fnx_fromfs to convert from
-         filesystem format to "input" format.  This makes completing
-         filenames with accented characters work on Mac OS X
-
-                                  8/20
-                                  ----
-lib/readline/bind.c
-       - new bindable variable "skip-completed-text", bound to
-         _rl_skip_completed_text.  If enabled, it means to note when
-         completing before the end of a word and skipping over characters
-         after rl_point that match in both the completion to be inserted
-         and the word being completed.  It means that completing
-         `Makefile' with the cursor after the `e' results in `Makefile'
-         instead of `Makefilefile'.  Inspired by an idea from Jared
-         Yanovich <phierunner@comcast.net> from back in 2004
-
-lib/readline/rlprivate.h
-       - extern declaration for _rl_skip_completed_text
-
-lib/readline/complete.c
-       - implement semantics of _rl_skip_completed_text in insert_match:
-         skip characters in `replacement' that match chars in rl_line_buffer
-         from the start of the word to be completed
-
-                                  8/21
-                                  ----
-error.c
-       - change parser_error to set last_command_exit_value to 2 before
-         calling exit_shell (if set -e is enabled), so any exit or ERR
-         trap gets the right value of $?.  Suggestion from Stefano
-         Lattarini <stefano.lattarini@gmail.com>
-
-braces.c
-       - fix expand_seqterm so that a non-zero-prefixed term that's longer
-         than a zero-prefixed term determines the length of each term
-         in the brace-expanded sequence.  This means that things like
-         {01..100} will have three digits in all the elements of the
-         expanded list.  Fixes bug reported by Jeff Haemer
-         <jeffrey.haemer@gmail.com>
-
-                                  8/24
-                                  ----
-{arrayfunc,variables}.c
-       - when inserting a value into an associative array using syntax like
-         T=v where T is an already-declared associative array using key "0",
-         make sure the key is in newly-allocated memory so it can be freed
-         when the variable is unset.  Fixes bug reported as redhat 518644
-         by Jon Fairbairn
-
-                                  8/26
-                                  ----
-lib/readline/funmap.c
-       - add "old-menu-complete" binding for rl_old_menu_complete
-
-lib/readline/readline.h
-       - add extern declaration for rl_old_menu_complete
-
-subst.c
-       - fix memory leak when processing ${!prefix@}.  Need to dispose all
-         words in the word list created from all matching variable.  Fixes
-         bug reported by muszi@muszi.kite.hu.
-
-                                  8/29
-                                  ----
-execute_cmd.c
-       - add fflush(stdout) and fflush(stderr) to child coproc code before
-         calling exit after execute_in_subshell
-
-                                  8/31
-                                  ----
-lib/readline/{{bind,readline}.c,rlprivate.h}
-       - new bindable variable, "echo-control-characters", enabled by default.
-         This controls whether or not readline honors the tty ECHOCTL bit
-         and displays characters corresponding to keyboard-generated signals.
-         Controlled by _rl_echo_control_chars variable, declared in readline.c
-
-lib/readline/signals.c
-       - if _rl_echo_control_chars == 0, don't go through _rl_echo_signal_char
-
-
-lib/readline/doc/{readline.3,rluser.texi}
-       - document "echo-control-characters" bindable variable
-
-                                   9/1
-                                   ---
-lib/readline/histexpand.c
-       - hist_string_extract_single_quoted now takes an additional argument:
-         a flags word.  The only defined value (flags & 1) allows backslash
-         to quote the single quote.  This is to inhibit history expansion
-         inside $'...' containing an escaped single quote.
-       - change history_expand to call hist_string_extract_single_quoted
-         with flags == 1 if it sees $'.  Fixes bug reported by Sean
-         Donner <sean.donner@gmail.com>
-
-                                   9/2
-                                   ---
-builtins/printf.def
-       - add a call to sh_wrerror if ferror() succeeds in the PRETURN macro,
-         to print an error message in the case that the final fflush fails
-         (for instance, because it attempts to write data that didn't have a
-         trailing newline).  Fixes bug reported by Stefano Lattarini
-         <stefano.lattarini@gmail.com>
-
-                                   9/7
-                                   ---
-arrayfunc.c
-       - some fixes to assign_compound_array_list to avoid null pointer
-         dereferences pointed out by clang/scan-build
-
-lib/glob/glob.c
-       - fixes to udequote_pathname and wdequote_pathname to avoid possible
-         null pointer dereferences pointed out by clang/scan-build
-
-lib/readline/undo.c
-       - fix to _rl_copy_undo_list (function unused) to avoid deref of
-         uninitialized pointer pointed out by clang/scan-build
-
-general.c
-       - fix string_to_rlimtype so it works if passed a null pointer (though
-         it never is)
-
-builtins/mapfile.def
-       - fix to mapfile() to avoid possible null pointer dereference pointed   
-         out by clang/scan-build
-
-variables.c
-       - fix to valid_exportstr to avoid possible null pointer dereferences
-         pointed out by clang/scan-build
-
-bashline.c
-       - fix to bash_execute_unix_command to avoid possible null pointer
-         dereference if READLINE_LINE or READLINE_POINT is not bound
-
-                                  9/11
-                                  ----
-[Prayers for the victimes of 9/11/2001]
-
-command.h
-       - add `rflags' member to struct redirect to hold private flags and
-         state information
-       - change redirector to a REDIRECTEE instead of int to prepare for
-         possible future changes
-
-{copy_cmd,dispose_cmd,make_cmd,print_cmd,redir}.c
-       - changes resulting from type change of `redirector' member of struct
-         redirect: change x->redirector to x->redirector.dest and add code
-         where appropriate to deal with x->redirector.filename
-
-make_cmd.h
-       - change extern declaration for make_redirection
-
-make_cmd.c
-       - first argument of make_redirection is now a `REDIRECTEE' to prepare
-         for possible future changes.  First arg is now assigned directly to
-         redirector member instead of assigning int to redirector.dest
-
-{make_cmd,redir}.c,parse.y
-       - changes resulting from type change of first argument to
-         make_redirection from int to REDIRECTEE.  In general, changes are
-         using REDIRECTEE sd and assigning old argument to sd.dest, then
-         passing sd to make_redirection
-
-make_cmd.[ch],parse.y
-       - add fourth argument to make_redirection: flags.  Sets initial value
-         of `rflags' member of struct redirect
-       - changed all callers of make_redirection to add fourth argument of 0
-
-                                  9/15
-                                  ----
-parse.y
-       - change read_token_word to return REDIR_WORD for tokens of the form
-         {var} where `var' is a valid shell identifier and the character
-         following the } is a `<' or `>'
-       - add REDIR_WORD versions of all input and output file redirections
-         and here documents
-
-print_cmd.c
-       - change input and output file redirection direction and here
-         document cases of print_redirection to print a varname
-         specification of the form {var} when appropriate.  Still need
-         to fix rest of cases
-
-redir.c
-       - implement REDIR_VARASSIGN semantics for file input and output
-         redirections and here documents
-
-                                  9/16
-                                  ----
-parse.y
-       - added REDIR_WORD versions of remaining redirection constructs except
-         for err_and_out ones
-
-redir.c
-       - handle REDIR_VARASSIGN semantics for rest of redirection constructs 
-       - accommodate REDIR_VARASSIGN when translating redirections
-       - new function, redir_varvalue, does variable lookup for {v} when
-         redirection needs the value (e.g., r_close_this)
-
-print_cmd.c
-       - fix rest of cases to print {varname} when REDIR_VARASSIGN is set in
-         redirect->rflags
-
-doc/{bash.1,bashref.texi}
-       - document new {varname} REDIR_VARASSIGN form of redirections
-
-tests/vredir.{right,tests},vredir[1-5].sub
-       - tests for new {varname} REDIR_VARASSIGN form of redirections
-
-                                  9/18
-                                  ----
-subst.c
-       - new flags argument to split_at_delims: these flags are ORd with
-         SD_NOJMP and passed to skip_to_delim
-       - change skip_to_delim to honor new SD_NOQUOTEDELIM flag by not
-         checking whether or not single and double quotes are delimiters
-         if it's set in passed flags until after skipping quoted strings.
-
-subst.h
-       - change extern declaration for split_at_delims
-       - new define for SD_NOQUOTEDELIM flag
-
-pcomplete.c
-       - pass SD_NOQUOTEDELIM in flags argument to split_at_delims so single
-         and double quotes, even though they're in
-         rl_completer_word_break_characters, don't act as word delimiters
-         for programmable completion.  Fixes bug reported by Freddy
-         Vulto <fvulto@gmail.com>
-
-lib/glob/glob.c
-       - in glob_filename, after recursively scanning a directory specified
-         with `**', turn off GX_ALLDIRS|GX_ADDCURDIR before calling
-         glob_vector on the rest of the pathname, since it may not apply to
-         the rest of the pattern.  Turned back on if the filename makes it
-         appropriate.  Fixes bug reported by Anders Kaseorg <andersk@mit.edu>
-
-redir.c
-       - change execute_null_command to fork a child to execute if any of
-         the commands redirections have the REDIR_VARASSIGN flag set, since
-         those commands are not supposed to have side effects
-
-test.c
-       - < and > binary operators will obey the locale by using strcoll if
-         the TEST_LOCALE flag is passed to binary_test
-
-test.h
-       - new define for TEST_LOCALE
-
-execute_cmd.c
-       - execute_cond_node sets TEST_LOCALE so [[ str1 < str2 ]] (and >)
-         obey the locale.  Fixes bug/incompatibility reported by Greg
-         Wooledge <wooledg@eeg.ccf.org>
-
-doc/{bash.1,bashref.texi}
-       - documented [[ command new locale-sensitive treatment of < and >
-
-                                  9/24
-                                  ----
-configure.in
-       - add "darwin10" cases like darwin8 and darwin9 to handle linking with
-         included readline and history libraries
-
-                                  9/26
-                                  ----
-lib/readline/display.c
-       - modify change of 7/24 to use prompt_physical_chars instead of
-         prompt_visible_length to account for visible multibyte characters in
-         the line (usually in the prompt).  Fixes debian bug #547264
-         reported by Pietro Battiston <toobaz@email.it>
-       - add flags argument to _rl_col_width; changed callers.  flags > 0
-         means that it's ok to use the already-computed prompt information;
-         flags == 0 means that we're expanding the prompt and we should not
-         short-circuit
-
-parse.y
-       - in decode_prompt_string, when expanding \w and \W on Mac OS X,
-         use fnx_fromfs to convert from "filesystem" form to "input" form.
-         This makes $PWD with multibyte characters work in the prompt
-         string on Mac OS X
-
-lib/sh/fnxform.c
-       - in fnx_fromfs and fnx_tofs, use templen instead of outlen as last
-         argument in calls to iconv, since outlen is used to keep track of
-         the size of the buffer, and iconv potentially modifies its
-         `outbytesleft' argument
-
-                                  9/29
-                                  ----
-subst.c
-       - make skip_to_delim understand how to skip over process substitution
-         constructs the way it skips $(...) command substitution
-
-                                  9/30
-                                  ----
-lib/readline/terminal.c
-       - don't set the `terminal has meta key' flag if the `MT' capability is
-         available; that means something completely different
-
-                                  10/1
-                                  ----
-builtins/help.def
-       - make sure width is at least 7, since we pass `width/2 - 3' to strncpy
-         as the length argument.  Terminal widths <= 6 are converted to 80.
-         Fixes bug reported by Chris Hall <c@pobox.co.uk>
-
-configure.in
-       - changed version to 4.1-alpha
-
-subst.h
-       - new flag for skip_to_delim: SD_NOSKIPCMD, which means to not skip
-         over embedded command and process substitutions, but rather to look
-         for delimiters within them
-
-subst.c
-       - implement semantics of SD_NOSKIPCMD in skip_to_delim
-
-bashline.c
-       - call skip_to_delim with SD_NOSKIPCMD from find_cmd_start, so
-         programmable completion can use the completion defined for `b' for
-         command lines like "a $(b c".  Fixes inconsistency/bug reported by
-         Freddy Vulto <fvulto@gmail.com>
-
-parser.h
-       - replace unused PST_CMDTOKEN parser state value with PST_EXTPAT,
-         means currently parsing an extended glob pattern (extglob)
-
-parse.y
-       - fix cond_node() so that extended_glob is set before parsing the
-         rhs of the `==' or `!=' operators.  For ksh93 compatibility.
-       - reset extended_glob to global value (saved in parse_cond_command())
-         in reset_parser()
-
-                                  10/5
-                                  ----
-jobs.c
-       - change waitchld() to only interrupt the wait builtin when the shell
-         receives SIGCHLD in Posix mode.  It's a posix requirement, but
-         makes easy things hard to do, like run a SIGCHLD trap for every
-         exiting child.  Change prompted by question from Alex Efros
-         <powerman@powerman.name>
-
-doc/bashref.texi
-       - document new posix mode behavior about SIGCHLD arriving while the
-         wait builtin is executing when a trap on SIGCHLD has been set
-
-                                  10/6
-                                  ----
-lib/readline/histexpand.c
-       - fix hist_expand to keep from stopping history expansion after the
-         first multibyte character (a `break' instead of a `continue').
-         Fixes debian bug (#549933) reported by Nikolaus Schulz
-         <microschulz@web.de>
-
-                                  10/8
-                                  ----
-builtins/read.def
-       - implement new `-N nchars' option: read exactly NCHARS characters,
-         ignoring any delimiter, and don't split the result on $IFS.
-         Feature requested by Richard Stallman <rms@gnu.org>
-
-doc/{bash.1,bashref.texi}
-       - document new `read -N' option
-
-                                  10/9
-                                  ----
-lib/readline/bind.c
-       - new bindable variable, "enable-meta-key", controls whether or not
-         readline enables any meta modifier key the terminal claims to
-         support.  Suggested by Werner Fink <werner@suse.de>
-
-lib/readline/doc/{readline.3,rluser.texi},doc/bash.1
-       - document new readline "enable-meta-key" bindable variable
-
-                                  10/10
-                                  -----
-trap.c
-       - new function, free_trap_string(), does what it says and turns off
-         SIG_TRAPPED flag without changing signal disposition
-
-[bash-4.1-alpha frozen]
-
-                                  10/16
-                                  -----
-builtins/mapfile.def
-       - return an error if the variable passed is not an indexed array.
-         Fixes bug reported by Nick Hobson <nick.hobson@yahoo.com>
-       - change help text to make it clear that an indexed array is required
-
-doc/{bash.1,bashref.texi}
-       - changed description of mapfile to note that the array variable
-         argument must be an indexed array, and mapfile will return an
-         error if it is not
-
-subst.c
-       - change expand_string_unsplit and expand_string_leave_quoted to
-         add the (previously unused) W_NOSPLIT2 flag to the created word
-       - change expand_word_internal to understand W_NOSPLIT2 to mean that
-         we're not going to split on $IFS, so we should not quote any
-         characters in IFS that we add to the result string.  Fixes bug
-         reported by Enrique Perez-Terron <enrio@online.no>
-       - change cond_expand_word similarly.  Fixes rest of bug reported by
-         Enrique Perez-Terron <enrio@online.no>
-
-parse.y
-       - save and restore value of last_command_subst_pid around call to
-         expand_prompt_string in decode_prompt_string.  Fixes bug that causes
-         $? to be set wrong when using a construct like false || A=3 when
-         set -x is enabled and $PS4 contains a command substitution.  Reported
-         by Jeff Haemer <jeffrey.haemer@gmail.com>
-
-                                  10/17
-                                  -----
-execute_cmd.c
-       - in execute_in_subshell, make sure we set setjmp(return_catch) before
-         running the command, in case the command or its word expansion
-         calls jump_to_top_level.  Fixes bug reported by Nils Bernhard
-         <nils.bernhard@yahoo.de>
-
-subst.c
-       - new PF_NOSPLIT2 flag for param_expand
-       - parameter_brace_expand takes a new `pflags' argument, before the
-         `output' parameters; passes to param_expand as necessary
-       - change parameter_brace_expand to call parameter_brace_expand_word
-         with the PF_NOSPLIT2 flag if the pflags argument to
-         parameter_brace_expand has it set
-
-parse.y
-       - change report_syntax_error to set last_command_exit_value to
-         EX_BADSYNTAX if parse_and_execute_level is > 0, indicating a
-         syntax error while we're executing a dot script, eval string,
-         trap command, etc.
-
-builtins/evalstring.c
-       - in parse_and_execute, if parse_command() returns non-zero,
-         indicating a parse error, print a warning message if the conditions
-         would require  a posix-mode shell to abort (parse error in a `.'
-         script or eval string)
-
-                                  10/19
-                                  -----
-builtins/evalfile.c
-       - even if the `check binary' flag is not passed to _evalfile, return an
-         error after reading 128 null characters if called by `source', on
-         the assumption that it's probably a binary file.  [This will be in
-         bash-4.1-beta]
-
-                                  10/24
-                                  -----
-[bash-4.1-alpha released]
-
-bashline.c
-       - don't call command_substitution_completion_function if we're
-         completing a substring delimited by a single quote.  Fixes bug
-         reported by bash-bugs@atu.cjb.net
-
-lib/readline/complete.c
-       - make sure _rl_skip_completed_text defaults to 0, as the
-         documentation states (incorrect in bash-4.1-alpha)
-       - in insert_match, skip over a close quote in the replacement text if
-         the character at point when completion is invoked is a single
-         quote.  Fixes complaint from bash-bugs@atu.cjb.net
-
-                                  10/26
-                                  -----
-shell.c
-       - in main, make sure "$EMACS" is non-null before calling strstr on its
-         value.  Fixes Red Hat bug 530911 submitted by Mitchell Berger
-
-builtins/mapfile.def
-       - don't save callback commands in shell history.  Suggested by
-         Jan Schampera <jan.schampera@web.de>
-
-mailcheck.c
-       - in file_mod_date_changed, make sure the modification time is later
-         than the saved modification date, not just that it's not equal.
-         Fix from Evgeniy Dushistov <dushistov@mail.ru>
-       - in file_access_date_changed, make sure the access time is later
-         than the saved access time, not just that it's not equal
-
-                                  10/27
-                                  -----
-builtins/shopt.def
-       - added new `compat40' compatibility variable, with associated changes
-         to shell_compatibility_level(), since the default compatibility level
-         is now 41
-
-test.c
-       - make the < and > operators to [[ use strcoll() only if the shell
-         compatibility level is greater than 40 (it is 41 by default in
-         bash-4.1)
-
-                                  10/28
-                                  -----
-support/shobj-conf
-       - decrease the default version of FreeBSD that creates shared libraries
-         to 4.x.  Advice from Peter Jeremy <peterjeremy@acm.org>
-
-                                  11/2
-                                  ----
-parse.y
-       - change parse_comsub to free `heredelim' and set it to 0 whenever the
-         comsub scanner finds the end of a here document.  Really need to
-         implement a stack of here doc delimiters like in the parser (can we
-         use redir_stack here, too?)
-       - fix parse_comsub to not attempt to read another here doc delimiter
-         after seeing a shell break character (that is not newline) if we
-         already have one.  Fixes Debian bash bug #553485, submitted by
-         Samuel Hym <samuel.hym@gmail.com>
-
-                                  11/3
-                                  ----
-variables.c
-       - fix bind_variable_internal to call a variable's dynamic 'set function'
-         with the right arguments depending on whether its an associative
-         array, an indexed array, or a scalar.  Fixes Ubuntu bug #471504
-         https://bugs.launchpad.net/ubuntu/+source/bash/+bug/471504 reported
-         by AJ Slater <aj.slater@gmail.com>
-
-[bash-4.1-beta frozen]
-
-                                  11/11
-                                  -----
-builtins/printf.def
-       - in getintmax(), in the case of a conversion error, return the partial
-         value accumulated so far, which is suppose to be what
-         strtoimax/strtoll/strtol returns
-
-                                  11/17
-                                  -----
-[bash-4.1-beta released]
-
-                                  11/18
-                                  -----
-builtins/{common.h,shopt.def},shell.c
-       - changed shopt variable "set functions" to take the option name as
-         the first argument; changed function prototypes and callers
-
-builtins/shopt.def
-       - change set_compatibility_level() to turn off other compatNN options
-         when one is set -- enforce mutual exclusivity.  Fixes problem noted
-         by Jan Schampera <jan.schampera@web.de>
-
-                                  11/19
-                                  -----
-lib/readline/rltty.c
-       - make sure prepare_terminal_settings() tests for the presence of
-         ECHOCTL before using it.  Fixes bug reported by Joachim Schmitz
-         <schmitz@hp.com>
-
-config-top.h
-       - new WORDEXP_OPTION define (off by default)
-
-shell.c
-       - don't include the --wordexp option or the supporting function
-         (run_wordexp) if WORDEXP_OPTION is not defined.  Suggested by
-         Aharon Robbins.
-
-execute_cmd.c
-       - in execute_cond_node, turn on comsub_ignore_return if the flags
-         indicate we're ignoring the return value before calling
-         cond_expand_word.  Fixes bug reported by Anirban Sinha
-         <asinha@zeugmasystems.com>
-
-                                  11/20
-                                  -----
-lib/sh/snprintf.c,builtins/printf.def
-       - change check for HAVE_ASPRINTF and HAVE_SNPRINTF to check if value
-         is 1 or 0 rather than whether they are defined or not.  This allows
-         a value of 0 to enable function replacement
-
-configure.in,aclocal.m4
-       - new autoconf macro, BASH_FUNC_SNPRINTF, checks for snprintf present
-         and working as C99 specifies with a zero length argument.  Idea
-         from Greg Wooledge <wooledg@eeg.ccf.org>
-       - new macro BASH_FUNC_VSNPRINTF, does same thing for vsnprintf
-
-                                  11/25
-                                  -----
-subst.c
-       - in command_substitute, only tell parse_and_execute to reset the line
-         number in an interactive shell if sourcelevel == 0 -- we'll use the
-         line numbers from the sourced file
-
-execute_cmd.c
-       - in execute_simple_command, only subtract function_line_number from
-         line_number if sourcelevel == 0.  If sourcing, we'll use the line
-         numbers from the sourced file.  Fixes bug reported by Hugo
-         Mildenberger <Hugo.Mildenberger@namir.de>
-
-builtins/declare.def
-       - in declare_internal, call bind_assoc_variable instead of
-         bind_array_variable in the case of declare -A foo=bar.  Fixes bug
-         reported by Bernd Eggink <monoped@sudrala.de>.
-
-                                  11/27
-                                  -----
-lib/readline/util.c
-       - change declaration for _rl_walphabetic to use prototype, assuming
-         that any system with multibyte characters has a compiler that can
-         handle prototypes.  Fix for AIX compilation problem reported by
-         Nick Hillman <nick_hillman@neverbox.com>
-
-                                  11/28
-                                  -----
-execute_cmd.c
-       - make funcnest file-scope static and unwind-protect its value in
-         execute_function, so it can be used as a real measure of function
-         call nesting
-
-general.c
-       - fix off-by-one error in trim_pathname that caused it to short-circuit 
-         when PROMPT_DIRTRIM == number of directories - 1.  Fixes bug
-         reported by Dennis Williamson <dennistwilliamson@gmail.com>
-
-                                  11/29
-                                  -----
-jobs.c
-       - when fork() returns -1/EAGAIN, call waitchld(-1, 0) so the shell can
-         reap any dead jobs before trying fork again.  Currently disabled
-         until bash-4.2 development starts
-
-lib/readline/complete.c
-       - when incrementing _rl_interrupt_immediately, make sure it's greater
-         than 0 before decrementing it.  In practice, not a problem, but
-         the right way to do it.  Suggested by Jan Kratochvil
-         <jan.kratochvil@redhat.com>
-
-lib/readline/signals.c
-       - make sure rl_signal_handler doesn't set rl_caught_signal if
-         _rl_interrupt_immediately is set, so RL_CHECK_SIGNALS doesn't
-         cause it to be processed twice.  Suggested by Jan Kratochvil
-         <jan.kratochvil@redhat.com>
-       - if the callback interface is being used, use the code path that
-         immediately handles signals.  This restores the readline-5.2
-         behavior.  Fixes GDB readline bug reported by Jan Kratochvil
-         <jan.kratochvil@redhat.com>
-
-                                  12/22
-                                  -----
-config-top.h
-       - don't have SYSLOG_HISTORY enabled by default
-
-lib/sh/Makefile.in
-       - add explicit dependency on pathnames.h for parallel make support
-
-externs.h
-       - add extern declaration for xtrace_fdchk
-
-lib/sh/snprintf.c
-       - add local prototype declarations for isinf, isnan if we are providing
-         local definitions
-
-lib/sh/fnxform.c
-       - add extern declaration for get_locale_var if HAVE_LOCALE_CHARSET not
-         defined
-
-execute_cmd.c
-       - define NEED_FPURGE_DECL so we pick up any extern declaration for
-         fpurge (e.g., if the system doesn't provide it)
-
-builtins/shopt.def
-       - correct prototype and declaration for set_shellopts_after_change so
-         it's the correct type for shopt_set_func_t
-       - add new function shopt_enable_hostname_completion that is the correct
-         type for shopt_set_func_t; just calls enable_hostname_completion and
-         returns its result
diff --git a/CWRU/POSIX.NOTES.old b/CWRU/POSIX.NOTES.old
deleted file mode 100644 (file)
index 1707ab1..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-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
deleted file mode 100644 (file)
index 87b78d7..0000000
+++ /dev/null
@@ -1,544 +0,0 @@
-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
deleted file mode 100644 (file)
index 998fd72..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/* 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/MANIFEST~ b/MANIFEST~
deleted file mode 100644 (file)
index 284dd0e..0000000
--- a/MANIFEST~
+++ /dev/null
@@ -1,1128 +0,0 @@
-#
-# Master distribution manifest for bash
-#
-#
-# Filename     type
-#
-CWRU           d
-CWRU/misc      d
-builtins       d
-cross-build    d
-doc    d
-examples       d
-examples/obashdb       d
-examples/complete      d
-examples/functions d
-examples/scripts d
-examples/scripts.v2    d
-examples/scripts.noah  d
-examples/startup-files d
-examples/startup-files/apple   d
-examples/misc  d
-examples/loadables d
-examples/loadables/perl        d
-include                d
-lib            d
-lib/glob       d
-lib/glob/doc   d
-lib/intl       d
-lib/malloc     d
-lib/readline   d
-lib/readline/doc d
-lib/readline/examples d
-lib/sh         d
-lib/termcap    d
-lib/tilde      d
-po             d
-support                d
-tests          d
-tests/misc     d
-ABOUT-NLS      f
-CHANGES                f
-COMPAT         f
-COPYING                f
-INSTALL                f
-MANIFEST       f
-NEWS           f
-NOTES          f
-POSIX          f
-README         f
-RBASH          f
-AUTHORS                f
-Y2K            f
-configure.in   f
-configure      f       755
-Makefile.in    f
-config-top.h   f
-config-bot.h   f
-config.h.in    f
-aclocal.m4     f
-array.c                f
-arrayfunc.c    f
-assoc.c                f
-eval.c         f
-print_cmd.c    f
-general.c      f
-list.c         f
-locale.c       f
-stringlib.c    f
-variables.c    f
-make_cmd.c     f
-copy_cmd.c     f
-unwind_prot.c  f
-dispose_cmd.c  f
-bashhist.c     f
-hashcmd.c      f
-hashlib.c      f
-parse.y                f
-pathexp.c      f
-subst.c                f
-shell.c                f
-trap.c         f
-sig.c          f
-siglist.c      f
-version.c      f
-flags.c                f
-jobs.c         f
-input.c                f
-mailcheck.c    f
-test.c         f
-expr.c         f
-alias.c                f
-execute_cmd.c  f
-findcmd.c      f
-redir.c                f
-bashline.c     f
-braces.c       f
-bracecomp.c    f
-nojobs.c       f
-error.c                f
-xmalloc.c      f
-pcomplete.c    f
-pcomplib.c     f
-mksyntax.c     f
-alias.h                f
-builtins.h     f
-bashhist.h     f
-bashline.h     f
-conftypes.h    f
-patchlevel.h   f
-variables.h    f
-array.h                f
-arrayfunc.h    f
-assoc.h                f
-jobs.h         f
-findcmd.h      f
-hashlib.h      f
-quit.h         f
-flags.h                f
-shell.h                f
-syntax.h       f
-pathexp.h      f
-parser.h       f
-pcomplete.h    f
-sig.h          f
-test.h         f
-trap.h         f
-general.h      f
-unwind_prot.h  f
-input.h                f
-error.h                f
-command.h      f
-externs.h      f
-siglist.h      f
-subst.h                f
-dispose_cmd.h  f
-hashcmd.h      f
-bashansi.h     f
-bashjmp.h      f
-bashintl.h     f
-make_cmd.h     f
-execute_cmd.h  f
-redir.h                f
-bashtypes.h    f
-mailcheck.h    f
-xmalloc.h      f
-y.tab.c                f
-y.tab.h                f
-parser-built   f
-pathnames.h.in f
-builtins/Makefile.in   f
-builtins/alias.def     f
-builtins/bind.def      f
-builtins/break.def     f
-builtins/builtin.def   f
-builtins/caller.def    f
-builtins/cd.def                f
-builtins/colon.def     f
-builtins/command.def   f
-builtins/complete.def  f
-builtins/common.c      f
-builtins/declare.def   f
-builtins/echo.def      f
-builtins/enable.def    f
-builtins/eval.def      f
-builtins/evalfile.c    f
-builtins/evalstring.c  f
-builtins/exec.def      f
-builtins/exit.def      f
-builtins/fc.def                f
-builtins/fg_bg.def     f
-builtins/getopt.c      f
-builtins/getopt.h      f
-builtins/getopts.def   f
-builtins/hash.def      f
-builtins/help.def      f
-builtins/let.def       f
-builtins/history.def   f
-builtins/jobs.def      f
-builtins/kill.def      f
-builtins/mapfile.def   f
-builtins/mkbuiltins.c  f
-builtins/printf.def    f
-builtins/pushd.def     f
-builtins/read.def      f
-builtins/reserved.def  f
-builtins/return.def    f
-builtins/set.def       f
-builtins/setattr.def   f
-builtins/shift.def     f
-builtins/shopt.def     f
-builtins/source.def    f
-builtins/suspend.def   f
-builtins/test.def      f
-builtins/times.def     f
-builtins/trap.def      f
-builtins/type.def      f
-builtins/ulimit.def    f
-builtins/umask.def     f
-builtins/wait.def      f
-builtins/psize.c       f
-builtins/psize.sh      f
-builtins/inlib.def     f
-builtins/bashgetopt.c  f
-builtins/common.h      f
-builtins/bashgetopt.h  f
-cross-build/cygwin32.cache     f
-cross-build/x86-beos.cache     f
-cross-build/opennt.cache       f
-include/ansi_stdlib.h  f
-include/chartypes.h    f
-include/filecntl.h     f
-include/gettext.h      f
-include/maxpath.h      f
-include/memalloc.h     f
-include/ocache.h       f
-include/posixdir.h     f
-include/posixjmp.h     f
-include/posixselect.h  f
-include/posixstat.h    f
-include/posixtime.h    f
-include/posixwait.h    f
-include/shmbutil.h     f
-include/shtty.h                f
-include/stdc.h         f
-include/systimes.h     f
-include/typemax.h      f
-include/unionwait.h    f
-lib/glob/Makefile.in   f
-lib/glob/sm_loop.c     f
-lib/glob/smatch.c      f
-lib/glob/strmatch.c    f
-lib/glob/strmatch.h    f
-lib/glob/glob.c                f
-lib/glob/glob.h                f
-lib/glob/glob_loop.c   f
-lib/glob/xmbsrtowcs.c  f
-lib/glob/collsyms.h    f
-lib/glob/doc/Makefile  f
-lib/glob/doc/glob.texi f
-lib/glob/ndir.h                f
-lib/intl/ChangeLog     f
-lib/intl/Makefile.in   f
-lib/intl/VERSION       f
-lib/intl/bindtextdom.c f
-lib/intl/config.charset        f
-lib/intl/dcgettext.c   f
-lib/intl/dcigettext.c  f
-lib/intl/dcngettext.c  f
-lib/intl/dgettext.c    f
-lib/intl/dngettext.c   f
-lib/intl/eval-plural.h f
-lib/intl/explodename.c f
-lib/intl/finddomain.c  f
-lib/intl/gettext.c     f
-lib/intl/gettextP.h    f
-lib/intl/gmo.h         f
-lib/intl/hash-string.h f
-lib/intl/intl-compat.c f
-lib/intl/l10nflist.c   f
-lib/intl/libgnuintl.h.in       f
-lib/intl/loadinfo.h    f
-lib/intl/loadmsgcat.c  f
-lib/intl/localcharset.c        f
-lib/intl/localcharset.h        f
-lib/intl/locale.alias  f
-lib/intl/localealias.c f
-lib/intl/localename.c  f
-lib/intl/log.c         f
-lib/intl/ngettext.c    f
-lib/intl/os2compat.c   f
-lib/intl/os2compat.h   f
-lib/intl/osdep.c       f
-lib/intl/plural-exp.c  f
-lib/intl/plural-exp.h  f
-lib/intl/plural.c      f
-lib/intl/plural.y      f
-lib/intl/ref-add.sin   f
-lib/intl/ref-del.sin   f
-lib/intl/relocatable.c f
-lib/intl/relocatable.h f
-lib/intl/textdomain.c  f
-lib/malloc/Makefile.in f
-lib/malloc/getpagesize.h       f
-lib/malloc/imalloc.h   f
-lib/malloc/mstats.h    f
-lib/malloc/shmalloc.h  f
-lib/malloc/table.h     f
-lib/malloc/watch.h     f
-lib/malloc/alloca.c    f
-lib/malloc/malloc.c    f
-lib/malloc/stats.c     f
-lib/malloc/table.c     f
-lib/malloc/trace.c     f
-lib/malloc/watch.c     f
-lib/malloc/xmalloc.c   f
-lib/malloc/xleaktrace  f       755
-lib/malloc/stub.c      f
-lib/malloc/i386-alloca.s       f
-lib/malloc/x386-alloca.s       f
-lib/readline/COPYING   f
-lib/readline/Makefile.in       f
-lib/readline/ChangeLog f
-lib/readline/README    f
-lib/readline/STANDALONE f
-lib/readline/readline.c        f
-lib/readline/vi_mode.c f
-lib/readline/emacs_keymap.c    f
-lib/readline/vi_keymap.c       f
-lib/readline/history.c f
-lib/readline/histexpand.c      f
-lib/readline/histsearch.c      f
-lib/readline/histfile.c        f
-lib/readline/funmap.c  f
-lib/readline/keymaps.c f
-lib/readline/util.c    f
-lib/readline/terminal.c        f
-lib/readline/xmalloc.c f
-lib/readline/search.c  f
-lib/readline/isearch.c f
-lib/readline/parens.c  f
-lib/readline/rltty.c   f
-lib/readline/compat.c  f
-lib/readline/complete.c        f
-lib/readline/bind.c    f
-lib/readline/display.c f
-lib/readline/signals.c f
-lib/readline/kill.c    f
-lib/readline/text.c    f
-lib/readline/undo.c    f
-lib/readline/macro.c   f
-lib/readline/input.c   f
-lib/readline/callback.c        f
-lib/readline/mbutil.c  f
-lib/readline/misc.c    f
-lib/readline/nls.c     f
-lib/readline/shell.c   f
-lib/readline/savestring.c      f
-lib/readline/tilde.c   f
-lib/readline/tilde.h   f
-lib/readline/rldefs.h  f
-lib/readline/rlconf.h  f
-lib/readline/rlmbutil.h        f
-lib/readline/rlshell.h f
-lib/readline/rltty.h   f
-lib/readline/rltypedefs.h      f
-lib/readline/rlwinsize.h       f
-lib/readline/readline.h        f
-lib/readline/tcap.h    f
-lib/readline/keymaps.h f
-lib/readline/history.h f
-lib/readline/histlib.h f
-lib/readline/chardefs.h        f
-lib/readline/posixdir.h        f
-lib/readline/posixjmp.h        f
-lib/readline/posixselect.h     f
-lib/readline/posixstat.h       f
-lib/readline/ansi_stdlib.h     f
-lib/readline/rlstdc.h  f
-lib/readline/rlprivate.h       f
-lib/readline/xmalloc.h f
-lib/readline/doc/Makefile      f
-lib/readline/doc/version.texi  f
-lib/readline/doc/rlman.texi    f
-lib/readline/doc/rltech.texi   f
-lib/readline/doc/rluser.texi   f
-lib/readline/doc/rluserman.texi        f
-lib/readline/doc/history.texi  f
-lib/readline/doc/hstech.texi   f
-lib/readline/doc/hsuser.texi   f
-lib/readline/doc/fdl.texi      f
-lib/readline/examples/Makefile f
-lib/readline/examples/excallback.c     f
-lib/readline/examples/fileman.c        f
-lib/readline/examples/manexamp.c       f
-lib/readline/examples/histexamp.c      f
-lib/readline/examples/rltest.c f
-lib/readline/examples/rl.c     f
-lib/readline/examples/rlcat.c  f
-lib/readline/examples/Inputrc  f
-lib/sh/Makefile.in     f
-lib/sh/casemod.c       f
-lib/sh/clktck.c                f
-lib/sh/clock.c         f
-lib/sh/eaccess.c       f
-lib/sh/fdprintf.c      f
-lib/sh/fmtullong.c     f
-lib/sh/fmtulong.c      f
-lib/sh/fmtumax.c       f
-lib/sh/fnxform.c       f
-lib/sh/fpurge.c                f
-lib/sh/getcwd.c                f
-lib/sh/getenv.c                f
-lib/sh/inet_aton.c     f
-lib/sh/input_avail.c   f
-lib/sh/itos.c          f
-lib/sh/mailstat.c      f
-lib/sh/makepath.c      f
-lib/sh/mbscasecmp.c    f
-lib/sh/mbschr.c                f
-lib/sh/mbscmp.c                f
-lib/sh/memset.c                f
-lib/sh/mktime.c                f
-lib/sh/netconn.c       f
-lib/sh/netopen.c       f
-lib/sh/oslib.c         f
-lib/sh/pathcanon.c     f
-lib/sh/pathphys.c      f
-lib/sh/rename.c                f
-lib/sh/setlinebuf.c    f
-lib/sh/shmatch.c       f
-lib/sh/shquote.c       f
-lib/sh/shtty.c         f
-lib/sh/snprintf.c      f
-lib/sh/spell.c         f
-lib/sh/strcasecmp.c    f
-lib/sh/strcasestr.c    f
-lib/sh/strerror.c      f
-lib/sh/strftime.c      f
-lib/sh/stringlist.c    f
-lib/sh/stringvec.c     f
-lib/sh/strnlen.c       f
-lib/sh/strpbrk.c       f
-lib/sh/strstr.c                f
-lib/sh/strtod.c                f
-lib/sh/strtoimax.c     f
-lib/sh/strtol.c                f
-lib/sh/strtoll.c       f
-lib/sh/strtoul.c       f
-lib/sh/strtoull.c      f
-lib/sh/strtoumax.c     f
-lib/sh/strtrans.c      f
-lib/sh/times.c         f
-lib/sh/timeval.c       f
-lib/sh/tmpfile.c       f
-lib/sh/uconvert.c      f
-lib/sh/ufuncs.c                f
-lib/sh/vprint.c                f
-lib/sh/wcsdup.c                f
-lib/sh/winsize.c       f
-lib/sh/zcatfd.c                f
-lib/sh/zgetline.c      f
-lib/sh/zmapfd.c                f
-lib/sh/zread.c         f
-lib/sh/zwrite.c                f
-lib/termcap/Makefile.in        f
-lib/termcap/ltcap.h    f
-lib/termcap/termcap.c  f
-lib/termcap/termcap.h  f
-lib/termcap/tparam.c   f
-lib/termcap/version.c  f
-lib/tilde/README       f
-lib/tilde/Makefile.in  f
-lib/tilde/tilde.c      f
-lib/tilde/tilde.h      f
-lib/tilde/shell.c      f
-po/LINGUAS             f
-po/Makefile.in.in      f
-po/Makevars            f
-po/POTFILES.in         f
-po/README              f
-po/Rules-builtins      f
-po/Rules-quot          f
-po/bash.pot            f
-po/boldquot.sed                f
-po/en@boldquot.gmo     f
-po/en@boldquot.header  f
-po/en@boldquot.po      f
-po/en@quot.gmo         f
-po/en@quot.header      f
-po/en@quot.po          f
-po/af.gmo              f
-po/af.po               f
-po/bg.gmo              f
-po/bg.po               f
-po/ca.gmo              f
-po/ca.po               f
-po/cs.gmo              f
-po/cs.po               f
-po/de.gmo              f
-po/de.po               f
-po/eo.gmo              f
-po/eo.po               f
-po/es.gmo              f
-po/es.po               f
-po/et.gmo              f
-po/et.po               f
-po/fi.gmo              f
-po/fi.po               f
-po/fr.gmo              f
-po/fr.po               f
-po/hu.gmo              f
-po/hu.po               f
-po/id.gmo              f
-po/id.po               f
-po/ja.gmo              f
-po/ja.po               f
-po/lt.gmo              f
-po/lt.po               f
-po/nl.gmo              f
-po/nl.po               f
-po/pl.gmo              f
-po/pl.po               f
-po/pt_BR.gmo           f
-po/pt_BR.po            f
-po/ro.gmo              f
-po/ro.po               f
-po/ru.gmo              f
-po/ru.po               f
-po/sk.gmo              f
-po/sk.po               f
-po/sv.gmo              f
-po/sv.po               f
-po/tr.gmo              f
-po/tr.po               f
-po/vi.gmo              f
-po/vi.po               f
-po/zh_TW.gmo           f
-po/zh_TW.po            f
-po/insert-header.sin   f
-po/quot.sed            f
-po/remove-potcdate.sin f
-CWRU/misc/open-files.c f
-CWRU/misc/sigs.c       f
-CWRU/misc/sigstat.c    f
-CWRU/misc/bison                f
-CWRU/misc/errlist.c    f
-CWRU/misc/hpux10-dlfcn.h       f
-CWRU/PLATFORMS         f
-CWRU/README            f
-CWRU/changelog         f
-CWRU/sh-redir-hack     f
-CWRU/mh-folder-comp    f
-doc/FAQ                f
-doc/Makefile.in        f
-doc/bash.1     f
-doc/bashbug.1  f
-doc/builtins.1 f
-doc/rbash.1    f
-doc/README     f
-doc/INTRO      f
-doc/texinfo.tex        f
-doc/bashref.texi       f
-doc/version.texi       f
-doc/bashref.info       f
-doc/article.ms f
-doc/htmlpost.sh        f       755
-doc/infopost.sh        f       755
-doc/fdl.texi   f
-doc/fdl.txt    f
-support/Makefile.in    f
-support/bashversion.c  f
-support/checkbashisms  f       755
-support/config.guess   f
-support/config.rpath   f       755
-support/config.sub     f
-support/printenv.sh    f       755
-support/printenv.c     f
-support/bash.xbm       f
-support/missing                f       755
-support/mkclone                f       755
-support/mkconffiles    f       755
-support/mkdirs         f       755
-support/mkinstalldirs  f       755
-support/mkversion.sh   f       755
-support/mksignames.c   f
-support/signames.c     f
-support/bashbug.sh     f
-support/man2html.c     f
-support/recho.c                f
-support/zecho.c                f
-support/xcase.c                f
-support/SYMLINKS       f
-support/fixlinks       f       755
-support/install.sh     f       755
-support/texi2dvi       f       755
-support/texi2html      f       755
-support/xenix-link.sh  f       755
-support/shobj-conf     f       755
-support/rlvers.sh      f       755
-examples/INDEX.txt     f
-examples/INDEX.html    f
-examples/obashdb/PERMISSION    f
-examples/obashdb/README        f
-examples/obashdb/bashdb                f
-examples/obashdb/bashdb.el     f
-examples/complete/bash_completion      f
-examples/complete/complete-examples    f
-examples/complete/complete.ianmac      f
-examples/complete/complete2.ianmac     f
-examples/complete/complete.freebsd     f
-examples/complete/complete.gnu-longopt f
-examples/complete/bashcc-1.0.1.tar.gz  f
-examples/loadables/README      f
-examples/loadables/template.c  f
-examples/loadables/Makefile.in f
-examples/loadables/necho.c     f
-examples/loadables/hello.c     f
-examples/loadables/print.c     f
-examples/loadables/realpath.c  f
-examples/loadables/sleep.c     f
-examples/loadables/strftime.c  f
-examples/loadables/truefalse.c f
-examples/loadables/getconf.h   f
-examples/loadables/getconf.c   f
-examples/loadables/finfo.c     f
-examples/loadables/cat.c       f
-examples/loadables/cut.c       f
-examples/loadables/logname.c   f
-examples/loadables/basename.c  f
-examples/loadables/dirname.c   f
-examples/loadables/tty.c       f
-examples/loadables/pathchk.c   f
-examples/loadables/tee.c       f
-examples/loadables/rmdir.c     f
-examples/loadables/head.c      f
-examples/loadables/printenv.c  f
-examples/loadables/push.c      f
-examples/loadables/id.c                f
-examples/loadables/whoami.c    f
-examples/loadables/uname.c     f
-examples/loadables/sync.c      f
-examples/loadables/mkdir.c     f
-examples/loadables/ln.c                f
-examples/loadables/mypid.c     f
-examples/loadables/unlink.c    f
-examples/loadables/perl/Makefile.in    f
-examples/loadables/perl/README f
-examples/loadables/perl/bperl.c        f
-examples/loadables/perl/iperl.c        f
-examples/functions/array-stuff f
-examples/functions/array-to-string     f
-examples/functions/autoload    f
-examples/functions/autoload.v2 f
-examples/functions/autoload.v3 f
-examples/functions/basename    f
-examples/functions/basename2   f
-examples/functions/coproc.bash f
-examples/functions/coshell.README      f
-examples/functions/coshell.bash        f
-examples/functions/csh-compat  f
-examples/functions/dirfuncs    f
-examples/functions/dirname     f
-examples/functions/emptydir    f
-examples/functions/exitstat    f
-examples/functions/external    f
-examples/functions/fact                f
-examples/functions/fstty       f
-examples/functions/func                f
-examples/functions/gethtml     f
-examples/functions/getoptx.bash        f
-examples/functions/inetaddr    f
-examples/functions/inpath      f
-examples/functions/isnum.bash  f
-examples/functions/isnum2      f
-examples/functions/isvalidip   f
-examples/functions/jdate.bash  f
-examples/functions/jj.bash     f
-examples/functions/keep                f
-examples/functions/ksh-cd      f
-examples/functions/ksh-compat-test     f
-examples/functions/kshenv      f
-examples/functions/login       f
-examples/functions/lowercase   f
-examples/functions/manpage     f
-examples/functions/mhfold      f
-examples/functions/notify.bash f
-examples/functions/pathfuncs   f
-examples/functions/recurse     f
-examples/functions/repeat2     f
-examples/functions/repeat3     f
-examples/functions/seq         f
-examples/functions/seq2                f
-examples/functions/shcat       f
-examples/functions/shcat2      f
-examples/functions/sort-pos-params     f
-examples/functions/substr      f
-examples/functions/substr2     f
-examples/functions/term                f
-examples/functions/whatis      f
-examples/functions/whence      f
-examples/functions/which       f
-examples/functions/xalias.bash f
-examples/functions/xfind.bash  f
-examples/scripts/adventure.sh  f
-examples/scripts/bcsh.sh       f
-examples/scripts/cat.sh                f
-examples/scripts/center                f
-examples/scripts/dd-ex.sh      f
-examples/scripts/fixfiles.bash f
-examples/scripts/hanoi.bash    f
-examples/scripts/inpath                f
-examples/scripts/krand.bash    f
-examples/scripts/line-input.bash       f
-examples/scripts/nohup.bash    f
-examples/scripts/precedence    f
-examples/scripts/randomcard.bash       f
-examples/scripts/scrollbar     f
-examples/scripts/scrollbar2    f
-examples/scripts/self-repro    f
-examples/scripts/showperm.bash f
-examples/scripts/shprompt      f
-examples/scripts/spin.bash     f
-examples/scripts/timeout       f
-examples/scripts/timeout2      f
-examples/scripts/timeout3      f
-examples/scripts/vtree2                f
-examples/scripts/vtree3                f
-examples/scripts/vtree3a       f
-examples/scripts/websrv.sh     f
-examples/scripts/xterm_title   f
-examples/scripts/zprintf       f
-examples/startup-files/README  f
-examples/startup-files/Bashrc.bfox     f
-examples/startup-files/Bash_aliases    f
-examples/startup-files/Bash_profile    f
-examples/startup-files/bash-profile    f
-examples/startup-files/bashrc  f
-examples/startup-files/apple/README    f
-examples/startup-files/apple/aliases   f
-examples/startup-files/apple/bash.defaults     f
-examples/startup-files/apple/environment       f
-examples/startup-files/apple/login     f
-examples/startup-files/apple/logout    f
-examples/startup-files/apple/rc                f
-examples/misc/suncmd.termcap   f
-examples/misc/aliasconv.sh     f
-examples/misc/aliasconv.bash   f
-examples/misc/cshtobash        f
-tests/README           f
-tests/COPYRIGHT                f
-tests/alias.tests      f
-tests/alias1.sub       f
-tests/alias.right      f
-tests/appendop.tests   f
-tests/appendop.right   f
-tests/arith-for.tests  f
-tests/arith-for.right  f
-tests/arith.tests      f
-tests/arith.right      f
-tests/arith1.sub       f
-tests/arith2.sub       f
-tests/array.tests      f
-tests/array.right      f
-tests/array1.sub       f
-tests/array2.sub       f
-tests/array3.sub       f
-tests/array4.sub       f
-tests/array5.sub       f
-tests/array6.sub       f
-tests/array7.sub       f
-tests/array8.sub       f
-tests/array9.sub       f
-tests/array-at-star    f
-tests/array2.right     f
-tests/assoc.tests      f
-tests/assoc.right      f
-tests/assoc1.sub       f
-tests/assoc2.sub       f
-tests/assoc3.sub       f
-tests/assoc4.sub       f
-tests/assoc5.sub       f
-tests/assoc6.sub       f
-tests/braces.tests     f
-tests/braces.right     f
-tests/builtins.tests   f
-tests/builtins.right   f
-tests/builtins1.sub    f
-tests/builtins2.sub    f
-tests/source1.sub      f
-tests/source2.sub      f
-tests/source3.sub      f
-tests/source4.sub      f
-tests/source5.sub      f
-tests/source6.sub      f
-tests/case.tests       f
-tests/case.right       f
-tests/casemod.tests    f
-tests/casemod.right    f
-tests/comsub.tests     f
-tests/comsub.right     f
-tests/comsub1.sub      f
-tests/comsub-eof.tests f
-tests/comsub-eof0.sub  f
-tests/comsub-eof1.sub  f
-tests/comsub-eof2.sub  f
-tests/comsub-eof3.sub  f
-tests/comsub-eof4.sub  f
-tests/comsub-eof5.sub  f
-tests/comsub-eof.right f
-tests/comsub-posix.tests       f
-tests/comsub-posix.right       f
-tests/comsub-posix1.sub        f
-tests/cond.tests       f
-tests/cond.right       f
-tests/cond-regexp.sub  f
-tests/coproc.tests     f
-tests/coproc.right     f
-tests/cprint.tests     f
-tests/cprint.right     f
-tests/dbg-support.right        f
-tests/dbg-support.sub  f
-tests/dbg-support.tests        f
-tests/dbg-support2.right       f
-tests/dbg-support2.tests       f
-tests/dbg-support3.sub f
-tests/dollar-at-star   f
-tests/dollar-at1.sub   f
-tests/dollar-at2.sub   f
-tests/dollar-at3.sub   f
-tests/dollar-star1.sub f
-tests/dollar-star2.sub f
-tests/dollar-star3.sub f
-tests/dollar-star4.sub f
-tests/dollar-star5.sub f
-tests/dollar.right     f
-tests/dstack.tests     f
-tests/dstack.right     f
-tests/dstack2.tests    f
-tests/dstack2.right    f
-tests/errors.tests     f
-tests/errors.right     f
-tests/execscript       f
-tests/exec.right       f
-tests/exec1.sub                f       755
-tests/exec2.sub                f
-tests/exec3.sub                f
-tests/exec4.sub                f
-tests/exec5.sub                f
-tests/exec6.sub                f
-tests/exec7.sub                f
-tests/exec8.sub                f
-tests/exp.tests                f
-tests/exp.right                f
-tests/exp1.sub         f
-tests/exp2.sub         f
-tests/exp3.sub         f
-tests/extglob.tests    f
-tests/extglob.right    f
-tests/extglob1.sub     f
-tests/extglob2.tests   f
-tests/extglob2.right   f
-tests/extglob3.tests   f
-tests/extglob3.right   f
-tests/func.tests       f
-tests/func.right       f
-tests/func1.sub                f
-tests/func2.sub                f
-tests/func3.sub                f
-tests/getopts.tests    f
-tests/getopts.right    f
-tests/getopts1.sub     f
-tests/getopts2.sub     f
-tests/getopts3.sub     f
-tests/getopts4.sub     f
-tests/getopts5.sub     f
-tests/getopts6.sub     f
-tests/getopts7.sub     f
-tests/glob.tests       f
-tests/glob1.sub                f
-tests/glob.right       f
-tests/globstar.tests   f
-tests/globstar.right   f
-tests/globstar1.sub    f
-tests/heredoc.tests    f
-tests/heredoc.right    f
-tests/heredoc1.sub     f
-tests/herestr.tests    f
-tests/herestr.right    f
-tests/histexp.tests    f
-tests/histexp.right    f
-tests/history.tests    f
-tests/history.right    f
-tests/history.list     f       444
-tests/history1.sub     f
-tests/history2.sub     f
-tests/ifs.tests                f
-tests/ifs.right                f
-tests/ifs-posix.tests  f
-tests/ifs-posix.right  f
-tests/input-line.sh    f
-tests/input-line.sub   f
-tests/input.right      f
-tests/intl.tests       f
-tests/intl1.sub                f
-tests/intl.right       f
-tests/iquote.tests     f
-tests/iquote.right     f
-tests/invert.tests     f
-tests/invert.right     f
-tests/jobs.tests       f
-tests/jobs1.sub                f
-tests/jobs2.sub                f
-tests/jobs3.sub                f
-tests/jobs4.sub                f
-tests/jobs.right       f
-tests/mapfile.data     f
-tests/mapfile.right    f
-tests/mapfile.tests    f
-tests/mapfile1.sub     f
-tests/more-exp.tests   f
-tests/more-exp.right   f
-tests/new-exp.tests    f
-tests/new-exp1.sub     f
-tests/new-exp2.sub     f
-tests/new-exp3.sub     f
-tests/new-exp4.sub     f
-tests/new-exp5.sub     f
-tests/new-exp6.sub     f
-tests/new-exp7.sub     f
-tests/new-exp.right    f
-tests/nquote.tests     f
-tests/nquote.right     f
-tests/nquote1.sub      f
-tests/nquote1.tests    f
-tests/nquote1.right    f
-tests/nquote2.tests    f
-tests/nquote2.right    f
-tests/nquote3.tests    f
-tests/nquote3.right    f
-tests/nquote4.tests    f
-tests/nquote4.right    f
-tests/nquote5.tests    f
-tests/nquote5.right    f
-tests/posix2.tests     f
-tests/posix2.right     f
-tests/posixpat.tests   f
-tests/posixpat.right   f
-tests/prec.right       f
-tests/precedence       f
-tests/printf.tests     f
-tests/printf.right     f
-tests/printf2.sub      f
-tests/quote.tests      f
-tests/quote.right      f
-tests/read.tests       f
-tests/read.right       f
-tests/read1.sub                f
-tests/read2.sub                f
-tests/read3.sub                f
-tests/read4.sub                f
-tests/read5.sub                f
-tests/read6.sub                f
-tests/redir.tests      f
-tests/redir.right      f
-tests/redir1.sub       f
-tests/redir2.sub       f
-tests/redir3.sub       f
-tests/redir3.in1       f
-tests/redir3.in2       f
-tests/redir4.sub       f
-tests/redir4.in1       f
-tests/redir5.sub       f
-tests/redir6.sub       f
-tests/redir7.sub       f
-tests/redir8.sub       f
-tests/redir9.sub       f
-tests/rhs-exp.tests    f
-tests/rhs-exp.right    f
-tests/rsh.tests                f
-tests/rsh.right                f
-tests/run-all          f
-tests/run-minimal      f
-tests/run-alias                f
-tests/run-appendop     f
-tests/run-arith-for    f
-tests/run-arith                f
-tests/run-array                f
-tests/run-array2       f
-tests/run-assoc                f
-tests/run-braces       f
-tests/run-builtins     f
-tests/run-case         f
-tests/run-casemod      f
-tests/run-comsub       f
-tests/run-comsub-eof   f
-tests/run-comsub-posix f
-tests/run-cond         f
-tests/run-coproc       f
-tests/run-cprint       f
-tests/run-dbg-support  f
-tests/run-dbg-support2 f
-tests/run-dirstack     f
-tests/run-dollars      f
-tests/run-errors       f
-tests/run-execscript   f
-tests/run-exp-tests    f
-tests/run-extglob      f
-tests/run-extglob2     f
-tests/run-extglob3     f
-tests/run-func         f
-tests/run-getopts      f
-tests/run-glob-test    f
-tests/run-globstar     f
-tests/run-heredoc      f
-tests/run-herestr      f
-tests/run-histexpand   f
-tests/run-history      f
-tests/run-ifs          f
-tests/run-ifs-posix    f
-tests/run-input-test   f
-tests/run-intl         f
-tests/run-iquote       f
-tests/run-invert       f
-tests/run-jobs         f
-tests/run-mapfile      f
-tests/run-more-exp     f
-tests/run-new-exp      f
-tests/run-nquote       f
-tests/run-nquote1      f
-tests/run-nquote2      f
-tests/run-nquote3      f
-tests/run-nquote4      f
-tests/run-nquote5      f
-tests/run-posix2       f
-tests/run-posixpat     f
-tests/run-precedence   f
-tests/run-printf       f
-tests/run-quote                f
-tests/run-read         f
-tests/run-redir                f
-tests/run-rhs-exp      f
-tests/run-rsh          f
-tests/run-set-e                f
-tests/run-set-x                f
-tests/run-shopt                f
-tests/run-strip                f
-tests/run-test         f
-tests/run-tilde                f
-tests/run-tilde2       f
-tests/run-trap         f
-tests/run-type         f
-tests/run-varenv       f
-tests/run-vredir       f
-tests/set-e.tests      f
-tests/set-e1.sub       f
-tests/set-e2.sub       f
-tests/set-e.right      f
-tests/set-x.tests      f
-tests/set-x1.sub       f
-tests/set-x.right      f
-tests/shopt.tests      f       
-tests/shopt.right      f
-tests/strip.tests      f
-tests/strip.right      f
-tests/test.tests       f
-tests/test.right       f
-tests/tilde.tests      f
-tests/tilde.right      f
-tests/tilde2.tests     f
-tests/tilde2.right     f
-tests/trap.tests       f
-tests/trap.right       f
-tests/trap1.sub                f       755
-tests/trap2.sub                f       755
-tests/trap2a.sub       f       755
-tests/trap3.sub                f
-tests/type.tests       f
-tests/type.right       f
-tests/type1.sub                f
-tests/type2.sub                f
-tests/varenv.right     f
-tests/varenv.sh                f
-tests/varenv1.sub      f
-tests/varenv2.sub      f
-tests/version          f
-tests/version.mini     f
-tests/vredir.tests     f
-tests/vredir.right     f
-tests/vredir1.sub      f
-tests/vredir2.sub      f
-tests/vredir3.sub      f
-tests/vredir4.sub      f
-tests/vredir5.sub      f
-tests/misc/dev-tcp.tests       f
-tests/misc/perf-script f
-tests/misc/perftest    f
-tests/misc/read-nchars.tests   f
-tests/misc/redir-t2.sh f
-tests/misc/run-r2.sh   f
-tests/misc/sigint-1.sh         f
-tests/misc/sigint-2.sh         f
-tests/misc/sigint-3.sh         f
-tests/misc/sigint-4.sh         f
-tests/misc/test-minus-e.1      f
-tests/misc/test-minus-e.2      f
-tests/misc/wait-bg.tests       f
-examples/scripts.v2/PERMISSION f
-examples/scripts.v2/README     f
-examples/scripts.v2/arc2tarz   f
-examples/scripts.v2/bashrand   f
-examples/scripts.v2/cal2day.bash       f
-examples/scripts.v2/cdhist.bash        f
-examples/scripts.v2/corename   f
-examples/scripts.v2/fman       f
-examples/scripts.v2/frcp       f
-examples/scripts.v2/lowercase  f
-examples/scripts.v2/ncp        f
-examples/scripts.v2/newext     f
-examples/scripts.v2/nmv        f
-examples/scripts.v2/pages      f
-examples/scripts.v2/pf f
-examples/scripts.v2/ren                f
-examples/scripts.v2/rename     f
-examples/scripts.v2/repeat     f
-examples/scripts.v2/untar      f
-examples/scripts.v2/uudec      f
-examples/scripts.v2/uuenc      f
-examples/scripts.v2/vtree      f
-examples/scripts.v2/where      f
-examples/scripts.v2/pmtop      f
-examples/scripts.v2/shprof     f
-examples/scripts.noah/PERMISSION       f
-examples/scripts.noah/README   f
-examples/scripts.noah/aref.bash        f
-examples/scripts.noah/bash.sub.bash    f
-examples/scripts.noah/bash_version.bash        f
-examples/scripts.noah/meta.bash        f
-examples/scripts.noah/mktmp.bash       f
-examples/scripts.noah/number.bash      f
-examples/scripts.noah/prompt.bash      f
-examples/scripts.noah/remap_keys.bash  f
-examples/scripts.noah/require.bash     f
-examples/scripts.noah/send_mail.bash   f
-examples/scripts.noah/shcat.bash       f
-examples/scripts.noah/source.bash      f
-examples/scripts.noah/string.bash      f
-examples/scripts.noah/stty.bash        f
-examples/scripts.noah/y_or_n_p.bash    f
diff --git a/Makefile.in~ b/Makefile.in~
deleted file mode 100644 (file)
index d61e450..0000000
+++ /dev/null
@@ -1,1521 +0,0 @@
-# Makefile for bash-4.0, version 3.5
-#
-# Copyright (C) 1996-2009 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
-
-# Make sure the first target in the makefile is the right one
-all: .made
-
-PACKAGE = @PACKAGE_NAME@
-VERSION = @PACKAGE_VERSION@
-
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-
-# Include some boilerplate Gnu makefile definitions.
-prefix = @prefix@
-
-exec_prefix = @exec_prefix@
-
-datarootdir = @datarootdir@
-
-bindir = @bindir@
-libdir = @libdir@
-infodir = @infodir@
-includedir = @includedir@
-datadir = @datadir@
-localedir = @localedir@
-
-mandir = @mandir@
-manpfx = man
-
-man1ext = .1
-man1dir = $(mandir)/$(manpfx)1
-man3ext = .3
-man3dir = $(mandir)/$(manpfx)3
-
-htmldir = @htmldir@
-
-# Support an alternate destination root directory for package building
-DESTDIR =
-
-topdir = @top_srcdir@
-BUILD_DIR = @BUILD_DIR@
-top_builddir = @BUILD_DIR@
-srcdir = @srcdir@
-VPATH = .:@srcdir@
-
-@SET_MAKE@
-CC = @CC@
-CC_FOR_BUILD = @CC_FOR_BUILD@
-YACC = @YACC@
-SHELL = @MAKE_SHELL@
-CP = cp
-RM = rm -f
-AR = @AR@
-ARFLAGS = @ARFLAGS@
-RANLIB = @RANLIB@
-SIZE = @SIZE@
-
-INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALLMODE= -m 0755
-INSTALLMODE2 = -m 0555
-
-TESTSCRIPT = @TESTSCRIPT@
-
-DEBUGGER_START_FILE = @DEBUGGER_START_FILE@
-
-#If you have purify, and want to use it, uncomment this definition or
-# run the make as `make PURIFY=purify'
-# or run configure with the --with-purify argument.
-PURIFY = @PURIFY@
-
-# Here is a rule for making .o files from .c files that does not
-# force the type of the machine (like -M_MACHINE) into the flags.
-.c.o:
-       $(RM) $@
-       $(CC) $(CCFLAGS) -c $<
-
-EXEEXT = @EXEEXT@
-OBJEXT = @OBJEXT@
-
-# The name of this program and some version information.
-VERSPROG = bashversion$(EXEEXT)
-VERSOBJ = bashversion.$(OBJEXT)
-
-Program = bash$(EXEEXT)
-Version = @BASHVERS@
-PatchLevel = `$(BUILD_DIR)/$(VERSPROG) -p`
-RELSTATUS = @RELSTATUS@
-
-Machine = @host_cpu@
-OS = @host_os@
-VENDOR = @host_vendor@
-MACHTYPE = @host@
-
-# comment out for release
-DEBUG = @DEBUG@
-MALLOC_DEBUG = @MALLOC_DEBUG@
-
-THIS_SH = $(BUILD_DIR)/$(Program)
-
-# PROFILE_FLAGS is either -pg, to generate profiling info for use
-# with gprof, or nothing (the default).
-PROFILE_FLAGS= @PROFILE_FLAGS@
-
-CFLAGS = @CFLAGS@
-CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ @CROSS_COMPILE@
-CPPFLAGS = @CPPFLAGS@
-CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@
-LOCAL_CFLAGS = @LOCAL_CFLAGS@ ${DEBUG} ${MALLOC_DEBUG}
-DEFS = @DEFS@
-LOCAL_DEFS = @LOCAL_DEFS@
-
-LOCALE_DEFS = -DLOCALEDIR='"$(localedir)"' -DPACKAGE='"$(PACKAGE)"'
-
-LOCAL_LIBS = @LOCAL_LIBS@
-LIBS = $(BUILTINS_LIB) $(LIBRARIES) @LIBS@
-LIBS_FOR_BUILD = 
-
-STATIC_LD = @STATIC_LD@
-LOCAL_LDFLAGS = @LOCAL_LDFLAGS@
-
-SYSTEM_FLAGS = -DPROGRAM='"$(Program)"' -DCONF_HOSTTYPE='"$(Machine)"' -DCONF_OSTYPE='"$(OS)"' -DCONF_MACHTYPE='"$(MACHTYPE)"' -DCONF_VENDOR='"$(VENDOR)"' $(LOCALE_DEFS)
-
-BASE_CCFLAGS = $(PROFILE_FLAGS) $(SYSTEM_FLAGS) $(LOCAL_DEFS) \
-         $(DEFS) $(LOCAL_CFLAGS) $(INCLUDES)
-
-CCFLAGS = $(BASE_CCFLAGS) $(CPPFLAGS) $(CFLAGS)
-
-CCFLAGS_FOR_BUILD = $(BASE_CCFLAGS) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD)
-
-LDFLAGS = @LDFLAGS@ $(STATIC_LD) $(LOCAL_LDFLAGS) $(PROFILE_FLAGS) $(CFLAGS)
-LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@ $(LOCAL_LDFLAGS) $(CFLAGS_FOR_BUILD)
-
-INCLUDES = -I. @RL_INCLUDE@ -I$(srcdir) -I$(BASHINCDIR) -I$(LIBSRC) $(INTL_INC)
-
-# Maybe add: -Wextra
-GCC_LINT_FLAGS = -O -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wno-parentheses \
-                -Wcast-align -Wstrict-prototypes -Wconversion -Wformat \
-                -Wformat-nonliteral -Wmissing-braces -Wuninitialized \
-                -Wmissing-declarations  -Winline \
-                -Wmissing-prototypes -Wtraditional -Wredundant-decls -pedantic
-
-GCC_LINT_CFLAGS = $(BASE_CCFLAGS) $(CPPFLAGS) $(GCC_LINT_FLAGS)
-
-#
-# Support libraries
-# 
-
-dot = .
-
-LIBSUBDIR = lib
-LIBSRC = $(srcdir)/$(LIBSUBDIR)
-
-LIBBUILD = ${BUILD_DIR}/${LIBSUBDIR}
-
-SUBDIR_INCLUDES = -I. @RL_INCLUDE@ -I$(topdir) -I$(topdir)/$(LIBSUBDIR)
-
-BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
-USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
-
-# the bash library
-# the library is a mix of functions that the C library does not provide on
-# some platforms and general shell utility functions
-SH_LIBSRC = $(LIBSRC)/sh
-SH_LIBDIR = $(dot)/${LIBSUBDIR}/sh
-SH_ABSSRC = ${topdir}/${SH_LIBSRC}
-
-SHLIB_SOURCE = ${SH_LIBSRC}/clktck.c ${SH_LIBSRC}/getcwd.c \
-               ${SH_LIBSRC}/getenv.c ${SH_LIBSRC}/oslib.c \
-               ${SH_LIBSRC}/setlinebuf.c \
-               ${SH_LIBSRC}/strcasecmp.c ${SH_LIBSRC}/strerror.c \
-               ${SH_LIBSRC}/strtod.c ${SH_LIBSRC}/strtol.c \
-               ${SH_LIBSRC}/strtoul.c ${SH_LIBSRC}/vprint.c \
-               ${SH_LIBSRC}/itos.c ${SH_LIBSRC}/rename.c \
-               ${SH_LIBSRC}/zread.c ${SH_LIBSRC}/zwrite.c \
-               ${SH_LIBSRC}/shtty.c ${SH_LIBSRC}/inet_aton.c \
-               ${SH_LIBSRC}/netopen.c ${SH_LIBSRC}/strpbrk.c \
-               ${SH_LIBSRC}/timeval.c ${SH_LIBSRC}/clock.c \
-               ${SH_LIBSRC}/makepath.c ${SH_LIBSRC}/pathcanon.c \
-               ${SH_LIBSRC}/pathphys.c ${SH_LIBSRC}/stringlist.c \
-               ${SH_LIBSRC}/stringvec.c ${SH_LIBSRC}/tmpfile.c \
-               ${SH_LIBSRC}/spell.c ${SH_LIBSRC}/strtrans.c \
-               ${SH_LIBSRC}/strcasestr.c ${SH_LIBSRC}/shquote.c \
-               ${SH_LIBSRC}/snprintf.c ${SH_LIBSRC}/mailstat.c \
-               ${SH_LIBSRC}/fmtulong.c ${SH_LIBSRC}/fmtullong.c \
-               ${SH_LIBSRC}/strtoll.c ${SH_LIBSRC}/strtoull.c \
-               ${SH_LIBSRC}/strtoimax.c ${SH_LIBSRC}/strtoumax.c \
-               ${SH_LIBSRC}/fmtumax.c ${SH_LIBSRC}/netconn.c \
-               ${SH_LIBSRC}/mktime.c ${SH_LIBSRC}/strftime.c \
-               ${SH_LIBSRC}/memset.c ${SH_LIBSRC}/mbschr.c \
-               ${SH_LIBSRC}/zcatfd.c ${SH_LIBSRC}/shmatch.c \
-               ${SH_LIBSRC}/strnlen.c ${SH_LIBSRC}/winsize.c \
-               ${SH_LIBSRC}/eaccess.c ${SH_LIBSRC}/wcsdup.c \
-               ${SH_LIBSRC}/zmapfd.c ${SH_LIBSRC}/fpurge.c \
-               ${SH_LIBSRC}/zgetline.c ${SH_LIBSRC}/mbscmp.c \
-               ${SH_LIBSRC}/casemod.c ${SH_LIBSRC}/uconvert.c \
-               ${SH_LIBSRC}/ufuncs.c ${SH_LIBSRC}/fdprintf.c \
-               ${SH_LIBSRC}/input_avail.c ${SH_LIBSRC}/mbscasecmp.c \
-               ${SH_LIBSRC}/fnxform.c
-
-SHLIB_LIB = -lsh
-SHLIB_LIBNAME = libsh.a
-SHLIB_LIBRARY = ${SH_LIBDIR}/${SHLIB_LIBNAME}
-SHLIB_LDFLAGS = -L${SH_LIBDIR}
-SHLIB_DEP = ${SHLIB_LIBRARY}
-
-# we assume for now that readline source is being shipped with bash
-RL_LIBSRC = $(LIBSRC)/readline
-RL_LIBDOC = $(RL_LIBSRC)/doc
-RL_LIBDIR = @RL_LIBDIR@
-RL_ABSSRC = ${topdir}/$(RL_LIBDIR)
-
-RL_INCLUDEDIR = @RL_INCLUDEDIR@
-
-READLINE_LIB = @READLINE_LIB@
-READLINE_LIBRARY = $(RL_LIBDIR)/libreadline.a
-READLINE_LDFLAGS = -L${RL_LIBDIR}
-READLINE_DEP = @READLINE_DEP@
-
-# The source, object and documentation of the GNU Readline library.
-READLINE_SOURCE        = $(RL_LIBSRC)/rldefs.h $(RL_LIBSRC)/rlconf.h \
-                 $(RL_LIBSRC)/readline.h $(RL_LIBSRC)/tcap.h \
-                 $(RL_LIBSRC)/chardefs.h $(RL_LIBSRC)/keymaps.h \
-                 $(RL_LIBSRC)/history.h $(RL_LIBSRC)/histlib.h \
-                 $(RL_LIBSRC)/posixstat.h $(RL_LIBSRC)/tilde.h \
-                 $(RL_LIBSRC)/rlstdc.h ${RL_LIBSRC}/xmalloc.h \
-                 $(RL_LIBSRC)/rlshell.h ${RL_LIBSRC}/rlprivate.h \
-                 $(RL_LIBSRC)/funmap.c $(RL_LIBSRC)/emacs_keymap.c \
-                 $(RL_LIBSRC)/search.c $(RL_LIBSRC)/vi_keymap.c \
-                 $(RL_LIBSRC)/keymaps.c $(RL_LIBSRC)/parens.c \
-                 $(RL_LIBSRC)/vi_mode.c $(RL_LIBSRC)/callback.c \
-                 $(RL_LIBSRC)/readline.c $(RL_LIBSRC)/tilde.c \
-                 $(RL_LIBSRC)/rltty.c $(RL_LIBSRC)/complete.c \
-                 $(RL_LIBSRC)/bind.c $(RL_LIBSRC)/isearch.c \
-                 $(RL_LIBSRC)/display.c $(RL_LIBSRC)/signals.c \
-                 $(RL_LIBSRC)/util.c $(RL_LIBSRC)/kill.c $(RL_LIBSRC)/text.c \
-                 $(RL_LIBSRC)/undo.c $(RL_LIBSRC)/macro.c \
-                 $(RL_LIBSRC)/terminal.c $(RL_LIBSRC)/nls.c \
-                 $(RL_LIBSRC)/input.c $(RL_LIBSRC)/xmalloc.c \
-                 $(RL_LIBSRC)/shell.c $(RL_LIBSRC)/savestring.c \
-                 $(RL_LIBSRC)/misc.c $(RL_LIBSRC)/mbutil.c $(RL_LIBSRC)/compat.c \
-                 $(RL_LIBSRC)/histexpand.c $(RL_LIBSRC)/history.c \
-                 $(RL_LIBSRC)/histsearch.c $(RL_LIBSRC)/histfile.c
-
-READLINE_OBJ   = $(RL_LIBDIR)/readline.o $(RL_LIBDIR)/funmap.o \
-                 $(RL_LIBDIR)/parens.o $(RL_LIBDIR)/search.o \
-                 $(RL_LIBDIR)/keymaps.o $(RL_LIBDIR)/xmalloc.o \
-                 $(RL_LIBDIR)/rltty.o $(RL_LIBDIR)/complete.o \
-                 $(RL_LIBDIR)/bind.o $(RL_LIBDIR)/isearch.o \
-                 $(RL_LIBDIR)/display.o $(RL_LIBDIR)/signals.o \
-                 $(RL_LIBDIR)/tilde.o $(RL_LIBDIR)/util.o \
-                 $(RL_LIBDIR)/kill.o $(RL_LIBDIR)/undo.o $(RL_LIBDIR)/nls.o \
-                 $(RL_LIBDIR)/macro.o $(RL_LIBDIR)/input.o \
-                 $(RL_LIBDIR)/terminal.o $(RL_LIBDIR)/callback.o \
-                 $(RL_LIBDIR)/shell.o $(RL_LIBDIR)/savestring.o \
-                 $(RL_LIBDIR)/mbutil.o $(RL_LIBDIR)/compat.o \
-                 $(RL_LIBDIR)/history.o $(RL_LIBDIR)/histexpand.o \
-                 $(RL_LIBDIR)/histsearch.o $(RL_LIBDIR)/histfile.o
-
-HIST_LIBSRC = $(LIBSRC)/readline
-HIST_LIBDIR = @HIST_LIBDIR@
-HIST_ABSSRC = ${topdir}/$(HIST_LIBDIR)
-
-HISTORY_LIB = @HISTORY_LIB@
-HISTORY_LIBRARY = $(HIST_LIBDIR)/libhistory.a
-HISTORY_LDFLAGS = -L$(HIST_LIBDIR)
-HISTORY_DEP = @HISTORY_DEP@
-
-# The source, object and documentation of the history library.
-HISTORY_SOURCE = $(HIST_LIBSRC)/history.c $(HIST_LIBSRC)/histexpand.c \
-                 $(HIST_LIBSRC)/histsearch.c $(HIST_LIBSRC)/histfile.c \
-                 $(HIST_LIBSRC)/shell.c \
-                 $(HIST_LIBSRC)/history.h $(HIST_LIBSRC)/histlib.h
-HISTORY_OBJ    = $(HIST_LIBDIR)/history.o $(HIST_LIBDIR)/histexpand.o \
-                 $(HIST_LIBDIR)/histsearch.o $(HIST_LIBDIR)/histfile.o \
-                 $(HIST_LIBDIR)/shell.o
-
-# You only need termcap (or curses) if you are linking with GNU Readline.
-TERM_LIBSRC = $(LIBSRC)/termcap
-TERM_LIBDIR = $(dot)/$(LIBSUBDIR)/termcap
-TERM_ABSSRC = ${topdir}/$(TERM_LIBDIR)
-
-TERMCAP_LIB = @TERMCAP_LIB@
-TERMCAP_LIBRARY = $(TERM_LIBDIR)/libtermcap.a
-TERMCAP_LDFLAGS = -L$(TERM_LIBDIR)
-TERMCAP_DEP = @TERMCAP_DEP@
-
-TERMCAP_SOURCE = $(TERM_LIBSRC)/termcap.c $(TERM_LIBSRC)/tparam.c
-TERMCAP_OBJ    = $(TERM_LIBDIR)/termcap.o $(TERM_LIBDIR)/tparam.o
-
-GLOB_LIBSRC = $(LIBSRC)/glob
-GLOB_LIBDIR = $(dot)/$(LIBSUBDIR)/glob
-GLOB_ABSSRC = ${topdir}/$(GLOB_LIBDIR)
-
-GLOB_LIB     = -lglob
-GLOB_LIBRARY = $(GLOB_LIBDIR)/libglob.a
-GLOB_LDFLAGS = -L$(GLOB_LIBDIR)
-GLOB_DEP = $(GLOB_LIBRARY)
-
-GLOB_SOURCE = $(GLOB_LIBSRC)/glob.c $(GLOB_LIBSRC)/strmatch.c \
-             $(GLOB_LIBSRC)/smatch.c $(GLOB_LIBSRC)/xmbsrtowcs.c \
-             $(GLOB_LIBSRC)/glob_loop.c $(GLOB_LIBSRC)/sm_loop.c \
-             $(GLOB_LIBSRC)/glob.h $(GLOB_LIBSRC)/strmatch.h
-GLOB_OBJ    = $(GLOB_LIBDIR)/glob.o $(GLOB_LIBDIR)/strmatch.o \
-             $(GLOB_LIBDIR)/smatch.o $(GLOB_LIBDIR)/xmbsrtowcs.o
-
-# The source, object and documentation for the GNU Tilde library.
-TILDE_LIBSRC = $(LIBSRC)/tilde
-TILDE_LIBDIR = $(dot)/$(LIBSUBDIR)/tilde
-TILDE_ABSSRC = ${topdir}/$(TILDE_LIBDIR)
-
-TILDE_LIB = @TILDE_LIB@
-TILDE_LIBRARY = $(TILDE_LIBDIR)/libtilde.a
-TILDE_LDFLAGS = -L$(TILDE_LIBDIR)
-TILDE_DEP = $(TILDE_LIBRARY)
-
-TILDE_SOURCE   = $(TILDE_LIBSRC)/tilde.c $(TILDE_LIBSRC)/tilde.h
-TILDE_OBJ      = $(TILDE_LIBDIR)/tilde.o
-
-# libintl
-INTL_LIBSRC = $(LIBSRC)/intl
-INTL_LIBDIR = $(dot)/$(LIBSUBDIR)/intl
-INTL_ABSSRC = ${topdir}/$(INTL_LIB)
-INTL_BUILDDIR = ${LIBBUILD}/intl
-
-INTL_LIB     = @LIBINTL@
-INTL_LIBRARY = $(INTL_LIBDIR)/libintl.a
-INTL_DEP = @INTL_DEP@
-INTL_INC = @INTL_INC@
-
-LIBINTL_H = @LIBINTL_H@
-
-# tests
-LIBINTL = @LIBINTL@
-LTLIBINTL = @LTLIBINTL@
-INTLLIBS = @INTLLIBS@
-INTLOBJS = @INTLOBJS@
-
-# Our malloc.
-MALLOC_TARGET = @MALLOC_TARGET@
-
-# set to alloca.o if we are using the C alloca in lib/malloc
-ALLOCA = @ALLOCA@
-
-ALLOC_LIBSRC = $(LIBSRC)/malloc
-ALLOC_LIBDIR = $(dot)/$(LIBSUBDIR)/malloc
-ALLOC_ABSSRC = ${topdir}/$(ALLOC_LIBDIR)
-
-MALLOC_SRC = @MALLOC_SRC@
-MALLOC_OTHERSRC = ${ALLOC_LIBSRC}/trace.c ${ALLOC_LIBSRC}/stats.c \
-                 ${ALLOC_LIBSRC}/table.c ${ALLOC_LIBSRC}/watch.c
-MALLOC_SOURCE = ${ALLOC_LIBSRC}/${MALLOC_SRC} ${MALLOC_OTHERSRC}
-MALLOC_CFLAGS = -DRCHECK -Dbotch=programming_error ${MALLOC_DEBUG}
-
-MALLOC_LIB     = @MALLOC_LIB@
-MALLOC_LIBRARY = @MALLOC_LIBRARY@
-MALLOC_LDFLAGS = @MALLOC_LDFLAGS@
-MALLOC_DEP = @MALLOC_DEP@
-
-ALLOC_HEADERS = $(ALLOC_LIBSRC)/getpagesize.h $(ALLOC_LIBSRC)/shmalloc.h \
-               $(ALLOC_LIBSRC)/imalloc.h $(ALLOC_LIBSRC)/mstats.h \
-               $(ALLOC_LIBSRC)/table.h $(ALLOC_LIBSRC)/watch.h
-
-$(MALLOC_LIBRARY):     ${MALLOC_SOURCE} ${ALLOC_HEADERS} config.h
-               @(cd $(ALLOC_LIBDIR) && \
-                $(MAKE) $(MFLAGS) \
-                MALLOC_CFLAGS="$(MALLOC_CFLAGS)" ${MALLOC_TARGET} ) || exit 1
-
-BASHINCDIR = ${srcdir}/include
-BASHINCFILES =  $(BASHINCDIR)/posixstat.h $(BASHINCDIR)/ansi_stdlib.h \
-                $(BASHINCDIR)/filecntl.h $(BASHINCDIR)/posixdir.h \
-                $(BASHINCDIR)/memalloc.h $(BASHINCDIR)/stdc.h \
-                $(BASHINCDIR)/posixjmp.h $(BASHINCDIR)/posixwait.h \
-                $(BASHINCDIR)/posixtime.h $(BASHINCDIR)/systimes.h \
-                $(BASHINCDIR)/unionwait.h $(BASHINCDIR)/maxpath.h \
-                $(BASHINCDIR)/shtty.h $(BASHINCDIR)/typemax.h \
-                $(BASHINCDIR)/ocache.h
-
-LIBRARIES = $(SHLIB_LIB) $(READLINE_LIB) $(HISTORY_LIB) $(TERMCAP_LIB) $(GLOB_LIB) \
-           $(TILDE_LIB) $(MALLOC_LIB) $(INTL_LIB) $(LOCAL_LIBS)
-
-LIBDEP = $(SHLIB_DEP) $(INTL_DEP) $(READLINE_DEP) $(HISTORY_DEP) $(TERMCAP_DEP) $(GLOB_DEP) \
-        $(TILDE_DEP) $(MALLOC_DEP)
-
-LIBRARY_LDFLAGS = $(READLINE_LDFLAGS) $(HISTORY_LDFLAGS) $(GLOB_LDFLAGS) \
-                 $(TILDE_LDFLAGS) $(MALLOC_LDFLAGS) $(SHLIB_LDFLAGS)
-
-#
-# The shell itself
-#
-
-# The main source code for the Bourne Again SHell.
-CSOURCES = shell.c eval.c parse.y general.c make_cmd.c print_cmd.c y.tab.c \
-          dispose_cmd.c execute_cmd.c variables.c $(GLOBC) version.c \
-          expr.c copy_cmd.c flags.c subst.c hashcmd.c hashlib.c mailcheck.c \
-          test.c trap.c alias.c jobs.c nojobs.c $(ALLOC_FILES) braces.c \
-          input.c bashhist.c array.c arrayfunc.c assoc.c sig.c pathexp.c \
-          unwind_prot.c siglist.c bashline.c bracecomp.c error.c \
-          list.c stringlib.c locale.c findcmd.c redir.c \
-          pcomplete.c pcomplib.c syntax.c xmalloc.c
-
-HSOURCES = shell.h flags.h trap.h hashcmd.h hashlib.h jobs.h builtins.h \
-          general.h variables.h config.h $(ALLOC_HEADERS) alias.h \
-          quit.h unwind_prot.h syntax.h ${GRAM_H} \
-          command.h input.h error.h bashansi.h dispose_cmd.h make_cmd.h \
-          subst.h externs.h siglist.h bashhist.h bashline.h bashtypes.h \
-          array.h arrayfunc.h sig.h mailcheck.h bashintl.h bashjmp.h \
-          execute_cmd.h parser.h pathexp.h pathnames.h pcomplete.h assoc.h \
-          $(BASHINCFILES)
-
-SOURCES         = $(CSOURCES) $(HSOURCES) $(BUILTIN_DEFS)
-
-# header files chosen based on running of configure
-SIGNAMES_H = @SIGNAMES_H@
-
-# object files chosen based on running of configure
-JOBS_O = @JOBS_O@
-SIGLIST_O = @SIGLIST_O@
-SIGNAMES_O = @SIGNAMES_O@
-
-# Matching object files.
-OBJECTS         = shell.o eval.o y.tab.o general.o make_cmd.o print_cmd.o $(GLOBO) \
-          dispose_cmd.o execute_cmd.o variables.o copy_cmd.o error.o \
-          expr.o flags.o $(JOBS_O) subst.o hashcmd.o hashlib.o mailcheck.o \
-          trap.o input.o unwind_prot.o pathexp.o sig.o test.o version.o \
-          alias.o array.o arrayfunc.o assoc.o braces.o bracecomp.o bashhist.o \
-          bashline.o $(SIGLIST_O) list.o stringlib.o locale.o findcmd.o redir.o \
-          pcomplete.o pcomplib.o syntax.o xmalloc.o $(SIGNAMES_O)
-
-# Where the source code of the shell builtins resides.
-BUILTIN_SRCDIR=$(srcdir)/builtins
-DEFSRC=$(BUILTIN_SRCDIR)
-BUILTIN_ABSSRC=${topdir}/builtins
-DEFDIR = $(dot)/builtins
-DEBUGGER_DIR = $(dot)/debugger
-
-BUILTIN_DEFS = $(DEFSRC)/alias.def $(DEFSRC)/bind.def $(DEFSRC)/break.def \
-              $(DEFSRC)/builtin.def $(DEFSRC)/cd.def $(DEFSRC)/colon.def \
-              $(DEFSRC)/command.def ${DEFSRC}/complete.def \
-              $(DEFSRC)/caller.def $(DEFSRC)/declare.def \
-              $(DEFSRC)/echo.def $(DEFSRC)/enable.def $(DEFSRC)/eval.def \
-              $(DEFSRC)/exec.def $(DEFSRC)/exit.def $(DEFSRC)/fc.def \
-              $(DEFSRC)/fg_bg.def $(DEFSRC)/hash.def $(DEFSRC)/help.def \
-              $(DEFSRC)/history.def $(DEFSRC)/jobs.def $(DEFSRC)/kill.def \
-              $(DEFSRC)/let.def $(DEFSRC)/read.def $(DEFSRC)/return.def \
-              $(DEFSRC)/set.def $(DEFSRC)/setattr.def $(DEFSRC)/shift.def \
-              $(DEFSRC)/source.def $(DEFSRC)/suspend.def $(DEFSRC)/test.def \
-              $(DEFSRC)/times.def $(DEFSRC)/trap.def $(DEFSRC)/type.def \
-              $(DEFSRC)/ulimit.def $(DEFSRC)/umask.def $(DEFSRC)/wait.def \
-              $(DEFSRC)/getopts.def $(DEFSRC)/reserved.def \
-              $(DEFSRC)/pushd.def $(DEFSRC)/shopt.def $(DEFSRC)/printf.def \
-              $(DEFSRC)/mapfile.def
-BUILTIN_C_SRC  = $(DEFSRC)/mkbuiltins.c $(DEFSRC)/common.c \
-                $(DEFSRC)/evalstring.c $(DEFSRC)/evalfile.c \
-                $(DEFSRC)/bashgetopt.c $(GETOPT_SOURCE)
-BUILTIN_C_OBJ  = $(DEFDIR)/common.o $(DEFDIR)/evalstring.o \
-                $(DEFDIR)/evalfile.o $(DEFDIR)/bashgetopt.o
-BUILTIN_OBJS = $(DEFDIR)/alias.o $(DEFDIR)/bind.o $(DEFDIR)/break.o \
-              $(DEFDIR)/builtin.o $(DEFDIR)/cd.o $(DEFDIR)/colon.o \
-              $(DEFDIR)/command.o $(DEFDIR)/caller.o $(DEFDIR)/declare.o \
-              $(DEFDIR)/echo.o $(DEFDIR)/enable.o $(DEFDIR)/eval.o \
-              $(DEFDIR)/exec.o $(DEFDIR)/exit.o $(DEFDIR)/fc.o \
-              $(DEFDIR)/fg_bg.o $(DEFDIR)/hash.o $(DEFDIR)/help.o \
-              $(DEFDIR)/history.o $(DEFDIR)/jobs.o $(DEFDIR)/kill.o \
-              $(DEFDIR)/let.o $(DEFDIR)/pushd.o $(DEFDIR)/read.o \
-              $(DEFDIR)/return.o $(DEFDIR)/shopt.o $(DEFDIR)/printf.o \
-              $(DEFDIR)/set.o $(DEFDIR)/setattr.o $(DEFDIR)/shift.o \
-              $(DEFDIR)/source.o $(DEFDIR)/suspend.o $(DEFDIR)/test.o \
-              $(DEFDIR)/times.o $(DEFDIR)/trap.o $(DEFDIR)/type.o \
-              $(DEFDIR)/ulimit.o $(DEFDIR)/umask.o $(DEFDIR)/wait.o \
-              $(DEFDIR)/getopts.o $(DEFDIR)/mapfile.o $(BUILTIN_C_OBJ)
-GETOPT_SOURCE   = $(DEFSRC)/getopt.c $(DEFSRC)/getopt.h
-PSIZE_SOURCE   = $(DEFSRC)/psize.sh $(DEFSRC)/psize.c
-
-BUILTINS_LIBRARY = $(DEFDIR)/libbuiltins.a
-BUILTINS_LIB = -lbuiltins
-BUILTINS_LDFLAGS = -L$(DEFDIR)
-BUILTINS_DEP = $(BUILTINS_LIBRARY)
-
-# Documentation for the shell.
-DOCSRC = $(srcdir)/doc
-DOCDIR = $(dot)/doc
-
-# Translations and other i18n support files
-PO_SRC = $(srcdir)/po/
-PO_DIR = $(dot)/po/
-
-SIGNAMES_SUPPORT = $(SUPPORT_SRC)mksignames.c
-
-SUPPORT_SRC = $(srcdir)/support/
-SDIR = $(dot)/support/
-
-TESTS_SUPPORT = recho$(EXEEXT) zecho$(EXEEXT) printenv$(EXEEXT) xcase$(EXEEXT)
-CREATED_SUPPORT = signames.h recho$(EXEEXT) zecho$(EXEEXT) printenv$(EXEEXT) \
-                 tests/recho$(EXEEXT) tests/zecho$(EXEEXT) \
-                 tests/printenv$(EXEEXT) xcase$(EXEEXT) tests/xcase$(EXEEXT) \
-                 mksignames$(EXEEXT) lsignames.h \
-                 mksyntax${EXEEXT} syntax.c $(VERSPROG) $(VERSOBJ) \
-                 buildversion.o mksignames.o signames.o buildsignames.o
-CREATED_CONFIGURE = config.h config.cache config.status config.log \
-                   stamp-h po/POTFILES
-CREATED_MAKEFILES = Makefile builtins/Makefile doc/Makefile \
-                   lib/readline/Makefile lib/glob/Makefile \
-                   lib/sh/Makefile lib/tilde/Makefile lib/malloc/Makefile \
-                   lib/termcap/Makefile examples/loadables/Makefile \
-                   examples/loadables/perl/Makefile support/Makefile \
-                   lib/intl/Makefile po/Makefile po/Makefile.in
-
-# Keep GNU Make from exporting the entire environment for small machines.
-.NOEXPORT:
-
-.made: $(Program) bashbug
-       @echo "$(Program) last made for a $(Machine) running $(OS)" >.made
-
-$(Program):  .build $(OBJECTS) $(BUILTINS_DEP) $(LIBDEP)
-       $(RM) $@
-       $(PURIFY) $(CC) $(BUILTINS_LDFLAGS) $(LIBRARY_LDFLAGS) $(LDFLAGS) -o $(Program) $(OBJECTS) $(LIBS)
-       ls -l $(Program)
-       -$(SIZE) $(Program)
-
-.build:        $(SOURCES) config.h Makefile version.h $(VERSPROG)
-       @echo
-       @echo "   ***********************************************************"
-       @echo "   *                                                         *"
-       @echo "   * `$(BUILD_DIR)/$(VERSPROG) -l`"
-       @echo "   *                                                         *"
-       @echo "   ***********************************************************"
-       @echo
-
-bashbug: $(SUPPORT_SRC)bashbug.sh config.h Makefile $(VERSPROG)
-       @sed -e "s%!MACHINE!%$(Machine)%" -e "s%!OS!%$(OS)%" \
-            -e "s%!CFLAGS!%$(CCFLAGS)%" -e "s%!CC!%$(CC)%" \
-            -e "s%!RELEASE!%$(Version)%" -e "s%!PATCHLEVEL!%$(PatchLevel)%" \
-            -e "s%!MACHTYPE!%$(MACHTYPE)%" -e "s%!RELSTATUS!%$(RELSTATUS)%" \
-            $(SUPPORT_SRC)bashbug.sh > $@
-       @chmod a+rx bashbug
-
-strip: $(Program) .made
-       strip $(Program)
-       ls -l $(Program)
-       -$(SIZE) $(Program)
-
-lint:
-       ${MAKE} ${MFLAGS} CFLAGS='${GCC_LINT_FLAGS}' .made
-
-version.h:  $(SOURCES) config.h Makefile 
-       $(SHELL) $(SUPPORT_SRC)mkversion.sh -b -S ${topdir} -s $(RELSTATUS) -d $(Version) -o newversion.h \
-               && mv newversion.h version.h
-
-bashversion$(EXEEXT):  patchlevel.h conftypes.h version.h buildversion.o $(SUPPORT_SRC)bashversion.c
-       $(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ $(SUPPORT_SRC)bashversion.c buildversion.o ${LIBS_FOR_BUILD}
-
-buildversion.o: version.h conftypes.h patchlevel.h $(srcdir)/version.c
-       $(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -DBUILDTOOL -c -o $@ $(srcdir)/version.c
-
-# old rules
-GRAM_H = parser-built
-y.tab.o: y.tab.c ${GRAM_H} command.h ${BASHINCDIR}/stdc.h input.h
-${GRAM_H}:     y.tab.h
-       @-if test -f y.tab.h ; then \
-               cmp -s $@ y.tab.h 2>/dev/null || cp -p y.tab.h $@; \
-       fi
-y.tab.c y.tab.h: parse.y
-#      -if test -f y.tab.h; then mv -f y.tab.h old-y.tab.h; fi
-       $(YACC) -d $(srcdir)/parse.y
-       touch parser-built
-#      -if cmp -s old-y.tab.h y.tab.h; then mv old-y.tab.h y.tab.h; else cp -p y.tab.h ${GRAM_H}; fi
-
-# experimental new rules - work with GNU make but not BSD (or OSF) make
-#y.tab.o: y.tab.c y.tab.h
-#y.tab.c y.tab.h: parse.y command.h ${BASHINCDIR}/stdc.h input.h
-#      -if test -f y.tab.h; then mv -f y.tab.h old-y.tab.h; fi
-#      $(YACC) -d $(srcdir)/parse.y
-#      -if cmp -s old-y.tab.h y.tab.h; then mv old-y.tab.h y.tab.h; fi
-
-$(READLINE_LIBRARY): config.h $(READLINE_SOURCE)
-       @echo making $@ in ${RL_LIBDIR}
-       @( { test "${RL_LIBDIR}" = "${libdir}" && exit 0; } || \
-               cd ${RL_LIBDIR} && $(MAKE) $(MFLAGS) libreadline.a) || exit 1
-
-$(HISTORY_LIBRARY): config.h $(HISTORY_SOURCE) $(READLINE_DEP)
-       @echo making $@ in ${HIST_LIBDIR}
-       @( { test "${HIST_LIBDIR}" = "${libdir}" && exit 0; } || \
-               cd ${HIST_LIBDIR} && $(MAKE) $(MFLAGS) libhistory.a) || exit 1
-
-$(GLOB_LIBRARY): config.h $(GLOB_SOURCE)
-       @echo making $@ in ${GLOB_LIBDIR}
-       @(cd ${GLOB_LIBDIR} && \
-               $(MAKE) $(MFLAGS) DEBUG=${DEBUG} libglob.a) || exit 1
-
-$(TILDE_LIBRARY): config.h $(TILDE_SOURCE)
-       @echo making $@ in ${TILDE_LIBDIR}
-       @(cd ${TILDE_LIBDIR} && \
-               $(MAKE) $(MFLAGS) libtilde.a) || exit 1
-
-$(TERMCAP_LIBRARY): config.h ${TERMCAP_SOURCE}
-       @echo making $@ in ${TERM_LIBDIR}       
-       @(cd ${TERM_LIBDIR} && \
-               $(MAKE) $(MFLAGS) libtermcap.a) || exit 1
-
-$(SHLIB_LIBRARY): config.h ${SHLIB_SOURCE}
-       @echo making $@ in ${SH_LIBDIR}
-       @(cd ${SH_LIBDIR} && \
-               $(MAKE) $(MFLAGS) DEBUG=${DEBUG} ${SHLIB_LIBNAME}) || exit 1
-
-${INTL_LIBRARY}: config.h ${INTL_LIBDIR}/Makefile
-       @echo making $@ in ${INTL_LIBDIR}
-       @(cd ${INTL_LIBDIR} && \
-               $(MAKE) $(MFLAGS) all) || exit 1
-
-${LIBINTL_H}:  ${INTL_DEP}
-
-signames.o: $(SUPPORT_SRC)signames.c
-       $(RM) $@
-       $(CC) $(CCFLAGS) -c $(SUPPORT_SRC)signames.c
-
-buildsignames.o:       $(SUPPORT_SRC)signames.c
-       $(RM) $@
-       $(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -DBUILDTOOL -o $@ -c $(SUPPORT_SRC)signames.c
-
-mksignames.o:  $(SUPPORT_SRC)mksignames.c
-       $(RM) $@
-       $(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -DBUILDTOOL -c $(SUPPORT_SRC)mksignames.c
-
-mksignames$(EXEEXT):   mksignames.o buildsignames.o
-       $(RM) $@
-       $(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ mksignames.o buildsignames.o ${LIBS_FOR_BUILD}
-
-mksyntax$(EXEEXT):     ${srcdir}/mksyntax.c config.h syntax.h ${BASHINCDIR}/chartypes.h
-       $(RM) $@
-       ${CC_FOR_BUILD} ${CCFLAGS_FOR_BUILD} -o $@ ${srcdir}/mksyntax.c ${LIBS_FOR_BUILD}
-
-# make a list of signals for the local system -- this is done when we're
-# *not* cross-compiling
-lsignames.h:   mksignames$(EXEEXT)
-       $(RM) $@
-       ./mksignames$(EXEEXT) $@
-
-# copy the correct signames header file to signames.h
-signames.h: $(SIGNAMES_H)
-       -if cmp -s $(SIGNAMES_H) $@ ; then :; else $(RM) $@ ; $(CP) $(SIGNAMES_H) $@ ; fi
-
-syntax.c:      mksyntax${EXEEXT} $(srcdir)/syntax.h 
-       $(RM) $@
-       ./mksyntax$(EXEEXT) -o $@
-
-$(BUILTINS_LIBRARY): $(BUILTIN_DEFS) $(BUILTIN_C_SRC) config.h ${BASHINCDIR}/memalloc.h version.h
-       @(cd $(DEFDIR) && $(MAKE) $(MFLAGS) DEBUG=${DEBUG} libbuiltins.a ) || exit 1
-
-# these require special rules to circumvent make builtin rules
-${DEFDIR}/common.o:    $(BUILTIN_SRCDIR)/common.c
-       @(cd $(DEFDIR) && $(MAKE) $(MFLAGS) DEBUG=${DEBUG} common.o) || exit 1
-
-${DEFDIR}/bashgetopt.o:        $(BUILTIN_SRCDIR)/bashgetopt.c
-       @(cd $(DEFDIR) && $(MAKE) $(MFLAGS) DEBUG=${DEBUG} bashgetopt.o) || exit 1
-
-${DEFDIR}/builtext.h: $(BUILTIN_DEFS)
-       @(cd $(DEFDIR) && $(MAKE) $(MFLAGS) builtext.h ) || exit 1
-
-# For the justification of the following Makefile rules, see node
-# `Automatic Remaking' in GNU Autoconf documentation.
-
-Makefile makefile:     config.status $(srcdir)/Makefile.in
-       CONFIG_FILES=Makefile CONFIG_HEADERS= $(SHELL) ./config.status
-
-Makefiles makefiles:   config.status $(srcdir)/Makefile.in
-       @for mf in $(CREATED_MAKEFILES); do \
-               CONFIG_FILES=$$mf CONFIG_HEADERS= $(SHELL) ./config.status ; \
-       done
-
-config.h:      stamp-h 
-
-stamp-h:       config.status $(srcdir)/config.h.in $(srcdir)/config-top.h $(srcdir)/config-bot.h
-       CONFIG_FILES= CONFIG_HEADERS=config.h $(SHELL) ./config.status
-
-config.status: $(srcdir)/configure
-       $(SHELL) ./config.status --recheck
-
-pathnames.h:           Makefile $(srcdir)/pathnames.h.in
-       @sed -e 's|@DEBUGGER_START_FILE\@|${DEBUGGER_START_FILE}|g' $(srcdir)/pathnames.h.in > pathnames.tmp
-       @if test -f $@; then \
-               cmp -s pathnames.tmp $@ || mv pathnames.tmp $@; \
-       else \
-               mv pathnames.tmp $@; \
-       fi
-       @${RM} pathnames.tmp
-
-# comment out for distribution
-$(srcdir)/configure:   $(srcdir)/configure.in $(srcdir)/aclocal.m4 $(srcdir)/config.h.in
-       cd $(srcdir) && autoconf
-
-# for chet
-reconfig: force
-       sh $(srcdir)/configure -C
-
-#newversion:   mkversion
-#      $(RM) .build
-#      ./mkversion -dir $(srcdir) -dist
-#      mv -f newversion.h version.h
-#      $(MAKE) -f $(srcdir)/Makefile $(MFLAGS) srcdir=$(srcdir)
-
-doc documentation:  force
-       @(cd $(DOCDIR) ; $(MAKE) $(MFLAGS) )
-
-info dvi ps: force
-       @(cd $(DOCDIR) ; $(MAKE) $(MFLAGS) CFLAGS='$(CCFLAGS)' $@ )
-
-force:
-
-TAGS:  $(SOURCES) $(BUILTIN_C_SRC) $(LIBRARY_SOURCE)
-       etags $(SOURCES) $(BUILTIN_C_SRC) $(LIBRARY_SOURCE)
-
-tags:  $(SOURCES) $(BUILTIN_C_SRC) $(LIBRARY_SOURCE)
-       ctags -x $(SOURCES) $(BUILTIN_C_SRC) $(LIBRARY_SOURCE) > $@
-
-# Targets that actually do things not part of the build
-
-installdirs:
-       @${SHELL} $(SUPPORT_SRC)mkinstalldirs $(DESTDIR)$(bindir)
-       @${SHELL} $(SUPPORT_SRC)mkinstalldirs $(DESTDIR)$(man1dir)
-       @${SHELL} $(SUPPORT_SRC)mkinstalldirs $(DESTDIR)$(infodir)
-       -( cd $(PO_DIR) ; $(MAKE) $(MFLAGS) DESTDIR=$(DESTDIR) $@ )
-
-install:       .made installdirs
-       $(INSTALL_PROGRAM) $(INSTALLMODE) $(Program) $(DESTDIR)$(bindir)/$(Program)
-       $(INSTALL_SCRIPT) $(INSTALLMODE2) bashbug $(DESTDIR)$(bindir)/bashbug
-       -( cd $(DOCDIR) ; $(MAKE) $(MFLAGS) \
-               man1dir=$(man1dir) man1ext=$(man1ext) \
-               man3dir=$(man3dir) man3ext=$(man3ext) \
-               infodir=$(infodir) htmldir=$(htmldir) DESTDIR=$(DESTDIR) $@ )
-       -( cd $(DEFDIR) ; $(MAKE) $(MFLAGS) DESTDIR=$(DESTDIR) $@ )
-       -( cd $(PO_DIR) ; $(MAKE) $(MFLAGS) DESTDIR=$(DESTDIR) $@ )
-
-install-strip:
-       $(MAKE) $(MFLAGS) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' \
-               prefix=${prefix} exec_prefix=${exec_prefix} \
-               DESTDIR=$(DESTDIR) install
-
-uninstall:     .made
-       $(RM) $(DESTDIR)$(bindir)/$(Program) $(DESTDIR)$(bindir)/bashbug
-       -( cd $(DOCDIR) ; $(MAKE) $(MFLAGS) \
-               man1dir=$(man1dir) man1ext=$(man1ext) \
-               man3dir=$(man3dir) man3ext=$(man3ext) \
-               infodir=$(infodir) htmldir=$(htmldir) DESTDIR=$(DESTDIR) $@ )
-       -( cd $(PO_DIR) ; $(MAKE) $(MFLAGS) DESTDIR=$(DESTDIR) $@ )
-
-.PHONY: basic-clean clean realclean maintainer-clean distclean mostlyclean maybe-clean
-
-LIB_SUBDIRS = ${RL_LIBDIR}  ${HIST_LIBDIR} ${TERM_LIBDIR} ${GLOB_LIBDIR} \
-               ${INTL_LIBDIR} ${TILDE_LIBDIR} ${ALLOC_LIBDIR} ${SH_LIBDIR}
-
-basic-clean:
-       $(RM) $(OBJECTS) $(Program) bashbug
-       $(RM) .build .made version.h 
-
-clean: basic-clean
-       ( cd $(DOCDIR) && $(MAKE) $(MFLAGS) $@ )
-       ( cd builtins && $(MAKE) $(MFLAGS) $@ )
-       -( cd $(SDIR) && $(MAKE) $(MFLAGS) $@ )
-       -for libdir in ${LIB_SUBDIRS}; do \
-               (cd $$libdir && test -f Makefile && $(MAKE) $(MFLAGS) $@) ;\
-       done
-       -( cd $(PO_DIR) ; $(MAKE) $(MFLAGS) DESTDIR=$(DESTDIR) $@ )
-       $(RM) $(CREATED_SUPPORT)
-
-mostlyclean: basic-clean
-       ( cd $(DOCDIR) && $(MAKE) $(MFLAGS) $@ )
-       ( cd builtins && $(MAKE) $(MFLAGS) $@ )
-       -( cd $(SDIR) && $(MAKE) $(MFLAGS) $@ )
-       -for libdir in ${LIB_SUBDIRS}; do \
-               (cd $$libdir && test -f Makefile && $(MAKE) $(MFLAGS) $@) ;\
-       done
-       -( cd $(PO_DIR) ; $(MAKE) $(MFLAGS) DESTDIR=$(DESTDIR) $@ )
-
-distclean:     basic-clean maybe-clean
-       ( cd $(DOCDIR) && $(MAKE) $(MFLAGS) $@ )
-       ( cd builtins && $(MAKE) $(MFLAGS) $@ )
-       -( cd $(SDIR) && $(MAKE) $(MFLAGS) $@ )
-       -for libdir in ${LIB_SUBDIRS}; do \
-               (cd $$libdir && test -f Makefile && $(MAKE) $(MFLAGS) $@) ;\
-       done
-       -( cd $(PO_DIR) ; $(MAKE) $(MFLAGS) DESTDIR=$(DESTDIR) $@ )
-       $(RM) $(CREATED_CONFIGURE) tags TAGS 
-       $(RM) $(CREATED_SUPPORT) Makefile $(CREATED_MAKEFILES) pathnames.h
-
-maintainer-clean:      basic-clean
-       @echo This command is intended for maintainers to use.
-       @echo It deletes files that may require special tools to rebuild.
-       $(RM) y.tab.c y.tab.h parser-built tags TAGS
-       ( cd $(DOCDIR) && $(MAKE) $(MFLAGS) $@ )
-       ( cd builtins && $(MAKE) $(MFLAGS) $@ )
-       ( cd $(SDIR) && $(MAKE) $(MFLAGS) $@ )
-       -for libdir in ${LIB_SUBDIRS}; do \
-               (cd $$libdir && test -f Makefile && $(MAKE) $(MFLAGS) $@) ;\
-       done
-       -( cd $(PO_DIR) ; $(MAKE) $(MFLAGS) DESTDIR=$(DESTDIR) $@ )
-       $(RM) $(CREATED_CONFIGURE) $(CREATED_MAKEFILES)
-       $(RM) $(CREATED_SUPPORT) Makefile pathnames.h
-
-maybe-clean:
-       -if test "X$(topdir)" != "X$(BUILD_DIR)" ; then \
-               $(RM) parser-built y.tab.c y.tab.h ; \
-       fi
-
-recho$(EXEEXT):                $(SUPPORT_SRC)recho.c
-       @$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ $(SUPPORT_SRC)recho.c ${LIBS_FOR_BUILD}
-
-zecho$(EXEEXT):                $(SUPPORT_SRC)zecho.c
-       @$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ $(SUPPORT_SRC)zecho.c ${LIBS_FOR_BUILD}
-
-printenv$(EXEEXT):     $(SUPPORT_SRC)printenv.c
-       @$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ $(SUPPORT_SRC)printenv.c ${LIBS_FOR_BUILD}
-
-xcase$(EXEEXT):        $(SUPPORT_SRC)xcase.c
-       @$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ $(SUPPORT_SRC)xcase.c ${LIBS_FOR_BUILD}
-
-test tests check:      force $(Program) $(TESTS_SUPPORT)
-       @-test -d tests || mkdir tests
-       @cp $(TESTS_SUPPORT) tests
-       @( cd $(srcdir)/tests && \
-               PATH=$(BUILD_DIR)/tests:$$PATH THIS_SH=$(THIS_SH) $(SHELL) ${TESTSCRIPT} )
-
-symlinks:
-       $(SHELL) $(SUPPORT_SRC)fixlinks -s $(srcdir)
-
-dist:  force
-       @echo Bash distributions are created using $(srcdir)/support/mkdist.
-       @echo Here is a sample of the necessary commands:
-       @echo $(Program) $(srcdir)/support/mkdist -m $(srcdir)/MANIFEST -s $(srcdir) -r ${PACKAGE} $(PACKAGE_VERSION)
-       @echo tar cf $(PACKAGE)-${PACKAGE_VERSION}.tar ${PACKAGE}-$(PACKAGE_VERSION)
-       @echo gzip $(PACKAGE)-$(PACKAGE_VERSION).tar
-
-depend:        depends
-
-depends: force
-       $(Program) $(SUPPORT_SRC)mkdep -c ${CC} -- ${CCFLAGS} ${CSOURCES}
-
-#### PRIVATE TARGETS ####
-hashtest:      hashlib.c
-       $(CC) -DTEST_HASHING $(CCFLAGS) -o $@ $(srcdir)/hashlib.c
-
-############################ DEPENDENCIES ###############################
-
-# Files that depend on the definitions in config-top.h, which are not meant
-# to be changed
-shell.o: config-top.h
-input.o: config-top.h
-y.tab.o: config-top.h
-jobs.o: config-top.h
-nojobs.o: config-top.h
-execute_cmd.o: config-top.h
-variables.o: config-top.h
-builtins/command.o: config-top.h
-builtins/common.o: config-top.h
-builtins/break.o: config-top.h
-builtins/echo.o: config-top.h
-builtins/evalstring.o: config-top.h
-builtins/exit.o: config-top.h
-builtins/kill.o: config-top.h
-
-# shell basics
-copy_cmd.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-copy_cmd.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-copy_cmd.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-copy_cmd.o: make_cmd.h subst.h sig.h pathnames.h externs.h
-dispose_cmd.o: bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-dispose_cmd.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h
-dispose_cmd.o: error.h general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-dispose_cmd.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-dispose_cmd.o: make_cmd.h subst.h sig.h pathnames.h externs.h
-dispose_cmd.o: ${BASHINCDIR}/ocache.h
-error.o: config.h bashtypes.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h flags.h ${BASHINCDIR}/stdc.h error.h
-error.o: command.h general.h xmalloc.h externs.h input.h bashhist.h
-error.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-error.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-error.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-error.o: make_cmd.h subst.h sig.h pathnames.h externs.h
-error.o: input.h execute_cmd.h 
-eval.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h trap.h flags.h ${DEFSRC}/common.h
-eval.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-eval.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-eval.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-eval.o: make_cmd.h subst.h sig.h pathnames.h externs.h
-eval.o: input.h execute_cmd.h 
-execute_cmd.o: config.h bashtypes.h ${BASHINCDIR}/filecntl.h ${BASHINCDIR}/posixstat.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-execute_cmd.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-execute_cmd.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-execute_cmd.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-execute_cmd.o: make_cmd.h subst.h sig.h pathnames.h externs.h 
-execute_cmd.o: ${BASHINCDIR}/memalloc.h ${GRAM_H} flags.h builtins.h jobs.h quit.h siglist.h
-execute_cmd.o: execute_cmd.h findcmd.h redir.h trap.h test.h pathexp.h
-execute_cmd.o: $(DEFSRC)/common.h ${DEFDIR}/builtext.h ${GLOB_LIBSRC}/strmatch.h
-execute_cmd.o: ${BASHINCDIR}/posixtime.h ${BASHINCDIR}/chartypes.h
-expr.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h 
-expr.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-expr.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-expr.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-expr.o: make_cmd.h subst.h sig.h pathnames.h externs.h
-expr.o: ${BASHINCDIR}/chartypes.h
-findcmd.o: config.h bashtypes.h ${BASHINCDIR}/filecntl.h ${BASHINCDIR}/posixstat.h bashansi.h
-findcmd.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/memalloc.h shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h
-findcmd.o: ${BASHINCDIR}/stdc.h error.h general.h xmalloc.h variables.h arrayfunc.h conftypes.h quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h
-findcmd.o: dispose_cmd.h make_cmd.h subst.h sig.h pathnames.h externs.h
-findcmd.o: flags.h hashlib.h pathexp.h hashcmd.h 
-findcmd.o: ${BASHINCDIR}/chartypes.h
-flags.o: config.h flags.h 
-flags.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-flags.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-flags.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-flags.o: make_cmd.h subst.h sig.h pathnames.h externs.h bashhist.h
-general.o: config.h bashtypes.h ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-general.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-general.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-general.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-general.o: make_cmd.h subst.h sig.h pathnames.h externs.h 
-general.o: ${BASHINCDIR}/maxpath.h ${BASHINCDIR}/posixtime.h
-general.o: ${BASHINCDIR}/chartypes.h
-hashcmd.o: config.h ${BASHINCDIR}/posixstat.h bashtypes.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-hashcmd.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-hashcmd.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashcmd.h
-hashcmd.o: execute_cmd.h findcmd.h ${BASHINCDIR}/stdc.h pathnames.h hashlib.h
-hashlib.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-hashlib.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-hashlib.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-hashlib.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-hashlib.o: make_cmd.h subst.h sig.h pathnames.h externs.h 
-input.o: config.h bashtypes.h ${BASHINCDIR}/filecntl.h ${BASHINCDIR}/posixstat.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-input.o: command.h ${BASHINCDIR}/stdc.h general.h xmalloc.h input.h error.h externs.h
-input.o: quit.h
-list.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-list.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-list.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-list.o: make_cmd.h subst.h sig.h pathnames.h externs.h 
-locale.o: config.h bashtypes.h bashintl.h ${LIBINTL_H} bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-locale.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-locale.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-locale.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-locale.o: make_cmd.h subst.h sig.h pathnames.h externs.h 
-locale.o: ${BASHINCDIR}/chartypes.h
-mailcheck.o: config.h bashtypes.h ${BASHINCDIR}/posixstat.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-mailcheck.o: ${BASHINCDIR}/posixtime.h
-mailcheck.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-mailcheck.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-mailcheck.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-mailcheck.o: make_cmd.h subst.h sig.h pathnames.h externs.h
-mailcheck.o: execute_cmd.h mailcheck.h 
-make_cmd.o: config.h bashtypes.h ${BASHINCDIR}/filecntl.h bashansi.h
-make_cmd.o: command.h ${BASHINCDIR}/stdc.h general.h xmalloc.h error.h flags.h make_cmd.h
-make_cmd.o: variables.h arrayfunc.h conftypes.h array.h hashlib.h subst.h input.h externs.h
-make_cmd.o: jobs.h quit.h siglist.h syntax.h dispose_cmd.h
-make_cmd.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/ocache.h
-y.tab.o: config.h bashtypes.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/memalloc.h
-y.tab.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-y.tab.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-y.tab.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-y.tab.o: make_cmd.h subst.h sig.h pathnames.h externs.h test.h
-y.tab.o: trap.h flags.h parser.h input.h mailcheck.h $(DEFSRC)/common.h
-y.tab.o: $(DEFDIR)/builtext.h bashline.h bashhist.h jobs.h siglist.h alias.h
-pathexp.o: config.h bashtypes.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-pathexp.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-pathexp.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-pathexp.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-pathexp.o: make_cmd.h subst.h sig.h pathnames.h externs.h
-pathexp.o: pathexp.h flags.h 
-pathexp.o: $(GLOB_LIBSRC)/glob.h $(GLOB_LIBSRC)/strmatch.h
-pathexp.o: ${BASHINCDIR}/shmbutil.h
-print_cmd.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-print_cmd.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-print_cmd.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-print_cmd.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-print_cmd.o: make_cmd.h subst.h sig.h pathnames.h externs.h 
-print_cmd.o: ${GRAM_H} $(DEFSRC)/common.h
-redir.o: config.h bashtypes.h ${BASHINCDIR}/posixstat.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/filecntl.h
-redir.o: ${BASHINCDIR}/memalloc.h shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-redir.o: general.h xmalloc.h variables.h arrayfunc.h conftypes.h array.h hashlib.h quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h
-redir.o: dispose_cmd.h make_cmd.h subst.h sig.h pathnames.h externs.h 
-redir.o: flags.h execute_cmd.h redir.h input.h
-shell.o: config.h bashtypes.h ${BASHINCDIR}/posixstat.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/filecntl.h
-shell.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-shell.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-shell.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-shell.o: make_cmd.h subst.h sig.h pathnames.h externs.h 
-shell.o: flags.h trap.h mailcheck.h builtins.h $(DEFSRC)/common.h
-shell.o: jobs.h siglist.h input.h execute_cmd.h findcmd.h bashhist.h bashline.h
-shell.o: ${GLOB_LIBSRC}/strmatch.h ${BASHINCDIR}/posixtime.h
-sig.o: config.h bashtypes.h
-sig.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-sig.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-sig.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-sig.o: make_cmd.h subst.h sig.h pathnames.h externs.h 
-sig.o: jobs.h siglist.h trap.h $(DEFSRC)/common.h bashline.h bashhist.h
-siglist.o: config.h bashtypes.h siglist.h trap.h 
-stringlib.o: bashtypes.h ${BASHINCDIR}/chartypes.h
-stringlib.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-stringlib.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-stringlib.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-stringlib.o: make_cmd.h subst.h sig.h pathnames.h externs.h 
-stringlib.o: ${GLOB_LIBSRC}/glob.h ${GLOB_LIBSRC}/strmatch.h
-subst.o: config.h bashtypes.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/posixstat.h
-subst.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-subst.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-subst.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-subst.o: make_cmd.h subst.h sig.h pathnames.h externs.h 
-subst.o: flags.h jobs.h siglist.h execute_cmd.h ${BASHINCDIR}/filecntl.h trap.h pathexp.h
-subst.o: mailcheck.h input.h $(DEFSRC)/getopt.h $(DEFSRC)/common.h
-subst.o: bashline.h bashhist.h ${GLOB_LIBSRC}/strmatch.h
-subst.o: ${BASHINCDIR}/chartypes.h
-subst.o: ${BASHINCDIR}/shmbutil.h
-subst.o: ${DEFDIR}/builtext.h
-test.o: bashtypes.h ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h
-test.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-test.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-test.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-test.o: make_cmd.h subst.h sig.h pathnames.h externs.h test.h
-test.o: ${DEFSRC}/common.h 
-trap.o: config.h bashtypes.h trap.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-trap.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-trap.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-trap.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-trap.o: make_cmd.h subst.h sig.h pathnames.h externs.h 
-trap.o: signames.h $(DEFSRC)/common.h
-trap.o: ${DEFDIR}/builtext.h jobs.h
-unwind_prot.o: config.h bashtypes.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h command.h ${BASHINCDIR}/stdc.h
-unwind_prot.o: general.h xmalloc.h unwind_prot.h quit.h sig.h
-variables.o: config.h bashtypes.h ${BASHINCDIR}/posixstat.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-variables.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-variables.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-variables.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-variables.o: make_cmd.h subst.h sig.h pathnames.h externs.h 
-variables.o: flags.h execute_cmd.h mailcheck.h input.h $(DEFSRC)/common.h
-variables.o: findcmd.h bashhist.h hashcmd.h pathexp.h
-variables.o: pcomplete.h  ${BASHINCDIR}/chartypes.h
-variables.o: ${BASHINCDIR}/posixtime.h assoc.h
-version.o:  conftypes.h patchlevel.h version.h
-xmalloc.o: config.h bashtypes.h ${BASHINCDIR}/ansi_stdlib.h error.h
-
-# job control
-
-jobs.o: config.h bashtypes.h trap.h ${BASHINCDIR}/filecntl.h input.h ${BASHINCDIR}/shtty.h
-jobs.o: bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-jobs.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-jobs.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-jobs.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-jobs.o: execute_cmd.h make_cmd.h subst.h sig.h pathnames.h externs.h 
-jobs.o: jobs.h flags.h $(DEFSRC)/common.h $(DEFDIR)/builtext.h
-jobs.o: ${BASHINCDIR}/posixwait.h ${BASHINCDIR}/unionwait.h
-jobs.o: ${BASHINCDIR}/posixtime.h
-nojobs.o: config.h bashtypes.h ${BASHINCDIR}/filecntl.h bashjmp.h ${BASHINCDIR}/posixjmp.h
-nojobs.o: command.h ${BASHINCDIR}/stdc.h general.h xmalloc.h jobs.h quit.h siglist.h externs.h
-nojobs.o: sig.h error.h ${BASHINCDIR}/shtty.h input.h
-nojobs.o: $(DEFDIR)/builtext.h
-
-# shell features that may be compiled in
-
-array.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-array.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-array.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-array.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-array.o: make_cmd.h subst.h sig.h pathnames.h externs.h 
-array.o: $(DEFSRC)/common.h
-arrayfunc.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-arrayfunc.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-arrayfunc.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-arrayfunc.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-arrayfunc.o: make_cmd.h subst.h sig.h pathnames.h externs.h pathexp.h
-arrayfunc.o: $(DEFSRC)/common.h
-arrayfunc.o: ${BASHINCDIR}/shmbutil.h
-assoc.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-assoc.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h
-assoc.o: command.h ${BASHINCDIR}/stdc.h error.h
-assoc.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h
-assoc.o: assoc.h hashlib.h
-assoc.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-assoc.o: make_cmd.h subst.h sig.h pathnames.h externs.h 
-assoc.o: $(DEFSRC)/common.h
-braces.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-braces.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-braces.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-braces.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-braces.o: make_cmd.h subst.h sig.h pathnames.h externs.h 
-braces.o: ${BASHINCDIR}/shmbutil.h
-alias.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h command.h ${BASHINCDIR}/stdc.h
-alias.o: general.h xmalloc.h bashtypes.h externs.h alias.h
-alias.o: pcomplete.h 
-alias.o: ${BASHINCDIR}/chartypes.h
-
-pcomplib.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h bashtypes.h
-pcomplib.o: ${BASHINCDIR}/stdc.h hashlib.h pcomplete.h shell.h syntax.h
-pcomplib.o: bashjmp.h command.h general.h xmalloc.h error.h variables.h arrayfunc.h conftypes.h quit.h
-pcomplib.o: unwind_prot.h dispose_cmd.h make_cmd.h subst.h sig.h pathnames.h
-pcomplib.o: externs.h ${BASHINCDIR}/maxpath.h
-
-pcomplete.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h bashtypes.h
-pcomplete.o: ${BASHINCDIR}/stdc.h hashlib.h pcomplete.h shell.h syntax.h
-pcomplete.o: bashjmp.h command.h general.h xmalloc.h error.h variables.h arrayfunc.h conftypes.h quit.h
-pcomplete.o: unwind_prot.h dispose_cmd.h make_cmd.h subst.h sig.h pathnames.h
-pcomplete.o: externs.h ${BASHINCDIR}/maxpath.h execute_cmd.h 
-
-# library support files
-
-bashhist.o: config.h bashtypes.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/posixstat.h
-bashhist.o: ${BASHINCDIR}/filecntl.h
-bashhist.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-bashhist.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-bashhist.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-bashhist.o: make_cmd.h subst.h sig.h pathnames.h externs.h 
-bashhist.o: flags.h input.h parser.h pathexp.h $(DEFSRC)/common.h bashline.h
-bashhist.o: $(GLOB_LIBSRC)/strmatch.h
-bashline.o: config.h bashtypes.h ${BASHINCDIR}/posixstat.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-bashline.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
-bashline.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
-bashline.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-bashline.o: make_cmd.h subst.h sig.h pathnames.h externs.h 
-bashline.o: builtins.h bashhist.h bashline.h execute_cmd.h findcmd.h pathexp.h
-bashline.o: $(DEFSRC)/common.h $(GLOB_LIBSRC)/glob.h alias.h
-bashline.o: pcomplete.h ${BASHINCDIR}/chartypes.h input.h
-bracecomp.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-bracecomp.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h
-bracecomp.o: command.h ${BASHINCDIR}/stdc.h error.h
-bracecomp.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h
-bracecomp.o: array.h hashlib.h alias.h builtins.h 
-bracecomp.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-bracecomp.o: make_cmd.h subst.h sig.h pathnames.h externs.h 
-
-# library dependencies
-
-bashline.o: $(RL_LIBSRC)/rlconf.h
-bashline.o: $(RL_LIBSRC)/keymaps.h $(RL_LIBSRC)/rlstdc.h
-bashline.o: $(RL_LIBSRC)/chardefs.h $(RL_LIBSRC)/readline.h
-bracecomp.o: $(RL_LIBSRC)/keymaps.h $(RL_LIBSRC)/chardefs.h
-bracecomp.o: $(RL_LIBSRC)/readline.h $(RL_LIBSRC)/rlstdc.h
-y.tab.o: $(RL_LIBSRC)/keymaps.h $(RL_LIBSRC)/chardefs.h
-y.tab.o: $(RL_LIBSRC)/readline.h $(RL_LIBSRC)/rlstdc.h
-subst.o: $(RL_LIBSRC)/keymaps.h $(RL_LIBSRC)/chardefs.h
-subst.o: $(RL_LIBSRC)/readline.h $(RL_LIBSRC)/rlstdc.h
-
-shell.o: $(HIST_LIBSRC)/history.h $(HIST_LIBSRC)/rlstdc.h
-subst.o: $(HIST_LIBSRC)/history.h $(HIST_LIBSRC)/rlstdc.h
-bashline.o: $(HIST_LIBSRC)/history.h $(HIST_LIBSRC)/rlstdc.h
-bashhist.o: $(HIST_LIBSRC)/history.h $(HIST_LIBSRC)/rlstdc.h
-y.tab.o: $(HIST_LIBSRC)/history.h $(HIST_LIBSRC)/rlstdc.h
-
-execute_cmd.o: $(TILDE_LIBSRC)/tilde.h
-general.o: $(TILDE_LIBSRC)/tilde.h
-mailcheck.o: $(TILDE_LIBSRC)/tilde.h
-shell.o: $(TILDE_LIBSRC)/tilde.h
-subst.o: $(TILDE_LIBSRC)/tilde.h
-variables.o: $(TILDE_LIBSRC)/tilde.h
-
-# libintl dependencies
-arrayfunc.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-bashhist.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-bashline.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-braces.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-error.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-eval.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-execute_cmd.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-expr.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-general.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-input.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-jobs.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-mailcheck.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-make_cmd.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-nojobs.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-parse.y: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-pcomplete.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-pcomplib.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-print_cmd.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-redir.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-shell.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-sig.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-siglist.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-subst.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-test.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-trap.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-variables.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-version.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-xmalloc.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-
-signames.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-
-# XXX - dependencies checked through here
-
-# builtin c sources
-builtins/bashgetopt.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-builtins/bashgetopt.o: shell.h syntax.h config.h bashjmp.h command.h general.h xmalloc.h error.h
-builtins/bashgetopt.o: variables.h arrayfunc.h conftypes.h quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-builtins/bashgetopt.o: make_cmd.h subst.h sig.h pathnames.h externs.h 
-builtins/bashgetopt.o: $(DEFSRC)/common.h
-builtins/bashgetopt.o: ${BASHINCDIR}/chartypes.h
-builtins/common.o: bashtypes.h ${BASHINCDIR}/posixstat.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-builtins/common.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h command.h
-builtins/common.o: ${BASHINCDIR}/memalloc.h variables.h arrayfunc.h conftypes.h input.h siglist.h
-builtins/common.o: quit.h unwind_prot.h ${BASHINCDIR}/maxpath.h jobs.h builtins.h
-builtins/common.o: dispose_cmd.h make_cmd.h subst.h externs.h bashhist.h 
-builtins/common.o: execute_cmd.h ${BASHINCDIR}/stdc.h general.h xmalloc.h error.h pathnames.h
-builtins/common.o: ${DEFDIR}/builtext.h
-builtins/common.o: ${BASHINCDIR}/chartypes.h
-builtins/evalfile.o: bashtypes.h ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-builtins/evalfile.o: shell.h syntax.h config.h bashjmp.h command.h general.h xmalloc.h error.h
-builtins/evalfile.o: variables.h arrayfunc.h conftypes.h quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-builtins/evalfile.o: make_cmd.h subst.h sig.h pathnames.h externs.h 
-builtins/evalfile.o: jobs.h builtins.h flags.h input.h execute_cmd.h
-builtins/evalfile.o: bashhist.h $(DEFSRC)/common.h
-builtins/evalstring.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-builtins/evalstring.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h command.h siglist.h
-builtins/evalstring.o: ${BASHINCDIR}/memalloc.h variables.h arrayfunc.h conftypes.h input.h
-builtins/evalstring.o: quit.h unwind_prot.h ${BASHINCDIR}/maxpath.h jobs.h builtins.h
-builtins/evalstring.o: dispose_cmd.h make_cmd.h subst.h externs.h 
-builtins/evalstring.o: jobs.h builtins.h flags.h input.h execute_cmd.h
-builtins/evalstring.o: bashhist.h $(DEFSRC)/common.h
-builtins/getopt.o: config.h ${BASHINCDIR}/memalloc.h
-builtins/getopt.o: shell.h syntax.h bashjmp.h command.h general.h xmalloc.h error.h
-builtins/getopt.o: variables.h arrayfunc.h conftypes.h quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
-builtins/getopt.o: make_cmd.h subst.h sig.h pathnames.h externs.h 
-builtins/getopt.o: $(DEFSRC)/getopt.h
-builtins/mkbuiltins.o: config.h bashtypes.h ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h
-builtins/mkbuiltins.o: bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-
-# builtin def files
-builtins/alias.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/alias.o: quit.h $(DEFSRC)/common.h pathnames.h
-builtins/alias.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h command.h ${BASHINCDIR}/stdc.h unwind_prot.h
-builtins/alias.o: dispose_cmd.h make_cmd.h subst.h externs.h variables.h arrayfunc.h conftypes.h 
-builtins/bind.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/bind.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/bind.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h quit.h
-builtins/bind.o: $(DEFSRC)/bashgetopt.h pathnames.h
-builtins/break.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/break.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h quit.h
-builtins/break.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/break.o: pathnames.h
-builtins/builtin.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/builtin.o: quit.h $(DEFSRC)/common.h $(DEFSRC)/bashgetopt.h
-builtins/builtin.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h 
-builtins/builtin.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/builtin.o: pathnames.h
-builtins/caller.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/caller.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h
-builtins/caller.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/caller.o: $(DEFSRC)/common.h quit.h 
-builtins/caller.o: ${BASHINCDIR}/chartypes.h bashtypes.h
-builtins/caller.o: ${DEFDIR}/builtext.h pathnames.h
-builtins/cd.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/cd.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h
-builtins/cd.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/cd.o: $(DEFSRC)/common.h quit.h pathnames.h
-builtins/command.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/command.o: quit.h $(DEFSRC)/bashgetopt.h
-builtins/command.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h 
-builtins/command.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h pathnames.h
-builtins/declare.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/declare.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h quit.h
-builtins/declare.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/declare.o: $(DEFSRC)/bashgetopt.h pathnames.h
-builtins/echo.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/echo.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h quit.h
-builtins/echo.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/echo.o: pathnames.h
-builtins/enable.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/enable.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h quit.h
-builtins/enable.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/enable.o: pcomplete.h pathnames.h
-builtins/eval.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/eval.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h quit.h 
-builtins/eval.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/exec.o: bashtypes.h pathnames.h
-builtins/exec.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/exec.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h
-builtins/exec.o: dispose_cmd.h make_cmd.h subst.h externs.h execute_cmd.h 
-builtins/exec.o: findcmd.h flags.h quit.h $(DEFSRC)/common.h ${BASHINCDIR}/stdc.h
-builtins/exec.o: pathnames.h
-builtins/exit.o: bashtypes.h 
-builtins/exit.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/exit.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h quit.h
-builtins/exit.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/exit.o: pathnames.h
-builtins/fc.o: bashtypes.h ${BASHINCDIR}/posixstat.h
-builtins/fc.o: bashansi.h ${BASHINCDIR}/ansi_stdlib.h builtins.h command.h ${BASHINCDIR}/stdc.h 
-builtins/fc.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/fc.o: flags.h unwind_prot.h variables.h arrayfunc.h conftypes.h shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h 
-builtins/fc.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h quit.h 
-builtins/fc.o: $(DEFSRC)/bashgetopt.h bashhist.h pathnames.h
-builtins/fc.o: ${BASHINCDIR}/chartypes.h
-builtins/fg_bg.o: bashtypes.h $(DEFSRC)/bashgetopt.h 
-builtins/fg_bg.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/fg_bg.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h quit.h
-builtins/fg_bg.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/fg_bg.o: pathnames.h
-builtins/getopts.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/getopts.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h quit.h 
-builtins/getopts.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/getopts.o: pathnames.h
-builtins/hash.o: bashtypes.h 
-builtins/hash.o: builtins.h command.h findcmd.h ${BASHINCDIR}/stdc.h $(DEFSRC)/common.h
-builtins/hash.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/hash.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h quit.h 
-builtins/hash.o: pathnames.h
-builtins/help.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/help.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/help.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h quit.h
-builtins/help.o: $(GLOB_LIBSRC)/glob.h pathnames.h
-builtins/history.o: bashtypes.h pathnames.h
-builtins/history.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/history.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/history.o: ${BASHINCDIR}/filecntl.h shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h
-builtins/history.o: bashhist.h variables.h arrayfunc.h conftypes.h 
-builtins/inlib.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/inlib.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h quit.h 
-builtins/inlib.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/inlib.o: pathnames.h
-builtins/jobs.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/jobs.o: quit.h $(DEFSRC)/bashgetopt.h
-builtins/jobs.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h 
-builtins/jobs.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/jobs.o: pathnames.h
-builtins/kill.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/kill.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/kill.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h trap.h unwind_prot.h variables.h arrayfunc.h conftypes.h 
-builtins/kill.o: pathnames.h
-builtins/let.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/let.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/let.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h 
-builtins/let.o: pathnames.h
-builtins/printf.o: config.h ${BASHINCDIR}/memalloc.h bashjmp.h command.h error.h
-builtins/printf.o: general.h xmalloc.h quit.h dispose_cmd.h make_cmd.h subst.h
-builtins/printf.o: externs.h sig.h pathnames.h shell.h syntax.h unwind_prot.h
-builtins/printf.o: variables.h arrayfunc.h conftypes.h ${BASHINCDIR}/stdc.h $(DEFSRC)/bashgetopt.h
-builtins/printf.o: ${BASHINCDIR}/chartypes.h 
-builtins/pushd.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/pushd.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/pushd.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h
-builtins/pushd.o: $(DEFSRC)/common.h pathnames.h
-builtins/read.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/read.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/read.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h 
-builtins/read.o: pathnames.h
-builtins/return.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/return.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/return.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h 
-builtins/return.o: pathnames.h
-builtins/set.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/set.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/set.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h flags.h
-builtins/set.o: pathnames.h
-builtins/setattr.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/setattr.o: quit.h $(DEFSRC)/common.h $(DEFSRC)/bashgetopt.h
-builtins/setattr.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h 
-builtins/setattr.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/setattr.o: pathnames.h
-builtins/shift.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/shift.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/shift.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h 
-builtins/shift.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/shift.o: pathnames.h
-builtins/shopt.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h
-builtins/shopt.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h
-builtins/shopt.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h unwind_prot.h variables.h arrayfunc.h conftypes.h ${BASHINCDIR}/maxpath.h
-builtins/shopt.o: $(DEFSRC)/common.h $(DEFSRC)/bashgetopt.h pathnames.h
-builtins/shopt.o: bashhist.h
-builtins/source.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/source.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/source.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h
-builtins/source.o: findcmd.h $(DEFSRC)/bashgetopt.h flags.h trap.h
-builtins/source.o: pathnames.h
-builtins/suspend.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/suspend.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/suspend.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h 
-builtins/suspend.o: pathnames.h
-builtins/test.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/test.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/test.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h 
-builtins/test.o: test.h pathnames.h
-builtins/times.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/times.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/times.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h 
-builtins/times.o: pathnames.h
-builtins/trap.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/trap.o: quit.h $(DEFSRC)/common.h
-builtins/trap.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h 
-builtins/trap.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/trap.o: pathnames.h
-builtins/type.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/type.o: quit.h $(DEFSRC)/common.h findcmd.h
-builtins/type.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h
-builtins/type.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/type.o: pathnames.h
-builtins/ulimit.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/ulimit.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/ulimit.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h 
-builtins/ulimit.o: pathnames.h
-builtins/umask.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/umask.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/umask.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h 
-builtins/umask.o: ${BASHINCDIR}/chartypes.h pathnames.h
-builtins/wait.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/wait.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/wait.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h
-builtins/wait.o: ${BASHINCDIR}/chartypes.h pathnames.h
-
-builtins/complete.o: config.h shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h
-builtins/complete.o: unwind_prot.h variables.h arrayfunc.h conftypes.h
-builtins/complete.o: bashtypes.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-builtins/complete.o: builtins.h pathnames.h
-builtins/complete.o: pcomplete.h
-builtins/complete.o: ${DEFSRC}/common.h ${DEFSRC}/bashgetopt.h
-builtins/mapfile.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h
-builtins/mapfile.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h
-builtins/mapfile.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h 
-builtins/mapfile.o: pathnames.h
-
-# libintl dependencies
-builtins/bind.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/break.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/caller.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/cd.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/common.c: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/complete.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/declare.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/enable.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/evalfile.c: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/exec.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/exit.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/fc.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/fg_bg.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/getopt.c: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/hash.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/help.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/history.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/inlib.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/jobs.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/kill.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/let.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/mapfile.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/mkbuiltins.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/printf.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/pushd.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/read.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/return.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/set.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/setattr.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/shift.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/shopt.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/source.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/suspend.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/type.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/ulimit.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-builtins/umask.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-
-# builtin library dependencies
-builtins/bind.o: $(RL_LIBSRC)/chardefs.h $(RL_LIBSRC)/readline.h
-builtins/bind.o: $(RL_LIBSRC)/keymaps.h $(RL_LIBSRC)/rlstdc.h
-
-builtins/bind.o: $(HIST_LIBSRC)/history.h $(RL_LIBSRC)/rlstdc.h
-builtins/fc.o: $(HIST_LIBSRC)/history.h $(RL_LIBSRC)/rlstdc.h
-builtins/history.o: $(HIST_LIBSRC)/history.h $(RL_LIBSRC)/rlstdc.h
-
-builtins/common.o: $(TILDE_LIBSRC)/tilde.h
-builtins/cd.o: $(TILDE_LIBSRC)/tilde.h 
-
-builtins/alias.o: $(DEFSRC)/alias.def
-builtins/bind.o: $(DEFSRC)/bind.def
-builtins/break.o: $(DEFSRC)/break.def
-builtins/builtin.o: $(DEFSRC)/builtin.def
-builtins/caller.o: $(DEFSRC)/caller.def
-builtins/cd.o: $(DEFSRC)/cd.def
-builtins/colon.o: $(DEFSRC)/colon.def
-builtins/command.o: $(DEFSRC)/command.def
-builtins/complete.o: $(DEFSRC)/complete.def
-builtins/declare.o: $(DEFSRC)/declare.def
-builtins/echo.o: $(DEFSRC)/echo.def
-builtins/enable.o: $(DEFSRC)/enable.def
-builtins/eval.o: $(DEFSRC)/eval.def
-builtins/exec.o: $(DEFSRC)/exec.def
-builtins/exit.o: $(DEFSRC)/exit.def
-builtins/fc.o: $(DEFSRC)/fc.def
-builtins/fg_bg.o: $(DEFSRC)/fg_bg.def
-builtins/getopts.o: $(DEFSRC)/getopts.def
-builtins/hash.o: $(DEFSRC)/hash.def
-builtins/help.o: $(DEFSRC)/help.def
-builtins/history.o: $(DEFSRC)/history.def
-builtins/inlib.o: $(DEFSRC)/inlib.def
-builtins/jobs.o: $(DEFSRC)/jobs.def
-builtins/kill.o: $(DEFSRC)/kill.def
-builtins/let.o: $(DEFSRC)/let.def
-builtins/mapfile.o: $(DEFSRC)/mapfile.def
-builtins/pushd.o: $(DEFSRC)/pushd.def
-builtins/read.o: $(DEFSRC)/read.def
-builtins/reserved.o: $(DEFSRC)/reserved.def
-builtins/return.o: $(DEFSRC)/return.def
-builtins/set.o: $(DEFSRC)/set.def
-builtins/setattr.o: $(DEFSRC)/setattr.def
-builtins/shift.o: $(DEFSRC)/shift.def
-builtins/shopt.o: $(DEFSRC)/shopt.def
-builtins/source.o: $(DEFSRC)/source.def
-builtins/suspend.o: $(DEFSRC)/suspend.def
-builtins/test.o: $(DEFSRC)/test.def
-builtins/times.o: $(DEFSRC)/times.def
-builtins/trap.o: $(DEFSRC)/trap.def
-builtins/type.o: $(DEFSRC)/type.def
-builtins/ulimit.o: $(DEFSRC)/ulimit.def
-builtins/umask.o: $(DEFSRC)/umask.def
-builtins/wait.o: $(DEFSRC)/wait.def
diff --git a/NEWS-4.1~ b/NEWS-4.1~
deleted file mode 100644 (file)
index 2d929b6..0000000
--- a/NEWS-4.1~
+++ /dev/null
@@ -1,1537 +0,0 @@
-This is a terse description of the new features added to bash-4.1 since
-the release of bash-4.0.  As always, the manual page (doc/bash.1) is
-the place to look for complete descriptions.
-
-1.  New Features in Bash
-
-a.  Here-documents within $(...) command substitutions may once more be
-    delimited by the closing right paren, instead of requiring a newline.
-
-b.  Bash's file status checks (executable, readable, etc.) now take file
-    system ACLs into account on file systems that support them.
-
-c.  Bash now passes environment variables with names that are not valid
-    shell variable names through into the environment passed to child
-    processes.
-
-d.  The `execute-unix-command' readline function now attempts to clear and
-    reuse the current line rather than move to a new one after the command
-    executes.
-
-e.  `printf -v' can now assign values to array indices.
-
-f.  New `complete -E' and `compopt -E' options that work on the "empty"
-    completion: completion attempted on an empty command line.
-
-g.  New complete/compgen/compopt -D option to define a `default' completion:
-    a completion to be invoked on command for which no completion has been
-    defined.  If this function returns 124, programmable completion is
-    attempted again, allowing a user to dynamically build a set of completions
-    as completion is attempted by having the default completion function
-    install individual completion functions each time it is invoked.
-
-h.  When displaying associative arrays, subscripts are now quoted.
-
-i.  Changes to dabbrev-expand to make it more `emacs-like': no space appended
-    after matches, completions are not sorted, and most recent history entries
-    are presented first.
-
-j.  The [[ and (( commands are now subject to the setting of `set -e' and the
-    ERR trap.
-
-k.  The source/. builtin now removes NUL bytes from the file before attempting
-    to parse commands.
-
-l.  There is a new configuration option (in config-top.h) that forces bash to
-    forward all history entries to syslog.
-
-m.  A new variable $BASHOPTS to export shell options settable using `shopt' to
-    child processes.
-
-n.  There is a new confgure option that forces the extglob option to be
-    enabled by default.
-
-o.  New variable $BASH_XTRACEFD; when set to an integer bash will write xtrace
-    output to that file descriptor.
-
-p.  If the optional left-hand-side of a redirection is of the form {var}, the
-    shell assigns the file descriptor used to $var or uses $var as the file
-    descriptor to move or close, depending on the redirection operator.
-
-q.  The < and > operators to the [[ conditional command now do string
-    comparison according to the current locale.
-
-r.  Programmable completion now uses the completion for `b' instead of `a'
-    when completion is attempted on a line like: a $(b c.
-
-s.  Force extglob on temporarily when parsing the pattern argument to
-    the == and != operators to the [[ command, for compatibility.
-
-t.  Changed the behavior of interrupting the wait builtin when a SIGCHLD is
-    received and a trap on SIGCHLD is set to be Posix-mode only.
-
-u.  The read builtin has a new `-N nchars' option, which reads exactly NCHARS
-    characters, ignoring delimiters like newline.
-
-v.  The mapfile/readarray builtin no longer stores the commands it invokes via
-    callbacks in the history list.
-
-w.  There is a new `compat40' shopt option.
-
-x.  The < and > operators to [[ do string comparisons using the current locale
-    only if the compatibility level is greater than 40 (set to 41 by default).
-
-2.  New Features in Readline
-
-a.  New bindable function: menu-complete-backward.
-
-b.  In the vi insertion keymap, C-n is now bound to menu-complete by default,
-    and C-p to menu-complete-backward.
-
-c.  When in vi command mode, repeatedly hitting ESC now does nothing, even
-    when ESC introduces a bound key sequence.  This is closer to how
-    historical vi behaves.
-
-d.  New bindable function: skip-csi-sequence.  Can be used as a default to
-    consume key sequences generated by keys like Home and End without having
-    to bind all keys.
-
-e.  New application-settable function: rl_filename_rewrite_hook.  Can be used
-    to rewite or modify filenames read from the file system before they are
-    compared to the word to be completed.
-
-f.  New bindable variable: skip-completed-text, active when completing in the
-    middle of a word.  If enabled, it means that characters in the completion
-    that match characters in the remainder of the word are "skipped" rather
-    than inserted into the line.
-
-g.  The pre-readline-6.0 version of menu completion is available as
-    "old-menu-complete" for users who do not like the readline-6.0 version.
-
-h.  New bindable variable: echo-control-characters.  If enabled, and the
-    tty ECHOCTL bit is set, controls the echoing of characters corresponding
-    to keyboard-generated signals.
-
-i.  New bindable variable: enable-meta-key.  Controls whether or not readline
-    sends the smm/rmm sequences if the terminal indicates it has a meta key
-    that enables eight-bit characters.
-
--------------------------------------------------------------------------------
-This is a terse description of the new features added to bash-4.0 since
-the release of bash-3.2.  As always, the manual page (doc/bash.1) is
-the place to look for complete descriptions.
-
-1.  New Features in Bash
-
-a.  When using substring expansion on the positional parameters, a starting
-    index of 0 now causes $0 to be prefixed to the list.
-
-b.  The `help' builtin now prints its columns with entries sorted vertically
-    rather than horizontally.
-
-c.  There is a new variable, $BASHPID, which always returns the process id of
-    the current shell.
-
-d.  There is a new `autocd' option that, when enabled, causes bash to attempt
-    to `cd' to a directory name that is supplied as the first word of a
-    simple command.
-
-e.  There is a new `checkjobs' option that causes the shell to check for and
-    report any running or stopped jobs at exit.
-
-f.  The programmable completion code exports a new COMP_TYPE variable, set to
-    a character describing the type of completion being attempted.
-
-g.  The programmable completion code exports a new COMP_KEY variable, set to
-    the character that caused the completion to be invoked (e.g., TAB).
-
-h.  If creation of a child process fails due to insufficient resources, bash
-    will try again several times before reporting failure.
-
-i.  The programmable completion code now uses the same set of characters as
-    readline when breaking the command line into a list of words.
-
-j.  The block multiplier for the ulimit -c and -f options is now 512 when in
-    Posix mode, as Posix specifies.
-
-k.  Changed the behavior of the read builtin to save any partial input received
-    in the specified variable when the read builtin times out.  This also
-    results in variables specified as arguments to read to be set to the empty
-    string when there is no input available.  When the read builtin times out,
-    it returns an exit status greater than 128.
-
-l.  The shell now has the notion of a `compatibility level', controlled by
-    new variables settable by `shopt'.  Setting this variable currently
-    restores the bash-3.1 behavior when processing quoted strings on the rhs
-    of the `=~' operator to the `[[' command.
-
-m.  The `ulimit' builtin now has new -b (socket buffer size) and -T (number
-    of threads) options.
-
-n.  The -p option to `declare' now displays all variable values and attributes
-    (or function values and attributes if used with -f).
-
-o.  There is a new `compopt' builtin that allows completion functions to modify
-    completion options for existing completions or the completion currently
-    being executed.
-
-p.  The `read' builtin has a new -i option which inserts text into the reply
-    buffer when using readline.
-
-q.  A new `-E' option to the complete builtin allows control of the default
-    behavior for completion on an empty line.
-
-r.  There is now limited support for completing command name words containing
-    globbing characters.
-
-s.  Changed format of internal help documentation for all builtins to roughly
-    follow man page format.
-
-t.  The `help' builtin now has a new -d option, to display a short description,
-    and a -m option, to print help information in a man page-like format.
-
-u.  There is a new `mapfile' builtin to populate an array with lines from a
-    given file.  The name `readarray' is a synonym.
-
-v.  If a command is not found, the shell attempts to execute a shell function
-    named `command_not_found_handle', supplying the command words as the
-    function arguments.
-
-w.  There is a new shell option: `globstar'.  When enabled, the globbing code
-    treats `**' specially -- it matches all directories (and files within
-    them, when appropriate) recursively.
-
-x.  There is a new shell option: `dirspell'.  When enabled, the filename
-    completion code performs spelling correction on directory names during
-    completion.
-
-y.  The `-t' option to the `read' builtin now supports fractional timeout
-    values.
-
-z.  Brace expansion now allows zero-padding of expanded numeric values and
-    will add the proper number of zeroes to make sure all values contain the
-    same number of digits.
-
-aa. There is a new bash-specific bindable readline function: `dabbrev-expand'.
-    It uses menu completion on a set of words taken from the history list.
-
-bb. The command assigned to a key sequence with `bind -x' now sets two new
-    variables in the environment of the executed command:  READLINE_LINE_BUFFER
-    and READLINE_POINT.  The command can change the current readline line
-    and cursor position by modifying READLINE_LINE_BUFFER and READLINE_POINT,
-    respectively.
-
-cc. There is a new &>> redirection operator, which appends the standard output
-    and standard error to the named file.
-
-dd. The parser now understands `|&' as a synonym for `2>&1 |', which redirects
-    the standard error for a command through a pipe.
-
-ee. The new `;&' case statement action list terminator causes execution to
-    continue with the action associated with the next pattern in the
-    statement rather than terminating the command.
-
-ff. The new `;;&' case statement action list terminator causes the shell to
-    test the next set of patterns after completing execution of the current
-    action, rather than terminating the command.
-
-gg. The shell understands a new variable: PROMPT_DIRTRIM.  When set to an
-    integer value greater than zero, prompt expansion of \w and \W  will
-    retain only that number of trailing pathname components and replace
-    the intervening characters with `...'.
-
-hh. There are new case-modifying word expansions: uppercase (^[^]) and
-    lowercase (,[,]).  They can work on either the first character or
-    array element, or globally.  They accept an optional shell pattern
-    that determines which characters to modify.  There is an optionally-
-    configured feature to include capitalization operators.
-
-ii. The shell provides associative array variables, with the appropriate
-    support to create, delete, assign values to, and expand them.
-
-jj. The `declare' builtin now has new -l (convert value to lowercase upon
-    assignment) and -u (convert value to uppercase upon assignment) options.
-    There is an optionally-configurable -c option to capitalize a value at
-    assignment.
-
-kk. There is a new `coproc' reserved word that specifies a coprocess: an
-    asynchronous command run with two pipes connected to the creating shell.
-    Coprocs can be named.  The input and output file descriptors and the
-    PID of the coprocess are available to the calling shell in variables
-    with coproc-specific names.
-
-ll. A value of 0 for the -t option to `read' now returns success if there is
-    input available to be read from the specified file descriptor.
-
-mm. CDPATH and GLOBIGNORE are ignored when the shell is running in privileged
-    mode.
-
-nn. New bindable readline functions shell-forward-word and shell-backward-word,
-    which move forward and backward words delimited by shell metacharacters
-    and honor shell quoting.
-
-oo.  New bindable readline functions shell-backward-kill-word and shell-kill-word
-    which kill words backward and forward, but use the same word boundaries
-    as shell-forward-word and shell-backward-word.
-
-2.  New Features in Readline
-
-a.  A new variable, rl_sort_completion_matches; allows applications to inhibit
-    match list sorting (but beware: some things don't work right if
-    applications do this).
-
-b.  A new variable, rl_completion_invoking_key; allows applications to discover
-    the key that invoked rl_complete or rl_menu_complete.
-
-c.  The functions rl_block_sigint and rl_release_sigint are now public and
-    available to calling applications who want to protect critical sections
-    (like redisplay).
-
-d.  The functions rl_save_state and rl_restore_state are now public and
-    available to calling applications; documented rest of readline's state
-    flag values.
-
-e.  A new user-settable variable, `history-size', allows setting the maximum
-    number of entries in the history list.
-
-f.  There is a new implementation of menu completion, with several improvements
-    over the old; the most notable improvement is a better `completions
-    browsing' mode.
-
-g.  The menu completion code now uses the rl_menu_completion_entry_function
-    variable, allowing applications to provide their own menu completion
-    generators.
-
-h.  There is support for replacing a prefix  of a pathname with a `...' when
-    displaying possible completions.  This is controllable by setting the
-    `completion-prefix-display-length' variable.  Matches with a common prefix
-    longer than this value have the common prefix replaced with `...'.
-
-i.  There is a new `revert-all-at-newline' variable.  If enabled, readline will
-    undo all outstanding changes to all history lines when `accept-line' is
-    executed.
-
-j.  If the kernel supports it, readline displays special characters
-    corresponding to a keyboard-generated signal when the signal is received.
-
--------------------------------------------------------------------------------
-This is a terse description of the new features added to bash-3.2 since
-the release of bash-3.1.  As always, the manual page (doc/bash.1) is
-the place to look for complete descriptions.
-
-1.  New Features in Bash
-
-a.  Changed the parameter pattern replacement functions to not anchor the
-    pattern at the beginning of the string if doing global replacement - that
-    combination doesn't make any sense.
-
-b.  When running in `word expansion only' mode (--wordexp option), inhibit
-    process substitution.
-
-c.  Loadable builtins now work on MacOS X 10.[34].
-
-d.  Shells running in posix mode no longer set $HOME, as POSIX requires.
-
-e.  The code that checks for binary files being executed as shell scripts now
-    checks only for NUL rather than any non-printing character.
-
-f.  Quoting the string argument to the [[ command's  =~ operator now forces
-    string matching, as with the other pattern-matching operators.
-
-2.  New Features in Readline
-
-a.  Calling applications can now set the keyboard timeout to 0, allowing
-    poll-like behavior.
-
-b.  The value of SYS_INPUTRC (configurable at compilation time) is now used as
-    the default last-ditch startup file.
-
-c.  The history file reading functions now allow windows-like \r\n line
-    terminators.
-
--------------------------------------------------------------------------------
-This is a terse description of the new features added to bash-3.1 since
-the release of bash-3.0.  As always, the manual page (doc/bash.1) is
-the place to look for complete descriptions.
-
-1.  New Features in Bash
-
-a.  Bash now understands LC_TIME as a special variable so that time display
-    tracks the current locale.
-
-b.  BASH_ARGC, BASH_ARGV, BASH_SOURCE, and BASH_LINENO are no longer created
-    as `invisible' variables and may not be unset.
-
-c.  In POSIX mode, if `xpg_echo' option is enabled, the `echo' builtin doesn't
-    try to interpret any options at all, as POSIX requires.
-
-d.  The `bg' builtin now accepts multiple arguments, as POSIX seems to specify.
-
-e.  Fixed vi-mode word completion and glob expansion to perform tilde
-    expansion.
-
-f.  The `**' mathematic exponentiation operator is now right-associative.
-
-g.  The `ulimit' builtin has new options: -i (max number of pending signals),
-    -q (max size of POSIX message queues), and -x (max number of file locks).
-
-h.  A bare `%' once again expands to the current job when used as a job
-    specifier.
-
-i.  The `+=' assignment operator (append to the value of a string or array) is
-    now supported for assignment statements and arguments to builtin commands
-    that accept assignment statements.
-
-j.  BASH_COMMAND now preserves its value when a DEBUG trap is executed.
-
-k.  The `gnu_errfmt' option is enabled automatically if the shell is running
-    in an emacs terminal window.
-
-l.  New configuration option:  --single-help-strings.  Causes long help text
-    to be written as a single string; intended to ease translation.
-
-m.  The COMP_WORDBREAKS variable now causes the list of word break characters
-    to be emptied when the variable is unset.
-
-n.  An unquoted expansion of $* when $IFS is empty now causes the positional
-    parameters to be concatenated if the expansion doesn't undergo word
-    splitting.
-
-o.  Bash now inherits $_ from the environment if it appears there at startup.
-
-p.  New shell option: nocasematch.  If non-zero, shell pattern matching ignores
-    case when used by `case' and `[[' commands.
-
-q.  The `printf' builtin takes a new option: -v var.  That causes the output
-    to be placed into var instead of on stdout.
-
-r.  By default, the shell no longer reports processes dying from SIGPIPE.
-
-s.  Bash now sets the extern variable `environ' to the export environment it
-    creates, so C library functions that call getenv() (and can't use the
-    shell-provided replacement) get current values of environment variables.
-
-t.  A new configuration option, `--enable-strict-posix-default', which will
-    build bash to be POSIX conforming by default.
-
-u.  If compiled for strict POSIX conformance, LINES and COLUMNS may now
-    override the true terminal size.
-
-2.  New Features in Readline
-
-a.  The key sequence sent by the keypad `delete' key is now automatically
-    bound to delete-char.
-
-b.  A negative argument to menu-complete now cycles backward through the
-    completion list.
-
-c.  A new bindable readline variable:  bind-tty-special-chars.  If non-zero,
-    readline will bind the terminal special characters to their readline
-    equivalents when it's called (on by default).
-
-d.  New bindable command: vi-rubout.  Saves deleted text for possible
-    reinsertion, as with any vi-mode `text modification' command; `X' is bound
-    to this in vi command mode.
-
-e.  A new external application-controllable variable that allows the LINES
-    and COLUMNS environment variables to set the window size regardless of
-    what the kernel returns: rl_prefer_env_winsize
-
--------------------------------------------------------------------------------
-This is a terse description of the new features added to bash-3.0 since
-the release of bash-2.05b.  As always, the manual page (doc/bash.1) is
-the place to look for complete descriptions.
-
-1.  New Features in Bash
-
-a.  ANSI string expansion now implements the \x{hexdigits} escape.
-
-b.  There is a new loadable `strftime' builtin.
-
-c.  New variable, COMP_WORDBREAKS, which controls the readline completer's
-    idea of word break characters.
-
-d.  The `type' builtin no longer reports on aliases unless alias expansion
-    will actually be performed.    
-
-e.  HISTCONTROL is now a colon-separated list of values, which permits
-    more extensibility and backwards compatibility.
-
-f.  HISTCONTROL may now include the `erasedups' option, which causes all lines
-    matching a line being added to be removed from the history list.
-
-g.  `configure' has a new `--enable-multibyte' argument that permits multibyte
-    character support to be disabled even on systems that support it.
-
-h.  New variables to support the bash debugger:  BASH_ARGC, BASH_ARGV,
-    BASH_SOURCE, BASH_LINENO, BASH_SUBSHELL, BASH_EXECUTION_STRING,
-    BASH_COMMAND
-
-i.  FUNCNAME has been changed to support the debugger: it's now an array
-    variable.
-
-j.  for, case, select, arithmetic commands now keep line number information
-    for the debugger.
-
-k.  There is a new `RETURN' trap executed when a function or sourced script
-    returns (not inherited child processes; inherited by command substitution
-    if function tracing is enabled and the debugger is active).
-
-l.  New invocation option:  --debugger.  Enables debugging and turns on new
-    `extdebug' shell option.
-
-m.  New `functrace' and `errtrace' options to `set -o' cause DEBUG and ERR
-    traps, respectively, to be inherited by shell functions.  Equivalent to
-    `set -T' and `set -E' respectively.  The `functrace' option also controls
-    whether or not the DEBUG trap is inherited by sourced scripts.
-
-n.  The DEBUG trap is run before binding the variable and running the action
-    list in a `for' command, binding the selection variable and running the
-    query in a `select' command, and before attempting a match in a `case'
-    command.
-
-o.  New `--enable-debugger' option to `configure' to compile in the debugger
-    support code.
-
-p.  `declare -F' now prints out extra line number and source file information
-    if the `extdebug' option is set.
-
-q.  If `extdebug' is enabled, a non-zero return value from a DEBUG trap causes
-    the next command to be skipped, and a return value of 2 while in a
-    function or sourced script forces a `return'.
-
-r.  New `caller' builtin to provide a call stack for the bash debugger.
-
-s.  The DEBUG trap is run just before the first command in a function body is
-    executed, for the debugger.
-
-t.  `for', `select', and `case' command heads are printed when `set -x' is
-    enabled.
-
-u.  There is a new {x..y} brace expansion, which is shorthand for {x.x+1,
-    x+2,...,y}.  x and y can be integers or single characters; the sequence
-    may ascend or descend; the increment is always 1.
-
-v.  New ksh93-like ${!array[@]} expansion, expands to all the keys (indices)
-    of array.
-
-w.  New `force_fignore' shopt option; if enabled, suffixes specified by
-    FIGNORE cause words to be ignored when performing word completion even
-    if they're the only possibilities.
-
-x.  New `gnu_errfmt' shopt option; if enabled, error messages follow the `gnu
-    style' (filename:lineno:message) format.
-
-y.  New `-o bashdefault' option to complete and compgen; if set, causes the
-    whole set of bash completions to be performed if the compspec doesn't
-    result in a match.
-
-z.  New `-o plusdirs' option to complete and compgen; if set, causes directory
-    name completion to be performed and the results added to the rest of the
-    possible completions.
-
-aa. `kill' is available as a builtin even when the shell is built without
-    job control.
-
-bb. New HISTTIMEFORMAT variable; value is a format string to pass to
-    strftime(3).  If set and not null, the `history' builtin prints out
-    timestamp information according to the specified format when displaying
-    history entries.  If set, bash tells the history library to write out
-    timestamp information when the history file is written.
-
-cc. The [[ ... ]] command has a new binary `=~' operator that performs
-    extended regular expression (egrep-like) matching.
-
-dd. `configure' has a new `--enable-cond-regexp' option (enabled by default)
-    to enable the =~ operator and regexp matching in [[ ... ]].
-
-ee. Subexpressions matched by the =~ operator are placed in the new
-    BASH_REMATCH array variable.
-
-ff. New `failglob' option that causes an expansion error when pathname
-    expansion fails to produce a match.
-
-gg. New `set -o pipefail' option that causes a pipeline to return a failure
-    status if any of the processes in the pipeline fail, not just the last
-    one.
-
-hh. printf builtin understands two new escape sequences:  \" and \?.
-
-ii. `echo -e' understands two new escape sequences:  \" and \?.
-
-jj. The GNU `gettext' package and libintl have been integrated; the shell's
-    messages can be translated into different languages.
-
-kk. The `\W' prompt expansion now abbreviates $HOME as `~', like `\w'.
-
-ll. The error message printed when bash cannot open a shell script supplied
-    as argument 1 now includes the name of the shell, to better identify
-    the error as coming from bash.
-
-mm. The parameter pattern removal and substitution expansions are now much
-    faster and more efficient when using multibyte characters.
-
-nn. The `jobs', `kill', and `wait' builtins now accept job control notation
-    even if job control is not enabled.
-
-oo. The historical behavior of `trap' that allows a missing `action' argument
-    to cause each specified signal's handling to be reset to its default is
-    now only supported when `trap' is given a single non-option argument.
-
-2.  New Features in Readline
-
-a.  History expansion has a new `a' modifier equivalent to the `g' modifier
-    for compatibility with the BSD csh.
-
-b.  History expansion has a new `G' modifier equivalent to the BSD csh `g'
-    modifier, which performs a substitution once per word.
-
-c.  All non-incremental search operations may now undo the operation of
-    replacing the current line with the history line.
-
-d.  The text inserted by an `a' command in vi mode can be reinserted with
-    `.'.
-
-e.  New bindable variable, `show-all-if-unmodified'.  If set, the readline
-    completer will list possible completions immediately if there is more
-    than one completion and partial completion cannot be performed.
-
-f.  There is a new application-callable `free_history_entry()' function.
-
-g.  History list entries now contain timestamp information; the history file
-    functions know how to read and write timestamp information associated
-    with each entry.
-
-h.  Four new key binding functions have been added:
-
-       rl_bind_key_if_unbound()
-       rl_bind_key_if_unbound_in_map()
-       rl_bind_keyseq_if_unbound()
-       rl_bind_keyseq_if_unbound_in_map()
-
-i.  New application variable, rl_completion_quote_character, set to any
-    quote character readline finds before it calls the application completion
-    function.
-
-j.  New application variable, rl_completion_suppress_quote, settable by an
-    application completion function.  If set to non-zero, readline does not
-    attempt to append a closing quote to a completed word.
-
-k.  New application variable, rl_completion_found_quote, set to a non-zero
-    value if readline determines that the word to be completed is quoted.
-    Set before readline calls any application completion function.
-
-l.  New function hook, rl_completion_word_break_hook, called when readline
-    needs to break a line into words when completion is attempted.  Allows
-    the word break characters to vary based on position in the line.
-
-m.  New bindable command: unix-filename-rubout.  Does the same thing as
-    unix-word-rubout, but adds `/' to the set of word delimiters.
-
-n.  When listing completions, directories have a `/' appended if the
-    `mark-directories' option has been enabled.
-
--------------------------------------------------------------------------------
-This is a terse description of the new features added to bash-2.05b since
-the release of bash-2.05a.  As always, the manual page (doc/bash.1) is
-the place to look for complete descriptions.
-
-1.  New Features in Bash
-
-a.  If set, TMOUT is the default timeout for the `read' builtin.
-
-b.  `type' has two new options:  `-f' suppresses shell function lookup, and
-    `-P' forces a $PATH search.
-
-c.  New code to handle multibyte characters.
-
-d.  `select' was changed to be more ksh-compatible, in that the menu is
-    reprinted each time through the loop only if REPLY is set to NULL.
-    The previous behavior is available as a compile-time option.
-
-e.  `complete -d' and `complete -o dirnames' now force a slash to be
-    appended to names which are symlinks to directories.
-
-f.  There is now a bindable edit-and-execute-command readline command,
-    like the vi-mode `v' command, bound to C-xC-e in emacs mode.
-
-g.  Added support for ksh93-like [:word:] character class in pattern matching.
-
-h.  The  $'...' quoting construct now expands \cX to Control-X.
-
-i.  A new \D{...} prompt expansion; passes the `...' to strftime and inserts
-    the result into the expanded prompt.
-
-j.  The shell now performs arithmetic in the largest integer size the
-    machine supports (intmax_t), instead of long.
-
-k.  If a numeric argument is supplied to one of the bash globbing completion
-    functions, a `*' is appended to the word before expansion is attempted.
-
-l.  The bash globbing completion functions now allow completions to be listed
-    with double tabs or if `show-all-if-ambiguous' is set.
-
-m.  New `-o nospace' option for `complete' and `compgen' builtins; suppresses
-    readline's appending a space to the completed word.
-
-n.  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).
-
-p.  There is a new configuration option `--enable-mem-scramble', controls
-    bash malloc behavior of writing garbage characters into memory at
-    allocation and free time.
-
-q.  The `complete' and `compgen' builtins now have a new `-s/-A service'
-    option to complete on names from /etc/services.
-
-r.  `read' has a new `-u fd' option to read from a specified file descriptor.
-
-s.  Fix the completion code so that expansion errors in a directory name
-    don't cause a longjmp back to the command loop.
-
-t.  Fixed word completion inside command substitution to work a little more
-    intuitively.
-
-u.  The `printf' %q format specifier now uses $'...' quoting to print the
-    argument if it contains non-printing characters.
-
-v.  The `declare' and `typeset' builtins have a new `-t' option.  When applied
-    to functions, it causes the DEBUG trap to be inherited by the named
-    function.  Currently has no effect on variables.
-
-w.  The DEBUG trap is now run *before* simple commands, ((...)) commands,
-    [[...]] conditional commands, and for ((...)) loops.
-
-x.  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.
-
-y.  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.  Code
-    from Gary Vaughan.
-
-z.  New [n]<&word- and [n]>&word- redirections from ksh93 -- move fds (dup
-    and close).
-
-aa. There is a new `-l' invocation option, equivalent to `--login'.
-
-bb. The `hash' builtin has a new `-l' option to list contents in a reusable
-    format, and a `-d' option to remove a name from the hash table.
-
-cc. There is now support for placing the long help text into separate files 
-    installed into ${datadir}/bash.  Not enabled by default; can be turned  
-    on with `--enable-separate-helpfiles' option to configure.
-    
-dd. All builtins that take operands accept a `--' pseudo-option, except
-    `echo'.
-
-ee. The `echo' builtin now accepts \0xxx (zero to three octal digits following
-    the `0') in addition to \xxx (one to three octal digits) for SUSv3/XPG6/
-    POSIX.1-2001 compliance.
-
-
-2.  New Features in Readline
-
-a.  Support for key `subsequences':  allows, e.g., ESC and ESC-a to both
-    be bound to readline functions.  Now the arrow keys may be used in vi
-    insert mode.
-
-b.  When listing completions, and the number of lines displayed is more than
-    the screen length, readline uses an internal pager to display the results.
-    This is controlled by the `page-completions' variable (default on).
-
-c.  New code to handle editing and displaying multibyte characters.
-
-d.  The behavior introduced in bash-2.05a of deciding whether or not to
-    append a slash to a completed name that is a symlink to a directory has
-    been made optional, controlled by the `mark-symlinked-directories'
-    variable (default is the 2.05a behavior).
-
-e.  The `insert-comment' command now acts as a toggle if given a numeric
-    argument:  if the first characters on the line don't specify a
-    comment, insert one; if they do, delete the comment text
-
-f.  New application-settable completion variable:
-    rl_completion_mark_symlink_dirs, allows an application's completion
-    function to temporarily override the user's preference for appending
-    slashes to names which are symlinks to directories.
-
-g.  New function available to application completion functions:
-    rl_completion_mode, to tell how the completion function was invoked
-    and decide which argument to supply to rl_complete_internal (to list
-    completions, etc.).
-
-h.  Readline now has an overwrite mode, toggled by the `overwrite-mode'
-    bindable command, which could be bound to `Insert'.
-
-i.  New application-settable completion variable:
-    rl_completion_suppress_append, inhibits appending of
-    rl_completion_append_character to completed words.
-
-j.  New key bindings when reading an incremental search string:  ^W yanks
-    the currently-matched word out of the current line into the search
-    string; ^Y yanks the rest of the current line into the search string,
-    DEL or ^H deletes characters from the search string.
-
--------------------------------------------------------------------------------
-This is a terse description of the new features added to bash-2.05a since
-the release of bash-2.05.  As always, the manual page (doc/bash.1) is
-the place to look for complete descriptions.
-
-1.  New Features in Bash
-
-a.  Added support for DESTDIR installation root prefix, so you can do a
-    `make install DESTDIR=bash-root' and do easier binary packaging.
-
-b.  Added support for builtin printf "'" flag character as per latest POSIX
-    drafts.
-
-c.  Support for POSIX.2 printf(1) length specifiers `j', `t', and `z' (from
-    ISO C99).
-
-d.  New autoconf macro, RL_LIB_READLINE_VERSION, for use by other applications
-    (bash doesn't use very much of what it returns).
-
-e.  `set [-+]o nolog' is recognized as required by the latest POSIX drafts,
-    but ignored.
-
-f.  New read-only `shopt' option:  login_shell.  Set to non-zero value if the
-    shell is a login shell.
-
-g.  New `\A' prompt string escape sequence; expands to time in 24 HH:MM format.
-
-h.  New `-A group/-g' option to complete and compgen; does group name
-    completion.
-
-i.  New `-t' option to `hash' to list hash values for each filename argument.
-
-j.  New [-+]O invocation option to set and unset `shopt' options at startup.
-
-k.  configure's `--with-installed-readline' option now takes an optional
-    `=PATH' suffix to set the root of the tree where readline is installed
-    to PATH.
-
-l.  The ksh-like `ERR' trap has been added.  The `ERR' trap will be run
-    whenever the shell would have exited if the -e option were enabled.
-    It is not inherited by shell functions.
-
-m.  `readonly', `export', and `declare' now print variables which have been
-    given attributes but not set by assigning a value as just a command and
-    a variable name (like `export foo') when listing, as the latest POSIX
-    drafts require.
-
-n.  `bashbug' now requires that the subject be changed from the default.
-
-o.  configure has a new `--enable-largefile' option, like other GNU utilities.
-
-p.  `for' loops now allow empty word lists after `in', like the latest POSIX
-    drafts require.
-
-q.  The builtin `ulimit' now takes two new non-numeric arguments:  `hard',
-    meaning the current hard limit, and `soft', meaning the current soft  
-    limit, in addition to `unlimited'
-    
-r.  `ulimit' now prints the option letter associated with a particular
-    resource when printing more than one limit.
-
-s.  `ulimit' prints `hard' or `soft' when a value is not `unlimited' but is
-    one of RLIM_SAVED_MAX or RLIM_SAVED_CUR, respectively.
-
-t.  The `printf' builtin now handles the %a and %A conversions if they're
-    implemented by printf(3).
-
-u.  The `printf' builtin now handles the %F conversion (just about like %f).
-
-v.  The `printf' builtin now handles the %n conversion like printf(3).  The
-    corresponding argument is the name of a shell variable to which the
-    value is assigned.
-
-2.  New Features in Readline
-
-a.  Added extern declaration for rl_get_termcap to readline.h, making it a
-    public function (it was always there, just not in readline.h).
-
-b.  New #defines in readline.h:  RL_READLINE_VERSION, currently 0x0402,
-    RL_VERSION_MAJOR, currently 4, and RL_VERSION_MINOR, currently 2.
-
-c.  New readline variable:  rl_readline_version, mirrors RL_READLINE_VERSION.
-
-d.  New bindable boolean readline variable:  match-hidden-files.  Controls
-    completion of files beginning with a `.' (on Unix).  Enabled by default.
-
-e.  The history expansion code now allows any character to terminate a
-    `:first-' modifier, like csh.
-
-f.  New bindable variable `history-preserve-point'.  If set, the history
-    code attempts to place the user at the same location on each history
-    line retrived with previous-history or next-history.
-
--------------------------------------------------------------------------------
-This is a terse description of the new features added to bash-2.05 since
-the release of bash-2.04.  As always, the manual page (doc/bash.1) is
-the place to look for complete descriptions.
-
-1.  New Features in Bash
-
-a.  Added a new `--init-file' invocation argument as a synonym for `--rcfile',
-    per the new GNU coding standards.
-
-b.  The /dev/tcp and /dev/udp redirections now accept service names as well as
-    port numbers.
-
-c.  `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
-
-d.  A new loadable builtin, realpath, which canonicalizes and expands symlinks
-    in pathname arguments.
-    
-e.  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.
-
-f.  Bash-2.05 once again honors the current locale setting when processing
-    ranges within pattern matching bracket expressions (e.g., [A-Z]).
-
-2.  New Features in Readline
-
-a.  The blink timeout for paren matching is now settable by applications,
-    via the rl_set_paren_blink_timeout() function.
-
-b.  _rl_executing_macro has been renamed to rl_executing_macro, which means
-    it's now part of the public interface.
-
-c.  Readline has a new variable, rl_readline_state, which is a bitmap that
-    encapsulates the current state of the library; intended for use by
-    callbacks and hook functions.
-
-d.  New application-callable function rl_set_prompt(const char *prompt):
-    expands its prompt string argument and sets rl_prompt to the result.
-
-e.  New application-callable function rl_set_screen_size(int rows, int cols):
-    public method for applications to set readline's idea of the screen
-    dimensions.
-
-f.  New function, rl_get_screen_size (int *rows, int *columns), returns
-    readline's idea of the screen dimensions.
-
-g.  The timeout in rl_gather_tyi (readline keyboard input polling function)
-    is now settable via a function (rl_set_keyboard_input_timeout()).
-
-h.  Renamed the max_input_history variable to history_max_entries; the old
-    variable is maintained for backwards compatibility.
-
-i.  The list of characters that separate words for the history tokenizer is
-    now settable with a variable:  history_word_delimiters.  The default
-    value is as before.
-
--------------------------------------------------------------------------------
-This is a terse description of the new features added to bash-2.04 since
-the release of bash-2.03.  As always, the manual page (doc/bash.1) is
-the place to look for complete descriptions.
-
-1.  New Features in Bash
-
-a.  The history builtin has a `-d offset' option to delete the history entry
-    at position `offset'.
-
-b.  The prompt expansion code has two new escape sequences: \j, the number of
-    active jobs; and \l, the basename of the shell's tty device name.
-
-c.  The `bind' builtin has a new `-x' option to bind key sequences to shell   
-    commands.
-
-d.  There is a new shell option, no_empty_command_completion, which, when
-    enabled, disables command completion when TAB is typed on an empty line.
-
-e.  The `help' builtin has a `-s' option to just print a builtin's usage
-    synopsis.
-
-f.  There are several new arithmetic operators:  id++, id-- (variable
-    post-increment/decrement), ++id, --id (variable pre-increment/decrement),
-    expr1 , expr2 (comma operator).
-
-g.  There is a new ksh-93 style arithmetic for command:
-        for ((expr1 ; expr2; expr3 )); do list; done
-
-h.  The `read' builtin has a number of new options:
-        -t timeout      only wait timeout seconds for input
-        -n nchars       only read nchars from input instead of a full line
-        -d delim        read until delim rather than newline
-        -s              don't echo input chars as they are read
-
-i.  The redirection code now handles several filenames specially:
-    /dev/fd/N, /dev/stdin, /dev/stdout, and /dev/stderr, whether or
-    not they are present in the file system.
-
-j.  The redirection code now recognizes pathnames of the form
-    /dev/tcp/host/port and /dev/udp/host/port, and tries to open a socket
-    of the appropriate type to the specified port on the specified host.
-
-k.  The ksh-93 ${!prefix*} expansion, which expands to the names of all
-    shell variables with prefix PREFIX, has been implemented.
-
-l.  There is a new dynamic variable, FUNCNAME, which expands to the name of
-    a currently-executing function.  Assignments to FUNCNAME have no effect.
-
-m.  The GROUPS variable is no longer readonly; assignments to it are silently
-    discarded.  This means it can be unset.
-
-n.  A new programmable completion facility, with two new builtin commands:
-    complete and compgen.
-
-o.  configure has a new option, `--enable-progcomp', to compile in the
-    programmable completion features (enabled by default).
-
-p.  `shopt' has a new option, `progcomp', to enable and disable programmable
-    completion at runtime.
-
-q.  Unsetting HOSTFILE now clears the list of hostnames used for completion.
-
-r.  configure has a new option, `--enable-bash-malloc', replacing the old
-    `--with-gnu-malloc' (which is still present for backwards compatibility).
-
-s.  There is a new manual page describing rbash, the restricted shell.
-
-t.  `bashbug' has new `--help' and `--version' options.
-
-u.  `shopt' has a new `xpg_echo' option, which controls the behavior of
-    `echo' with respect to backslash-escaped characters at runtime.
-
-v.  If NON_INTERACTIVE_LOGIN_SHELLS is defined, all login shells read the
-    startup files, even if they are not interactive.
-
-w.  The LC_NUMERIC variable is now treated specially, and used to set the
-    LC_NUMERIC locale category for number formatting, e.g., when `printf'
-    displays floating-point numbers.
-
-2.  New features in Readline
-
-a.  Parentheses matching is now always compiled into readline, and enabled
-    or disabled when the value of the `blink-matching-paren' variable is
-    changed.
-
-b.  MS-DOS systems now use ~/_inputrc as the last-ditch inputrc filename.
-
-c.  MS-DOS systems now use ~/_history as the default history file.
-
-d.  history-search-{forward,backward} now leave the point at the end of the
-    line when the string to search for is empty, like
-    {reverse,forward}-search-history.
-
-e.  history-search-{forward,backward} now leave the last history line found
-    in the readline buffer if the second or subsequent search fails.
-
-f.  New function for use by applications:  rl_on_new_line_with_prompt, used
-    when an application displays the prompt itself before calling readline().
-
-g.  New variable for use by applications:  rl_already_prompted.  An application
-    that displays the prompt itself before calling readline() must set this to
-    a non-zero value.
-
-h.  A new variable, rl_gnu_readline_p, always 1.  The intent is that an
-    application can verify whether or not it is linked with the `real'
-    readline library or some substitute.
-
--------------------------------------------------------------------------------
-This is a terse description of the new features added to bash-2.03 since
-the release of bash-2.02.  As always, the manual page (doc/bash.1) is
-the place to look for complete descriptions.
-
-1.  New Features in Bash
-
-a.  New `shopt' option, `restricted_shell', indicating whether or not the
-    shell was started in restricted mode, for use in startup files.
-
-b.  Filename generation is now performed on the words between ( and ) in
-    array assignments (which it probably should have done all along).
-
-c.  OLDPWD is now auto-exported, as POSIX.2 seems to require.
-
-d.  ENV and BASH_ENV are read-only variables in a restricted shell.
-
-e.  A change was made to the startup file code so that any shell begun with
-    the `--login' option, even non-interactive shells, will source the login
-    shell startup files.
-
-2.  New Features in Readline
-
-a.  Many changes to the signal handling:
-        o Readline now catches SIGQUIT and cleans up the tty before returning;
-        o A new variable, rl_catch_signals, is available to application writers 
-          to indicate to readline whether or not it should install its own
-          signal handlers for SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP,
-          SIGTTIN, and SIGTTOU;
-        o A new variable, rl_catch_sigwinch, is available to application
-          writers to indicate to readline whether or not it should install its
-          own signal handler for SIGWINCH, which will chain to the calling
-          applications's SIGWINCH handler, if one is installed;
-        o There is a new function, rl_free_line_state, for application signal
-          handlers to call to free up the state associated with the current
-          line after receiving a signal;
-        o There is a new function, rl_cleanup_after_signal, to clean up the
-          display and terminal state after receiving a signal;
-        o There is a new function, rl_reset_after_signal, to reinitialize the
-          terminal and display state after an application signal handler
-          returns and readline continues
-
-b.  There is a new function, rl_resize_terminal, to reset readline's idea of
-    the screen size after a SIGWINCH.
-
-c.  New public functions: rl_save_prompt and rl_restore_prompt.  These were
-    previously private functions with a `_' prefix.
-
-d.  New function hook: rl_pre_input_hook, called just before readline starts
-    reading input, after initialization.
-
-e.  New function hook: rl_display_matches_hook, called when readline would
-    display the list of completion matches.  The new function
-    rl_display_match_list is what readline uses internally, and is available
-    for use by application functions called via this hook.
-
-f.  New bindable function, delete-char-or-list, like tcsh.
-
-g.  A new variable, rl_erase_empty_line, which, if set by an application using
-    readline, will cause readline to erase, prompt and all, lines on which the
-    only thing typed was a newline.
-
-h.  New bindable variable: `isearch-terminators'.
-
-i.  New bindable function: `forward-backward-delete-char' (unbound by default).
-
--------------------------------------------------------------------------------
-This is a terse description of the new features added to bash-2.02 since
-the release of bash-2.01.1.  As always, the manual page (doc/bash.1) is
-the place to look for complete descriptions.
-
-1. New Features in Bash
-
-a.  A new version of malloc, based on the older GNU malloc, that has many
-    changes, is more page-based, is more conservative with memory usage,
-    and does not `orphan' large blocks when they are freed.
-
-b.  A new version of gmalloc, based on the old GLIBC malloc, with many
-    changes and range checking included by default.
-
-c.  A new implementation of fnmatch(3) that includes full POSIX.2 Basic
-    Regular Expression matching, including character classes, collating
-    symbols, equivalence classes, and support for case-insensitive pattern
-    matching.
-
-d.  ksh-88 egrep-style extended pattern matching ([@+*?!](patlist)) has been
-    implemented, controlled by a new `shopt' option, `extglob'.  
-    
-e.  There is a new ksh-like `[[' compound command, which implements   
-    extended `test' functionality.
-    
-f.  There is a new `printf' builtin, implemented according to the POSIX.2
-    specification.
-    
-g.  There is a new feature for command substitution: $(< filename) now expands
-    to the contents of `filename', with any trailing newlines removed
-    (equivalent to $(cat filename)).
-
-h.  There are new tilde prefixes which expand to directories from the
-    directory stack.
-
-i.  There is a new `**' arithmetic operator to do exponentiation.
-
-j.  There are new configuration options to control how bash is linked:
-    `--enable-profiling', to allow bash to be profiled with gprof, and
-    `--enable-static-link', to allow bash to be linked statically.
-
-k.  There is a new configuration option, `--enable-cond-command', which
-    controls whether or not the `[[' command is included.  It is on by
-    default. 
-
-l.  There is a new configuration option, `--enable-extended-glob', which
-    controls whether or not the ksh extended globbing feature is included.
-    It is enabled by default.
-
-m.  There is a new configuration #define in config.h.top that, when enabled,
-    will cause all login shells to source /etc/profile and one of the user-
-    specific login shell startup files, whether or not the shell is
-    interactive.  
-    
-n.  There is a new invocation option, `--dump-po-strings', to dump
-    a shell script's translatable strings ($"...") in GNU `po' format. 
-    
-o.  There is a new `shopt' option, `nocaseglob', to enable case-insensitive
-    pattern matching when globbing filenames and using the `case' construct.
-
-p.  There is a new `shopt' option, `huponexit', which, when enabled, causes
-    the shell to send SIGHUP to all jobs when an interactive login shell
-    exits.
-
-q.  `bind' has a new `-u' option, which takes a readline function name as an
-    argument and unbinds all key sequences bound to that function in a
-    specified keymap.
-    
-r.  `disown' now has `-a' and `-r' options, to limit operation to all jobs
-    and running jobs, respectively.
-
-s.  The `shopt' `-p' option now causes output to be displayed in a reusable
-    format.
-    
-t.  `test' has a new `-N' option, which returns true if the filename argument
-    has been modified since it was last accessed.
-
-u.  `umask' now has a `-p' option to print output in a reusable format.
-    
-v.  A new escape sequence, `\xNNN', has been added to the `echo -e' and $'...'
-    translation code.  It expands to the character whose ascii code is NNN
-    in hexadecimal.
-    
-w.  The prompt string expansion code has a new `\r' escape sequence.
-
-x.  The shell may now be cross-compiled for the CYGWIN32 environment on
-    a Unix machine.
-
-2. New Features in Readline
-
-a.  There is now an option for `iterative' yank-last-arg handline, so a user
-    can keep entering `M-.', yanking the last argument of successive history
-    lines.
-
-b.  New variable, `print-completions-horizontally', which causes completion
-    matches to be displayed across the screen (like `ls -x') rather than up
-    and down the screen (like `ls').
-
-c.  New variable, `completion-ignore-case', which causes filename completion
-    and matching to be performed case-insensitively.
-
-d.  There is a new bindable command, `magic-space', which causes history
-    expansion to be performed on the current readline buffer and a space to
-    be inserted into the result.
-
-e.  There is a new bindable command, `menu-complete', which enables tcsh-like
-    menu completion (successive executions of menu-complete insert a single
-    completion match, cycling through the list of possible completions).
-
-f.  There is a new bindable command, `paste-from-clipboard', for use on Win32
-    systems, to insert the text from the Win32 clipboard into the editing
-    buffer.
-
-g.  The key sequence translation code now understands printf-style backslash
-    escape sequences, including \NNN octal escapes.  These escape sequences
-    may be used in key sequence definitions or macro values.
-
-h.  An `$include' inputrc file parser directive has been added.
-
--------------------------------------------------------------------------------
-This is a terse description of the new features added to bash-2.01 since
-the release of bash-2.0.  As always, the manual page (doc/bash.1) is the
-place to look for complete descriptions.
-
-1. New Features in Bash
-
-a.  There is a new builtin array variable: GROUPS, the set of groups to which
-    the user belongs.  This is used by the test suite.
-
-2.  New Features in Readline
-
-a.  If a key sequence bound to `universal-argument' is read while reading a
-    numeric argument started with `universal-argument', it terminates the
-    argument but is otherwise ignored.  This provides a way to insert multiple
-    instances of a digit string, and is how GNU emacs does it.
-
--------------------------------------------------------------------------------
-This is a terse description of the new features added to bash-2.0 since
-the release of bash-1.14.7.  As always, the manual page (doc/bash.1) is
-the place to look for complete descriptions.
-
-1.  New Features in Bash
-
-a.  There is a new invocation option, -D, that dumps translatable strings
-    in a script.
-
-b.  The `long' invocation options must now be prefixed with `--'.
-
-c.  New long invocation options:  --dump-strings, --help, --verbose
-
-d.  The `nolineediting' invocation option was renamed to `noediting'.
-
-e.  The `nobraceexpansion' and `quiet' long invocation options were removed.
-
-f.  The `--help' and `--version' long options now work as the GNU coding
-    standards specify.
-
-g.  If invoked as `sh', bash now enters posix mode after reading the
-    startup files, and reads and executes commands from the file named
-    by $ENV if interactive (as POSIX.2 specifies).  A login shell invoked
-    as `sh' reads $ENV after /etc/profile and ~/.profile.
-
-h.  There is a new reserved word, `time', for timing pipelines, builtin
-    commands, and shell functions.  It uses the value of the TIMEFORMAT
-    variable as a format string describing how to print the timing
-    statistics.
-
-i.  The $'...' quoting syntax expands ANSI-C escapes in ... and leaves the
-    result single-quoted.
-
-j.  The $"..." quoting syntax performs locale-specific translation of ...
-    and leaves the result double-quoted.
-
-k.  LINENO now works correctly in functions.
-
-l.  New variables: DIRSTACK, PIPESTATUS, BASH_VERSINFO, HOSTNAME, SHELLOPTS,
-    MACHTYPE.  The first three are array variables.
-
-m.  The BASH_VERSION and BASH_VERSINFO variables now include the shell's
-    `release status' (alpha[N], beta[N], release).
-
-n.  Some variables have been removed:  MAIL_WARNING, notify, history_control,
-    command_oriented_history, glob_dot_filenames, allow_null_glob_expansion,
-    nolinks, hostname_completion_file, noclobber, no_exit_on_failed_exec, and
-    cdable_vars.  Most of them are now implemented with the new `shopt'
-    builtin; others were already implemented by `set'.
-
-o.  Bash now uses some new variables:  LC_ALL, LC_MESSAGES, LC_CTYPE,
-    LC_COLLATE, LANG, GLOBIGNORE, HISTIGNORE.
-
-p.  The shell now supports integer-indexed arrays of unlimited length,
-    with a new compound assignment syntax and changes to the appropriate
-    builtin commands (declare/typeset, read, readonly, etc.).  The array
-    index may be an arithmetic expression.
-
-q.  ${!var}: indirect variable expansion, equivalent to eval \${$var}.
-
-r.  ${paramter:offset[:length]}: variable substring extraction.
-
-s.  ${parameter/pattern[/[/]string]}: variable pattern substitution.
-
-t.  The $[...] arithmetic expansion syntax is no longer supported, in
-    favor of $((...)).
-
-u.  Aliases can now be expanded in shell scripts with a shell option
-    (shopt expand_aliases).
-
-v.  History and history expansion can now be used in scripts with
-    set -o history and set -H.
-
-w.  All builtins now return an exit status of 2 for incorrect usage.
-
-x.  Interactive shells resend SIGHUP to all running or stopped children
-    if (and only if) they exit due to a SIGHUP.
-
-y.  New prompting expansions: \a, \e, \H, \T, \@, \v, \V.
-
-z.  Variable expansion in prompt strings is now controllable via a shell
-    option (shopt promptvars).
-
-aa. Bash now defaults to using command-oriented history.
-
-bb. The history file ($HISTFILE) is now truncated to $HISTFILESIZE after
-    being written.
-
-cc. The POSIX.2 conditional arithmetic evaluation syntax (expr ? expr : expr)
-    has been implemented.
-
-dd. Each builtin now accepts `--' to signify the end of the options, except
-    as documented (echo, etc.).
-
-ee. All builtins use -p to display values in a re-readable format where
-    appropriate, except as documented (echo, type, etc.).
-
-ff. The `alias' builtin has a new -p option.
-
-gg. Changes to the `bind' builtin:
-       o has new options: -psPSVr.
-       o the `-d' option was renamed to `-p'
-       o the `-v' option now dumps variables; the old `-v' is now `-P'
-
-hh. The `bye' synonym for `exit' was removed.
-
-ii. The -L and -P options to `cd' and `pwd' have been documented.
-
-jj. The `cd' builtin now does spelling correction on the directory name
-    by default.  This is settable with a shell option (shopt cdspell).
-
-kk. The `declare' builtin has new options: -a, -F, -p.
-
-ll. The `dirs' builtin has new options: -c, -p, -v.
-
-mm. The new `disown' builtin removes jobs from the shell's jobs table
-    or inhibits the resending of SIGHUP when the shell receives a
-    SIGHUP.
-
-nn. The `echo' builtin has a new escape character: \e.
-
-oo. The `enable' builtin can now load new builtins dynamically from shared
-    objects on systems with the dlopen/dlsym interface.  There are a number
-    of examples in the examples/loadables directory.  There are also
-    new options: -d, -f, -s, -p.
-
-pp. The `-all' option to `enable' was removed in favor of `-a'.
-
-qq. The `exec' builtin has new options: -l, -c, -a.
-
-rr. The `hash' builtin has a new option: -p.
-
-ss. The `history' builtin has new options: -c, -p, -s.
-
-tt. The `jobs' builtin has new options: -r, -s.
-
-uu. The `kill' builtin has new options: -n signum, -l signame.
-
-vv. The `pushd' and `popd' builtins have a new option: -n.
-
-ww. The `read' builtin has new options: -p prompt, -e, -a.
-
-xx. The `readonly' builtin has a new -a option, and the -n option was removed.
-
-yy. Changes to the `set' builtin:
-       o new options: -B, -o keyword, -o onecmd, -o history
-       o options removed: -l, -d, -o nohash
-       o options changed: +o, -h, -o hashall
-       o now displays variables in a format that can be re-read as input
-
-zz. The new `shopt' builtin controls shell optional behavior previously
-    done by setting and unsetting certain shell variables.
-
-aaa. The `test' builtin has new operators: -o option, s1 == s2, s1 < s2,
-     and s1 > s2, where s1 and s2 are strings.
-
-bbb. There is a new trap, DEBUG, executed after every simple command.
-
-ccc. The `trap' builtin has a new -p option.
-
-ddd. The `ulimit' builtin has a new -l option on 4.4BSD-based systems.
-
-eee. The PS1, PS2, PATH, and IFS variables may now be unset.
-
-fff. The restricted shell mode has been expanded and is now documented.
-
-ggg. Security improvements:
-       o functions are not imported from the environment if running setuid
-         or with -p
-       o no startup files are sourced if running setuid or with -p
-
-hhh. The documentation has been overhauled:  the texinfo manual was
-     expanded, and HTML versions of the man page and texinfo manual
-     are included.
-
-iii. Changes to Posix mode:
-       o Command lookup now finds special builtins before shell functions.
-       o Failure of a special builtin causes a non-interactive shell to
-         exit.  Failures are defined in the POSIX.2 specification.
-       o If the `cd' builtin finds a directory to change to using $CDPATH,
-         the value assigned to PWD when `cd' completes does not contain
-         any symbolic links.
-       o A non-interactive shell exits if a variable assignment error
-         occurs when no command name follows the assignment statements.
-       o A non-interactive shell exits if the interation variable in a
-         `for' statement or the selection variable in a `select' statement
-         is read-only or another variable assignment error occurs.
-       o The `<>' redirection operator now opens a file for both stdin and
-         stdout by default, not just when in posix mode.
-       o Assignment statements preceding special builtins now persist in
-         the shell's environment when the builtin completes.
-
-     Posix mode is now completely POSIX.2-compliant (modulo bugs).  When
-     invoked as sh, bash should be completely POSIX.2-compliant.
-
-jjj. The default value of PS1 is now "\s-\v\$ ".
-
-kkk. The ksh-like ((...)) arithmetic command syntax has been implemented.
-     This is exactly equivalent to `let "..."'.
-
-lll. Integer constants have been extended to base 64.
-
-mmm. The `ulimit' builtin now sets both hard and soft limits and reports the
-     soft limit by default.
-
-2.  New Features in Readline
-
-a.  New variables:  enable-keypad, input-meta (new name for meta-flag),
-    mark-directories, visible-stats (now documented), disable-completion,
-    comment-begin.
-
-b.  New bindable commands:  kill-region, copy-region-as-kill,
-    copy-backward-word, copy-forward-word, set-mark, exchange-point-and-mark,
-    character-search, character-search-backward, insert-comment,
-    glob-expand-word, glob-list-expansions, dump-variables, dump-macros.
-
-c.  New emacs keybindings:  delete-horizontal-space (M-\),
-    insert-completions (M-*), possible-completions (M-=).
-
-d.  The history-search-backward and history-search-forward commands were
-    modified to be the same as previous-line and next-line if point is at
-    the start of the line.
-
-e.  More file types are available for the visible-stats mode.
-
-3.  Changes of interest in the Bash implementation
-
-a.  There is a new autoconf-based configuration mechanism.
-
-b.  More things have been moved from Posix mode to standard shell behavior.
-
-c.  The trace output (set -x) now inserts quotes where necessary so it can
-    be reused as input.
-
-d.  There is a compile-time option for a system-wide interactive shell
-    startup file (disabled by default).
-
-e.  The YACC grammar is smaller and tighter, and all 66 shift-reduce
-    conflicts are gone.  Several parsing bugs have been fixed.
-
-f.  Builtin option parsing has been regularized (using internal_getopt()),
-    with the exception of `echo', `type', and `set'.
-
-g.  Builtins now return standard usage messages constructed from the
-    `short doc' used by the help builtin.
-
-h.  Completion now quotes using backslashes by default, but honors
-    user-supplied quotes.
-
-i.  The GNU libc malloc is available as a configure-time option.
-
-j.  There are more internationalization features; bash uses gettext if
-    it is available.  The $"..." translation syntax uses the current
-    locale and gettext.
-
-k.  There is better reporting of job termination when the shell is not
-    interactive.
-
-l.  The shell is somewhat more efficient: it uses a little less memory and
-    makes fewer system calls.
-
-4.  Changes of interest in the Readline implementation
-
-a.  There is now support for readline `callback' functions.
-
-b.  There is now support for user-supplied input, redisplay, and terminal
-    preparation functions.
-
-c.  Most of the shell-specific code in readline has been generalized or
-    removed.
-
-d.  Most of the annoying redisplay bugs have been fixed, notably the problems
-    with incremental search and excessive redrawing when special characters
-    appear in the prompt string.
-
-e.  There are new library functions and variables available to application
-    writers, most having to do with completion and quoting.
-
-f.  The NEWLINE character (^J) is now treated as a search terminator by the
-    incremental search functions.
--------------------------------------------------------------------------------
-
-Copying and distribution of this file, with or without modification,
-are permitted in any medium without royalty provided the copyright
-notice and this notice are preserved.  This file is offered as-is,
-without any warranty.
diff --git a/NEWS~ b/NEWS~
deleted file mode 100644 (file)
index 2d929b6..0000000
--- a/NEWS~
+++ /dev/null
@@ -1,1537 +0,0 @@
-This is a terse description of the new features added to bash-4.1 since
-the release of bash-4.0.  As always, the manual page (doc/bash.1) is
-the place to look for complete descriptions.
-
-1.  New Features in Bash
-
-a.  Here-documents within $(...) command substitutions may once more be
-    delimited by the closing right paren, instead of requiring a newline.
-
-b.  Bash's file status checks (executable, readable, etc.) now take file
-    system ACLs into account on file systems that support them.
-
-c.  Bash now passes environment variables with names that are not valid
-    shell variable names through into the environment passed to child
-    processes.
-
-d.  The `execute-unix-command' readline function now attempts to clear and
-    reuse the current line rather than move to a new one after the command
-    executes.
-
-e.  `printf -v' can now assign values to array indices.
-
-f.  New `complete -E' and `compopt -E' options that work on the "empty"
-    completion: completion attempted on an empty command line.
-
-g.  New complete/compgen/compopt -D option to define a `default' completion:
-    a completion to be invoked on command for which no completion has been
-    defined.  If this function returns 124, programmable completion is
-    attempted again, allowing a user to dynamically build a set of completions
-    as completion is attempted by having the default completion function
-    install individual completion functions each time it is invoked.
-
-h.  When displaying associative arrays, subscripts are now quoted.
-
-i.  Changes to dabbrev-expand to make it more `emacs-like': no space appended
-    after matches, completions are not sorted, and most recent history entries
-    are presented first.
-
-j.  The [[ and (( commands are now subject to the setting of `set -e' and the
-    ERR trap.
-
-k.  The source/. builtin now removes NUL bytes from the file before attempting
-    to parse commands.
-
-l.  There is a new configuration option (in config-top.h) that forces bash to
-    forward all history entries to syslog.
-
-m.  A new variable $BASHOPTS to export shell options settable using `shopt' to
-    child processes.
-
-n.  There is a new confgure option that forces the extglob option to be
-    enabled by default.
-
-o.  New variable $BASH_XTRACEFD; when set to an integer bash will write xtrace
-    output to that file descriptor.
-
-p.  If the optional left-hand-side of a redirection is of the form {var}, the
-    shell assigns the file descriptor used to $var or uses $var as the file
-    descriptor to move or close, depending on the redirection operator.
-
-q.  The < and > operators to the [[ conditional command now do string
-    comparison according to the current locale.
-
-r.  Programmable completion now uses the completion for `b' instead of `a'
-    when completion is attempted on a line like: a $(b c.
-
-s.  Force extglob on temporarily when parsing the pattern argument to
-    the == and != operators to the [[ command, for compatibility.
-
-t.  Changed the behavior of interrupting the wait builtin when a SIGCHLD is
-    received and a trap on SIGCHLD is set to be Posix-mode only.
-
-u.  The read builtin has a new `-N nchars' option, which reads exactly NCHARS
-    characters, ignoring delimiters like newline.
-
-v.  The mapfile/readarray builtin no longer stores the commands it invokes via
-    callbacks in the history list.
-
-w.  There is a new `compat40' shopt option.
-
-x.  The < and > operators to [[ do string comparisons using the current locale
-    only if the compatibility level is greater than 40 (set to 41 by default).
-
-2.  New Features in Readline
-
-a.  New bindable function: menu-complete-backward.
-
-b.  In the vi insertion keymap, C-n is now bound to menu-complete by default,
-    and C-p to menu-complete-backward.
-
-c.  When in vi command mode, repeatedly hitting ESC now does nothing, even
-    when ESC introduces a bound key sequence.  This is closer to how
-    historical vi behaves.
-
-d.  New bindable function: skip-csi-sequence.  Can be used as a default to
-    consume key sequences generated by keys like Home and End without having
-    to bind all keys.
-
-e.  New application-settable function: rl_filename_rewrite_hook.  Can be used
-    to rewite or modify filenames read from the file system before they are
-    compared to the word to be completed.
-
-f.  New bindable variable: skip-completed-text, active when completing in the
-    middle of a word.  If enabled, it means that characters in the completion
-    that match characters in the remainder of the word are "skipped" rather
-    than inserted into the line.
-
-g.  The pre-readline-6.0 version of menu completion is available as
-    "old-menu-complete" for users who do not like the readline-6.0 version.
-
-h.  New bindable variable: echo-control-characters.  If enabled, and the
-    tty ECHOCTL bit is set, controls the echoing of characters corresponding
-    to keyboard-generated signals.
-
-i.  New bindable variable: enable-meta-key.  Controls whether or not readline
-    sends the smm/rmm sequences if the terminal indicates it has a meta key
-    that enables eight-bit characters.
-
--------------------------------------------------------------------------------
-This is a terse description of the new features added to bash-4.0 since
-the release of bash-3.2.  As always, the manual page (doc/bash.1) is
-the place to look for complete descriptions.
-
-1.  New Features in Bash
-
-a.  When using substring expansion on the positional parameters, a starting
-    index of 0 now causes $0 to be prefixed to the list.
-
-b.  The `help' builtin now prints its columns with entries sorted vertically
-    rather than horizontally.
-
-c.  There is a new variable, $BASHPID, which always returns the process id of
-    the current shell.
-
-d.  There is a new `autocd' option that, when enabled, causes bash to attempt
-    to `cd' to a directory name that is supplied as the first word of a
-    simple command.
-
-e.  There is a new `checkjobs' option that causes the shell to check for and
-    report any running or stopped jobs at exit.
-
-f.  The programmable completion code exports a new COMP_TYPE variable, set to
-    a character describing the type of completion being attempted.
-
-g.  The programmable completion code exports a new COMP_KEY variable, set to
-    the character that caused the completion to be invoked (e.g., TAB).
-
-h.  If creation of a child process fails due to insufficient resources, bash
-    will try again several times before reporting failure.
-
-i.  The programmable completion code now uses the same set of characters as
-    readline when breaking the command line into a list of words.
-
-j.  The block multiplier for the ulimit -c and -f options is now 512 when in
-    Posix mode, as Posix specifies.
-
-k.  Changed the behavior of the read builtin to save any partial input received
-    in the specified variable when the read builtin times out.  This also
-    results in variables specified as arguments to read to be set to the empty
-    string when there is no input available.  When the read builtin times out,
-    it returns an exit status greater than 128.
-
-l.  The shell now has the notion of a `compatibility level', controlled by
-    new variables settable by `shopt'.  Setting this variable currently
-    restores the bash-3.1 behavior when processing quoted strings on the rhs
-    of the `=~' operator to the `[[' command.
-
-m.  The `ulimit' builtin now has new -b (socket buffer size) and -T (number
-    of threads) options.
-
-n.  The -p option to `declare' now displays all variable values and attributes
-    (or function values and attributes if used with -f).
-
-o.  There is a new `compopt' builtin that allows completion functions to modify
-    completion options for existing completions or the completion currently
-    being executed.
-
-p.  The `read' builtin has a new -i option which inserts text into the reply
-    buffer when using readline.
-
-q.  A new `-E' option to the complete builtin allows control of the default
-    behavior for completion on an empty line.
-
-r.  There is now limited support for completing command name words containing
-    globbing characters.
-
-s.  Changed format of internal help documentation for all builtins to roughly
-    follow man page format.
-
-t.  The `help' builtin now has a new -d option, to display a short description,
-    and a -m option, to print help information in a man page-like format.
-
-u.  There is a new `mapfile' builtin to populate an array with lines from a
-    given file.  The name `readarray' is a synonym.
-
-v.  If a command is not found, the shell attempts to execute a shell function
-    named `command_not_found_handle', supplying the command words as the
-    function arguments.
-
-w.  There is a new shell option: `globstar'.  When enabled, the globbing code
-    treats `**' specially -- it matches all directories (and files within
-    them, when appropriate) recursively.
-
-x.  There is a new shell option: `dirspell'.  When enabled, the filename
-    completion code performs spelling correction on directory names during
-    completion.
-
-y.  The `-t' option to the `read' builtin now supports fractional timeout
-    values.
-
-z.  Brace expansion now allows zero-padding of expanded numeric values and
-    will add the proper number of zeroes to make sure all values contain the
-    same number of digits.
-
-aa. There is a new bash-specific bindable readline function: `dabbrev-expand'.
-    It uses menu completion on a set of words taken from the history list.
-
-bb. The command assigned to a key sequence with `bind -x' now sets two new
-    variables in the environment of the executed command:  READLINE_LINE_BUFFER
-    and READLINE_POINT.  The command can change the current readline line
-    and cursor position by modifying READLINE_LINE_BUFFER and READLINE_POINT,
-    respectively.
-
-cc. There is a new &>> redirection operator, which appends the standard output
-    and standard error to the named file.
-
-dd. The parser now understands `|&' as a synonym for `2>&1 |', which redirects
-    the standard error for a command through a pipe.
-
-ee. The new `;&' case statement action list terminator causes execution to
-    continue with the action associated with the next pattern in the
-    statement rather than terminating the command.
-
-ff. The new `;;&' case statement action list terminator causes the shell to
-    test the next set of patterns after completing execution of the current
-    action, rather than terminating the command.
-
-gg. The shell understands a new variable: PROMPT_DIRTRIM.  When set to an
-    integer value greater than zero, prompt expansion of \w and \W  will
-    retain only that number of trailing pathname components and replace
-    the intervening characters with `...'.
-
-hh. There are new case-modifying word expansions: uppercase (^[^]) and
-    lowercase (,[,]).  They can work on either the first character or
-    array element, or globally.  They accept an optional shell pattern
-    that determines which characters to modify.  There is an optionally-
-    configured feature to include capitalization operators.
-
-ii. The shell provides associative array variables, with the appropriate
-    support to create, delete, assign values to, and expand them.
-
-jj. The `declare' builtin now has new -l (convert value to lowercase upon
-    assignment) and -u (convert value to uppercase upon assignment) options.
-    There is an optionally-configurable -c option to capitalize a value at
-    assignment.
-
-kk. There is a new `coproc' reserved word that specifies a coprocess: an
-    asynchronous command run with two pipes connected to the creating shell.
-    Coprocs can be named.  The input and output file descriptors and the
-    PID of the coprocess are available to the calling shell in variables
-    with coproc-specific names.
-
-ll. A value of 0 for the -t option to `read' now returns success if there is
-    input available to be read from the specified file descriptor.
-
-mm. CDPATH and GLOBIGNORE are ignored when the shell is running in privileged
-    mode.
-
-nn. New bindable readline functions shell-forward-word and shell-backward-word,
-    which move forward and backward words delimited by shell metacharacters
-    and honor shell quoting.
-
-oo.  New bindable readline functions shell-backward-kill-word and shell-kill-word
-    which kill words backward and forward, but use the same word boundaries
-    as shell-forward-word and shell-backward-word.
-
-2.  New Features in Readline
-
-a.  A new variable, rl_sort_completion_matches; allows applications to inhibit
-    match list sorting (but beware: some things don't work right if
-    applications do this).
-
-b.  A new variable, rl_completion_invoking_key; allows applications to discover
-    the key that invoked rl_complete or rl_menu_complete.
-
-c.  The functions rl_block_sigint and rl_release_sigint are now public and
-    available to calling applications who want to protect critical sections
-    (like redisplay).
-
-d.  The functions rl_save_state and rl_restore_state are now public and
-    available to calling applications; documented rest of readline's state
-    flag values.
-
-e.  A new user-settable variable, `history-size', allows setting the maximum
-    number of entries in the history list.
-
-f.  There is a new implementation of menu completion, with several improvements
-    over the old; the most notable improvement is a better `completions
-    browsing' mode.
-
-g.  The menu completion code now uses the rl_menu_completion_entry_function
-    variable, allowing applications to provide their own menu completion
-    generators.
-
-h.  There is support for replacing a prefix  of a pathname with a `...' when
-    displaying possible completions.  This is controllable by setting the
-    `completion-prefix-display-length' variable.  Matches with a common prefix
-    longer than this value have the common prefix replaced with `...'.
-
-i.  There is a new `revert-all-at-newline' variable.  If enabled, readline will
-    undo all outstanding changes to all history lines when `accept-line' is
-    executed.
-
-j.  If the kernel supports it, readline displays special characters
-    corresponding to a keyboard-generated signal when the signal is received.
-
--------------------------------------------------------------------------------
-This is a terse description of the new features added to bash-3.2 since
-the release of bash-3.1.  As always, the manual page (doc/bash.1) is
-the place to look for complete descriptions.
-
-1.  New Features in Bash
-
-a.  Changed the parameter pattern replacement functions to not anchor the
-    pattern at the beginning of the string if doing global replacement - that
-    combination doesn't make any sense.
-
-b.  When running in `word expansion only' mode (--wordexp option), inhibit
-    process substitution.
-
-c.  Loadable builtins now work on MacOS X 10.[34].
-
-d.  Shells running in posix mode no longer set $HOME, as POSIX requires.
-
-e.  The code that checks for binary files being executed as shell scripts now
-    checks only for NUL rather than any non-printing character.
-
-f.  Quoting the string argument to the [[ command's  =~ operator now forces
-    string matching, as with the other pattern-matching operators.
-
-2.  New Features in Readline
-
-a.  Calling applications can now set the keyboard timeout to 0, allowing
-    poll-like behavior.
-
-b.  The value of SYS_INPUTRC (configurable at compilation time) is now used as
-    the default last-ditch startup file.
-
-c.  The history file reading functions now allow windows-like \r\n line
-    terminators.
-
--------------------------------------------------------------------------------
-This is a terse description of the new features added to bash-3.1 since
-the release of bash-3.0.  As always, the manual page (doc/bash.1) is
-the place to look for complete descriptions.
-
-1.  New Features in Bash
-
-a.  Bash now understands LC_TIME as a special variable so that time display
-    tracks the current locale.
-
-b.  BASH_ARGC, BASH_ARGV, BASH_SOURCE, and BASH_LINENO are no longer created
-    as `invisible' variables and may not be unset.
-
-c.  In POSIX mode, if `xpg_echo' option is enabled, the `echo' builtin doesn't
-    try to interpret any options at all, as POSIX requires.
-
-d.  The `bg' builtin now accepts multiple arguments, as POSIX seems to specify.
-
-e.  Fixed vi-mode word completion and glob expansion to perform tilde
-    expansion.
-
-f.  The `**' mathematic exponentiation operator is now right-associative.
-
-g.  The `ulimit' builtin has new options: -i (max number of pending signals),
-    -q (max size of POSIX message queues), and -x (max number of file locks).
-
-h.  A bare `%' once again expands to the current job when used as a job
-    specifier.
-
-i.  The `+=' assignment operator (append to the value of a string or array) is
-    now supported for assignment statements and arguments to builtin commands
-    that accept assignment statements.
-
-j.  BASH_COMMAND now preserves its value when a DEBUG trap is executed.
-
-k.  The `gnu_errfmt' option is enabled automatically if the shell is running
-    in an emacs terminal window.
-
-l.  New configuration option:  --single-help-strings.  Causes long help text
-    to be written as a single string; intended to ease translation.
-
-m.  The COMP_WORDBREAKS variable now causes the list of word break characters
-    to be emptied when the variable is unset.
-
-n.  An unquoted expansion of $* when $IFS is empty now causes the positional
-    parameters to be concatenated if the expansion doesn't undergo word
-    splitting.
-
-o.  Bash now inherits $_ from the environment if it appears there at startup.
-
-p.  New shell option: nocasematch.  If non-zero, shell pattern matching ignores
-    case when used by `case' and `[[' commands.
-
-q.  The `printf' builtin takes a new option: -v var.  That causes the output
-    to be placed into var instead of on stdout.
-
-r.  By default, the shell no longer reports processes dying from SIGPIPE.
-
-s.  Bash now sets the extern variable `environ' to the export environment it
-    creates, so C library functions that call getenv() (and can't use the
-    shell-provided replacement) get current values of environment variables.
-
-t.  A new configuration option, `--enable-strict-posix-default', which will
-    build bash to be POSIX conforming by default.
-
-u.  If compiled for strict POSIX conformance, LINES and COLUMNS may now
-    override the true terminal size.
-
-2.  New Features in Readline
-
-a.  The key sequence sent by the keypad `delete' key is now automatically
-    bound to delete-char.
-
-b.  A negative argument to menu-complete now cycles backward through the
-    completion list.
-
-c.  A new bindable readline variable:  bind-tty-special-chars.  If non-zero,
-    readline will bind the terminal special characters to their readline
-    equivalents when it's called (on by default).
-
-d.  New bindable command: vi-rubout.  Saves deleted text for possible
-    reinsertion, as with any vi-mode `text modification' command; `X' is bound
-    to this in vi command mode.
-
-e.  A new external application-controllable variable that allows the LINES
-    and COLUMNS environment variables to set the window size regardless of
-    what the kernel returns: rl_prefer_env_winsize
-
--------------------------------------------------------------------------------
-This is a terse description of the new features added to bash-3.0 since
-the release of bash-2.05b.  As always, the manual page (doc/bash.1) is
-the place to look for complete descriptions.
-
-1.  New Features in Bash
-
-a.  ANSI string expansion now implements the \x{hexdigits} escape.
-
-b.  There is a new loadable `strftime' builtin.
-
-c.  New variable, COMP_WORDBREAKS, which controls the readline completer's
-    idea of word break characters.
-
-d.  The `type' builtin no longer reports on aliases unless alias expansion
-    will actually be performed.    
-
-e.  HISTCONTROL is now a colon-separated list of values, which permits
-    more extensibility and backwards compatibility.
-
-f.  HISTCONTROL may now include the `erasedups' option, which causes all lines
-    matching a line being added to be removed from the history list.
-
-g.  `configure' has a new `--enable-multibyte' argument that permits multibyte
-    character support to be disabled even on systems that support it.
-
-h.  New variables to support the bash debugger:  BASH_ARGC, BASH_ARGV,
-    BASH_SOURCE, BASH_LINENO, BASH_SUBSHELL, BASH_EXECUTION_STRING,
-    BASH_COMMAND
-
-i.  FUNCNAME has been changed to support the debugger: it's now an array
-    variable.
-
-j.  for, case, select, arithmetic commands now keep line number information
-    for the debugger.
-
-k.  There is a new `RETURN' trap executed when a function or sourced script
-    returns (not inherited child processes; inherited by command substitution
-    if function tracing is enabled and the debugger is active).
-
-l.  New invocation option:  --debugger.  Enables debugging and turns on new
-    `extdebug' shell option.
-
-m.  New `functrace' and `errtrace' options to `set -o' cause DEBUG and ERR
-    traps, respectively, to be inherited by shell functions.  Equivalent to
-    `set -T' and `set -E' respectively.  The `functrace' option also controls
-    whether or not the DEBUG trap is inherited by sourced scripts.
-
-n.  The DEBUG trap is run before binding the variable and running the action
-    list in a `for' command, binding the selection variable and running the
-    query in a `select' command, and before attempting a match in a `case'
-    command.
-
-o.  New `--enable-debugger' option to `configure' to compile in the debugger
-    support code.
-
-p.  `declare -F' now prints out extra line number and source file information
-    if the `extdebug' option is set.
-
-q.  If `extdebug' is enabled, a non-zero return value from a DEBUG trap causes
-    the next command to be skipped, and a return value of 2 while in a
-    function or sourced script forces a `return'.
-
-r.  New `caller' builtin to provide a call stack for the bash debugger.
-
-s.  The DEBUG trap is run just before the first command in a function body is
-    executed, for the debugger.
-
-t.  `for', `select', and `case' command heads are printed when `set -x' is
-    enabled.
-
-u.  There is a new {x..y} brace expansion, which is shorthand for {x.x+1,
-    x+2,...,y}.  x and y can be integers or single characters; the sequence
-    may ascend or descend; the increment is always 1.
-
-v.  New ksh93-like ${!array[@]} expansion, expands to all the keys (indices)
-    of array.
-
-w.  New `force_fignore' shopt option; if enabled, suffixes specified by
-    FIGNORE cause words to be ignored when performing word completion even
-    if they're the only possibilities.
-
-x.  New `gnu_errfmt' shopt option; if enabled, error messages follow the `gnu
-    style' (filename:lineno:message) format.
-
-y.  New `-o bashdefault' option to complete and compgen; if set, causes the
-    whole set of bash completions to be performed if the compspec doesn't
-    result in a match.
-
-z.  New `-o plusdirs' option to complete and compgen; if set, causes directory
-    name completion to be performed and the results added to the rest of the
-    possible completions.
-
-aa. `kill' is available as a builtin even when the shell is built without
-    job control.
-
-bb. New HISTTIMEFORMAT variable; value is a format string to pass to
-    strftime(3).  If set and not null, the `history' builtin prints out
-    timestamp information according to the specified format when displaying
-    history entries.  If set, bash tells the history library to write out
-    timestamp information when the history file is written.
-
-cc. The [[ ... ]] command has a new binary `=~' operator that performs
-    extended regular expression (egrep-like) matching.
-
-dd. `configure' has a new `--enable-cond-regexp' option (enabled by default)
-    to enable the =~ operator and regexp matching in [[ ... ]].
-
-ee. Subexpressions matched by the =~ operator are placed in the new
-    BASH_REMATCH array variable.
-
-ff. New `failglob' option that causes an expansion error when pathname
-    expansion fails to produce a match.
-
-gg. New `set -o pipefail' option that causes a pipeline to return a failure
-    status if any of the processes in the pipeline fail, not just the last
-    one.
-
-hh. printf builtin understands two new escape sequences:  \" and \?.
-
-ii. `echo -e' understands two new escape sequences:  \" and \?.
-
-jj. The GNU `gettext' package and libintl have been integrated; the shell's
-    messages can be translated into different languages.
-
-kk. The `\W' prompt expansion now abbreviates $HOME as `~', like `\w'.
-
-ll. The error message printed when bash cannot open a shell script supplied
-    as argument 1 now includes the name of the shell, to better identify
-    the error as coming from bash.
-
-mm. The parameter pattern removal and substitution expansions are now much
-    faster and more efficient when using multibyte characters.
-
-nn. The `jobs', `kill', and `wait' builtins now accept job control notation
-    even if job control is not enabled.
-
-oo. The historical behavior of `trap' that allows a missing `action' argument
-    to cause each specified signal's handling to be reset to its default is
-    now only supported when `trap' is given a single non-option argument.
-
-2.  New Features in Readline
-
-a.  History expansion has a new `a' modifier equivalent to the `g' modifier
-    for compatibility with the BSD csh.
-
-b.  History expansion has a new `G' modifier equivalent to the BSD csh `g'
-    modifier, which performs a substitution once per word.
-
-c.  All non-incremental search operations may now undo the operation of
-    replacing the current line with the history line.
-
-d.  The text inserted by an `a' command in vi mode can be reinserted with
-    `.'.
-
-e.  New bindable variable, `show-all-if-unmodified'.  If set, the readline
-    completer will list possible completions immediately if there is more
-    than one completion and partial completion cannot be performed.
-
-f.  There is a new application-callable `free_history_entry()' function.
-
-g.  History list entries now contain timestamp information; the history file
-    functions know how to read and write timestamp information associated
-    with each entry.
-
-h.  Four new key binding functions have been added:
-
-       rl_bind_key_if_unbound()
-       rl_bind_key_if_unbound_in_map()
-       rl_bind_keyseq_if_unbound()
-       rl_bind_keyseq_if_unbound_in_map()
-
-i.  New application variable, rl_completion_quote_character, set to any
-    quote character readline finds before it calls the application completion
-    function.
-
-j.  New application variable, rl_completion_suppress_quote, settable by an
-    application completion function.  If set to non-zero, readline does not
-    attempt to append a closing quote to a completed word.
-
-k.  New application variable, rl_completion_found_quote, set to a non-zero
-    value if readline determines that the word to be completed is quoted.
-    Set before readline calls any application completion function.
-
-l.  New function hook, rl_completion_word_break_hook, called when readline
-    needs to break a line into words when completion is attempted.  Allows
-    the word break characters to vary based on position in the line.
-
-m.  New bindable command: unix-filename-rubout.  Does the same thing as
-    unix-word-rubout, but adds `/' to the set of word delimiters.
-
-n.  When listing completions, directories have a `/' appended if the
-    `mark-directories' option has been enabled.
-
--------------------------------------------------------------------------------
-This is a terse description of the new features added to bash-2.05b since
-the release of bash-2.05a.  As always, the manual page (doc/bash.1) is
-the place to look for complete descriptions.
-
-1.  New Features in Bash
-
-a.  If set, TMOUT is the default timeout for the `read' builtin.
-
-b.  `type' has two new options:  `-f' suppresses shell function lookup, and
-    `-P' forces a $PATH search.
-
-c.  New code to handle multibyte characters.
-
-d.  `select' was changed to be more ksh-compatible, in that the menu is
-    reprinted each time through the loop only if REPLY is set to NULL.
-    The previous behavior is available as a compile-time option.
-
-e.  `complete -d' and `complete -o dirnames' now force a slash to be
-    appended to names which are symlinks to directories.
-
-f.  There is now a bindable edit-and-execute-command readline command,
-    like the vi-mode `v' command, bound to C-xC-e in emacs mode.
-
-g.  Added support for ksh93-like [:word:] character class in pattern matching.
-
-h.  The  $'...' quoting construct now expands \cX to Control-X.
-
-i.  A new \D{...} prompt expansion; passes the `...' to strftime and inserts
-    the result into the expanded prompt.
-
-j.  The shell now performs arithmetic in the largest integer size the
-    machine supports (intmax_t), instead of long.
-
-k.  If a numeric argument is supplied to one of the bash globbing completion
-    functions, a `*' is appended to the word before expansion is attempted.
-
-l.  The bash globbing completion functions now allow completions to be listed
-    with double tabs or if `show-all-if-ambiguous' is set.
-
-m.  New `-o nospace' option for `complete' and `compgen' builtins; suppresses
-    readline's appending a space to the completed word.
-
-n.  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).
-
-p.  There is a new configuration option `--enable-mem-scramble', controls
-    bash malloc behavior of writing garbage characters into memory at
-    allocation and free time.
-
-q.  The `complete' and `compgen' builtins now have a new `-s/-A service'
-    option to complete on names from /etc/services.
-
-r.  `read' has a new `-u fd' option to read from a specified file descriptor.
-
-s.  Fix the completion code so that expansion errors in a directory name
-    don't cause a longjmp back to the command loop.
-
-t.  Fixed word completion inside command substitution to work a little more
-    intuitively.
-
-u.  The `printf' %q format specifier now uses $'...' quoting to print the
-    argument if it contains non-printing characters.
-
-v.  The `declare' and `typeset' builtins have a new `-t' option.  When applied
-    to functions, it causes the DEBUG trap to be inherited by the named
-    function.  Currently has no effect on variables.
-
-w.  The DEBUG trap is now run *before* simple commands, ((...)) commands,
-    [[...]] conditional commands, and for ((...)) loops.
-
-x.  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.
-
-y.  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.  Code
-    from Gary Vaughan.
-
-z.  New [n]<&word- and [n]>&word- redirections from ksh93 -- move fds (dup
-    and close).
-
-aa. There is a new `-l' invocation option, equivalent to `--login'.
-
-bb. The `hash' builtin has a new `-l' option to list contents in a reusable
-    format, and a `-d' option to remove a name from the hash table.
-
-cc. There is now support for placing the long help text into separate files 
-    installed into ${datadir}/bash.  Not enabled by default; can be turned  
-    on with `--enable-separate-helpfiles' option to configure.
-    
-dd. All builtins that take operands accept a `--' pseudo-option, except
-    `echo'.
-
-ee. The `echo' builtin now accepts \0xxx (zero to three octal digits following
-    the `0') in addition to \xxx (one to three octal digits) for SUSv3/XPG6/
-    POSIX.1-2001 compliance.
-
-
-2.  New Features in Readline
-
-a.  Support for key `subsequences':  allows, e.g., ESC and ESC-a to both
-    be bound to readline functions.  Now the arrow keys may be used in vi
-    insert mode.
-
-b.  When listing completions, and the number of lines displayed is more than
-    the screen length, readline uses an internal pager to display the results.
-    This is controlled by the `page-completions' variable (default on).
-
-c.  New code to handle editing and displaying multibyte characters.
-
-d.  The behavior introduced in bash-2.05a of deciding whether or not to
-    append a slash to a completed name that is a symlink to a directory has
-    been made optional, controlled by the `mark-symlinked-directories'
-    variable (default is the 2.05a behavior).
-
-e.  The `insert-comment' command now acts as a toggle if given a numeric
-    argument:  if the first characters on the line don't specify a
-    comment, insert one; if they do, delete the comment text
-
-f.  New application-settable completion variable:
-    rl_completion_mark_symlink_dirs, allows an application's completion
-    function to temporarily override the user's preference for appending
-    slashes to names which are symlinks to directories.
-
-g.  New function available to application completion functions:
-    rl_completion_mode, to tell how the completion function was invoked
-    and decide which argument to supply to rl_complete_internal (to list
-    completions, etc.).
-
-h.  Readline now has an overwrite mode, toggled by the `overwrite-mode'
-    bindable command, which could be bound to `Insert'.
-
-i.  New application-settable completion variable:
-    rl_completion_suppress_append, inhibits appending of
-    rl_completion_append_character to completed words.
-
-j.  New key bindings when reading an incremental search string:  ^W yanks
-    the currently-matched word out of the current line into the search
-    string; ^Y yanks the rest of the current line into the search string,
-    DEL or ^H deletes characters from the search string.
-
--------------------------------------------------------------------------------
-This is a terse description of the new features added to bash-2.05a since
-the release of bash-2.05.  As always, the manual page (doc/bash.1) is
-the place to look for complete descriptions.
-
-1.  New Features in Bash
-
-a.  Added support for DESTDIR installation root prefix, so you can do a
-    `make install DESTDIR=bash-root' and do easier binary packaging.
-
-b.  Added support for builtin printf "'" flag character as per latest POSIX
-    drafts.
-
-c.  Support for POSIX.2 printf(1) length specifiers `j', `t', and `z' (from
-    ISO C99).
-
-d.  New autoconf macro, RL_LIB_READLINE_VERSION, for use by other applications
-    (bash doesn't use very much of what it returns).
-
-e.  `set [-+]o nolog' is recognized as required by the latest POSIX drafts,
-    but ignored.
-
-f.  New read-only `shopt' option:  login_shell.  Set to non-zero value if the
-    shell is a login shell.
-
-g.  New `\A' prompt string escape sequence; expands to time in 24 HH:MM format.
-
-h.  New `-A group/-g' option to complete and compgen; does group name
-    completion.
-
-i.  New `-t' option to `hash' to list hash values for each filename argument.
-
-j.  New [-+]O invocation option to set and unset `shopt' options at startup.
-
-k.  configure's `--with-installed-readline' option now takes an optional
-    `=PATH' suffix to set the root of the tree where readline is installed
-    to PATH.
-
-l.  The ksh-like `ERR' trap has been added.  The `ERR' trap will be run
-    whenever the shell would have exited if the -e option were enabled.
-    It is not inherited by shell functions.
-
-m.  `readonly', `export', and `declare' now print variables which have been
-    given attributes but not set by assigning a value as just a command and
-    a variable name (like `export foo') when listing, as the latest POSIX
-    drafts require.
-
-n.  `bashbug' now requires that the subject be changed from the default.
-
-o.  configure has a new `--enable-largefile' option, like other GNU utilities.
-
-p.  `for' loops now allow empty word lists after `in', like the latest POSIX
-    drafts require.
-
-q.  The builtin `ulimit' now takes two new non-numeric arguments:  `hard',
-    meaning the current hard limit, and `soft', meaning the current soft  
-    limit, in addition to `unlimited'
-    
-r.  `ulimit' now prints the option letter associated with a particular
-    resource when printing more than one limit.
-
-s.  `ulimit' prints `hard' or `soft' when a value is not `unlimited' but is
-    one of RLIM_SAVED_MAX or RLIM_SAVED_CUR, respectively.
-
-t.  The `printf' builtin now handles the %a and %A conversions if they're
-    implemented by printf(3).
-
-u.  The `printf' builtin now handles the %F conversion (just about like %f).
-
-v.  The `printf' builtin now handles the %n conversion like printf(3).  The
-    corresponding argument is the name of a shell variable to which the
-    value is assigned.
-
-2.  New Features in Readline
-
-a.  Added extern declaration for rl_get_termcap to readline.h, making it a
-    public function (it was always there, just not in readline.h).
-
-b.  New #defines in readline.h:  RL_READLINE_VERSION, currently 0x0402,
-    RL_VERSION_MAJOR, currently 4, and RL_VERSION_MINOR, currently 2.
-
-c.  New readline variable:  rl_readline_version, mirrors RL_READLINE_VERSION.
-
-d.  New bindable boolean readline variable:  match-hidden-files.  Controls
-    completion of files beginning with a `.' (on Unix).  Enabled by default.
-
-e.  The history expansion code now allows any character to terminate a
-    `:first-' modifier, like csh.
-
-f.  New bindable variable `history-preserve-point'.  If set, the history
-    code attempts to place the user at the same location on each history
-    line retrived with previous-history or next-history.
-
--------------------------------------------------------------------------------
-This is a terse description of the new features added to bash-2.05 since
-the release of bash-2.04.  As always, the manual page (doc/bash.1) is
-the place to look for complete descriptions.
-
-1.  New Features in Bash
-
-a.  Added a new `--init-file' invocation argument as a synonym for `--rcfile',
-    per the new GNU coding standards.
-
-b.  The /dev/tcp and /dev/udp redirections now accept service names as well as
-    port numbers.
-
-c.  `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
-
-d.  A new loadable builtin, realpath, which canonicalizes and expands symlinks
-    in pathname arguments.
-    
-e.  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.
-
-f.  Bash-2.05 once again honors the current locale setting when processing
-    ranges within pattern matching bracket expressions (e.g., [A-Z]).
-
-2.  New Features in Readline
-
-a.  The blink timeout for paren matching is now settable by applications,
-    via the rl_set_paren_blink_timeout() function.
-
-b.  _rl_executing_macro has been renamed to rl_executing_macro, which means
-    it's now part of the public interface.
-
-c.  Readline has a new variable, rl_readline_state, which is a bitmap that
-    encapsulates the current state of the library; intended for use by
-    callbacks and hook functions.
-
-d.  New application-callable function rl_set_prompt(const char *prompt):
-    expands its prompt string argument and sets rl_prompt to the result.
-
-e.  New application-callable function rl_set_screen_size(int rows, int cols):
-    public method for applications to set readline's idea of the screen
-    dimensions.
-
-f.  New function, rl_get_screen_size (int *rows, int *columns), returns
-    readline's idea of the screen dimensions.
-
-g.  The timeout in rl_gather_tyi (readline keyboard input polling function)
-    is now settable via a function (rl_set_keyboard_input_timeout()).
-
-h.  Renamed the max_input_history variable to history_max_entries; the old
-    variable is maintained for backwards compatibility.
-
-i.  The list of characters that separate words for the history tokenizer is
-    now settable with a variable:  history_word_delimiters.  The default
-    value is as before.
-
--------------------------------------------------------------------------------
-This is a terse description of the new features added to bash-2.04 since
-the release of bash-2.03.  As always, the manual page (doc/bash.1) is
-the place to look for complete descriptions.
-
-1.  New Features in Bash
-
-a.  The history builtin has a `-d offset' option to delete the history entry
-    at position `offset'.
-
-b.  The prompt expansion code has two new escape sequences: \j, the number of
-    active jobs; and \l, the basename of the shell's tty device name.
-
-c.  The `bind' builtin has a new `-x' option to bind key sequences to shell   
-    commands.
-
-d.  There is a new shell option, no_empty_command_completion, which, when
-    enabled, disables command completion when TAB is typed on an empty line.
-
-e.  The `help' builtin has a `-s' option to just print a builtin's usage
-    synopsis.
-
-f.  There are several new arithmetic operators:  id++, id-- (variable
-    post-increment/decrement), ++id, --id (variable pre-increment/decrement),
-    expr1 , expr2 (comma operator).
-
-g.  There is a new ksh-93 style arithmetic for command:
-        for ((expr1 ; expr2; expr3 )); do list; done
-
-h.  The `read' builtin has a number of new options:
-        -t timeout      only wait timeout seconds for input
-        -n nchars       only read nchars from input instead of a full line
-        -d delim        read until delim rather than newline
-        -s              don't echo input chars as they are read
-
-i.  The redirection code now handles several filenames specially:
-    /dev/fd/N, /dev/stdin, /dev/stdout, and /dev/stderr, whether or
-    not they are present in the file system.
-
-j.  The redirection code now recognizes pathnames of the form
-    /dev/tcp/host/port and /dev/udp/host/port, and tries to open a socket
-    of the appropriate type to the specified port on the specified host.
-
-k.  The ksh-93 ${!prefix*} expansion, which expands to the names of all
-    shell variables with prefix PREFIX, has been implemented.
-
-l.  There is a new dynamic variable, FUNCNAME, which expands to the name of
-    a currently-executing function.  Assignments to FUNCNAME have no effect.
-
-m.  The GROUPS variable is no longer readonly; assignments to it are silently
-    discarded.  This means it can be unset.
-
-n.  A new programmable completion facility, with two new builtin commands:
-    complete and compgen.
-
-o.  configure has a new option, `--enable-progcomp', to compile in the
-    programmable completion features (enabled by default).
-
-p.  `shopt' has a new option, `progcomp', to enable and disable programmable
-    completion at runtime.
-
-q.  Unsetting HOSTFILE now clears the list of hostnames used for completion.
-
-r.  configure has a new option, `--enable-bash-malloc', replacing the old
-    `--with-gnu-malloc' (which is still present for backwards compatibility).
-
-s.  There is a new manual page describing rbash, the restricted shell.
-
-t.  `bashbug' has new `--help' and `--version' options.
-
-u.  `shopt' has a new `xpg_echo' option, which controls the behavior of
-    `echo' with respect to backslash-escaped characters at runtime.
-
-v.  If NON_INTERACTIVE_LOGIN_SHELLS is defined, all login shells read the
-    startup files, even if they are not interactive.
-
-w.  The LC_NUMERIC variable is now treated specially, and used to set the
-    LC_NUMERIC locale category for number formatting, e.g., when `printf'
-    displays floating-point numbers.
-
-2.  New features in Readline
-
-a.  Parentheses matching is now always compiled into readline, and enabled
-    or disabled when the value of the `blink-matching-paren' variable is
-    changed.
-
-b.  MS-DOS systems now use ~/_inputrc as the last-ditch inputrc filename.
-
-c.  MS-DOS systems now use ~/_history as the default history file.
-
-d.  history-search-{forward,backward} now leave the point at the end of the
-    line when the string to search for is empty, like
-    {reverse,forward}-search-history.
-
-e.  history-search-{forward,backward} now leave the last history line found
-    in the readline buffer if the second or subsequent search fails.
-
-f.  New function for use by applications:  rl_on_new_line_with_prompt, used
-    when an application displays the prompt itself before calling readline().
-
-g.  New variable for use by applications:  rl_already_prompted.  An application
-    that displays the prompt itself before calling readline() must set this to
-    a non-zero value.
-
-h.  A new variable, rl_gnu_readline_p, always 1.  The intent is that an
-    application can verify whether or not it is linked with the `real'
-    readline library or some substitute.
-
--------------------------------------------------------------------------------
-This is a terse description of the new features added to bash-2.03 since
-the release of bash-2.02.  As always, the manual page (doc/bash.1) is
-the place to look for complete descriptions.
-
-1.  New Features in Bash
-
-a.  New `shopt' option, `restricted_shell', indicating whether or not the
-    shell was started in restricted mode, for use in startup files.
-
-b.  Filename generation is now performed on the words between ( and ) in
-    array assignments (which it probably should have done all along).
-
-c.  OLDPWD is now auto-exported, as POSIX.2 seems to require.
-
-d.  ENV and BASH_ENV are read-only variables in a restricted shell.
-
-e.  A change was made to the startup file code so that any shell begun with
-    the `--login' option, even non-interactive shells, will source the login
-    shell startup files.
-
-2.  New Features in Readline
-
-a.  Many changes to the signal handling:
-        o Readline now catches SIGQUIT and cleans up the tty before returning;
-        o A new variable, rl_catch_signals, is available to application writers 
-          to indicate to readline whether or not it should install its own
-          signal handlers for SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP,
-          SIGTTIN, and SIGTTOU;
-        o A new variable, rl_catch_sigwinch, is available to application
-          writers to indicate to readline whether or not it should install its
-          own signal handler for SIGWINCH, which will chain to the calling
-          applications's SIGWINCH handler, if one is installed;
-        o There is a new function, rl_free_line_state, for application signal
-          handlers to call to free up the state associated with the current
-          line after receiving a signal;
-        o There is a new function, rl_cleanup_after_signal, to clean up the
-          display and terminal state after receiving a signal;
-        o There is a new function, rl_reset_after_signal, to reinitialize the
-          terminal and display state after an application signal handler
-          returns and readline continues
-
-b.  There is a new function, rl_resize_terminal, to reset readline's idea of
-    the screen size after a SIGWINCH.
-
-c.  New public functions: rl_save_prompt and rl_restore_prompt.  These were
-    previously private functions with a `_' prefix.
-
-d.  New function hook: rl_pre_input_hook, called just before readline starts
-    reading input, after initialization.
-
-e.  New function hook: rl_display_matches_hook, called when readline would
-    display the list of completion matches.  The new function
-    rl_display_match_list is what readline uses internally, and is available
-    for use by application functions called via this hook.
-
-f.  New bindable function, delete-char-or-list, like tcsh.
-
-g.  A new variable, rl_erase_empty_line, which, if set by an application using
-    readline, will cause readline to erase, prompt and all, lines on which the
-    only thing typed was a newline.
-
-h.  New bindable variable: `isearch-terminators'.
-
-i.  New bindable function: `forward-backward-delete-char' (unbound by default).
-
--------------------------------------------------------------------------------
-This is a terse description of the new features added to bash-2.02 since
-the release of bash-2.01.1.  As always, the manual page (doc/bash.1) is
-the place to look for complete descriptions.
-
-1. New Features in Bash
-
-a.  A new version of malloc, based on the older GNU malloc, that has many
-    changes, is more page-based, is more conservative with memory usage,
-    and does not `orphan' large blocks when they are freed.
-
-b.  A new version of gmalloc, based on the old GLIBC malloc, with many
-    changes and range checking included by default.
-
-c.  A new implementation of fnmatch(3) that includes full POSIX.2 Basic
-    Regular Expression matching, including character classes, collating
-    symbols, equivalence classes, and support for case-insensitive pattern
-    matching.
-
-d.  ksh-88 egrep-style extended pattern matching ([@+*?!](patlist)) has been
-    implemented, controlled by a new `shopt' option, `extglob'.  
-    
-e.  There is a new ksh-like `[[' compound command, which implements   
-    extended `test' functionality.
-    
-f.  There is a new `printf' builtin, implemented according to the POSIX.2
-    specification.
-    
-g.  There is a new feature for command substitution: $(< filename) now expands
-    to the contents of `filename', with any trailing newlines removed
-    (equivalent to $(cat filename)).
-
-h.  There are new tilde prefixes which expand to directories from the
-    directory stack.
-
-i.  There is a new `**' arithmetic operator to do exponentiation.
-
-j.  There are new configuration options to control how bash is linked:
-    `--enable-profiling', to allow bash to be profiled with gprof, and
-    `--enable-static-link', to allow bash to be linked statically.
-
-k.  There is a new configuration option, `--enable-cond-command', which
-    controls whether or not the `[[' command is included.  It is on by
-    default. 
-
-l.  There is a new configuration option, `--enable-extended-glob', which
-    controls whether or not the ksh extended globbing feature is included.
-    It is enabled by default.
-
-m.  There is a new configuration #define in config.h.top that, when enabled,
-    will cause all login shells to source /etc/profile and one of the user-
-    specific login shell startup files, whether or not the shell is
-    interactive.  
-    
-n.  There is a new invocation option, `--dump-po-strings', to dump
-    a shell script's translatable strings ($"...") in GNU `po' format. 
-    
-o.  There is a new `shopt' option, `nocaseglob', to enable case-insensitive
-    pattern matching when globbing filenames and using the `case' construct.
-
-p.  There is a new `shopt' option, `huponexit', which, when enabled, causes
-    the shell to send SIGHUP to all jobs when an interactive login shell
-    exits.
-
-q.  `bind' has a new `-u' option, which takes a readline function name as an
-    argument and unbinds all key sequences bound to that function in a
-    specified keymap.
-    
-r.  `disown' now has `-a' and `-r' options, to limit operation to all jobs
-    and running jobs, respectively.
-
-s.  The `shopt' `-p' option now causes output to be displayed in a reusable
-    format.
-    
-t.  `test' has a new `-N' option, which returns true if the filename argument
-    has been modified since it was last accessed.
-
-u.  `umask' now has a `-p' option to print output in a reusable format.
-    
-v.  A new escape sequence, `\xNNN', has been added to the `echo -e' and $'...'
-    translation code.  It expands to the character whose ascii code is NNN
-    in hexadecimal.
-    
-w.  The prompt string expansion code has a new `\r' escape sequence.
-
-x.  The shell may now be cross-compiled for the CYGWIN32 environment on
-    a Unix machine.
-
-2. New Features in Readline
-
-a.  There is now an option for `iterative' yank-last-arg handline, so a user
-    can keep entering `M-.', yanking the last argument of successive history
-    lines.
-
-b.  New variable, `print-completions-horizontally', which causes completion
-    matches to be displayed across the screen (like `ls -x') rather than up
-    and down the screen (like `ls').
-
-c.  New variable, `completion-ignore-case', which causes filename completion
-    and matching to be performed case-insensitively.
-
-d.  There is a new bindable command, `magic-space', which causes history
-    expansion to be performed on the current readline buffer and a space to
-    be inserted into the result.
-
-e.  There is a new bindable command, `menu-complete', which enables tcsh-like
-    menu completion (successive executions of menu-complete insert a single
-    completion match, cycling through the list of possible completions).
-
-f.  There is a new bindable command, `paste-from-clipboard', for use on Win32
-    systems, to insert the text from the Win32 clipboard into the editing
-    buffer.
-
-g.  The key sequence translation code now understands printf-style backslash
-    escape sequences, including \NNN octal escapes.  These escape sequences
-    may be used in key sequence definitions or macro values.
-
-h.  An `$include' inputrc file parser directive has been added.
-
--------------------------------------------------------------------------------
-This is a terse description of the new features added to bash-2.01 since
-the release of bash-2.0.  As always, the manual page (doc/bash.1) is the
-place to look for complete descriptions.
-
-1. New Features in Bash
-
-a.  There is a new builtin array variable: GROUPS, the set of groups to which
-    the user belongs.  This is used by the test suite.
-
-2.  New Features in Readline
-
-a.  If a key sequence bound to `universal-argument' is read while reading a
-    numeric argument started with `universal-argument', it terminates the
-    argument but is otherwise ignored.  This provides a way to insert multiple
-    instances of a digit string, and is how GNU emacs does it.
-
--------------------------------------------------------------------------------
-This is a terse description of the new features added to bash-2.0 since
-the release of bash-1.14.7.  As always, the manual page (doc/bash.1) is
-the place to look for complete descriptions.
-
-1.  New Features in Bash
-
-a.  There is a new invocation option, -D, that dumps translatable strings
-    in a script.
-
-b.  The `long' invocation options must now be prefixed with `--'.
-
-c.  New long invocation options:  --dump-strings, --help, --verbose
-
-d.  The `nolineediting' invocation option was renamed to `noediting'.
-
-e.  The `nobraceexpansion' and `quiet' long invocation options were removed.
-
-f.  The `--help' and `--version' long options now work as the GNU coding
-    standards specify.
-
-g.  If invoked as `sh', bash now enters posix mode after reading the
-    startup files, and reads and executes commands from the file named
-    by $ENV if interactive (as POSIX.2 specifies).  A login shell invoked
-    as `sh' reads $ENV after /etc/profile and ~/.profile.
-
-h.  There is a new reserved word, `time', for timing pipelines, builtin
-    commands, and shell functions.  It uses the value of the TIMEFORMAT
-    variable as a format string describing how to print the timing
-    statistics.
-
-i.  The $'...' quoting syntax expands ANSI-C escapes in ... and leaves the
-    result single-quoted.
-
-j.  The $"..." quoting syntax performs locale-specific translation of ...
-    and leaves the result double-quoted.
-
-k.  LINENO now works correctly in functions.
-
-l.  New variables: DIRSTACK, PIPESTATUS, BASH_VERSINFO, HOSTNAME, SHELLOPTS,
-    MACHTYPE.  The first three are array variables.
-
-m.  The BASH_VERSION and BASH_VERSINFO variables now include the shell's
-    `release status' (alpha[N], beta[N], release).
-
-n.  Some variables have been removed:  MAIL_WARNING, notify, history_control,
-    command_oriented_history, glob_dot_filenames, allow_null_glob_expansion,
-    nolinks, hostname_completion_file, noclobber, no_exit_on_failed_exec, and
-    cdable_vars.  Most of them are now implemented with the new `shopt'
-    builtin; others were already implemented by `set'.
-
-o.  Bash now uses some new variables:  LC_ALL, LC_MESSAGES, LC_CTYPE,
-    LC_COLLATE, LANG, GLOBIGNORE, HISTIGNORE.
-
-p.  The shell now supports integer-indexed arrays of unlimited length,
-    with a new compound assignment syntax and changes to the appropriate
-    builtin commands (declare/typeset, read, readonly, etc.).  The array
-    index may be an arithmetic expression.
-
-q.  ${!var}: indirect variable expansion, equivalent to eval \${$var}.
-
-r.  ${paramter:offset[:length]}: variable substring extraction.
-
-s.  ${parameter/pattern[/[/]string]}: variable pattern substitution.
-
-t.  The $[...] arithmetic expansion syntax is no longer supported, in
-    favor of $((...)).
-
-u.  Aliases can now be expanded in shell scripts with a shell option
-    (shopt expand_aliases).
-
-v.  History and history expansion can now be used in scripts with
-    set -o history and set -H.
-
-w.  All builtins now return an exit status of 2 for incorrect usage.
-
-x.  Interactive shells resend SIGHUP to all running or stopped children
-    if (and only if) they exit due to a SIGHUP.
-
-y.  New prompting expansions: \a, \e, \H, \T, \@, \v, \V.
-
-z.  Variable expansion in prompt strings is now controllable via a shell
-    option (shopt promptvars).
-
-aa. Bash now defaults to using command-oriented history.
-
-bb. The history file ($HISTFILE) is now truncated to $HISTFILESIZE after
-    being written.
-
-cc. The POSIX.2 conditional arithmetic evaluation syntax (expr ? expr : expr)
-    has been implemented.
-
-dd. Each builtin now accepts `--' to signify the end of the options, except
-    as documented (echo, etc.).
-
-ee. All builtins use -p to display values in a re-readable format where
-    appropriate, except as documented (echo, type, etc.).
-
-ff. The `alias' builtin has a new -p option.
-
-gg. Changes to the `bind' builtin:
-       o has new options: -psPSVr.
-       o the `-d' option was renamed to `-p'
-       o the `-v' option now dumps variables; the old `-v' is now `-P'
-
-hh. The `bye' synonym for `exit' was removed.
-
-ii. The -L and -P options to `cd' and `pwd' have been documented.
-
-jj. The `cd' builtin now does spelling correction on the directory name
-    by default.  This is settable with a shell option (shopt cdspell).
-
-kk. The `declare' builtin has new options: -a, -F, -p.
-
-ll. The `dirs' builtin has new options: -c, -p, -v.
-
-mm. The new `disown' builtin removes jobs from the shell's jobs table
-    or inhibits the resending of SIGHUP when the shell receives a
-    SIGHUP.
-
-nn. The `echo' builtin has a new escape character: \e.
-
-oo. The `enable' builtin can now load new builtins dynamically from shared
-    objects on systems with the dlopen/dlsym interface.  There are a number
-    of examples in the examples/loadables directory.  There are also
-    new options: -d, -f, -s, -p.
-
-pp. The `-all' option to `enable' was removed in favor of `-a'.
-
-qq. The `exec' builtin has new options: -l, -c, -a.
-
-rr. The `hash' builtin has a new option: -p.
-
-ss. The `history' builtin has new options: -c, -p, -s.
-
-tt. The `jobs' builtin has new options: -r, -s.
-
-uu. The `kill' builtin has new options: -n signum, -l signame.
-
-vv. The `pushd' and `popd' builtins have a new option: -n.
-
-ww. The `read' builtin has new options: -p prompt, -e, -a.
-
-xx. The `readonly' builtin has a new -a option, and the -n option was removed.
-
-yy. Changes to the `set' builtin:
-       o new options: -B, -o keyword, -o onecmd, -o history
-       o options removed: -l, -d, -o nohash
-       o options changed: +o, -h, -o hashall
-       o now displays variables in a format that can be re-read as input
-
-zz. The new `shopt' builtin controls shell optional behavior previously
-    done by setting and unsetting certain shell variables.
-
-aaa. The `test' builtin has new operators: -o option, s1 == s2, s1 < s2,
-     and s1 > s2, where s1 and s2 are strings.
-
-bbb. There is a new trap, DEBUG, executed after every simple command.
-
-ccc. The `trap' builtin has a new -p option.
-
-ddd. The `ulimit' builtin has a new -l option on 4.4BSD-based systems.
-
-eee. The PS1, PS2, PATH, and IFS variables may now be unset.
-
-fff. The restricted shell mode has been expanded and is now documented.
-
-ggg. Security improvements:
-       o functions are not imported from the environment if running setuid
-         or with -p
-       o no startup files are sourced if running setuid or with -p
-
-hhh. The documentation has been overhauled:  the texinfo manual was
-     expanded, and HTML versions of the man page and texinfo manual
-     are included.
-
-iii. Changes to Posix mode:
-       o Command lookup now finds special builtins before shell functions.
-       o Failure of a special builtin causes a non-interactive shell to
-         exit.  Failures are defined in the POSIX.2 specification.
-       o If the `cd' builtin finds a directory to change to using $CDPATH,
-         the value assigned to PWD when `cd' completes does not contain
-         any symbolic links.
-       o A non-interactive shell exits if a variable assignment error
-         occurs when no command name follows the assignment statements.
-       o A non-interactive shell exits if the interation variable in a
-         `for' statement or the selection variable in a `select' statement
-         is read-only or another variable assignment error occurs.
-       o The `<>' redirection operator now opens a file for both stdin and
-         stdout by default, not just when in posix mode.
-       o Assignment statements preceding special builtins now persist in
-         the shell's environment when the builtin completes.
-
-     Posix mode is now completely POSIX.2-compliant (modulo bugs).  When
-     invoked as sh, bash should be completely POSIX.2-compliant.
-
-jjj. The default value of PS1 is now "\s-\v\$ ".
-
-kkk. The ksh-like ((...)) arithmetic command syntax has been implemented.
-     This is exactly equivalent to `let "..."'.
-
-lll. Integer constants have been extended to base 64.
-
-mmm. The `ulimit' builtin now sets both hard and soft limits and reports the
-     soft limit by default.
-
-2.  New Features in Readline
-
-a.  New variables:  enable-keypad, input-meta (new name for meta-flag),
-    mark-directories, visible-stats (now documented), disable-completion,
-    comment-begin.
-
-b.  New bindable commands:  kill-region, copy-region-as-kill,
-    copy-backward-word, copy-forward-word, set-mark, exchange-point-and-mark,
-    character-search, character-search-backward, insert-comment,
-    glob-expand-word, glob-list-expansions, dump-variables, dump-macros.
-
-c.  New emacs keybindings:  delete-horizontal-space (M-\),
-    insert-completions (M-*), possible-completions (M-=).
-
-d.  The history-search-backward and history-search-forward commands were
-    modified to be the same as previous-line and next-line if point is at
-    the start of the line.
-
-e.  More file types are available for the visible-stats mode.
-
-3.  Changes of interest in the Bash implementation
-
-a.  There is a new autoconf-based configuration mechanism.
-
-b.  More things have been moved from Posix mode to standard shell behavior.
-
-c.  The trace output (set -x) now inserts quotes where necessary so it can
-    be reused as input.
-
-d.  There is a compile-time option for a system-wide interactive shell
-    startup file (disabled by default).
-
-e.  The YACC grammar is smaller and tighter, and all 66 shift-reduce
-    conflicts are gone.  Several parsing bugs have been fixed.
-
-f.  Builtin option parsing has been regularized (using internal_getopt()),
-    with the exception of `echo', `type', and `set'.
-
-g.  Builtins now return standard usage messages constructed from the
-    `short doc' used by the help builtin.
-
-h.  Completion now quotes using backslashes by default, but honors
-    user-supplied quotes.
-
-i.  The GNU libc malloc is available as a configure-time option.
-
-j.  There are more internationalization features; bash uses gettext if
-    it is available.  The $"..." translation syntax uses the current
-    locale and gettext.
-
-k.  There is better reporting of job termination when the shell is not
-    interactive.
-
-l.  The shell is somewhat more efficient: it uses a little less memory and
-    makes fewer system calls.
-
-4.  Changes of interest in the Readline implementation
-
-a.  There is now support for readline `callback' functions.
-
-b.  There is now support for user-supplied input, redisplay, and terminal
-    preparation functions.
-
-c.  Most of the shell-specific code in readline has been generalized or
-    removed.
-
-d.  Most of the annoying redisplay bugs have been fixed, notably the problems
-    with incremental search and excessive redrawing when special characters
-    appear in the prompt string.
-
-e.  There are new library functions and variables available to application
-    writers, most having to do with completion and quoting.
-
-f.  The NEWLINE character (^J) is now treated as a search terminator by the
-    incremental search functions.
--------------------------------------------------------------------------------
-
-Copying and distribution of this file, with or without modification,
-are permitted in any medium without royalty provided the copyright
-notice and this notice are preserved.  This file is offered as-is,
-without any warranty.
diff --git a/README~ b/README~
deleted file mode 100644 (file)
index 73bb5f3..0000000
--- a/README~
+++ /dev/null
@@ -1,91 +0,0 @@
-Introduction
-============
-
-This is GNU Bash, version 4.1.  Bash is the GNU Project's Bourne
-Again SHell, a complete implementation of the POSIX.2 shell spec,
-but also with interactive command line editing, job control on
-architectures that support it, csh-like features such as history
-substitution and brace expansion, and a slew of other features. 
-For more information on the features of Bash that are new to this
-type of shell, see the file `doc/bashref.texi'.  There is also a
-large Unix-style man page.  The man page is the definitive description
-of the shell's features. 
-
-See the file POSIX for a discussion of how the Bash defaults differ
-from the POSIX.2 spec and a description of the Bash `posix mode'.
-
-There are some user-visible incompatibilities between this version
-of Bash and previous widely-distributed versions, bash-2.05b and
-bash-3.2.  For details, see the file COMPAT.  The NEWS file tersely
-lists features that are new in this release. 
-
-Bash is free software, distributed under the terms of the [GNU] General
-Public License as published by the Free Software Foundation,
-version 3 of the License (or any later version).  For more information,
-see the file COPYING. 
-
-A number of frequently-asked questions are answered in the file
-`doc/FAQ'.
-
-To compile Bash, try typing `./configure', then `make'.  Bash
-auto-configures the build process, so no further intervention
-should be necessary.  Bash builds with `gcc' by default if it is
-available.  If you want to use `cc' instead, type
-
-       CC=cc ./configure
-
-if you are using a Bourne-style shell.  If you are not, the following
-may work:
-
-       env CC=cc ./configure
-
-Read the file INSTALL in this directory for more information about how
-to customize and control the build process.  The file NOTES contains
-platform-specific installation and configuration information.
-
-If you are a csh user and wish to convert your csh aliases to Bash
-aliases, you may wish to use the script `examples/misc/alias-conv.sh'
-as a starting point.  The script `examples/misc/cshtobash' is a
-more ambitious script that attempts to do a more complete job.
-
-Reporting Bugs
-==============
-
-Bug reports for bash should be sent to:
-
-       bug-bash@gnu.org
-
-using the `bashbug' program that is built and installed at the same
-time as bash.
-
-The discussion list `bug-bash@gnu.org' often contains information
-about new ports of Bash, or discussions of new features or behavior
-changes that people would like.  This mailing list is also available
-as a usenet newsgroup: gnu.bash.bug. 
-
-When you send a bug report, please use the `bashbug' program that is
-built at the same time as bash.  If bash fails to build, try building
-bashbug directly with `make bashbug'.  If you cannot build `bashbug',
-please send mail to bug-bash@gnu.org with the following information:
-
-       * the version number and release status of Bash (e.g., 2.05a-release)
-       * the machine and OS that it is running on (you may run
-         `bashversion -l' from the bash build directory for this information)
-       * a list of the compilation flags or the contents of `config.h', if
-         appropriate
-       * a description of the bug
-       * a recipe for recreating the bug reliably
-       * a fix for the bug if you have one!
-
-The `bashbug' program includes much of this automatically.
-
-If you would like to contact the Bash maintainers directly, send mail
-to bash-maintainers@gnu.org.
-
-While the Bash maintainers do not promise to fix all bugs, we would
-like this shell to be the best that we can make it.
-
-Enjoy!
-
-Chet Ramey
-chet.ramey@case.edu
diff --git a/aclocal.m4~ b/aclocal.m4~
deleted file mode 100644 (file)
index b3bd62f..0000000
+++ /dev/null
@@ -1,4116 +0,0 @@
-dnl
-dnl Bash specific tests
-dnl
-dnl Some derived from PDKSH 5.1.3 autoconf tests
-dnl
-
-AC_DEFUN(BASH_C_LONG_LONG,
-[AC_CACHE_CHECK(for long long, ac_cv_c_long_long,
-[if test "$GCC" = yes; then
-  ac_cv_c_long_long=yes
-else
-AC_TRY_RUN([
-int
-main()
-{
-long long foo = 0;
-exit(sizeof(long long) < sizeof(long));
-}
-], ac_cv_c_long_long=yes, ac_cv_c_long_long=no)
-fi])
-if test $ac_cv_c_long_long = yes; then
-  AC_DEFINE(HAVE_LONG_LONG, 1, [Define if the `long long' type works.])
-fi
-])
-
-dnl
-dnl This is very similar to AC_C_LONG_DOUBLE, with the fix for IRIX
-dnl (< changed to <=) added.
-dnl
-AC_DEFUN(BASH_C_LONG_DOUBLE,
-[AC_CACHE_CHECK(for long double, ac_cv_c_long_double,
-[if test "$GCC" = yes; then
-  ac_cv_c_long_double=yes
-else
-AC_TRY_RUN([
-int
-main()
-{
-  /* The Stardent Vistra knows sizeof(long double), but does not
-     support it. */
-  long double foo = 0.0;
-  /* On Ultrix 4.3 cc, long double is 4 and double is 8.  */
-  /* On IRIX 5.3, the compiler converts long double to double with a warning,
-     but compiles this successfully. */
-  exit(sizeof(long double) <= sizeof(double));
-}
-], ac_cv_c_long_double=yes, ac_cv_c_long_double=no)
-fi])
-if test $ac_cv_c_long_double = yes; then
-  AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if the `long double' type works.])
-fi
-])
-
-dnl
-dnl Check for <inttypes.h>.  This is separated out so that it can be
-dnl AC_REQUIREd.
-dnl
-dnl BASH_HEADER_INTTYPES
-AC_DEFUN(BASH_HEADER_INTTYPES,
-[
- AC_CHECK_HEADERS(inttypes.h)
-])
-
-dnl
-dnl check for typedef'd symbols in header files, but allow the caller to
-dnl specify the include files to be checked in addition to the default
-dnl 
-dnl BASH_CHECK_TYPE(TYPE, HEADERS, DEFAULT[, VALUE-IF-FOUND])
-AC_DEFUN(BASH_CHECK_TYPE,
-[
-AC_REQUIRE([AC_HEADER_STDC])dnl
-AC_REQUIRE([BASH_HEADER_INTTYPES])
-AC_MSG_CHECKING(for $1)
-AC_CACHE_VAL(bash_cv_type_$1,
-[AC_EGREP_CPP($1, [#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-#if HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-#if HAVE_STDINT_H
-#include <stdint.h>
-#endif
-$2
-], bash_cv_type_$1=yes, bash_cv_type_$1=no)])
-AC_MSG_RESULT($bash_cv_type_$1)
-ifelse($#, 4, [if test $bash_cv_type_$1 = yes; then
-       AC_DEFINE($4)
-       fi])
-if test $bash_cv_type_$1 = no; then
-  AC_DEFINE_UNQUOTED($1, $3)
-fi
-])
-
-dnl
-dnl BASH_CHECK_DECL(FUNC)
-dnl
-dnl Check for a declaration of FUNC in stdlib.h and inttypes.h like
-dnl AC_CHECK_DECL
-dnl
-AC_DEFUN(BASH_CHECK_DECL,
-[
-AC_REQUIRE([AC_HEADER_STDC])
-AC_REQUIRE([BASH_HEADER_INTTYPES])
-AC_CACHE_CHECK([for declaration of $1], bash_cv_decl_$1,
-[AC_TRY_LINK(
-[
-#if STDC_HEADERS
-#  include <stdlib.h>
-#endif
-#if HAVE_INTTYPES_H
-#  include <inttypes.h>
-#endif
-],
-[return !$1;],
-bash_cv_decl_$1=yes, bash_cv_decl_$1=no)])
-bash_tr_func=HAVE_DECL_`echo $1 | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
-if test $bash_cv_decl_$1 = yes; then
-  AC_DEFINE_UNQUOTED($bash_tr_func, 1)
-else
-  AC_DEFINE_UNQUOTED($bash_tr_func, 0)
-fi
-])
-
-AC_DEFUN(BASH_DECL_PRINTF,
-[AC_MSG_CHECKING(for declaration of printf in <stdio.h>)
-AC_CACHE_VAL(bash_cv_printf_declared,
-[AC_TRY_RUN([
-#include <stdio.h>
-#ifdef __STDC__
-typedef int (*_bashfunc)(const char *, ...);
-#else
-typedef int (*_bashfunc)();
-#endif
-main()
-{
-_bashfunc pf;
-pf = (_bashfunc) printf;
-exit(pf == 0);
-}
-], bash_cv_printf_declared=yes, bash_cv_printf_declared=no,
-   [AC_MSG_WARN(cannot check printf declaration if cross compiling -- defaulting to yes)
-    bash_cv_printf_declared=yes]
-)])
-AC_MSG_RESULT($bash_cv_printf_declared)
-if test $bash_cv_printf_declared = yes; then
-AC_DEFINE(PRINTF_DECLARED)
-fi
-])
-
-AC_DEFUN(BASH_DECL_SBRK,
-[AC_MSG_CHECKING(for declaration of sbrk in <unistd.h>)
-AC_CACHE_VAL(bash_cv_sbrk_declared,
-[AC_EGREP_HEADER(sbrk, unistd.h,
- bash_cv_sbrk_declared=yes, bash_cv_sbrk_declared=no)])
-AC_MSG_RESULT($bash_cv_sbrk_declared)
-if test $bash_cv_sbrk_declared = yes; then
-AC_DEFINE(SBRK_DECLARED)
-fi
-])
-
-dnl
-dnl Check for sys_siglist[] or _sys_siglist[]
-dnl
-AC_DEFUN(BASH_DECL_UNDER_SYS_SIGLIST,
-[AC_MSG_CHECKING([for _sys_siglist in signal.h or unistd.h])
-AC_CACHE_VAL(bash_cv_decl_under_sys_siglist,
-[AC_TRY_COMPILE([
-#include <sys/types.h>
-#include <signal.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif], [ char *msg = _sys_siglist[2]; ],
-  bash_cv_decl_under_sys_siglist=yes, bash_cv_decl_under_sys_siglist=no,
-  [AC_MSG_WARN(cannot check for _sys_siglist[] if cross compiling -- defaulting to no)])])dnl
-AC_MSG_RESULT($bash_cv_decl_under_sys_siglist)
-if test $bash_cv_decl_under_sys_siglist = yes; then
-AC_DEFINE(UNDER_SYS_SIGLIST_DECLARED)
-fi
-])
-
-AC_DEFUN(BASH_UNDER_SYS_SIGLIST,
-[AC_REQUIRE([BASH_DECL_UNDER_SYS_SIGLIST])
-AC_MSG_CHECKING([for _sys_siglist in system C library])
-AC_CACHE_VAL(bash_cv_under_sys_siglist,
-[AC_TRY_RUN([
-#include <sys/types.h>
-#include <signal.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifndef UNDER_SYS_SIGLIST_DECLARED
-extern char *_sys_siglist[];
-#endif
-main()
-{
-char *msg = (char *)_sys_siglist[2];
-exit(msg == 0);
-}],
-       bash_cv_under_sys_siglist=yes, bash_cv_under_sys_siglist=no,
-       [AC_MSG_WARN(cannot check for _sys_siglist[] if cross compiling -- defaulting to no)
-        bash_cv_under_sys_siglist=no])])
-AC_MSG_RESULT($bash_cv_under_sys_siglist)
-if test $bash_cv_under_sys_siglist = yes; then
-AC_DEFINE(HAVE_UNDER_SYS_SIGLIST)
-fi
-])
-
-AC_DEFUN(BASH_SYS_SIGLIST,
-[AC_REQUIRE([AC_DECL_SYS_SIGLIST])
-AC_MSG_CHECKING([for sys_siglist in system C library])
-AC_CACHE_VAL(bash_cv_sys_siglist,
-[AC_TRY_RUN([
-#include <sys/types.h>
-#include <signal.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#if !HAVE_DECL_SYS_SIGLIST
-extern char *sys_siglist[];
-#endif
-main()
-{
-char *msg = sys_siglist[2];
-exit(msg == 0);
-}],
-       bash_cv_sys_siglist=yes, bash_cv_sys_siglist=no,
-       [AC_MSG_WARN(cannot check for sys_siglist if cross compiling -- defaulting to no)
-        bash_cv_sys_siglist=no])])
-AC_MSG_RESULT($bash_cv_sys_siglist)
-if test $bash_cv_sys_siglist = yes; then
-AC_DEFINE(HAVE_SYS_SIGLIST)
-fi
-])
-
-dnl Check for the various permutations of sys_siglist and make sure we
-dnl compile in siglist.o if they're not defined
-AC_DEFUN(BASH_CHECK_SYS_SIGLIST, [
-AC_REQUIRE([BASH_SYS_SIGLIST])
-AC_REQUIRE([BASH_DECL_UNDER_SYS_SIGLIST])
-AC_REQUIRE([BASH_FUNC_STRSIGNAL])
-if test "$bash_cv_sys_siglist" = no && test "$bash_cv_under_sys_siglist" = no && test "$bash_cv_have_strsignal" = no; then
-  SIGLIST_O=siglist.o
-else
-  SIGLIST_O=
-fi
-AC_SUBST([SIGLIST_O])
-])
-
-dnl Check for sys_errlist[] and sys_nerr, check for declaration
-AC_DEFUN(BASH_SYS_ERRLIST,
-[AC_MSG_CHECKING([for sys_errlist and sys_nerr])
-AC_CACHE_VAL(bash_cv_sys_errlist,
-[AC_TRY_LINK([#include <errno.h>],
-[extern char *sys_errlist[];
- extern int sys_nerr;
- char *msg = sys_errlist[sys_nerr - 1];],
-    bash_cv_sys_errlist=yes, bash_cv_sys_errlist=no)])dnl
-AC_MSG_RESULT($bash_cv_sys_errlist)
-if test $bash_cv_sys_errlist = yes; then
-AC_DEFINE(HAVE_SYS_ERRLIST)
-fi
-])
-
-dnl
-dnl Check if dup2() does not clear the close on exec flag
-dnl
-AC_DEFUN(BASH_FUNC_DUP2_CLOEXEC_CHECK,
-[AC_MSG_CHECKING(if dup2 fails to clear the close-on-exec flag)
-AC_CACHE_VAL(bash_cv_dup2_broken,
-[AC_TRY_RUN([
-#include <sys/types.h>
-#include <fcntl.h>
-main()
-{
-  int fd1, fd2, fl;
-  fd1 = open("/dev/null", 2);
-  if (fcntl(fd1, 2, 1) < 0)
-    exit(1);
-  fd2 = dup2(fd1, 1);
-  if (fd2 < 0)
-    exit(2);
-  fl = fcntl(fd2, 1, 0);
-  /* fl will be 1 if dup2 did not reset the close-on-exec flag. */
-  exit(fl != 1);
-}
-], bash_cv_dup2_broken=yes, bash_cv_dup2_broken=no,
-    [AC_MSG_WARN(cannot check dup2 if cross compiling -- defaulting to no)
-     bash_cv_dup2_broken=no])
-])
-AC_MSG_RESULT($bash_cv_dup2_broken)
-if test $bash_cv_dup2_broken = yes; then
-AC_DEFINE(DUP2_BROKEN)
-fi
-])
-
-AC_DEFUN(BASH_FUNC_STRSIGNAL,
-[AC_MSG_CHECKING([for the existence of strsignal])
-AC_CACHE_VAL(bash_cv_have_strsignal,
-[AC_TRY_LINK([#include <sys/types.h>
-#include <signal.h>],
-[char *s = (char *)strsignal(2);],
- bash_cv_have_strsignal=yes, bash_cv_have_strsignal=no)])
-AC_MSG_RESULT($bash_cv_have_strsignal)
-if test $bash_cv_have_strsignal = yes; then
-AC_DEFINE(HAVE_STRSIGNAL)
-fi
-])
-
-dnl Check to see if opendir will open non-directories (not a nice thing)
-AC_DEFUN(BASH_FUNC_OPENDIR_CHECK,
-[AC_REQUIRE([AC_HEADER_DIRENT])dnl
-AC_MSG_CHECKING(if opendir() opens non-directories)
-AC_CACHE_VAL(bash_cv_opendir_not_robust,
-[AC_TRY_RUN([
-#include <stdio.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-#if defined(HAVE_DIRENT_H)
-# include <dirent.h>
-#else
-# define dirent direct
-# ifdef HAVE_SYS_NDIR_H
-#  include <sys/ndir.h>
-# endif /* SYSNDIR */
-# ifdef HAVE_SYS_DIR_H
-#  include <sys/dir.h>
-# endif /* SYSDIR */
-# ifdef HAVE_NDIR_H
-#  include <ndir.h>
-# endif
-#endif /* HAVE_DIRENT_H */
-main()
-{
-DIR *dir;
-int fd, err;
-err = mkdir("bash-aclocal", 0700);
-if (err < 0) {
-  perror("mkdir");
-  exit(1);
-}
-unlink("bash-aclocal/not_a_directory");
-fd = open("bash-aclocal/not_a_directory", O_WRONLY|O_CREAT|O_EXCL, 0666);
-write(fd, "\n", 1);
-close(fd);
-dir = opendir("bash-aclocal/not_a_directory");
-unlink("bash-aclocal/not_a_directory");
-rmdir("bash-aclocal");
-exit (dir == 0);
-}], bash_cv_opendir_not_robust=yes,bash_cv_opendir_not_robust=no,
-    [AC_MSG_WARN(cannot check opendir if cross compiling -- defaulting to no)
-     bash_cv_opendir_not_robust=no]
-)])
-AC_MSG_RESULT($bash_cv_opendir_not_robust)
-if test $bash_cv_opendir_not_robust = yes; then
-AC_DEFINE(OPENDIR_NOT_ROBUST)
-fi
-])
-
-dnl
-AC_DEFUN(BASH_TYPE_SIGHANDLER,
-[AC_MSG_CHECKING([whether signal handlers are of type void])
-AC_CACHE_VAL(bash_cv_void_sighandler,
-[AC_TRY_COMPILE([#include <sys/types.h>
-#include <signal.h>
-#ifdef signal
-#undef signal
-#endif
-#ifdef __cplusplus
-extern "C"
-#endif
-void (*signal ()) ();],
-[int i;], bash_cv_void_sighandler=yes, bash_cv_void_sighandler=no)])dnl
-AC_MSG_RESULT($bash_cv_void_sighandler)
-if test $bash_cv_void_sighandler = yes; then
-AC_DEFINE(VOID_SIGHANDLER)
-fi
-])
-
-dnl
-dnl A signed 16-bit integer quantity
-dnl
-AC_DEFUN(BASH_TYPE_BITS16_T,
-[
-if test "$ac_cv_sizeof_short" = 2; then
-  AC_CHECK_TYPE(bits16_t, short)
-elif test "$ac_cv_sizeof_char" = 2; then
-  AC_CHECK_TYPE(bits16_t, char)
-else
-  AC_CHECK_TYPE(bits16_t, short)
-fi
-])
-
-dnl
-dnl An unsigned 16-bit integer quantity
-dnl
-AC_DEFUN(BASH_TYPE_U_BITS16_T,
-[
-if test "$ac_cv_sizeof_short" = 2; then
-  AC_CHECK_TYPE(u_bits16_t, unsigned short)
-elif test "$ac_cv_sizeof_char" = 2; then
-  AC_CHECK_TYPE(u_bits16_t, unsigned char)
-else
-  AC_CHECK_TYPE(u_bits16_t, unsigned short)
-fi
-])
-
-dnl
-dnl A signed 32-bit integer quantity
-dnl
-AC_DEFUN(BASH_TYPE_BITS32_T,
-[
-if test "$ac_cv_sizeof_int" = 4; then
-  AC_CHECK_TYPE(bits32_t, int)
-elif test "$ac_cv_sizeof_long" = 4; then
-  AC_CHECK_TYPE(bits32_t, long)
-else
-  AC_CHECK_TYPE(bits32_t, int)
-fi
-])
-
-dnl
-dnl An unsigned 32-bit integer quantity
-dnl
-AC_DEFUN(BASH_TYPE_U_BITS32_T,
-[
-if test "$ac_cv_sizeof_int" = 4; then
-  AC_CHECK_TYPE(u_bits32_t, unsigned int)
-elif test "$ac_cv_sizeof_long" = 4; then
-  AC_CHECK_TYPE(u_bits32_t, unsigned long)
-else
-  AC_CHECK_TYPE(u_bits32_t, unsigned int)
-fi
-])
-
-AC_DEFUN(BASH_TYPE_PTRDIFF_T,
-[
-if test "$ac_cv_sizeof_int" = "$ac_cv_sizeof_char_p"; then
-  AC_CHECK_TYPE(ptrdiff_t, int)
-elif test "$ac_cv_sizeof_long" = "$ac_cv_sizeof_char_p"; then
-  AC_CHECK_TYPE(ptrdiff_t, long)
-elif test "$ac_cv_type_long_long" = yes && test "$ac_cv_sizeof_long_long" = "$ac_cv_sizeof_char_p"; then
-  AC_CHECK_TYPE(ptrdiff_t, [long long])
-else
-  AC_CHECK_TYPE(ptrdiff_t, int)
-fi
-])
-
-dnl
-dnl A signed 64-bit quantity
-dnl
-AC_DEFUN(BASH_TYPE_BITS64_T,
-[
-if test "$ac_cv_sizeof_char_p" = 8; then
-  AC_CHECK_TYPE(bits64_t, char *)
-elif test "$ac_cv_sizeof_double" = 8; then
-  AC_CHECK_TYPE(bits64_t, double)
-elif test -n "$ac_cv_type_long_long" && test "$ac_cv_sizeof_long_long" = 8; then
-  AC_CHECK_TYPE(bits64_t, [long long])
-elif test "$ac_cv_sizeof_long" = 8; then
-  AC_CHECK_TYPE(bits64_t, long)
-else
-  AC_CHECK_TYPE(bits64_t, double)
-fi
-])
-
-AC_DEFUN(BASH_TYPE_LONG_LONG,
-[
-AC_CACHE_CHECK([for long long], bash_cv_type_long_long,
-[AC_TRY_LINK([
-long long ll = 1; int i = 63;],
-[
-long long llm = (long long) -1;
-return ll << i | ll >> i | llm / ll | llm % ll;
-], bash_cv_type_long_long='long long', bash_cv_type_long_long='long')])
-if test "$bash_cv_type_long_long" = 'long long'; then
-  AC_DEFINE(HAVE_LONG_LONG, 1)
-fi
-])
-
-AC_DEFUN(BASH_TYPE_UNSIGNED_LONG_LONG,
-[
-AC_CACHE_CHECK([for unsigned long long], bash_cv_type_unsigned_long_long,
-[AC_TRY_LINK([
-unsigned long long ull = 1; int i = 63;],
-[
-unsigned long long ullmax = (unsigned long long) -1;
-return ull << i | ull >> i | ullmax / ull | ullmax % ull;
-], bash_cv_type_unsigned_long_long='unsigned long long',
-   bash_cv_type_unsigned_long_long='unsigned long')])
-if test "$bash_cv_type_unsigned_long_long" = 'unsigned long long'; then
-  AC_DEFINE(HAVE_UNSIGNED_LONG_LONG, 1)
-fi
-])
-
-dnl
-dnl Type of struct rlimit fields: some systems (OSF/1, NetBSD, RISC/os 5.0)
-dnl have a rlim_t, others (4.4BSD based systems) use quad_t, others use
-dnl long and still others use int (HP-UX 9.01, SunOS 4.1.3).  To simplify
-dnl matters, this just checks for rlim_t, quad_t, or long.
-dnl
-AC_DEFUN(BASH_TYPE_RLIMIT,
-[AC_MSG_CHECKING(for size and type of struct rlimit fields)
-AC_CACHE_VAL(bash_cv_type_rlimit,
-[AC_TRY_COMPILE([#include <sys/types.h>
-#include <sys/resource.h>],
-[rlim_t xxx;], bash_cv_type_rlimit=rlim_t,[
-AC_TRY_RUN([
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-main()
-{
-#ifdef HAVE_QUAD_T
-  struct rlimit rl;
-  if (sizeof(rl.rlim_cur) == sizeof(quad_t))
-    exit(0);
-#endif
-  exit(1);
-}], bash_cv_type_rlimit=quad_t, bash_cv_type_rlimit=long,
-        [AC_MSG_WARN(cannot check quad_t if cross compiling -- defaulting to long)
-         bash_cv_type_rlimit=long])])
-])
-AC_MSG_RESULT($bash_cv_type_rlimit)
-if test $bash_cv_type_rlimit = quad_t; then
-AC_DEFINE(RLIMTYPE, quad_t)
-elif test $bash_cv_type_rlimit = rlim_t; then
-AC_DEFINE(RLIMTYPE, rlim_t)
-fi
-])
-
-AC_DEFUN(BASH_TYPE_SIG_ATOMIC_T,
-[AC_CACHE_CHECK([for sig_atomic_t in signal.h], ac_cv_have_sig_atomic_t,
-[AC_TRY_LINK([
-#include <signal.h>
-],[ sig_atomic_t x; ],
-ac_cv_have_sig_atomic_t=yes, ac_cv_have_sig_atomic_t=no)])
-if test "$ac_cv_have_sig_atomic_t" = "no"
-then
-    AC_CHECK_TYPE(sig_atomic_t,int)
-fi
-])
-
-AC_DEFUN(BASH_FUNC_LSTAT,
-[dnl Cannot use AC_CHECK_FUNCS(lstat) because Linux defines lstat() as an
-dnl inline function in <sys/stat.h>.
-AC_CACHE_CHECK([for lstat], bash_cv_func_lstat,
-[AC_TRY_LINK([
-#include <sys/types.h>
-#include <sys/stat.h>
-],[ lstat(".",(struct stat *)0); ],
-bash_cv_func_lstat=yes, bash_cv_func_lstat=no)])
-if test $bash_cv_func_lstat = yes; then
-  AC_DEFINE(HAVE_LSTAT)
-fi
-])
-
-AC_DEFUN(BASH_FUNC_INET_ATON,
-[
-AC_CACHE_CHECK([for inet_aton], bash_cv_func_inet_aton,
-[AC_TRY_LINK([
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-struct in_addr ap;], [ inet_aton("127.0.0.1", &ap); ],
-bash_cv_func_inet_aton=yes, bash_cv_func_inet_aton=no)])
-if test $bash_cv_func_inet_aton = yes; then
-  AC_DEFINE(HAVE_INET_ATON)
-else
-  AC_LIBOBJ(inet_aton)
-fi
-])
-
-AC_DEFUN(BASH_FUNC_GETENV,
-[AC_MSG_CHECKING(to see if getenv can be redefined)
-AC_CACHE_VAL(bash_cv_getenv_redef,
-[AC_TRY_RUN([
-#ifdef HAVE_UNISTD_H
-#  include <unistd.h>
-#endif
-#ifndef __STDC__
-#  ifndef const
-#    define const
-#  endif
-#endif
-char *
-getenv (name)
-#if defined (__linux__) || defined (__bsdi__) || defined (convex)
-     const char *name;
-#else
-     char const *name;
-#endif /* !__linux__ && !__bsdi__ && !convex */
-{
-return "42";
-}
-main()
-{
-char *s;
-/* The next allows this program to run, but does not allow bash to link
-   when it redefines getenv.  I'm not really interested in figuring out
-   why not. */
-#if defined (NeXT)
-exit(1);
-#endif
-s = getenv("ABCDE");
-exit(s == 0);  /* force optimizer to leave getenv in */
-}
-], bash_cv_getenv_redef=yes, bash_cv_getenv_redef=no,
-   [AC_MSG_WARN(cannot check getenv redefinition if cross compiling -- defaulting to yes)
-    bash_cv_getenv_redef=yes]
-)])
-AC_MSG_RESULT($bash_cv_getenv_redef)
-if test $bash_cv_getenv_redef = yes; then
-AC_DEFINE(CAN_REDEFINE_GETENV)
-fi
-])
-
-# We should check for putenv before calling this
-AC_DEFUN(BASH_FUNC_STD_PUTENV,
-[
-AC_REQUIRE([AC_HEADER_STDC])
-AC_REQUIRE([AC_C_PROTOTYPES])
-AC_CACHE_CHECK([for standard-conformant putenv declaration], bash_cv_std_putenv,
-[AC_TRY_LINK([
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-#ifndef __STDC__
-#  ifndef const
-#    define const
-#  endif
-#endif
-#ifdef PROTOTYPES
-extern int putenv (char *);
-#else
-extern int putenv ();
-#endif
-],
-[return (putenv == 0);],
-bash_cv_std_putenv=yes, bash_cv_std_putenv=no
-)])
-if test $bash_cv_std_putenv = yes; then
-AC_DEFINE(HAVE_STD_PUTENV)
-fi
-])
-
-# We should check for unsetenv before calling this
-AC_DEFUN(BASH_FUNC_STD_UNSETENV,
-[
-AC_REQUIRE([AC_HEADER_STDC])
-AC_REQUIRE([AC_C_PROTOTYPES])
-AC_CACHE_CHECK([for standard-conformant unsetenv declaration], bash_cv_std_unsetenv,
-[AC_TRY_LINK([
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-#ifndef __STDC__
-#  ifndef const
-#    define const
-#  endif
-#endif
-#ifdef PROTOTYPES
-extern int unsetenv (const char *);
-#else
-extern int unsetenv ();
-#endif
-],
-[return (unsetenv == 0);],
-bash_cv_std_unsetenv=yes, bash_cv_std_unsetenv=no
-)])
-if test $bash_cv_std_unsetenv = yes; then
-AC_DEFINE(HAVE_STD_UNSETENV)
-fi
-])
-
-AC_DEFUN(BASH_FUNC_ULIMIT_MAXFDS,
-[AC_MSG_CHECKING(whether ulimit can substitute for getdtablesize)
-AC_CACHE_VAL(bash_cv_ulimit_maxfds,
-[AC_TRY_RUN([
-main()
-{
-long maxfds = ulimit(4, 0L);
-exit (maxfds == -1L);
-}
-], bash_cv_ulimit_maxfds=yes, bash_cv_ulimit_maxfds=no,
-   [AC_MSG_WARN(cannot check ulimit if cross compiling -- defaulting to no)
-    bash_cv_ulimit_maxfds=no]
-)])
-AC_MSG_RESULT($bash_cv_ulimit_maxfds)
-if test $bash_cv_ulimit_maxfds = yes; then
-AC_DEFINE(ULIMIT_MAXFDS)
-fi
-])
-
-AC_DEFUN(BASH_FUNC_GETCWD,
-[AC_MSG_CHECKING([if getcwd() will dynamically allocate memory with 0 size])
-AC_CACHE_VAL(bash_cv_getcwd_malloc,
-[AC_TRY_RUN([
-#include <stdio.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-main()
-{
-       char    *xpwd;
-       xpwd = getcwd(0, 0);
-       exit (xpwd == 0);
-}
-], bash_cv_getcwd_malloc=yes, bash_cv_getcwd_malloc=no,
-   [AC_MSG_WARN(cannot check whether getcwd allocates memory when cross-compiling -- defaulting to no)
-    bash_cv_getcwd_malloc=no]
-)])
-AC_MSG_RESULT($bash_cv_getcwd_malloc)
-if test $bash_cv_getcwd_malloc = no; then
-AC_DEFINE(GETCWD_BROKEN)
-AC_LIBOBJ(getcwd)
-fi
-])
-
-dnl
-dnl This needs BASH_CHECK_SOCKLIB, but since that's not called on every
-dnl system, we can't use AC_PREREQ
-dnl
-AC_DEFUN(BASH_FUNC_GETHOSTBYNAME,
-[if test "X$bash_cv_have_gethostbyname" = "X"; then
-_bash_needmsg=yes
-else
-AC_MSG_CHECKING(for gethostbyname in socket library)
-_bash_needmsg=
-fi
-AC_CACHE_VAL(bash_cv_have_gethostbyname,
-[AC_TRY_LINK([#include <netdb.h>],
-[ struct hostent *hp;
-  hp = gethostbyname("localhost");
-], bash_cv_have_gethostbyname=yes, bash_cv_have_gethostbyname=no)]
-)
-if test "X$_bash_needmsg" = Xyes; then
-    AC_MSG_CHECKING(for gethostbyname in socket library)
-fi
-AC_MSG_RESULT($bash_cv_have_gethostbyname)
-if test "$bash_cv_have_gethostbyname" = yes; then
-AC_DEFINE(HAVE_GETHOSTBYNAME)
-fi
-])
-
-AC_DEFUN(BASH_FUNC_FNMATCH_EXTMATCH,
-[AC_MSG_CHECKING(if fnmatch does extended pattern matching with FNM_EXTMATCH)
-AC_CACHE_VAL(bash_cv_fnm_extmatch,
-[AC_TRY_RUN([
-#include <fnmatch.h>
-
-main()
-{
-#ifdef FNM_EXTMATCH
-  exit (0);
-#else
-  exit (1);
-#endif
-}
-], bash_cv_fnm_extmatch=yes, bash_cv_fnm_extmatch=no,
-    [AC_MSG_WARN(cannot check FNM_EXTMATCH if cross compiling -- defaulting to no)
-     bash_cv_fnm_extmatch=no])
-])
-AC_MSG_RESULT($bash_cv_fnm_extmatch)
-if test $bash_cv_fnm_extmatch = yes; then
-AC_DEFINE(HAVE_LIBC_FNM_EXTMATCH)
-fi
-])
-
-AC_DEFUN(BASH_FUNC_POSIX_SETJMP,
-[AC_REQUIRE([BASH_SYS_SIGNAL_VINTAGE])
-AC_MSG_CHECKING(for presence of POSIX-style sigsetjmp/siglongjmp)
-AC_CACHE_VAL(bash_cv_func_sigsetjmp,
-[AC_TRY_RUN([
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <sys/types.h>
-#include <signal.h>
-#include <setjmp.h>
-
-main()
-{
-#if !defined (_POSIX_VERSION) || !defined (HAVE_POSIX_SIGNALS)
-exit (1);
-#else
-
-int code;
-sigset_t set, oset;
-sigjmp_buf xx;
-
-/* get the mask */
-sigemptyset(&set);
-sigemptyset(&oset);
-sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &set);
-sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &oset);
-
-/* save it */
-code = sigsetjmp(xx, 1);
-if (code)
-  exit(0);     /* could get sigmask and compare to oset here. */
-
-/* change it */
-sigaddset(&set, SIGINT);
-sigprocmask(SIG_BLOCK, &set, (sigset_t *)NULL);
-
-/* and siglongjmp */
-siglongjmp(xx, 10);
-exit(1);
-#endif
-}], bash_cv_func_sigsetjmp=present, bash_cv_func_sigsetjmp=missing,
-    [AC_MSG_WARN(cannot check for sigsetjmp/siglongjmp if cross-compiling -- defaulting to missing)
-     bash_cv_func_sigsetjmp=missing]
-)])
-AC_MSG_RESULT($bash_cv_func_sigsetjmp)
-if test $bash_cv_func_sigsetjmp = present; then
-AC_DEFINE(HAVE_POSIX_SIGSETJMP)
-fi
-])
-
-AC_DEFUN(BASH_FUNC_STRCOLL,
-[
-AC_MSG_CHECKING(whether or not strcoll and strcmp differ)
-AC_CACHE_VAL(bash_cv_func_strcoll_broken,
-[AC_TRY_RUN([
-#include <stdio.h>
-#if defined (HAVE_LOCALE_H)
-#include <locale.h>
-#endif
-
-main(c, v)
-int     c;
-char    *v[];
-{
-        int     r1, r2;
-        char    *deflocale, *defcoll;
-
-#ifdef HAVE_SETLOCALE
-        deflocale = setlocale(LC_ALL, "");
-       defcoll = setlocale(LC_COLLATE, "");
-#endif
-
-#ifdef HAVE_STRCOLL
-       /* These two values are taken from tests/glob-test. */
-        r1 = strcoll("abd", "aXd");
-#else
-       r1 = 0;
-#endif
-        r2 = strcmp("abd", "aXd");
-
-       /* These two should both be greater than 0.  It is permissible for
-          a system to return different values, as long as the sign is the
-          same. */
-
-        /* Exit with 1 (failure) if these two values are both > 0, since
-          this tests whether strcoll(3) is broken with respect to strcmp(3)
-          in the default locale. */
-       exit (r1 > 0 && r2 > 0);
-}
-], bash_cv_func_strcoll_broken=yes, bash_cv_func_strcoll_broken=no,
-   [AC_MSG_WARN(cannot check strcoll if cross compiling -- defaulting to no)
-    bash_cv_func_strcoll_broken=no]
-)])
-AC_MSG_RESULT($bash_cv_func_strcoll_broken)
-if test $bash_cv_func_strcoll_broken = yes; then
-AC_DEFINE(STRCOLL_BROKEN)
-fi
-])
-
-AC_DEFUN(BASH_FUNC_PRINTF_A_FORMAT,
-[AC_MSG_CHECKING([for printf floating point output in hex notation])
-AC_CACHE_VAL(bash_cv_printf_a_format,
-[AC_TRY_RUN([
-#include <stdio.h>
-#include <string.h>
-
-int
-main()
-{
-       double y = 0.0;
-       char abuf[1024];
-
-       sprintf(abuf, "%A", y);
-       exit(strchr(abuf, 'P') == (char *)0);
-}
-], bash_cv_printf_a_format=yes, bash_cv_printf_a_format=no,
-   [AC_MSG_WARN(cannot check printf if cross compiling -- defaulting to no)
-    bash_cv_printf_a_format=no]
-)])
-AC_MSG_RESULT($bash_cv_printf_a_format)
-if test $bash_cv_printf_a_format = yes; then
-AC_DEFINE(HAVE_PRINTF_A_FORMAT)
-fi
-])
-
-AC_DEFUN(BASH_STRUCT_TERMIOS_LDISC,
-[
-AC_CHECK_MEMBER(struct termios.c_line, AC_DEFINE(TERMIOS_LDISC), ,[
-#include <sys/types.h>
-#include <termios.h>
-])
-])
-
-AC_DEFUN(BASH_STRUCT_TERMIO_LDISC,
-[
-AC_CHECK_MEMBER(struct termio.c_line, AC_DEFINE(TERMIO_LDISC), ,[
-#include <sys/types.h>
-#include <termio.h>
-])
-])
-
-dnl
-dnl Like AC_STRUCT_ST_BLOCKS, but doesn't muck with LIBOBJS
-dnl
-dnl sets bash_cv_struct_stat_st_blocks
-dnl
-dnl unused for now; we'll see how AC_CHECK_MEMBERS works
-dnl
-AC_DEFUN(BASH_STRUCT_ST_BLOCKS,
-[
-AC_MSG_CHECKING([for struct stat.st_blocks])
-AC_CACHE_VAL(bash_cv_struct_stat_st_blocks,
-[AC_TRY_COMPILE(
-[
-#include <sys/types.h>
-#include <sys/stat.h>
-],
-[
-main()
-{
-static struct stat a;
-if (a.st_blocks) return 0;
-return 0;
-}
-], bash_cv_struct_stat_st_blocks=yes, bash_cv_struct_stat_st_blocks=no)
-])
-AC_MSG_RESULT($bash_cv_struct_stat_st_blocks)
-if test "$bash_cv_struct_stat_st_blocks" = "yes"; then
-AC_DEFINE(HAVE_STRUCT_STAT_ST_BLOCKS)
-fi
-])
-
-AC_DEFUN([BASH_CHECK_LIB_TERMCAP],
-[
-if test "X$bash_cv_termcap_lib" = "X"; then
-_bash_needmsg=yes
-else
-AC_MSG_CHECKING(which library has the termcap functions)
-_bash_needmsg=
-fi
-AC_CACHE_VAL(bash_cv_termcap_lib,
-[AC_CHECK_FUNC(tgetent, bash_cv_termcap_lib=libc,
-  [AC_CHECK_LIB(termcap, tgetent, bash_cv_termcap_lib=libtermcap,
-    [AC_CHECK_LIB(tinfo, tgetent, bash_cv_termcap_lib=libtinfo,
-        [AC_CHECK_LIB(curses, tgetent, bash_cv_termcap_lib=libcurses,
-           [AC_CHECK_LIB(ncurses, tgetent, bash_cv_termcap_lib=libncurses,
-               bash_cv_termcap_lib=gnutermcap)])])])])])
-if test "X$_bash_needmsg" = "Xyes"; then
-AC_MSG_CHECKING(which library has the termcap functions)
-fi
-AC_MSG_RESULT(using $bash_cv_termcap_lib)
-if test $bash_cv_termcap_lib = gnutermcap && test -z "$prefer_curses"; then
-LDFLAGS="$LDFLAGS -L./lib/termcap"
-TERMCAP_LIB="./lib/termcap/libtermcap.a"
-TERMCAP_DEP="./lib/termcap/libtermcap.a"
-elif test $bash_cv_termcap_lib = libtermcap && test -z "$prefer_curses"; then
-TERMCAP_LIB=-ltermcap
-TERMCAP_DEP=
-elif test $bash_cv_termcap_lib = libtinfo; then
-TERMCAP_LIB=-ltinfo
-TERMCAP_DEP=
-elif test $bash_cv_termcap_lib = libncurses; then
-TERMCAP_LIB=-lncurses
-TERMCAP_DEP=
-elif test $bash_cv_termcap_lib = libc; then
-TERMCAP_LIB=
-TERMCAP_DEP=
-else
-TERMCAP_LIB=-lcurses
-TERMCAP_DEP=
-fi
-])
-
-dnl
-dnl Check for the presence of getpeername in libsocket.
-dnl If libsocket is present, check for libnsl and add it to LIBS if
-dnl it's there, since most systems with libsocket require linking
-dnl with libnsl as well.  This should only be called if getpeername
-dnl was not found in libc.
-dnl
-dnl NOTE: IF WE FIND GETPEERNAME, WE ASSUME THAT WE HAVE BIND/CONNECT
-dnl      AS WELL
-dnl
-AC_DEFUN(BASH_CHECK_LIB_SOCKET,
-[
-if test "X$bash_cv_have_socklib" = "X"; then
-_bash_needmsg=
-else
-AC_MSG_CHECKING(for socket library)
-_bash_needmsg=yes
-fi
-AC_CACHE_VAL(bash_cv_have_socklib,
-[AC_CHECK_LIB(socket, getpeername,
-        bash_cv_have_socklib=yes, bash_cv_have_socklib=no, -lnsl)])
-if test "X$_bash_needmsg" = Xyes; then
-  AC_MSG_RESULT($bash_cv_have_socklib)
-  _bash_needmsg=
-fi
-if test $bash_cv_have_socklib = yes; then
-  # check for libnsl, add it to LIBS if present
-  if test "X$bash_cv_have_libnsl" = "X"; then
-    _bash_needmsg=
-  else
-    AC_MSG_CHECKING(for libnsl)
-    _bash_needmsg=yes
-  fi
-  AC_CACHE_VAL(bash_cv_have_libnsl,
-          [AC_CHECK_LIB(nsl, t_open,
-                bash_cv_have_libnsl=yes, bash_cv_have_libnsl=no)])
-  if test "X$_bash_needmsg" = Xyes; then
-    AC_MSG_RESULT($bash_cv_have_libnsl)
-    _bash_needmsg=
-  fi
-  if test $bash_cv_have_libnsl = yes; then
-    LIBS="-lsocket -lnsl $LIBS"
-  else
-    LIBS="-lsocket $LIBS"
-  fi
-  AC_DEFINE(HAVE_LIBSOCKET)
-  AC_DEFINE(HAVE_GETPEERNAME)
-fi
-])
-
-AC_DEFUN(BASH_STRUCT_DIRENT_D_INO,
-[AC_REQUIRE([AC_HEADER_DIRENT])
-AC_MSG_CHECKING(for struct dirent.d_ino)
-AC_CACHE_VAL(bash_cv_dirent_has_dino,
-[AC_TRY_COMPILE([
-#include <stdio.h>
-#include <sys/types.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-#if defined(HAVE_DIRENT_H)
-# include <dirent.h>
-#else
-# define dirent direct
-# ifdef HAVE_SYS_NDIR_H
-#  include <sys/ndir.h>
-# endif /* SYSNDIR */
-# ifdef HAVE_SYS_DIR_H
-#  include <sys/dir.h>
-# endif /* SYSDIR */
-# ifdef HAVE_NDIR_H
-#  include <ndir.h>
-# endif
-#endif /* HAVE_DIRENT_H */
-],[
-struct dirent d; int z; z = d.d_ino;
-], bash_cv_dirent_has_dino=yes, bash_cv_dirent_has_dino=no)])
-AC_MSG_RESULT($bash_cv_dirent_has_dino)
-if test $bash_cv_dirent_has_dino = yes; then
-AC_DEFINE(HAVE_STRUCT_DIRENT_D_INO)
-fi
-])
-
-AC_DEFUN(BASH_STRUCT_DIRENT_D_FILENO,
-[AC_REQUIRE([AC_HEADER_DIRENT])
-AC_MSG_CHECKING(for struct dirent.d_fileno)
-AC_CACHE_VAL(bash_cv_dirent_has_d_fileno,
-[AC_TRY_COMPILE([
-#include <stdio.h>
-#include <sys/types.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-#if defined(HAVE_DIRENT_H)
-# include <dirent.h>
-#else
-# define dirent direct
-# ifdef HAVE_SYS_NDIR_H
-#  include <sys/ndir.h>
-# endif /* SYSNDIR */
-# ifdef HAVE_SYS_DIR_H
-#  include <sys/dir.h>
-# endif /* SYSDIR */
-# ifdef HAVE_NDIR_H
-#  include <ndir.h>
-# endif
-#endif /* HAVE_DIRENT_H */
-],[
-struct dirent d; int z; z = d.d_fileno;
-], bash_cv_dirent_has_d_fileno=yes, bash_cv_dirent_has_d_fileno=no)])
-AC_MSG_RESULT($bash_cv_dirent_has_d_fileno)
-if test $bash_cv_dirent_has_d_fileno = yes; then
-AC_DEFINE(HAVE_STRUCT_DIRENT_D_FILENO)
-fi
-])
-
-AC_DEFUN(BASH_STRUCT_DIRENT_D_NAMLEN,
-[AC_REQUIRE([AC_HEADER_DIRENT])
-AC_MSG_CHECKING(for struct dirent.d_namlen)
-AC_CACHE_VAL(bash_cv_dirent_has_d_namlen,
-[AC_TRY_COMPILE([
-#include <stdio.h>
-#include <sys/types.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-#if defined(HAVE_DIRENT_H)
-# include <dirent.h>
-#else
-# define dirent direct
-# ifdef HAVE_SYS_NDIR_H
-#  include <sys/ndir.h>
-# endif /* SYSNDIR */
-# ifdef HAVE_SYS_DIR_H
-#  include <sys/dir.h>
-# endif /* SYSDIR */
-# ifdef HAVE_NDIR_H
-#  include <ndir.h>
-# endif
-#endif /* HAVE_DIRENT_H */
-],[
-struct dirent d; int z; z = d.d_namlen;
-], bash_cv_dirent_has_d_namlen=yes, bash_cv_dirent_has_d_namlen=no)])
-AC_MSG_RESULT($bash_cv_dirent_has_d_namlen)
-if test $bash_cv_dirent_has_d_namlen = yes; then
-AC_DEFINE(HAVE_STRUCT_DIRENT_D_NAMLEN)
-fi
-])
-
-AC_DEFUN(BASH_STRUCT_TIMEVAL,
-[AC_MSG_CHECKING(for struct timeval in sys/time.h and time.h)
-AC_CACHE_VAL(bash_cv_struct_timeval,
-[
-AC_EGREP_HEADER(struct timeval, sys/time.h,
-               bash_cv_struct_timeval=yes,
-               AC_EGREP_HEADER(struct timeval, time.h,
-                       bash_cv_struct_timeval=yes,
-                       bash_cv_struct_timeval=no))
-])
-AC_MSG_RESULT($bash_cv_struct_timeval)
-if test $bash_cv_struct_timeval = yes; then
-  AC_DEFINE(HAVE_TIMEVAL)
-fi
-])
-
-AC_DEFUN(BASH_STRUCT_TIMEZONE,
-[AC_MSG_CHECKING(for struct timezone in sys/time.h and time.h)
-AC_CACHE_VAL(bash_cv_struct_timezone,
-[
-AC_EGREP_HEADER(struct timezone, sys/time.h,
-               bash_cv_struct_timezone=yes,
-               AC_EGREP_HEADER(struct timezone, time.h,
-                       bash_cv_struct_timezone=yes,
-                       bash_cv_struct_timezone=no))
-])
-AC_MSG_RESULT($bash_cv_struct_timezone)
-if test $bash_cv_struct_timezone = yes; then
-  AC_DEFINE(HAVE_STRUCT_TIMEZONE)
-fi
-])
-
-AC_DEFUN(BASH_STRUCT_WINSIZE,
-[AC_MSG_CHECKING(for struct winsize in sys/ioctl.h and termios.h)
-AC_CACHE_VAL(bash_cv_struct_winsize_header,
-[AC_TRY_COMPILE([#include <sys/types.h>
-#include <sys/ioctl.h>], [struct winsize x;],
-  bash_cv_struct_winsize_header=ioctl_h,
-  [AC_TRY_COMPILE([#include <sys/types.h>
-#include <termios.h>], [struct winsize x;],
-  bash_cv_struct_winsize_header=termios_h, bash_cv_struct_winsize_header=other)
-])])
-if test $bash_cv_struct_winsize_header = ioctl_h; then
-  AC_MSG_RESULT(sys/ioctl.h)
-  AC_DEFINE(STRUCT_WINSIZE_IN_SYS_IOCTL)
-elif test $bash_cv_struct_winsize_header = termios_h; then
-  AC_MSG_RESULT(termios.h)
-  AC_DEFINE(STRUCT_WINSIZE_IN_TERMIOS)
-else
-  AC_MSG_RESULT(not found)
-fi
-])
-
-dnl Check type of signal routines (posix, 4.2bsd, 4.1bsd or v7)
-AC_DEFUN(BASH_SYS_SIGNAL_VINTAGE,
-[AC_REQUIRE([AC_TYPE_SIGNAL])
-AC_MSG_CHECKING(for type of signal functions)
-AC_CACHE_VAL(bash_cv_signal_vintage,
-[
-  AC_TRY_LINK([#include <signal.h>],[
-    sigset_t ss;
-    struct sigaction sa;
-    sigemptyset(&ss); sigsuspend(&ss);
-    sigaction(SIGINT, &sa, (struct sigaction *) 0);
-    sigprocmask(SIG_BLOCK, &ss, (sigset_t *) 0);
-  ], bash_cv_signal_vintage=posix,
-  [
-    AC_TRY_LINK([#include <signal.h>], [
-       int mask = sigmask(SIGINT);
-       sigsetmask(mask); sigblock(mask); sigpause(mask);
-    ], bash_cv_signal_vintage=4.2bsd,
-    [
-      AC_TRY_LINK([
-       #include <signal.h>
-       RETSIGTYPE foo() { }], [
-               int mask = sigmask(SIGINT);
-               sigset(SIGINT, foo); sigrelse(SIGINT);
-               sighold(SIGINT); sigpause(SIGINT);
-        ], bash_cv_signal_vintage=svr3, bash_cv_signal_vintage=v7
-    )]
-  )]
-)
-])
-AC_MSG_RESULT($bash_cv_signal_vintage)
-if test "$bash_cv_signal_vintage" = posix; then
-AC_DEFINE(HAVE_POSIX_SIGNALS)
-elif test "$bash_cv_signal_vintage" = "4.2bsd"; then
-AC_DEFINE(HAVE_BSD_SIGNALS)
-elif test "$bash_cv_signal_vintage" = svr3; then
-AC_DEFINE(HAVE_USG_SIGHOLD)
-fi
-])
-
-dnl Check if the pgrp of setpgrp() can't be the pid of a zombie process.
-AC_DEFUN(BASH_SYS_PGRP_SYNC,
-[AC_REQUIRE([AC_FUNC_GETPGRP])
-AC_MSG_CHECKING(whether pgrps need synchronization)
-AC_CACHE_VAL(bash_cv_pgrp_pipe,
-[AC_TRY_RUN([
-#ifdef HAVE_UNISTD_H
-#  include <unistd.h>
-#endif
-main()
-{
-# ifdef GETPGRP_VOID
-#  define getpgID()    getpgrp()
-# else
-#  define getpgID()    getpgrp(0)
-#  define setpgid(x,y) setpgrp(x,y)
-# endif
-       int pid1, pid2, fds[2];
-       int status;
-       char ok;
-
-       switch (pid1 = fork()) {
-         case -1:
-           exit(1);
-         case 0:
-           setpgid(0, getpid());
-           exit(0);
-       }
-       setpgid(pid1, pid1);
-
-       sleep(2);       /* let first child die */
-
-       if (pipe(fds) < 0)
-         exit(2);
-
-       switch (pid2 = fork()) {
-         case -1:
-           exit(3);
-         case 0:
-           setpgid(0, pid1);
-           ok = getpgID() == pid1;
-           write(fds[1], &ok, 1);
-           exit(0);
-       }
-       setpgid(pid2, pid1);
-
-       close(fds[1]);
-       if (read(fds[0], &ok, 1) != 1)
-         exit(4);
-       wait(&status);
-       wait(&status);
-       exit(ok ? 0 : 5);
-}
-], bash_cv_pgrp_pipe=no,bash_cv_pgrp_pipe=yes,
-   [AC_MSG_WARN(cannot check pgrp synchronization if cross compiling -- defaulting to no)
-    bash_cv_pgrp_pipe=no])
-])
-AC_MSG_RESULT($bash_cv_pgrp_pipe)
-if test $bash_cv_pgrp_pipe = yes; then
-AC_DEFINE(PGRP_PIPE)
-fi
-])
-
-AC_DEFUN(BASH_SYS_REINSTALL_SIGHANDLERS,
-[AC_REQUIRE([AC_TYPE_SIGNAL])
-AC_REQUIRE([BASH_SYS_SIGNAL_VINTAGE])
-AC_MSG_CHECKING([if signal handlers must be reinstalled when invoked])
-AC_CACHE_VAL(bash_cv_must_reinstall_sighandlers,
-[AC_TRY_RUN([
-#include <signal.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-typedef RETSIGTYPE sigfunc();
-
-int nsigint;
-
-#ifdef HAVE_POSIX_SIGNALS
-sigfunc *
-set_signal_handler(sig, handler)
-     int sig;
-     sigfunc *handler;
-{
-  struct sigaction act, oact;
-  act.sa_handler = handler;
-  act.sa_flags = 0;
-  sigemptyset (&act.sa_mask);
-  sigemptyset (&oact.sa_mask);
-  sigaction (sig, &act, &oact);
-  return (oact.sa_handler);
-}
-#else
-#define set_signal_handler(s, h) signal(s, h)
-#endif
-
-RETSIGTYPE
-sigint(s)
-int s;
-{
-  nsigint++;
-}
-
-main()
-{
-       nsigint = 0;
-       set_signal_handler(SIGINT, sigint);
-       kill((int)getpid(), SIGINT);
-       kill((int)getpid(), SIGINT);
-       exit(nsigint != 2);
-}
-], bash_cv_must_reinstall_sighandlers=no, bash_cv_must_reinstall_sighandlers=yes,
-   [AC_MSG_WARN(cannot check signal handling if cross compiling -- defaulting to no)
-    bash_cv_must_reinstall_sighandlers=no]
-)])
-AC_MSG_RESULT($bash_cv_must_reinstall_sighandlers)
-if test $bash_cv_must_reinstall_sighandlers = yes; then
-AC_DEFINE(MUST_REINSTALL_SIGHANDLERS)
-fi
-])
-
-dnl check that some necessary job control definitions are present
-AC_DEFUN(BASH_SYS_JOB_CONTROL_MISSING,
-[AC_REQUIRE([BASH_SYS_SIGNAL_VINTAGE])
-AC_MSG_CHECKING(for presence of necessary job control definitions)
-AC_CACHE_VAL(bash_cv_job_control_missing,
-[AC_TRY_RUN([
-#include <sys/types.h>
-#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <signal.h>
-
-/* Add more tests in here as appropriate. */
-main()
-{
-/* signal type */
-#if !defined (HAVE_POSIX_SIGNALS) && !defined (HAVE_BSD_SIGNALS)
-exit(1);
-#endif
-
-/* signals and tty control. */
-#if !defined (SIGTSTP) || !defined (SIGSTOP) || !defined (SIGCONT)
-exit (1);
-#endif
-
-/* process control */
-#if !defined (WNOHANG) || !defined (WUNTRACED) 
-exit(1);
-#endif
-
-/* Posix systems have tcgetpgrp and waitpid. */
-#if defined (_POSIX_VERSION) && !defined (HAVE_TCGETPGRP)
-exit(1);
-#endif
-
-#if defined (_POSIX_VERSION) && !defined (HAVE_WAITPID)
-exit(1);
-#endif
-
-/* Other systems have TIOCSPGRP/TIOCGPRGP and wait3. */
-#if !defined (_POSIX_VERSION) && !defined (HAVE_WAIT3)
-exit(1);
-#endif
-
-exit(0);
-}], bash_cv_job_control_missing=present, bash_cv_job_control_missing=missing,
-    [AC_MSG_WARN(cannot check job control if cross-compiling -- defaulting to missing)
-     bash_cv_job_control_missing=missing]
-)])
-AC_MSG_RESULT($bash_cv_job_control_missing)
-if test $bash_cv_job_control_missing = missing; then
-AC_DEFINE(JOB_CONTROL_MISSING)
-fi
-])
-
-dnl check whether named pipes are present
-dnl this requires a previous check for mkfifo, but that is awkward to specify
-AC_DEFUN(BASH_SYS_NAMED_PIPES,
-[AC_MSG_CHECKING(for presence of named pipes)
-AC_CACHE_VAL(bash_cv_sys_named_pipes,
-[AC_TRY_RUN([
-#include <sys/types.h>
-#include <sys/stat.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-/* Add more tests in here as appropriate. */
-main()
-{
-int fd, err;
-
-#if defined (HAVE_MKFIFO)
-exit (0);
-#endif
-
-#if !defined (S_IFIFO) && (defined (_POSIX_VERSION) && !defined (S_ISFIFO))
-exit (1);
-#endif
-
-#if defined (NeXT)
-exit (1);
-#endif
-err = mkdir("bash-aclocal", 0700);
-if (err < 0) {
-  perror ("mkdir");
-  exit(1);
-}
-fd = mknod ("bash-aclocal/sh-np-autoconf", 0666 | S_IFIFO, 0);
-if (fd == -1) {
-  rmdir ("bash-aclocal");
-  exit (1);
-}
-close(fd);
-unlink ("bash-aclocal/sh-np-autoconf");
-rmdir ("bash-aclocal");
-exit(0);
-}], bash_cv_sys_named_pipes=present, bash_cv_sys_named_pipes=missing,
-    [AC_MSG_WARN(cannot check for named pipes if cross-compiling -- defaulting to missing)
-     bash_cv_sys_named_pipes=missing]
-)])
-AC_MSG_RESULT($bash_cv_sys_named_pipes)
-if test $bash_cv_sys_named_pipes = missing; then
-AC_DEFINE(NAMED_PIPES_MISSING)
-fi
-])
-
-AC_DEFUN(BASH_SYS_DEFAULT_MAIL_DIR,
-[AC_MSG_CHECKING(for default mail directory)
-AC_CACHE_VAL(bash_cv_mail_dir,
-[if test -d /var/mail; then
-   bash_cv_mail_dir=/var/mail
- elif test -d /var/spool/mail; then
-   bash_cv_mail_dir=/var/spool/mail
- elif test -d /usr/mail; then
-   bash_cv_mail_dir=/usr/mail
- elif test -d /usr/spool/mail; then
-   bash_cv_mail_dir=/usr/spool/mail
- else
-   bash_cv_mail_dir=unknown
- fi
-])
-AC_MSG_RESULT($bash_cv_mail_dir)
-AC_DEFINE_UNQUOTED(DEFAULT_MAIL_DIRECTORY, "$bash_cv_mail_dir")
-])
-
-AC_DEFUN(BASH_HAVE_TIOCGWINSZ,
-[AC_MSG_CHECKING(for TIOCGWINSZ in sys/ioctl.h)
-AC_CACHE_VAL(bash_cv_tiocgwinsz_in_ioctl,
-[AC_TRY_COMPILE([#include <sys/types.h>
-#include <sys/ioctl.h>], [int x = TIOCGWINSZ;],
-  bash_cv_tiocgwinsz_in_ioctl=yes,bash_cv_tiocgwinsz_in_ioctl=no)])
-AC_MSG_RESULT($bash_cv_tiocgwinsz_in_ioctl)
-if test $bash_cv_tiocgwinsz_in_ioctl = yes; then   
-AC_DEFINE(GWINSZ_IN_SYS_IOCTL)
-fi
-])
-
-AC_DEFUN(BASH_HAVE_TIOCSTAT,
-[AC_MSG_CHECKING(for TIOCSTAT in sys/ioctl.h)
-AC_CACHE_VAL(bash_cv_tiocstat_in_ioctl,
-[AC_TRY_COMPILE([#include <sys/types.h>
-#include <sys/ioctl.h>], [int x = TIOCSTAT;],
-  bash_cv_tiocstat_in_ioctl=yes,bash_cv_tiocstat_in_ioctl=no)])
-AC_MSG_RESULT($bash_cv_tiocstat_in_ioctl)
-if test $bash_cv_tiocstat_in_ioctl = yes; then   
-AC_DEFINE(TIOCSTAT_IN_SYS_IOCTL)
-fi
-])
-
-AC_DEFUN(BASH_HAVE_FIONREAD,
-[AC_MSG_CHECKING(for FIONREAD in sys/ioctl.h)
-AC_CACHE_VAL(bash_cv_fionread_in_ioctl,
-[AC_TRY_COMPILE([#include <sys/types.h>
-#include <sys/ioctl.h>], [int x = FIONREAD;],
-  bash_cv_fionread_in_ioctl=yes,bash_cv_fionread_in_ioctl=no)])
-AC_MSG_RESULT($bash_cv_fionread_in_ioctl)
-if test $bash_cv_fionread_in_ioctl = yes; then   
-AC_DEFINE(FIONREAD_IN_SYS_IOCTL)
-fi
-])
-
-dnl
-dnl See if speed_t is declared in <sys/types.h>.  Some versions of linux
-dnl require a definition of speed_t each time <termcap.h> is included,
-dnl but you can only get speed_t if you include <termios.h> (on some
-dnl versions) or <sys/types.h> (on others).
-dnl
-AC_DEFUN(BASH_CHECK_SPEED_T,
-[AC_MSG_CHECKING(for speed_t in sys/types.h)
-AC_CACHE_VAL(bash_cv_speed_t_in_sys_types,
-[AC_TRY_COMPILE([#include <sys/types.h>], [speed_t x;],
-  bash_cv_speed_t_in_sys_types=yes,bash_cv_speed_t_in_sys_types=no)])
-AC_MSG_RESULT($bash_cv_speed_t_in_sys_types)
-if test $bash_cv_speed_t_in_sys_types = yes; then   
-AC_DEFINE(SPEED_T_IN_SYS_TYPES)
-fi
-])
-
-AC_DEFUN(BASH_CHECK_GETPW_FUNCS,
-[AC_MSG_CHECKING(whether getpw functions are declared in pwd.h)
-AC_CACHE_VAL(bash_cv_getpw_declared,
-[AC_EGREP_CPP(getpwuid,
-[
-#include <sys/types.h>
-#ifdef HAVE_UNISTD_H
-#  include <unistd.h>
-#endif
-#include <pwd.h>
-],
-bash_cv_getpw_declared=yes,bash_cv_getpw_declared=no)])
-AC_MSG_RESULT($bash_cv_getpw_declared)
-if test $bash_cv_getpw_declared = yes; then
-AC_DEFINE(HAVE_GETPW_DECLS)
-fi
-])
-
-AC_DEFUN(BASH_CHECK_DEV_FD,
-[AC_MSG_CHECKING(whether /dev/fd is available)
-AC_CACHE_VAL(bash_cv_dev_fd,
-[bash_cv_dev_fd=""
-if test -d /dev/fd  && (exec test -r /dev/fd/0 < /dev/null) ; then
-# check for systems like FreeBSD 5 that only provide /dev/fd/[012]
-   if (exec test -r /dev/fd/3 3</dev/null) ; then
-     bash_cv_dev_fd=standard
-   else
-     bash_cv_dev_fd=absent
-   fi
-fi
-if test -z "$bash_cv_dev_fd" ; then 
-  if test -d /proc/self/fd && (exec test -r /proc/self/fd/0 < /dev/null) ; then
-    bash_cv_dev_fd=whacky
-  else
-    bash_cv_dev_fd=absent
-  fi
-fi
-])
-AC_MSG_RESULT($bash_cv_dev_fd)
-if test $bash_cv_dev_fd = "standard"; then
-  AC_DEFINE(HAVE_DEV_FD)
-  AC_DEFINE(DEV_FD_PREFIX, "/dev/fd/")
-elif test $bash_cv_dev_fd = "whacky"; then
-  AC_DEFINE(HAVE_DEV_FD)
-  AC_DEFINE(DEV_FD_PREFIX, "/proc/self/fd/")
-fi
-])
-
-AC_DEFUN(BASH_CHECK_DEV_STDIN,
-[AC_MSG_CHECKING(whether /dev/stdin stdout stderr are available)
-AC_CACHE_VAL(bash_cv_dev_stdin,
-[if test -d /dev/fd && (exec test -r /dev/stdin < /dev/null) ; then
-   bash_cv_dev_stdin=present
- elif test -d /proc/self/fd && (exec test -r /dev/stdin < /dev/null) ; then
-   bash_cv_dev_stdin=present
- else
-   bash_cv_dev_stdin=absent
- fi
-])
-AC_MSG_RESULT($bash_cv_dev_stdin)
-if test $bash_cv_dev_stdin = "present"; then
-  AC_DEFINE(HAVE_DEV_STDIN)
-fi
-])
-
-dnl
-dnl Check if HPUX needs _KERNEL defined for RLIMIT_* definitions
-dnl
-AC_DEFUN(BASH_CHECK_KERNEL_RLIMIT,
-[AC_MSG_CHECKING([whether $host_os needs _KERNEL for RLIMIT defines])
-AC_CACHE_VAL(bash_cv_kernel_rlimit,
-[AC_TRY_COMPILE([
-#include <sys/types.h>
-#include <sys/resource.h>
-],
-[
-  int f;
-  f = RLIMIT_DATA;
-], bash_cv_kernel_rlimit=no,
-[AC_TRY_COMPILE([
-#include <sys/types.h>
-#define _KERNEL
-#include <sys/resource.h>
-#undef _KERNEL
-],
-[
-       int f;
-        f = RLIMIT_DATA;
-], bash_cv_kernel_rlimit=yes, bash_cv_kernel_rlimit=no)]
-)])
-AC_MSG_RESULT($bash_cv_kernel_rlimit)
-if test $bash_cv_kernel_rlimit = yes; then
-AC_DEFINE(RLIMIT_NEEDS_KERNEL)
-fi
-])
-
-dnl
-dnl Check for 64-bit off_t -- used for malloc alignment
-dnl
-dnl C does not allow duplicate case labels, so the compile will fail if
-dnl sizeof(off_t) is > 4.
-dnl
-AC_DEFUN(BASH_CHECK_OFF_T_64,
-[AC_CACHE_CHECK(for 64-bit off_t, bash_cv_off_t_64,
-AC_TRY_COMPILE([
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <sys/types.h>
-],[
-switch (0) case 0: case (sizeof (off_t) <= 4):;
-], bash_cv_off_t_64=no, bash_cv_off_t_64=yes))
-if test $bash_cv_off_t_64 = yes; then
-        AC_DEFINE(HAVE_OFF_T_64)
-fi])
-
-AC_DEFUN(BASH_CHECK_RTSIGS,
-[AC_MSG_CHECKING(for unusable real-time signals due to large values)
-AC_CACHE_VAL(bash_cv_unusable_rtsigs,
-[AC_TRY_RUN([
-#include <sys/types.h>
-#include <signal.h>
-
-#ifndef NSIG
-#  define NSIG 64
-#endif
-
-main ()
-{
-  int n_sigs = 2 * NSIG;
-#ifdef SIGRTMIN
-  int rtmin = SIGRTMIN;
-#else
-  int rtmin = 0;
-#endif
-
-  exit(rtmin < n_sigs);
-}], bash_cv_unusable_rtsigs=yes, bash_cv_unusable_rtsigs=no,
-    [AC_MSG_WARN(cannot check real-time signals if cross compiling -- defaulting to yes)
-     bash_cv_unusable_rtsigs=yes]
-)])
-AC_MSG_RESULT($bash_cv_unusable_rtsigs)
-if test $bash_cv_unusable_rtsigs = yes; then
-AC_DEFINE(UNUSABLE_RT_SIGNALS)
-fi
-])
-
-dnl
-dnl check for availability of multibyte characters and functions
-dnl
-dnl geez, I wish I didn't have to check for all of this stuff separately
-dnl
-AC_DEFUN(BASH_CHECK_MULTIBYTE,
-[
-AC_CHECK_HEADERS(wctype.h)
-AC_CHECK_HEADERS(wchar.h)
-AC_CHECK_HEADERS(langinfo.h)
-
-AC_CHECK_FUNC(mbrlen, AC_DEFINE(HAVE_MBRLEN))
-AC_CHECK_FUNC(mbscasecmp, AC_DEFINE(HAVE_MBSCMP))
-AC_CHECK_FUNC(mbscmp, AC_DEFINE(HAVE_MBSCMP))
-AC_CHECK_FUNC(mbsrtowcs, AC_DEFINE(HAVE_MBSRTOWCS))
-
-AC_REPLACE_FUNCS(mbschr)
-
-AC_CHECK_FUNC(wcrtomb, AC_DEFINE(HAVE_WCRTOMB))
-AC_CHECK_FUNC(wcscoll, AC_DEFINE(HAVE_WCSCOLL))
-AC_CHECK_FUNC(wcsdup, AC_DEFINE(HAVE_WCSDUP))
-AC_CHECK_FUNC(wcwidth, AC_DEFINE(HAVE_WCWIDTH))
-AC_CHECK_FUNC(wctype, AC_DEFINE(HAVE_WCTYPE))
-
-dnl checks for both mbrtowc and mbstate_t
-AC_FUNC_MBRTOWC
-if test $ac_cv_func_mbrtowc = yes; then
-       AC_DEFINE(HAVE_MBSTATE_T)
-fi
-
-AC_CHECK_FUNCS(iswlower iswupper towlower towupper iswctype)
-
-AC_CACHE_CHECK([for nl_langinfo and CODESET], bash_cv_langinfo_codeset,
-[AC_TRY_LINK(
-[#include <langinfo.h>],
-[char* cs = nl_langinfo(CODESET);],
-bash_cv_langinfo_codeset=yes, bash_cv_langinfo_codeset=no)])
-if test $bash_cv_langinfo_codeset = yes; then
-  AC_DEFINE(HAVE_LANGINFO_CODESET)
-fi
-
-dnl check for wchar_t in <wchar.h>
-AC_CACHE_CHECK([for wchar_t in wchar.h], bash_cv_type_wchar_t,
-[AC_TRY_COMPILE(
-[#include <wchar.h>
-],
-[
-        wchar_t foo;
-        foo = 0;
-], bash_cv_type_wchar_t=yes, bash_cv_type_wchar_t=no)])
-if test $bash_cv_type_wchar_t = yes; then
-        AC_DEFINE(HAVE_WCHAR_T, 1, [systems should define this type here])
-fi
-
-dnl check for wctype_t in <wctype.h>
-AC_CACHE_CHECK([for wctype_t in wctype.h], bash_cv_type_wctype_t,
-[AC_TRY_COMPILE(
-[#include <wctype.h>],
-[
-        wctype_t foo;
-        foo = 0;
-], bash_cv_type_wctype_t=yes, bash_cv_type_wctype_t=no)])
-if test $bash_cv_type_wctype_t = yes; then
-        AC_DEFINE(HAVE_WCTYPE_T, 1, [systems should define this type here])
-fi
-
-dnl check for wint_t in <wctype.h>
-AC_CACHE_CHECK([for wint_t in wctype.h], bash_cv_type_wint_t,
-[AC_TRY_COMPILE(
-[#include <wctype.h>],
-[
-        wint_t foo;
-        foo = 0;
-], bash_cv_type_wint_t=yes, bash_cv_type_wint_t=no)])
-if test $bash_cv_type_wint_t = yes; then
-        AC_DEFINE(HAVE_WINT_T, 1, [systems should define this type here])
-fi
-
-if test "$am_cv_func_iconv" = yes; then
-       OLDLIBS="$LIBS"
-       LIBS="$LIBS $LIBICONV"
-       AC_CHECK_FUNCS(locale_charset)
-       LIBS="$OLDLIBS"
-fi
-
-])
-
-dnl need: prefix exec_prefix libdir includedir CC TERMCAP_LIB
-dnl require:
-dnl    AC_PROG_CC
-dnl    BASH_CHECK_LIB_TERMCAP
-
-AC_DEFUN([RL_LIB_READLINE_VERSION],
-[
-AC_REQUIRE([BASH_CHECK_LIB_TERMCAP])
-
-AC_MSG_CHECKING([version of installed readline library])
-
-# What a pain in the ass this is.
-
-# save cpp and ld options
-_save_CFLAGS="$CFLAGS"
-_save_LDFLAGS="$LDFLAGS"
-_save_LIBS="$LIBS"
-
-# Don't set ac_cv_rl_prefix if the caller has already assigned a value.  This
-# allows the caller to do something like $_rl_prefix=$withval if the user
-# specifies --with-installed-readline=PREFIX as an argument to configure
-
-if test -z "$ac_cv_rl_prefix"; then
-test "x$prefix" = xNONE && ac_cv_rl_prefix=$ac_default_prefix || ac_cv_rl_prefix=${prefix}
-fi
-
-eval ac_cv_rl_includedir=${ac_cv_rl_prefix}/include
-eval ac_cv_rl_libdir=${ac_cv_rl_prefix}/lib
-
-LIBS="$LIBS -lreadline ${TERMCAP_LIB}"
-CFLAGS="$CFLAGS -I${ac_cv_rl_includedir}"
-LDFLAGS="$LDFLAGS -L${ac_cv_rl_libdir}"
-
-AC_CACHE_VAL(ac_cv_rl_version,
-[AC_TRY_RUN([
-#include <stdio.h>
-#include <readline/readline.h>
-
-extern int rl_gnu_readline_p;
-
-main()
-{
-       FILE *fp;
-       fp = fopen("conftest.rlv", "w");
-       if (fp == 0)
-               exit(1);
-       if (rl_gnu_readline_p != 1)
-               fprintf(fp, "0.0\n");
-       else
-               fprintf(fp, "%s\n", rl_library_version ? rl_library_version : "0.0");
-       fclose(fp);
-       exit(0);
-}
-],
-ac_cv_rl_version=`cat conftest.rlv`,
-ac_cv_rl_version='0.0',
-ac_cv_rl_version='4.2')])
-
-CFLAGS="$_save_CFLAGS"
-LDFLAGS="$_save_LDFLAGS"
-LIBS="$_save_LIBS"
-
-RL_MAJOR=0
-RL_MINOR=0
-
-# (
-case "$ac_cv_rl_version" in
-2*|3*|4*|5*|6*|7*|8*|9*)
-       RL_MAJOR=`echo $ac_cv_rl_version | sed 's:\..*$::'`
-       RL_MINOR=`echo $ac_cv_rl_version | sed -e 's:^.*\.::' -e 's:[[a-zA-Z]]*$::'`
-       ;;
-esac
-
-# (((
-case $RL_MAJOR in
-[[0-9][0-9]])  _RL_MAJOR=$RL_MAJOR ;;
-[[0-9]])       _RL_MAJOR=0$RL_MAJOR ;;
-*)             _RL_MAJOR=00 ;;
-esac
-
-# (((
-case $RL_MINOR in
-[[0-9][0-9]])  _RL_MINOR=$RL_MINOR ;;
-[[0-9]])       _RL_MINOR=0$RL_MINOR ;;
-*)             _RL_MINOR=00 ;;
-esac
-
-RL_VERSION="0x${_RL_MAJOR}${_RL_MINOR}"
-
-# Readline versions greater than 4.2 have these defines in readline.h
-
-if test $ac_cv_rl_version = '0.0' ; then
-       AC_MSG_WARN([Could not test version of installed readline library.])
-elif test $RL_MAJOR -gt 4 || { test $RL_MAJOR = 4 && test $RL_MINOR -gt 2 ; } ; then
-       # set these for use by the caller
-       RL_PREFIX=$ac_cv_rl_prefix
-       RL_LIBDIR=$ac_cv_rl_libdir
-       RL_INCLUDEDIR=$ac_cv_rl_includedir
-       AC_MSG_RESULT($ac_cv_rl_version)
-else
-
-AC_DEFINE_UNQUOTED(RL_READLINE_VERSION, $RL_VERSION, [encoded version of the installed readline library])
-AC_DEFINE_UNQUOTED(RL_VERSION_MAJOR, $RL_MAJOR, [major version of installed readline library])
-AC_DEFINE_UNQUOTED(RL_VERSION_MINOR, $RL_MINOR, [minor version of installed readline library])
-
-AC_SUBST(RL_VERSION)
-AC_SUBST(RL_MAJOR)
-AC_SUBST(RL_MINOR)
-
-# set these for use by the caller
-RL_PREFIX=$ac_cv_rl_prefix
-RL_LIBDIR=$ac_cv_rl_libdir
-RL_INCLUDEDIR=$ac_cv_rl_includedir
-
-AC_MSG_RESULT($ac_cv_rl_version)
-
-fi
-])
-
-AC_DEFUN(BASH_FUNC_CTYPE_NONASCII,
-[
-AC_MSG_CHECKING(whether the ctype macros accept non-ascii characters)
-AC_CACHE_VAL(bash_cv_func_ctype_nonascii,
-[AC_TRY_RUN([
-#ifdef HAVE_LOCALE_H
-#include <locale.h>
-#endif
-#include <stdio.h>
-#include <ctype.h>
-
-main(c, v)
-int    c;
-char   *v[];
-{
-       char    *deflocale;
-       unsigned char x;
-       int     r1, r2;
-
-#ifdef HAVE_SETLOCALE
-       /* We take a shot here.  If that locale is not known, try the
-          system default.  We try this one because '\342' (226) is
-          known to be a printable character in that locale. */
-       deflocale = setlocale(LC_ALL, "en_US.ISO8859-1");
-       if (deflocale == 0)
-               deflocale = setlocale(LC_ALL, "");
-#endif
-
-       x = '\342';
-       r1 = isprint(x);
-       x -= 128;
-       r2 = isprint(x);
-       exit (r1 == 0 || r2 == 0);
-}
-], bash_cv_func_ctype_nonascii=yes, bash_cv_func_ctype_nonascii=no,
-   [AC_MSG_WARN(cannot check ctype macros if cross compiling -- defaulting to no)
-    bash_cv_func_ctype_nonascii=no]
-)])
-AC_MSG_RESULT($bash_cv_func_ctype_nonascii)
-if test $bash_cv_func_ctype_nonascii = yes; then
-AC_DEFINE(CTYPE_NON_ASCII)
-fi
-])
-
-AC_DEFUN(BASH_CHECK_WCONTINUED,
-[
-AC_MSG_CHECKING(whether WCONTINUED flag to waitpid is unavailable or available but broken)
-AC_CACHE_VAL(bash_cv_wcontinued_broken,
-[AC_TRY_RUN([
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <errno.h>
-
-#ifndef errno
-extern int errno;
-#endif
-main()
-{
-       int     x;
-
-       x = waitpid(-1, (int *)0, WNOHANG|WCONTINUED);
-       if (x == -1 && errno == EINVAL)
-               exit (1);
-       else
-               exit (0);
-}
-], bash_cv_wcontinued_broken=no,bash_cv_wcontinued_broken=yes,
-   [AC_MSG_WARN(cannot check WCONTINUED if cross compiling -- defaulting to no)
-    bash_cv_wcontinued_broken=no]
-)])
-AC_MSG_RESULT($bash_cv_wcontinued_broken)
-if test $bash_cv_wcontinued_broken = yes; then
-AC_DEFINE(WCONTINUED_BROKEN)
-fi
-])
-
-dnl
-dnl tests added for bashdb
-dnl
-
-
-AC_DEFUN([AM_PATH_LISPDIR],
- [AC_ARG_WITH(lispdir, AC_HELP_STRING([--with-lispdir], [override the default lisp directory]),
-  [ lispdir="$withval" 
-    AC_MSG_CHECKING([where .elc files should go])
-    AC_MSG_RESULT([$lispdir])],
-  [
-  # If set to t, that means we are running in a shell under Emacs.
-  # If you have an Emacs named "t", then use the full path.
-  test x"$EMACS" = xt && EMACS=
-  AC_CHECK_PROGS(EMACS, emacs xemacs, no)
-  if test $EMACS != "no"; then
-    if test x${lispdir+set} != xset; then
-      AC_CACHE_CHECK([where .elc files should go], [am_cv_lispdir], [dnl
-       am_cv_lispdir=`$EMACS -batch -q -eval '(while load-path (princ (concat (car load-path) "\n")) (setq load-path (cdr load-path)))' | sed -n -e 's,/$,,' -e '/.*\/lib\/\(x\?emacs\/site-lisp\)$/{s,,${libdir}/\1,;p;q;}' -e '/.*\/share\/\(x\?emacs\/site-lisp\)$/{s,,${datadir}/\1,;p;q;}'`
-       if test -z "$am_cv_lispdir"; then
-         am_cv_lispdir='${datadir}/emacs/site-lisp'
-       fi
-      ])
-      lispdir="$am_cv_lispdir"
-    fi
-  fi
- ])
- AC_SUBST(lispdir)
-])
-
-dnl
-dnl tests added for gettext
-dnl
-# codeset.m4 serial AM1 (gettext-0.10.40)
-dnl Copyright (C) 2000-2002 Free Software Foundation, Inc.
-dnl This file is free software, distributed under the terms of the GNU
-dnl General Public License.  As a special exception to the GNU General
-dnl Public License, this file may be distributed as part of a program
-dnl that contains a configuration script generated by Autoconf, under
-dnl the same distribution terms as the rest of that program.
-
-dnl From Bruno Haible.
-
-AC_DEFUN([AM_LANGINFO_CODESET],
-[
-  AC_CACHE_CHECK([for nl_langinfo and CODESET], am_cv_langinfo_codeset,
-    [AC_TRY_LINK([#include <langinfo.h>],
-      [char* cs = nl_langinfo(CODESET);],
-      am_cv_langinfo_codeset=yes,
-      am_cv_langinfo_codeset=no)
-    ])
-  if test $am_cv_langinfo_codeset = yes; then
-    AC_DEFINE(HAVE_LANGINFO_CODESET, 1,
-      [Define if you have <langinfo.h> and nl_langinfo(CODESET).])
-  fi
-])
-# gettext.m4 serial 20 (gettext-0.12)
-dnl Copyright (C) 1995-2003 Free Software Foundation, Inc.
-dnl This file is free software, distributed under the terms of the GNU
-dnl General Public License.  As a special exception to the GNU General
-dnl Public License, this file may be distributed as part of a program
-dnl that contains a configuration script generated by Autoconf, under
-dnl the same distribution terms as the rest of that program.
-dnl
-dnl This file can can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
-dnl License but which still want to provide support for the GNU gettext
-dnl functionality.
-dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
-dnl gettext package package is covered by the GNU General Public License.
-dnl They are *not* in the public domain.
-
-dnl Authors:
-dnl   Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
-dnl   Bruno Haible <haible@clisp.cons.org>, 2000-2003.
-
-dnl Macro to add for using GNU gettext.
-
-dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]).
-dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The
-dnl    default (if it is not specified or empty) is 'no-libtool'.
-dnl    INTLSYMBOL should be 'external' for packages with no intl directory,
-dnl    and 'no-libtool' or 'use-libtool' for packages with an intl directory.
-dnl    If INTLSYMBOL is 'use-libtool', then a libtool library
-dnl    $(top_builddir)/intl/libintl.la will be created (shared and/or static,
-dnl    depending on --{enable,disable}-{shared,static} and on the presence of
-dnl    AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library
-dnl    $(top_builddir)/intl/libintl.a will be created.
-dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext
-dnl    implementations (in libc or libintl) without the ngettext() function
-dnl    will be ignored.  If NEEDSYMBOL is specified and is
-dnl    'need-formatstring-macros', then GNU gettext implementations that don't
-dnl    support the ISO C 99 <inttypes.h> formatstring macros will be ignored.
-dnl INTLDIR is used to find the intl libraries.  If empty,
-dnl    the value `$(top_builddir)/intl/' is used.
-dnl
-dnl The result of the configuration is one of three cases:
-dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled
-dnl    and used.
-dnl    Catalog format: GNU --> install in $(datadir)
-dnl    Catalog extension: .mo after installation, .gmo in source tree
-dnl 2) GNU gettext has been found in the system's C library.
-dnl    Catalog format: GNU --> install in $(datadir)
-dnl    Catalog extension: .mo after installation, .gmo in source tree
-dnl 3) No internationalization, always use English msgid.
-dnl    Catalog format: none
-dnl    Catalog extension: none
-dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur.
-dnl The use of .gmo is historical (it was needed to avoid overwriting the
-dnl GNU format catalogs when building on a platform with an X/Open gettext),
-dnl but we keep it in order not to force irrelevant filename changes on the
-dnl maintainers.
-dnl
-AC_DEFUN([AM_GNU_GETTEXT],
-[
-  dnl Argument checking.
-  ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], ,
-    [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT
-])])])])])
-  ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], ,
-    [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT
-])])])])
-  define(gt_included_intl, ifelse([$1], [external], [no], [yes]))
-  define(gt_libtool_suffix_prefix, ifelse([$1], [use-libtool], [l], []))
-
-  AC_REQUIRE([AM_PO_SUBDIRS])dnl
-  ifelse(gt_included_intl, yes, [
-    AC_REQUIRE([AM_INTL_SUBDIR])dnl
-  ])
-
-  dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
-  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
-  AC_REQUIRE([AC_LIB_RPATH])
-
-  dnl Sometimes libintl requires libiconv, so first search for libiconv.
-  dnl Ideally we would do this search only after the
-  dnl      if test "$USE_NLS" = "yes"; then
-  dnl        if test "$gt_cv_func_gnugettext_libc" != "yes"; then
-  dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT
-  dnl the configure script would need to contain the same shell code
-  dnl again, outside any 'if'. There are two solutions:
-  dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'.
-  dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE.
-  dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not
-  dnl documented, we avoid it.
-  ifelse(gt_included_intl, yes, , [
-    AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
-  ])
-
-  dnl Set USE_NLS.
-  AM_NLS
-
-  ifelse(gt_included_intl, yes, [
-    BUILD_INCLUDED_LIBINTL=no
-    USE_INCLUDED_LIBINTL=no
-  ])
-  LIBINTL=
-  LTLIBINTL=
-  POSUB=
-
-  dnl If we use NLS figure out what method
-  if test "$USE_NLS" = "yes"; then
-    gt_use_preinstalled_gnugettext=no
-    ifelse(gt_included_intl, yes, [
-      AC_MSG_CHECKING([whether included gettext is requested])
-      AC_ARG_WITH(included-gettext,
-        [  --with-included-gettext use the GNU gettext library included here],
-        nls_cv_force_use_gnu_gettext=$withval,
-        nls_cv_force_use_gnu_gettext=no)
-      AC_MSG_RESULT($nls_cv_force_use_gnu_gettext)
-
-      nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
-      if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
-    ])
-        dnl User does not insist on using GNU NLS library.  Figure out what
-        dnl to use.  If GNU gettext is available we use this.  Else we have
-        dnl to fall back to GNU NLS library.
-
-        dnl Add a version number to the cache macros.
-        define([gt_api_version], ifelse([$2], [need-formatstring-macros], 3, ifelse([$2], [need-ngettext], 2, 1)))
-        define([gt_cv_func_gnugettext_libc], [gt_cv_func_gnugettext]gt_api_version[_libc])
-        define([gt_cv_func_gnugettext_libintl], [gt_cv_func_gnugettext]gt_api_version[_libintl])
-
-        AC_CACHE_CHECK([for GNU gettext in libc], gt_cv_func_gnugettext_libc,
-         [AC_TRY_LINK([#include <libintl.h>
-]ifelse([$2], [need-formatstring-macros],
-[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
-#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1)
-#endif
-changequote(,)dnl
-typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
-changequote([,])dnl
-], [])[extern int _nl_msg_cat_cntr;
-extern int *_nl_domain_bindings;],
-            [bindtextdomain ("", "");
-return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_domain_bindings],
-            gt_cv_func_gnugettext_libc=yes,
-            gt_cv_func_gnugettext_libc=no)])
-
-        if test "$gt_cv_func_gnugettext_libc" != "yes"; then
-          dnl Sometimes libintl requires libiconv, so first search for libiconv.
-          ifelse(gt_included_intl, yes, , [
-            AM_ICONV_LINK
-          ])
-          dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL
-          dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv])
-          dnl because that would add "-liconv" to LIBINTL and LTLIBINTL
-          dnl even if libiconv doesn't exist.
-          AC_LIB_LINKFLAGS_BODY([intl])
-          AC_CACHE_CHECK([for GNU gettext in libintl],
-            gt_cv_func_gnugettext_libintl,
-           [gt_save_CPPFLAGS="$CPPFLAGS"
-            CPPFLAGS="$CPPFLAGS $INCINTL"
-            gt_save_LIBS="$LIBS"
-            LIBS="$LIBS $LIBINTL"
-            dnl Now see whether libintl exists and does not depend on libiconv.
-            AC_TRY_LINK([#include <libintl.h>
-]ifelse([$2], [need-formatstring-macros],
-[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
-#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1)
-#endif
-changequote(,)dnl
-typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
-changequote([,])dnl
-], [])[extern int _nl_msg_cat_cntr;
-extern
-#ifdef __cplusplus
-"C"
-#endif
-const char *_nl_expand_alias ();],
-              [bindtextdomain ("", "");
-return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)],
-              gt_cv_func_gnugettext_libintl=yes,
-              gt_cv_func_gnugettext_libintl=no)
-            dnl Now see whether libintl exists and depends on libiconv.
-            if test "$gt_cv_func_gnugettext_libintl" != yes && test -n "$LIBICONV"; then
-              LIBS="$LIBS $LIBICONV"
-              AC_TRY_LINK([#include <libintl.h>
-]ifelse([$2], [need-formatstring-macros],
-[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
-#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1)
-#endif
-changequote(,)dnl
-typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
-changequote([,])dnl
-], [])[extern int _nl_msg_cat_cntr;
-extern
-#ifdef __cplusplus
-"C"
-#endif
-const char *_nl_expand_alias ();],
-                [bindtextdomain ("", "");
-return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)],
-               [LIBINTL="$LIBINTL $LIBICONV"
-                LTLIBINTL="$LTLIBINTL $LTLIBICONV"
-                gt_cv_func_gnugettext_libintl=yes
-               ])
-            fi
-            CPPFLAGS="$gt_save_CPPFLAGS"
-            LIBS="$gt_save_LIBS"])
-        fi
-
-        dnl If an already present or preinstalled GNU gettext() is found,
-        dnl use it.  But if this macro is used in GNU gettext, and GNU
-        dnl gettext is already preinstalled in libintl, we update this
-        dnl libintl.  (Cf. the install rule in intl/Makefile.in.)
-        if test "$gt_cv_func_gnugettext_libc" = "yes" \
-           || { test "$gt_cv_func_gnugettext_libintl" = "yes" \
-                && test "$PACKAGE" != gettext-runtime \
-                && test "$PACKAGE" != gettext-tools; }; then
-          gt_use_preinstalled_gnugettext=yes
-        else
-          dnl Reset the values set by searching for libintl.
-          LIBINTL=
-          LTLIBINTL=
-          INCINTL=
-        fi
-
-    ifelse(gt_included_intl, yes, [
-        if test "$gt_use_preinstalled_gnugettext" != "yes"; then
-          dnl GNU gettext is not found in the C library.
-          dnl Fall back on included GNU gettext library.
-          nls_cv_use_gnu_gettext=yes
-        fi
-      fi
-
-      if test "$nls_cv_use_gnu_gettext" = "yes"; then
-        dnl Mark actions used to generate GNU NLS library.
-        BUILD_INCLUDED_LIBINTL=yes
-        USE_INCLUDED_LIBINTL=yes
-        LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV"
-        LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV"
-        LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'`
-      fi
-
-      if test "$gt_use_preinstalled_gnugettext" = "yes" \
-         || test "$nls_cv_use_gnu_gettext" = "yes"; then
-        dnl Mark actions to use GNU gettext tools.
-        CATOBJEXT=.gmo
-      fi
-    ])
-
-    if test "$gt_use_preinstalled_gnugettext" = "yes" \
-       || test "$nls_cv_use_gnu_gettext" = "yes"; then
-      AC_DEFINE(ENABLE_NLS, 1,
-        [Define to 1 if translation of program messages to the user's native language
-   is requested.])
-    else
-      USE_NLS=no
-    fi
-  fi
-
-  AC_MSG_CHECKING([whether to use NLS])
-  AC_MSG_RESULT([$USE_NLS])
-  if test "$USE_NLS" = "yes"; then
-    AC_MSG_CHECKING([where the gettext function comes from])
-    if test "$gt_use_preinstalled_gnugettext" = "yes"; then
-      if test "$gt_cv_func_gnugettext_libintl" = "yes"; then
-        gt_source="external libintl"
-      else
-        gt_source="libc"
-      fi
-    else
-      gt_source="included intl directory"
-    fi
-    AC_MSG_RESULT([$gt_source])
-  fi
-
-  if test "$USE_NLS" = "yes"; then
-
-    if test "$gt_use_preinstalled_gnugettext" = "yes"; then
-      if test "$gt_cv_func_gnugettext_libintl" = "yes"; then
-        AC_MSG_CHECKING([how to link with libintl])
-        AC_MSG_RESULT([$LIBINTL])
-        AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL])
-      fi
-
-      dnl For backward compatibility. Some packages may be using this.
-      AC_DEFINE(HAVE_GETTEXT, 1,
-       [Define if the GNU gettext() function is already present or preinstalled.])
-      AC_DEFINE(HAVE_DCGETTEXT, 1,
-       [Define if the GNU dcgettext() function is already present or preinstalled.])
-    fi
-
-    dnl We need to process the po/ directory.
-    POSUB=po
-  fi
-
-  ifelse(gt_included_intl, yes, [
-    dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL
-    dnl to 'yes' because some of the testsuite requires it.
-    if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then
-      BUILD_INCLUDED_LIBINTL=yes
-    fi
-
-    dnl Make all variables we use known to autoconf.
-    AC_SUBST(BUILD_INCLUDED_LIBINTL)
-    AC_SUBST(USE_INCLUDED_LIBINTL)
-    AC_SUBST(CATOBJEXT)
-
-    dnl For backward compatibility. Some configure.ins may be using this.
-    nls_cv_header_intl=
-    nls_cv_header_libgt=
-
-    dnl For backward compatibility. Some Makefiles may be using this.
-    DATADIRNAME=share
-    AC_SUBST(DATADIRNAME)
-
-    dnl For backward compatibility. Some Makefiles may be using this.
-    INSTOBJEXT=.mo
-    AC_SUBST(INSTOBJEXT)
-
-    dnl For backward compatibility. Some Makefiles may be using this.
-    GENCAT=gencat
-    AC_SUBST(GENCAT)
-
-    dnl For backward compatibility. Some Makefiles may be using this.
-    if test "$USE_INCLUDED_LIBINTL" = yes; then
-      INTLOBJS="\$(GETTOBJS)"
-    fi
-    AC_SUBST(INTLOBJS)
-
-    dnl Enable libtool support if the surrounding package wishes it.
-    INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix
-    AC_SUBST(INTL_LIBTOOL_SUFFIX_PREFIX)
-  ])
-
-  dnl For backward compatibility. Some Makefiles may be using this.
-  INTLLIBS="$LIBINTL"
-  AC_SUBST(INTLLIBS)
-
-  dnl Make all documented variables known to autoconf.
-  AC_SUBST(LIBINTL)
-  AC_SUBST(LTLIBINTL)
-  AC_SUBST(POSUB)
-])
-
-
-dnl Checks for all prerequisites of the intl subdirectory,
-dnl except for INTL_LIBTOOL_SUFFIX_PREFIX (and possibly LIBTOOL), INTLOBJS,
-dnl            USE_INCLUDED_LIBINTL, BUILD_INCLUDED_LIBINTL.
-AC_DEFUN([AM_INTL_SUBDIR],
-[
-  AC_REQUIRE([AC_PROG_INSTALL])dnl
-  AC_REQUIRE([AM_MKINSTALLDIRS])dnl
-  AC_REQUIRE([AC_PROG_CC])dnl
-  AC_REQUIRE([AC_CANONICAL_HOST])dnl
-  AC_REQUIRE([AC_PROG_RANLIB])dnl
-  AC_REQUIRE([AC_ISC_POSIX])dnl
-  AC_REQUIRE([AC_HEADER_STDC])dnl
-  AC_REQUIRE([AC_C_CONST])dnl
-  AC_REQUIRE([AC_C_INLINE])dnl
-  AC_REQUIRE([AC_TYPE_OFF_T])dnl
-  AC_REQUIRE([AC_TYPE_SIZE_T])dnl
-  AC_REQUIRE([AC_FUNC_ALLOCA])dnl
-  AC_REQUIRE([AC_FUNC_MMAP])dnl
-  AC_REQUIRE([jm_GLIBC21])dnl
-  AC_REQUIRE([gt_INTDIV0])dnl
-  AC_REQUIRE([jm_AC_TYPE_UINTMAX_T])dnl
-  AC_REQUIRE([gt_HEADER_INTTYPES_H])dnl
-  AC_REQUIRE([gt_INTTYPES_PRI])dnl
-
-  AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h stddef.h \
-stdlib.h string.h unistd.h sys/param.h])
-  AC_CHECK_FUNCS([feof_unlocked fgets_unlocked getc_unlocked getcwd getegid \
-geteuid getgid getuid mempcpy munmap putenv setenv setlocale localeconv stpcpy \
-strcasecmp strdup strtoul tsearch __argz_count __argz_stringify __argz_next \
-__fsetlocking])
-
-  AM_ICONV
-  AM_LANGINFO_CODESET
-  if test $ac_cv_header_locale_h = yes; then
-    AM_LC_MESSAGES
-  fi
-
-  dnl intl/plural.c is generated from intl/plural.y. It requires bison,
-  dnl because plural.y uses bison specific features. It requires at least
-  dnl bison-1.26 because earlier versions generate a plural.c that doesn't
-  dnl compile.
-  dnl bison is only needed for the maintainer (who touches plural.y). But in
-  dnl order to avoid separate Makefiles or --enable-maintainer-mode, we put
-  dnl the rule in general Makefile. Now, some people carelessly touch the
-  dnl files or have a broken "make" program, hence the plural.c rule will
-  dnl sometimes fire. To avoid an error, defines BISON to ":" if it is not
-  dnl present or too old.
-  AC_CHECK_PROGS([INTLBISON], [bison])
-  if test -z "$INTLBISON"; then
-    ac_verc_fail=yes
-  else
-    dnl Found it, now check the version.
-    AC_MSG_CHECKING([version of bison])
-changequote(<<,>>)dnl
-    ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'`
-    case $ac_prog_version in
-      '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
-      1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*)
-changequote([,])dnl
-         ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
-      *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;;
-    esac
-    AC_MSG_RESULT([$ac_prog_version])
-  fi
-  if test $ac_verc_fail = yes; then
-    INTLBISON=:
-  fi
-])
-
-
-dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version])
-AC_DEFUN([AM_GNU_GETTEXT_VERSION], [])
-# glibc21.m4 serial 2 (fileutils-4.1.3, gettext-0.10.40)
-dnl Copyright (C) 2000-2002 Free Software Foundation, Inc.
-dnl This file is free software, distributed under the terms of the GNU
-dnl General Public License.  As a special exception to the GNU General
-dnl Public License, this file may be distributed as part of a program
-dnl that contains a configuration script generated by Autoconf, under
-dnl the same distribution terms as the rest of that program.
-
-# Test for the GNU C Library, version 2.1 or newer.
-# From Bruno Haible.
-
-AC_DEFUN([jm_GLIBC21],
-  [
-    AC_CACHE_CHECK(whether we are using the GNU C Library 2.1 or newer,
-      ac_cv_gnu_library_2_1,
-      [AC_EGREP_CPP([Lucky GNU user],
-       [
-#include <features.h>
-#ifdef __GNU_LIBRARY__
- #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2)
-  Lucky GNU user
- #endif
-#endif
-       ],
-       ac_cv_gnu_library_2_1=yes,
-       ac_cv_gnu_library_2_1=no)
-      ]
-    )
-    AC_SUBST(GLIBC21)
-    GLIBC21="$ac_cv_gnu_library_2_1"
-  ]
-)
-# iconv.m4 serial AM4 (gettext-0.11.3)
-dnl Copyright (C) 2000-2002 Free Software Foundation, Inc.
-dnl This file is free software, distributed under the terms of the GNU
-dnl General Public License.  As a special exception to the GNU General
-dnl Public License, this file may be distributed as part of a program
-dnl that contains a configuration script generated by Autoconf, under
-dnl the same distribution terms as the rest of that program.
-
-dnl From Bruno Haible.
-
-AC_DEFUN([AM_ICONV_LINKFLAGS_BODY],
-[
-  dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
-  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
-  AC_REQUIRE([AC_LIB_RPATH])
-
-  dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
-  dnl accordingly.
-  AC_LIB_LINKFLAGS_BODY([iconv])
-])
-
-AC_DEFUN([AM_ICONV_LINK],
-[
-  dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
-  dnl those with the standalone portable GNU libiconv installed).
-
-  dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
-  dnl accordingly.
-  AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
-
-  dnl Add $INCICONV to CPPFLAGS before performing the following checks,
-  dnl because if the user has installed libiconv and not disabled its use
-  dnl via --without-libiconv-prefix, he wants to use it. The first
-  dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed.
-  am_save_CPPFLAGS="$CPPFLAGS"
-  AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV])
-
-  AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [
-    am_cv_func_iconv="no, consider installing GNU libiconv"
-    am_cv_lib_iconv=no
-    AC_TRY_LINK([#include <stdlib.h>
-#include <iconv.h>],
-      [iconv_t cd = iconv_open("","");
-       iconv(cd,NULL,NULL,NULL,NULL);
-       iconv_close(cd);],
-      am_cv_func_iconv=yes)
-    if test "$am_cv_func_iconv" != yes; then
-      am_save_LIBS="$LIBS"
-      LIBS="$LIBS $LIBICONV"
-      AC_TRY_LINK([#include <stdlib.h>
-#include <iconv.h>],
-        [iconv_t cd = iconv_open("","");
-         iconv(cd,NULL,NULL,NULL,NULL);
-         iconv_close(cd);],
-        am_cv_lib_iconv=yes
-        am_cv_func_iconv=yes)
-      LIBS="$am_save_LIBS"
-    fi
-  ])
-  if test "$am_cv_func_iconv" = yes; then
-    AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.])
-  fi
-  if test "$am_cv_lib_iconv" = yes; then
-    AC_MSG_CHECKING([how to link with libiconv])
-    AC_MSG_RESULT([$LIBICONV])
-  else
-    dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV
-    dnl either.
-    CPPFLAGS="$am_save_CPPFLAGS"
-    LIBICONV=
-    LTLIBICONV=
-  fi
-  AC_SUBST(LIBICONV)
-  AC_SUBST(LTLIBICONV)
-])
-
-AC_DEFUN([AM_ICONV],
-[
-  AM_ICONV_LINK
-  if test "$am_cv_func_iconv" = yes; then
-    AC_MSG_CHECKING([for iconv declaration])
-    AC_CACHE_VAL(am_cv_proto_iconv, [
-      AC_TRY_COMPILE([
-#include <stdlib.h>
-#include <iconv.h>
-extern
-#ifdef __cplusplus
-"C"
-#endif
-#if defined(__STDC__) || defined(__cplusplus)
-size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
-#else
-size_t iconv();
-#endif
-], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const")
-      am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
-    am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
-    AC_MSG_RESULT([$]{ac_t:-
-         }[$]am_cv_proto_iconv)
-    AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1,
-      [Define as const if the declaration of iconv() needs const.])
-  fi
-])
-# intdiv0.m4 serial 1 (gettext-0.11.3)
-dnl Copyright (C) 2002 Free Software Foundation, Inc.
-dnl This file is free software, distributed under the terms of the GNU
-dnl General Public License.  As a special exception to the GNU General
-dnl Public License, this file may be distributed as part of a program
-dnl that contains a configuration script generated by Autoconf, under
-dnl the same distribution terms as the rest of that program.
-
-dnl From Bruno Haible.
-
-AC_DEFUN([gt_INTDIV0],
-[
-  AC_REQUIRE([AC_PROG_CC])dnl
-  AC_REQUIRE([AC_CANONICAL_HOST])dnl
-
-  AC_CACHE_CHECK([whether integer division by zero raises SIGFPE],
-    gt_cv_int_divbyzero_sigfpe,
-    [
-      AC_TRY_RUN([
-#include <stdlib.h>
-#include <signal.h>
-
-static void
-#ifdef __cplusplus
-sigfpe_handler (int sig)
-#else
-sigfpe_handler (sig) int sig;
-#endif
-{
-  /* Exit with code 0 if SIGFPE, with code 1 if any other signal.  */
-  exit (sig != SIGFPE);
-}
-
-int x = 1;
-int y = 0;
-int z;
-int nan;
-
-int main ()
-{
-  signal (SIGFPE, sigfpe_handler);
-/* IRIX and AIX (when "xlc -qcheck" is used) yield signal SIGTRAP.  */
-#if (defined (__sgi) || defined (_AIX)) && defined (SIGTRAP)
-  signal (SIGTRAP, sigfpe_handler);
-#endif
-/* Linux/SPARC yields signal SIGILL.  */
-#if defined (__sparc__) && defined (__linux__)
-  signal (SIGILL, sigfpe_handler);
-#endif
-
-  z = x / y;
-  nan = y / y;
-  exit (1);
-}
-], gt_cv_int_divbyzero_sigfpe=yes, gt_cv_int_divbyzero_sigfpe=no,
-        [
-          # Guess based on the CPU.
-          case "$host_cpu" in
-            alpha* | i[34567]86 | m68k | s390*)
-              gt_cv_int_divbyzero_sigfpe="guessing yes";;
-            *)
-              gt_cv_int_divbyzero_sigfpe="guessing no";;
-          esac
-        ])
-    ])
-  case "$gt_cv_int_divbyzero_sigfpe" in
-    *yes) value=1;;
-    *) value=0;;
-  esac
-  AC_DEFINE_UNQUOTED(INTDIV0_RAISES_SIGFPE, $value,
-    [Define if integer division by zero raises signal SIGFPE.])
-])
-# inttypes.m4 serial 1 (gettext-0.11.4)
-dnl Copyright (C) 1997-2002 Free Software Foundation, Inc.
-dnl This file is free software, distributed under the terms of the GNU
-dnl General Public License.  As a special exception to the GNU General
-dnl Public License, this file may be distributed as part of a program
-dnl that contains a configuration script generated by Autoconf, under
-dnl the same distribution terms as the rest of that program.
-
-dnl From Paul Eggert.
-
-# Define HAVE_INTTYPES_H if <inttypes.h> exists and doesn't clash with
-# <sys/types.h>.
-
-AC_DEFUN([gt_HEADER_INTTYPES_H],
-[
-  AC_CACHE_CHECK([for inttypes.h], gt_cv_header_inttypes_h,
-  [
-    AC_TRY_COMPILE(
-      [#include <sys/types.h>
-#include <inttypes.h>],
-      [], gt_cv_header_inttypes_h=yes, gt_cv_header_inttypes_h=no)
-  ])
-  if test $gt_cv_header_inttypes_h = yes; then
-    AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H, 1,
-      [Define if <inttypes.h> exists and doesn't clash with <sys/types.h>.])
-  fi
-])
-# inttypes_h.m4 serial 5 (gettext-0.12)
-dnl Copyright (C) 1997-2003 Free Software Foundation, Inc.
-dnl This file is free software, distributed under the terms of the GNU
-dnl General Public License.  As a special exception to the GNU General
-dnl Public License, this file may be distributed as part of a program
-dnl that contains a configuration script generated by Autoconf, under
-dnl the same distribution terms as the rest of that program.
-
-dnl From Paul Eggert.
-
-# Define HAVE_INTTYPES_H_WITH_UINTMAX if <inttypes.h> exists,
-# doesn't clash with <sys/types.h>, and declares uintmax_t.
-
-AC_DEFUN([jm_AC_HEADER_INTTYPES_H],
-[
-  AC_CACHE_CHECK([for inttypes.h], jm_ac_cv_header_inttypes_h,
-  [AC_TRY_COMPILE(
-    [#include <sys/types.h>
-#include <inttypes.h>],
-    [uintmax_t i = (uintmax_t) -1;],
-    jm_ac_cv_header_inttypes_h=yes,
-    jm_ac_cv_header_inttypes_h=no)])
-  if test $jm_ac_cv_header_inttypes_h = yes; then
-    AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H_WITH_UINTMAX, 1,
-      [Define if <inttypes.h> exists, doesn't clash with <sys/types.h>,
-       and declares uintmax_t. ])
-  fi
-])
-# inttypes-pri.m4 serial 1 (gettext-0.11.4)
-dnl Copyright (C) 1997-2002 Free Software Foundation, Inc.
-dnl This file is free software, distributed under the terms of the GNU
-dnl General Public License.  As a special exception to the GNU General
-dnl Public License, this file may be distributed as part of a program
-dnl that contains a configuration script generated by Autoconf, under
-dnl the same distribution terms as the rest of that program.
-
-dnl From Bruno Haible.
-
-# Define PRI_MACROS_BROKEN if <inttypes.h> exists and defines the PRI*
-# macros to non-string values.  This is the case on AIX 4.3.3.
-
-AC_DEFUN([gt_INTTYPES_PRI],
-[
-  AC_REQUIRE([gt_HEADER_INTTYPES_H])
-  if test $gt_cv_header_inttypes_h = yes; then
-    AC_CACHE_CHECK([whether the inttypes.h PRIxNN macros are broken],
-      gt_cv_inttypes_pri_broken,
-      [
-        AC_TRY_COMPILE([#include <inttypes.h>
-#ifdef PRId32
-char *p = PRId32;
-#endif
-], [], gt_cv_inttypes_pri_broken=no, gt_cv_inttypes_pri_broken=yes)
-      ])
-  fi
-  if test "$gt_cv_inttypes_pri_broken" = yes; then
-    AC_DEFINE_UNQUOTED(PRI_MACROS_BROKEN, 1,
-      [Define if <inttypes.h> exists and defines unusable PRI* macros.])
-  fi
-])
-# isc-posix.m4 serial 2 (gettext-0.11.2)
-dnl Copyright (C) 1995-2002 Free Software Foundation, Inc.
-dnl This file is free software, distributed under the terms of the GNU
-dnl General Public License.  As a special exception to the GNU General
-dnl Public License, this file may be distributed as part of a program
-dnl that contains a configuration script generated by Autoconf, under
-dnl the same distribution terms as the rest of that program.
-
-# This file is not needed with autoconf-2.53 and newer.  Remove it in 2005.
-
-# This test replaces the one in autoconf.
-# Currently this macro should have the same name as the autoconf macro
-# because gettext's gettext.m4 (distributed in the automake package)
-# still uses it.  Otherwise, the use in gettext.m4 makes autoheader
-# give these diagnostics:
-#   configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX
-#   configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX
-
-undefine([AC_ISC_POSIX])
-
-AC_DEFUN([AC_ISC_POSIX],
-  [
-    dnl This test replaces the obsolescent AC_ISC_POSIX kludge.
-    AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"])
-  ]
-)
-# lcmessage.m4 serial 3 (gettext-0.11.3)
-dnl Copyright (C) 1995-2002 Free Software Foundation, Inc.
-dnl This file is free software, distributed under the terms of the GNU
-dnl General Public License.  As a special exception to the GNU General
-dnl Public License, this file may be distributed as part of a program
-dnl that contains a configuration script generated by Autoconf, under
-dnl the same distribution terms as the rest of that program.
-dnl
-dnl This file can can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
-dnl License but which still want to provide support for the GNU gettext
-dnl functionality.
-dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
-dnl gettext package package is covered by the GNU General Public License.
-dnl They are *not* in the public domain.
-
-dnl Authors:
-dnl   Ulrich Drepper <drepper@cygnus.com>, 1995.
-
-# Check whether LC_MESSAGES is available in <locale.h>.
-
-AC_DEFUN([AM_LC_MESSAGES],
-[
-  AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
-    [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
-       am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
-  if test $am_cv_val_LC_MESSAGES = yes; then
-    AC_DEFINE(HAVE_LC_MESSAGES, 1,
-      [Define if your <locale.h> file defines LC_MESSAGES.])
-  fi
-])
-# lib-ld.m4 serial 2 (gettext-0.12)
-dnl Copyright (C) 1996-2003 Free Software Foundation, Inc.
-dnl This file is free software, distributed under the terms of the GNU
-dnl General Public License.  As a special exception to the GNU General
-dnl Public License, this file may be distributed as part of a program
-dnl that contains a configuration script generated by Autoconf, under
-dnl the same distribution terms as the rest of that program.
-
-dnl Subroutines of libtool.m4,
-dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision
-dnl with libtool.m4.
-
-dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no.
-AC_DEFUN([AC_LIB_PROG_LD_GNU],
-[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld,
-[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
-if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
-  acl_cv_prog_gnu_ld=yes
-else
-  acl_cv_prog_gnu_ld=no
-fi])
-with_gnu_ld=$acl_cv_prog_gnu_ld
-])
-
-dnl From libtool-1.4. Sets the variable LD.
-AC_DEFUN([AC_LIB_PROG_LD],
-[AC_ARG_WITH(gnu-ld,
-[  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]],
-test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
-AC_REQUIRE([AC_PROG_CC])dnl
-AC_REQUIRE([AC_CANONICAL_HOST])dnl
-# Prepare PATH_SEPARATOR.
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conf$$.sh
-  echo  "exit 0"   >>conf$$.sh
-  chmod +x conf$$.sh
-  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
-    PATH_SEPARATOR=';'
-  else
-    PATH_SEPARATOR=:
-  fi
-  rm -f conf$$.sh
-fi
-ac_prog=ld
-if test "$GCC" = yes; then
-  # Check if gcc -print-prog-name=ld gives a path.
-  AC_MSG_CHECKING([for ld used by GCC])
-  case $host in
-  *-*-mingw*)
-    # gcc leaves a trailing carriage return which upsets mingw
-    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
-  *)
-    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
-  esac
-  case $ac_prog in
-    # Accept absolute paths.
-    [[\\/]* | [A-Za-z]:[\\/]*)]
-      [re_direlt='/[^/][^/]*/\.\./']
-      # Canonicalize the path of ld
-      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
-      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
-       ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
-      done
-      test -z "$LD" && LD="$ac_prog"
-      ;;
-  "")
-    # If it fails, then pretend we aren't using GCC.
-    ac_prog=ld
-    ;;
-  *)
-    # If it is relative, then search for the first ld in PATH.
-    with_gnu_ld=unknown
-    ;;
-  esac
-elif test "$with_gnu_ld" = yes; then
-  AC_MSG_CHECKING([for GNU ld])
-else
-  AC_MSG_CHECKING([for non-GNU ld])
-fi
-AC_CACHE_VAL(acl_cv_path_LD,
-[if test -z "$LD"; then
-  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
-  for ac_dir in $PATH; do
-    test -z "$ac_dir" && ac_dir=.
-    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
-      acl_cv_path_LD="$ac_dir/$ac_prog"
-      # Check to see if the program is GNU ld.  I'd rather use --version,
-      # but apparently some GNU ld's only accept -v.
-      # Break only if it was the GNU/non-GNU ld that we prefer.
-      if "$acl_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
-       test "$with_gnu_ld" != no && break
-      else
-       test "$with_gnu_ld" != yes && break
-      fi
-    fi
-  done
-  IFS="$ac_save_ifs"
-else
-  acl_cv_path_LD="$LD" # Let the user override the test with a path.
-fi])
-LD="$acl_cv_path_LD"
-if test -n "$LD"; then
-  AC_MSG_RESULT($LD)
-else
-  AC_MSG_RESULT(no)
-fi
-test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
-AC_LIB_PROG_LD_GNU
-])
-# lib-link.m4 serial 4 (gettext-0.12)
-dnl Copyright (C) 2001-2003 Free Software Foundation, Inc.
-dnl This file is free software, distributed under the terms of the GNU
-dnl General Public License.  As a special exception to the GNU General
-dnl Public License, this file may be distributed as part of a program
-dnl that contains a configuration script generated by Autoconf, under
-dnl the same distribution terms as the rest of that program.
-
-dnl From Bruno Haible.
-
-dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and
-dnl the libraries corresponding to explicit and implicit dependencies.
-dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and
-dnl augments the CPPFLAGS variable.
-AC_DEFUN([AC_LIB_LINKFLAGS],
-[
-  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
-  AC_REQUIRE([AC_LIB_RPATH])
-  define([Name],[translit([$1],[./-], [___])])
-  define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
-                               [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
-  AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [
-    AC_LIB_LINKFLAGS_BODY([$1], [$2])
-    ac_cv_lib[]Name[]_libs="$LIB[]NAME"
-    ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME"
-    ac_cv_lib[]Name[]_cppflags="$INC[]NAME"
-  ])
-  LIB[]NAME="$ac_cv_lib[]Name[]_libs"
-  LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs"
-  INC[]NAME="$ac_cv_lib[]Name[]_cppflags"
-  AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
-  AC_SUBST([LIB]NAME)
-  AC_SUBST([LTLIB]NAME)
-  dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the
-  dnl results of this search when this library appears as a dependency.
-  HAVE_LIB[]NAME=yes
-  undefine([Name])
-  undefine([NAME])
-])
-
-dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode)
-dnl searches for libname and the libraries corresponding to explicit and
-dnl implicit dependencies, together with the specified include files and
-dnl the ability to compile and link the specified testcode. If found, it
-dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and
-dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and
-dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs
-dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty.
-AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
-[
-  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
-  AC_REQUIRE([AC_LIB_RPATH])
-  define([Name],[translit([$1],[./-], [___])])
-  define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
-                               [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
-
-  dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME
-  dnl accordingly.
-  AC_LIB_LINKFLAGS_BODY([$1], [$2])
-
-  dnl Add $INC[]NAME to CPPFLAGS before performing the following checks,
-  dnl because if the user has installed lib[]Name and not disabled its use
-  dnl via --without-lib[]Name-prefix, he wants to use it.
-  ac_save_CPPFLAGS="$CPPFLAGS"
-  AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
-
-  AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [
-    ac_save_LIBS="$LIBS"
-    LIBS="$LIBS $LIB[]NAME"
-    AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no])
-    LIBS="$ac_save_LIBS"
-  ])
-  if test "$ac_cv_lib[]Name" = yes; then
-    HAVE_LIB[]NAME=yes
-    AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.])
-    AC_MSG_CHECKING([how to link with lib[]$1])
-    AC_MSG_RESULT([$LIB[]NAME])
-  else
-    HAVE_LIB[]NAME=no
-    dnl If $LIB[]NAME didn't lead to a usable library, we don't need
-    dnl $INC[]NAME either.
-    CPPFLAGS="$ac_save_CPPFLAGS"
-    LIB[]NAME=
-    LTLIB[]NAME=
-  fi
-  AC_SUBST([HAVE_LIB]NAME)
-  AC_SUBST([LIB]NAME)
-  AC_SUBST([LTLIB]NAME)
-  undefine([Name])
-  undefine([NAME])
-])
-
-dnl Determine the platform dependent parameters needed to use rpath:
-dnl libext, shlibext, hardcode_libdir_flag_spec, hardcode_libdir_separator,
-dnl hardcode_direct, hardcode_minus_L.
-AC_DEFUN([AC_LIB_RPATH],
-[
-  AC_REQUIRE([AC_PROG_CC])                dnl we use $CC, $GCC, $LDFLAGS
-  AC_REQUIRE([AC_LIB_PROG_LD])            dnl we use $LD, $with_gnu_ld
-  AC_REQUIRE([AC_CANONICAL_HOST])         dnl we use $host
-  AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir
-  AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [
-    CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \
-    ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh
-    . ./conftest.sh
-    rm -f ./conftest.sh
-    acl_cv_rpath=done
-  ])
-  wl="$acl_cv_wl"
-  libext="$acl_cv_libext"
-  shlibext="$acl_cv_shlibext"
-  hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
-  hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
-  hardcode_direct="$acl_cv_hardcode_direct"
-  hardcode_minus_L="$acl_cv_hardcode_minus_L"
-  dnl Determine whether the user wants rpath handling at all.
-  AC_ARG_ENABLE(rpath,
-    [  --disable-rpath         do not hardcode runtime library paths],
-    :, enable_rpath=yes)
-])
-
-dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and
-dnl the libraries corresponding to explicit and implicit dependencies.
-dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables.
-AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
-[
-  define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
-                               [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
-  dnl By default, look in $includedir and $libdir.
-  use_additional=yes
-  AC_LIB_WITH_FINAL_PREFIX([
-    eval additional_includedir=\"$includedir\"
-    eval additional_libdir=\"$libdir\"
-  ])
-  AC_LIB_ARG_WITH([lib$1-prefix],
-[  --with-lib$1-prefix[=DIR]  search for lib$1 in DIR/include and DIR/lib
-  --without-lib$1-prefix     don't search for lib$1 in includedir and libdir],
-[
-    if test "X$withval" = "Xno"; then
-      use_additional=no
-    else
-      if test "X$withval" = "X"; then
-        AC_LIB_WITH_FINAL_PREFIX([
-          eval additional_includedir=\"$includedir\"
-          eval additional_libdir=\"$libdir\"
-        ])
-      else
-        additional_includedir="$withval/include"
-        additional_libdir="$withval/lib"
-      fi
-    fi
-])
-  dnl Search the library and its dependencies in $additional_libdir and
-  dnl $LDFLAGS. Using breadth-first-seach.
-  LIB[]NAME=
-  LTLIB[]NAME=
-  INC[]NAME=
-  rpathdirs=
-  ltrpathdirs=
-  names_already_handled=
-  names_next_round='$1 $2'
-  while test -n "$names_next_round"; do
-    names_this_round="$names_next_round"
-    names_next_round=
-    for name in $names_this_round; do
-      already_handled=
-      for n in $names_already_handled; do
-        if test "$n" = "$name"; then
-          already_handled=yes
-          break
-        fi
-      done
-      if test -z "$already_handled"; then
-        names_already_handled="$names_already_handled $name"
-        dnl See if it was already located by an earlier AC_LIB_LINKFLAGS
-        dnl or AC_LIB_HAVE_LINKFLAGS call.
-        uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
-        eval value=\"\$HAVE_LIB$uppername\"
-        if test -n "$value"; then
-          if test "$value" = yes; then
-            eval value=\"\$LIB$uppername\"
-            test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value"
-            eval value=\"\$LTLIB$uppername\"
-            test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value"
-          else
-            dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined
-            dnl that this library doesn't exist. So just drop it.
-            :
-          fi
-        else
-          dnl Search the library lib$name in $additional_libdir and $LDFLAGS
-          dnl and the already constructed $LIBNAME/$LTLIBNAME.
-          found_dir=
-          found_la=
-          found_so=
-          found_a=
-          if test $use_additional = yes; then
-            if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then
-              found_dir="$additional_libdir"
-              found_so="$additional_libdir/lib$name.$shlibext"
-              if test -f "$additional_libdir/lib$name.la"; then
-                found_la="$additional_libdir/lib$name.la"
-              fi
-            else
-              if test -f "$additional_libdir/lib$name.$libext"; then
-                found_dir="$additional_libdir"
-                found_a="$additional_libdir/lib$name.$libext"
-                if test -f "$additional_libdir/lib$name.la"; then
-                  found_la="$additional_libdir/lib$name.la"
-                fi
-              fi
-            fi
-          fi
-          if test "X$found_dir" = "X"; then
-            for x in $LDFLAGS $LTLIB[]NAME; do
-              AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
-              case "$x" in
-                -L*)
-                  dir=`echo "X$x" | sed -e 's/^X-L//'`
-                  if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then
-                    found_dir="$dir"
-                    found_so="$dir/lib$name.$shlibext"
-                    if test -f "$dir/lib$name.la"; then
-                      found_la="$dir/lib$name.la"
-                    fi
-                  else
-                    if test -f "$dir/lib$name.$libext"; then
-                      found_dir="$dir"
-                      found_a="$dir/lib$name.$libext"
-                      if test -f "$dir/lib$name.la"; then
-                        found_la="$dir/lib$name.la"
-                      fi
-                    fi
-                  fi
-                  ;;
-              esac
-              if test "X$found_dir" != "X"; then
-                break
-              fi
-            done
-          fi
-          if test "X$found_dir" != "X"; then
-            dnl Found the library.
-            LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name"
-            if test "X$found_so" != "X"; then
-              dnl Linking with a shared library. We attempt to hardcode its
-              dnl directory into the executable's runpath, unless it's the
-              dnl standard /usr/lib.
-              if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then
-                dnl No hardcoding is needed.
-                LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
-              else
-                dnl Use an explicit option to hardcode DIR into the resulting
-                dnl binary.
-                dnl Potentially add DIR to ltrpathdirs.
-                dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
-                haveit=
-                for x in $ltrpathdirs; do
-                  if test "X$x" = "X$found_dir"; then
-                    haveit=yes
-                    break
-                  fi
-                done
-                if test -z "$haveit"; then
-                  ltrpathdirs="$ltrpathdirs $found_dir"
-                fi
-                dnl The hardcoding into $LIBNAME is system dependent.
-                if test "$hardcode_direct" = yes; then
-                  dnl Using DIR/libNAME.so during linking hardcodes DIR into the
-                  dnl resulting binary.
-                  LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
-                else
-                  if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then
-                    dnl Use an explicit option to hardcode DIR into the resulting
-                    dnl binary.
-                    LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
-                    dnl Potentially add DIR to rpathdirs.
-                    dnl The rpathdirs will be appended to $LIBNAME at the end.
-                    haveit=
-                    for x in $rpathdirs; do
-                      if test "X$x" = "X$found_dir"; then
-                        haveit=yes
-                        break
-                      fi
-                    done
-                    if test -z "$haveit"; then
-                      rpathdirs="$rpathdirs $found_dir"
-                    fi
-                  else
-                    dnl Rely on "-L$found_dir".
-                    dnl But don't add it if it's already contained in the LDFLAGS
-                    dnl or the already constructed $LIBNAME
-                    haveit=
-                    for x in $LDFLAGS $LIB[]NAME; do
-                      AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
-                      if test "X$x" = "X-L$found_dir"; then
-                        haveit=yes
-                        break
-                      fi
-                    done
-                    if test -z "$haveit"; then
-                      LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir"
-                    fi
-                    if test "$hardcode_minus_L" != no; then
-                      dnl FIXME: Not sure whether we should use
-                      dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
-                      dnl here.
-                      LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
-                    else
-                      dnl We cannot use $hardcode_runpath_var and LD_RUN_PATH
-                      dnl here, because this doesn't fit in flags passed to the
-                      dnl compiler. So give up. No hardcoding. This affects only
-                      dnl very old systems.
-                      dnl FIXME: Not sure whether we should use
-                      dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
-                      dnl here.
-                      LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
-                    fi
-                  fi
-                fi
-              fi
-            else
-              if test "X$found_a" != "X"; then
-                dnl Linking with a static library.
-                LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a"
-              else
-                dnl We shouldn't come here, but anyway it's good to have a
-                dnl fallback.
-                LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name"
-              fi
-            fi
-            dnl Assume the include files are nearby.
-            additional_includedir=
-            case "$found_dir" in
-              */lib | */lib/)
-                basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'`
-                additional_includedir="$basedir/include"
-                ;;
-            esac
-            if test "X$additional_includedir" != "X"; then
-              dnl Potentially add $additional_includedir to $INCNAME.
-              dnl But don't add it
-              dnl   1. if it's the standard /usr/include,
-              dnl   2. if it's /usr/local/include and we are using GCC on Linux,
-              dnl   3. if it's already present in $CPPFLAGS or the already
-              dnl      constructed $INCNAME,
-              dnl   4. if it doesn't exist as a directory.
-              if test "X$additional_includedir" != "X/usr/include"; then
-                haveit=
-                if test "X$additional_includedir" = "X/usr/local/include"; then
-                  if test -n "$GCC"; then
-                    case $host_os in
-                      linux*) haveit=yes;;
-                    esac
-                  fi
-                fi
-                if test -z "$haveit"; then
-                  for x in $CPPFLAGS $INC[]NAME; do
-                    AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
-                    if test "X$x" = "X-I$additional_includedir"; then
-                      haveit=yes
-                      break
-                    fi
-                  done
-                  if test -z "$haveit"; then
-                    if test -d "$additional_includedir"; then
-                      dnl Really add $additional_includedir to $INCNAME.
-                      INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir"
-                    fi
-                  fi
-                fi
-              fi
-            fi
-            dnl Look for dependencies.
-            if test -n "$found_la"; then
-              dnl Read the .la file. It defines the variables
-              dnl dlname, library_names, old_library, dependency_libs, current,
-              dnl age, revision, installed, dlopen, dlpreopen, libdir.
-              save_libdir="$libdir"
-              case "$found_la" in
-                */* | *\\*) . "$found_la" ;;
-                *) . "./$found_la" ;;
-              esac
-              libdir="$save_libdir"
-              dnl We use only dependency_libs.
-              for dep in $dependency_libs; do
-                case "$dep" in
-                  -L*)
-                    additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
-                    dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME.
-                    dnl But don't add it
-                    dnl   1. if it's the standard /usr/lib,
-                    dnl   2. if it's /usr/local/lib and we are using GCC on Linux,
-                    dnl   3. if it's already present in $LDFLAGS or the already
-                    dnl      constructed $LIBNAME,
-                    dnl   4. if it doesn't exist as a directory.
-                    if test "X$additional_libdir" != "X/usr/lib"; then
-                      haveit=
-                      if test "X$additional_libdir" = "X/usr/local/lib"; then
-                        if test -n "$GCC"; then
-                          case $host_os in
-                            linux*) haveit=yes;;
-                          esac
-                        fi
-                      fi
-                      if test -z "$haveit"; then
-                        haveit=
-                        for x in $LDFLAGS $LIB[]NAME; do
-                          AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
-                          if test "X$x" = "X-L$additional_libdir"; then
-                            haveit=yes
-                            break
-                          fi
-                        done
-                        if test -z "$haveit"; then
-                          if test -d "$additional_libdir"; then
-                            dnl Really add $additional_libdir to $LIBNAME.
-                            LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir"
-                          fi
-                        fi
-                        haveit=
-                        for x in $LDFLAGS $LTLIB[]NAME; do
-                          AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
-                          if test "X$x" = "X-L$additional_libdir"; then
-                            haveit=yes
-                            break
-                          fi
-                        done
-                        if test -z "$haveit"; then
-                          if test -d "$additional_libdir"; then
-                            dnl Really add $additional_libdir to $LTLIBNAME.
-                            LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir"
-                          fi
-                        fi
-                      fi
-                    fi
-                    ;;
-                  -R*)
-                    dir=`echo "X$dep" | sed -e 's/^X-R//'`
-                    if test "$enable_rpath" != no; then
-                      dnl Potentially add DIR to rpathdirs.
-                      dnl The rpathdirs will be appended to $LIBNAME at the end.
-                      haveit=
-                      for x in $rpathdirs; do
-                        if test "X$x" = "X$dir"; then
-                          haveit=yes
-                          break
-                        fi
-                      done
-                      if test -z "$haveit"; then
-                        rpathdirs="$rpathdirs $dir"
-                      fi
-                      dnl Potentially add DIR to ltrpathdirs.
-                      dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
-                      haveit=
-                      for x in $ltrpathdirs; do
-                        if test "X$x" = "X$dir"; then
-                          haveit=yes
-                          break
-                        fi
-                      done
-                      if test -z "$haveit"; then
-                        ltrpathdirs="$ltrpathdirs $dir"
-                      fi
-                    fi
-                    ;;
-                  -l*)
-                    dnl Handle this in the next round.
-                    names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
-                    ;;
-                  *.la)
-                    dnl Handle this in the next round. Throw away the .la's
-                    dnl directory; it is already contained in a preceding -L
-                    dnl option.
-                    names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
-                    ;;
-                  *)
-                    dnl Most likely an immediate library name.
-                    LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep"
-                    LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep"
-                    ;;
-                esac
-              done
-            fi
-          else
-            dnl Didn't find the library; assume it is in the system directories
-            dnl known to the linker and runtime loader. (All the system
-            dnl directories known to the linker should also be known to the
-            dnl runtime loader, otherwise the system is severely misconfigured.)
-            LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
-            LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name"
-          fi
-        fi
-      fi
-    done
-  done
-  if test "X$rpathdirs" != "X"; then
-    if test -n "$hardcode_libdir_separator"; then
-      dnl Weird platform: only the last -rpath option counts, the user must
-      dnl pass all path elements in one option. We can arrange that for a
-      dnl single library, but not when more than one $LIBNAMEs are used.
-      alldirs=
-      for found_dir in $rpathdirs; do
-        alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir"
-      done
-      dnl Note: hardcode_libdir_flag_spec uses $libdir and $wl.
-      acl_save_libdir="$libdir"
-      libdir="$alldirs"
-      eval flag=\"$hardcode_libdir_flag_spec\"
-      libdir="$acl_save_libdir"
-      LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
-    else
-      dnl The -rpath options are cumulative.
-      for found_dir in $rpathdirs; do
-        acl_save_libdir="$libdir"
-        libdir="$found_dir"
-        eval flag=\"$hardcode_libdir_flag_spec\"
-        libdir="$acl_save_libdir"
-        LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
-      done
-    fi
-  fi
-  if test "X$ltrpathdirs" != "X"; then
-    dnl When using libtool, the option that works for both libraries and
-    dnl executables is -R. The -R options are cumulative.
-    for found_dir in $ltrpathdirs; do
-      LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir"
-    done
-  fi
-])
-
-dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR,
-dnl unless already present in VAR.
-dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes
-dnl contains two or three consecutive elements that belong together.
-AC_DEFUN([AC_LIB_APPENDTOVAR],
-[
-  for element in [$2]; do
-    haveit=
-    for x in $[$1]; do
-      AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
-      if test "X$x" = "X$element"; then
-        haveit=yes
-        break
-      fi
-    done
-    if test -z "$haveit"; then
-      [$1]="${[$1]}${[$1]:+ }$element"
-    fi
-  done
-])
-# lib-prefix.m4 serial 2 (gettext-0.12)
-dnl Copyright (C) 2001-2003 Free Software Foundation, Inc.
-dnl This file is free software, distributed under the terms of the GNU
-dnl General Public License.  As a special exception to the GNU General
-dnl Public License, this file may be distributed as part of a program
-dnl that contains a configuration script generated by Autoconf, under
-dnl the same distribution terms as the rest of that program.
-
-dnl From Bruno Haible.
-
-dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and
-dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't
-dnl require excessive bracketing.
-ifdef([AC_HELP_STRING],
-[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])],
-[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])])
-
-dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed
-dnl to access previously installed libraries. The basic assumption is that
-dnl a user will want packages to use other packages he previously installed
-dnl with the same --prefix option.
-dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate
-dnl libraries, but is otherwise very convenient.
-AC_DEFUN([AC_LIB_PREFIX],
-[
-  AC_BEFORE([$0], [AC_LIB_LINKFLAGS])
-  AC_REQUIRE([AC_PROG_CC])
-  AC_REQUIRE([AC_CANONICAL_HOST])
-  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
-  dnl By default, look in $includedir and $libdir.
-  use_additional=yes
-  AC_LIB_WITH_FINAL_PREFIX([
-    eval additional_includedir=\"$includedir\"
-    eval additional_libdir=\"$libdir\"
-  ])
-  AC_LIB_ARG_WITH([lib-prefix],
-[  --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib
-  --without-lib-prefix    don't search for libraries in includedir and libdir],
-[
-    if test "X$withval" = "Xno"; then
-      use_additional=no
-    else
-      if test "X$withval" = "X"; then
-        AC_LIB_WITH_FINAL_PREFIX([
-          eval additional_includedir=\"$includedir\"
-          eval additional_libdir=\"$libdir\"
-        ])
-      else
-        additional_includedir="$withval/include"
-        additional_libdir="$withval/lib"
-      fi
-    fi
-])
-  if test $use_additional = yes; then
-    dnl Potentially add $additional_includedir to $CPPFLAGS.
-    dnl But don't add it
-    dnl   1. if it's the standard /usr/include,
-    dnl   2. if it's already present in $CPPFLAGS,
-    dnl   3. if it's /usr/local/include and we are using GCC on Linux,
-    dnl   4. if it doesn't exist as a directory.
-    if test "X$additional_includedir" != "X/usr/include"; then
-      haveit=
-      for x in $CPPFLAGS; do
-        AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
-        if test "X$x" = "X-I$additional_includedir"; then
-          haveit=yes
-          break
-        fi
-      done
-      if test -z "$haveit"; then
-        if test "X$additional_includedir" = "X/usr/local/include"; then
-          if test -n "$GCC"; then
-            case $host_os in
-              linux*) haveit=yes;;
-            esac
-          fi
-        fi
-        if test -z "$haveit"; then
-          if test -d "$additional_includedir"; then
-            dnl Really add $additional_includedir to $CPPFLAGS.
-            CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir"
-          fi
-        fi
-      fi
-    fi
-    dnl Potentially add $additional_libdir to $LDFLAGS.
-    dnl But don't add it
-    dnl   1. if it's the standard /usr/lib,
-    dnl   2. if it's already present in $LDFLAGS,
-    dnl   3. if it's /usr/local/lib and we are using GCC on Linux,
-    dnl   4. if it doesn't exist as a directory.
-    if test "X$additional_libdir" != "X/usr/lib"; then
-      haveit=
-      for x in $LDFLAGS; do
-        AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
-        if test "X$x" = "X-L$additional_libdir"; then
-          haveit=yes
-          break
-        fi
-      done
-      if test -z "$haveit"; then
-        if test "X$additional_libdir" = "X/usr/local/lib"; then
-          if test -n "$GCC"; then
-            case $host_os in
-              linux*) haveit=yes;;
-            esac
-          fi
-        fi
-        if test -z "$haveit"; then
-          if test -d "$additional_libdir"; then
-            dnl Really add $additional_libdir to $LDFLAGS.
-            LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir"
-          fi
-        fi
-      fi
-    fi
-  fi
-])
-
-dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix,
-dnl acl_final_exec_prefix, containing the values to which $prefix and
-dnl $exec_prefix will expand at the end of the configure script.
-AC_DEFUN([AC_LIB_PREPARE_PREFIX],
-[
-  dnl Unfortunately, prefix and exec_prefix get only finally determined
-  dnl at the end of configure.
-  if test "X$prefix" = "XNONE"; then
-    acl_final_prefix="$ac_default_prefix"
-  else
-    acl_final_prefix="$prefix"
-  fi
-  if test "X$exec_prefix" = "XNONE"; then
-    acl_final_exec_prefix='${prefix}'
-  else
-    acl_final_exec_prefix="$exec_prefix"
-  fi
-  acl_save_prefix="$prefix"
-  prefix="$acl_final_prefix"
-  eval acl_final_exec_prefix=\"$acl_final_exec_prefix\"
-  prefix="$acl_save_prefix"
-])
-
-dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the
-dnl variables prefix and exec_prefix bound to the values they will have
-dnl at the end of the configure script.
-AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX],
-[
-  acl_save_prefix="$prefix"
-  prefix="$acl_final_prefix"
-  acl_save_exec_prefix="$exec_prefix"
-  exec_prefix="$acl_final_exec_prefix"
-  $1
-  exec_prefix="$acl_save_exec_prefix"
-  prefix="$acl_save_prefix"
-])
-# nls.m4 serial 1 (gettext-0.12)
-dnl Copyright (C) 1995-2003 Free Software Foundation, Inc.
-dnl This file is free software, distributed under the terms of the GNU
-dnl General Public License.  As a special exception to the GNU General
-dnl Public License, this file may be distributed as part of a program
-dnl that contains a configuration script generated by Autoconf, under
-dnl the same distribution terms as the rest of that program.
-dnl
-dnl This file can can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
-dnl License but which still want to provide support for the GNU gettext
-dnl functionality.
-dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
-dnl gettext package package is covered by the GNU General Public License.
-dnl They are *not* in the public domain.
-
-dnl Authors:
-dnl   Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
-dnl   Bruno Haible <haible@clisp.cons.org>, 2000-2003.
-
-AC_DEFUN([AM_NLS],
-[
-  AC_MSG_CHECKING([whether NLS is requested])
-  dnl Default is enabled NLS
-  AC_ARG_ENABLE(nls,
-    [  --disable-nls           do not use Native Language Support],
-    USE_NLS=$enableval, USE_NLS=yes)
-  AC_MSG_RESULT($USE_NLS)
-  AC_SUBST(USE_NLS)
-])
-
-AC_DEFUN([AM_MKINSTALLDIRS],
-[
-  dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly
-  dnl find the mkinstalldirs script in another subdir but $(top_srcdir).
-  dnl Try to locate it.
-  MKINSTALLDIRS=
-  if test -n "$ac_aux_dir"; then
-    case "$ac_aux_dir" in
-      /*) MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" ;;
-      *) MKINSTALLDIRS="\$(top_builddir)/$ac_aux_dir/mkinstalldirs" ;;
-    esac
-  fi
-  if test -z "$MKINSTALLDIRS"; then
-    MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs"
-  fi
-  AC_SUBST(MKINSTALLDIRS)
-])
-# po.m4 serial 1 (gettext-0.12)
-dnl Copyright (C) 1995-2003 Free Software Foundation, Inc.
-dnl This file is free software, distributed under the terms of the GNU
-dnl General Public License.  As a special exception to the GNU General
-dnl Public License, this file may be distributed as part of a program
-dnl that contains a configuration script generated by Autoconf, under
-dnl the same distribution terms as the rest of that program.
-dnl
-dnl This file can can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
-dnl License but which still want to provide support for the GNU gettext
-dnl functionality.
-dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
-dnl gettext package package is covered by the GNU General Public License.
-dnl They are *not* in the public domain.
-
-dnl Authors:
-dnl   Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
-dnl   Bruno Haible <haible@clisp.cons.org>, 2000-2003.
-
-dnl Checks for all prerequisites of the po subdirectory.
-AC_DEFUN([AM_PO_SUBDIRS],
-[
-  AC_REQUIRE([AC_PROG_MAKE_SET])dnl
-  AC_REQUIRE([AC_PROG_INSTALL])dnl
-  AC_REQUIRE([AM_MKINSTALLDIRS])dnl
-  AC_REQUIRE([AM_NLS])dnl
-
-  dnl Perform the following tests also if --disable-nls has been given,
-  dnl because they are needed for "make dist" to work.
-
-  dnl Search for GNU msgfmt in the PATH.
-  dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions.
-  dnl The second test excludes FreeBSD msgfmt.
-  AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
-    [$ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1 &&
-     (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)],
-    :)
-  AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
-
-  dnl Search for GNU xgettext 0.12 or newer in the PATH.
-  dnl The first test excludes Solaris xgettext and early GNU xgettext versions.
-  dnl The second test excludes FreeBSD xgettext.
-  AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
-    [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 &&
-     (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)],
-    :)
-  dnl Remove leftover from FreeBSD xgettext call.
-  rm -f messages.po
-
-  dnl Search for GNU msgmerge 0.11 or newer in the PATH.
-  AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge,
-    [$ac_dir/$ac_word --update -q /dev/null /dev/null >/dev/null 2>&1], :)
-
-  dnl This could go away some day; the PATH_PROG_WITH_TEST already does it.
-  dnl Test whether we really found GNU msgfmt.
-  if test "$GMSGFMT" != ":"; then
-    dnl If it is no GNU msgfmt we define it as : so that the
-    dnl Makefiles still can work.
-    if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 &&
-       (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then
-      : ;
-    else
-      GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'`
-      AC_MSG_RESULT(
-        [found $GMSGFMT program is not GNU msgfmt; ignore it])
-      GMSGFMT=":"
-    fi
-  fi
-
-  dnl This could go away some day; the PATH_PROG_WITH_TEST already does it.
-  dnl Test whether we really found GNU xgettext.
-  if test "$XGETTEXT" != ":"; then
-    dnl If it is no GNU xgettext we define it as : so that the
-    dnl Makefiles still can work.
-    if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 &&
-       (if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then
-      : ;
-    else
-      AC_MSG_RESULT(
-        [found xgettext program is not GNU xgettext; ignore it])
-      XGETTEXT=":"
-    fi
-    dnl Remove leftover from FreeBSD xgettext call.
-    rm -f messages.po
-  fi
-
-  AC_OUTPUT_COMMANDS([
-    for ac_file in $CONFIG_FILES; do
-      # Support "outfile[:infile[:infile...]]"
-      case "$ac_file" in
-        *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
-      esac
-      # PO directories have a Makefile.in generated from Makefile.in.in.
-      case "$ac_file" in */Makefile.in)
-        # Adjust a relative srcdir.
-        ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
-        ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
-        ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
-        # In autoconf-2.13 it is called $ac_given_srcdir.
-        # In autoconf-2.50 it is called $srcdir.
-        test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
-        case "$ac_given_srcdir" in
-          .)  top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
-          /*) top_srcdir="$ac_given_srcdir" ;;
-          *)  top_srcdir="$ac_dots$ac_given_srcdir" ;;
-        esac
-        if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then
-          rm -f "$ac_dir/POTFILES"
-          test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES"
-          cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[  ]*\$/d" -e "s,.*,     $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES"
-          POMAKEFILEDEPS="POTFILES.in"
-          # ALL_LINGUAS, POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES depend
-          # on $ac_dir but don't depend on user-specified configuration
-          # parameters.
-          if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
-            # The LINGUAS file contains the set of available languages.
-            if test -n "$OBSOLETE_ALL_LINGUAS"; then
-              test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete"
-            fi
-            ALL_LINGUAS_=`sed -e "/^#/d" "$ac_given_srcdir/$ac_dir/LINGUAS"`
-            # Hide the ALL_LINGUAS assigment from automake.
-            eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
-            POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
-          else
-            # The set of available languages was given in configure.in.
-            eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS'
-          fi
-          case "$ac_given_srcdir" in
-            .) srcdirpre= ;;
-            *) srcdirpre='$(srcdir)/' ;;
-          esac
-          POFILES=
-          GMOFILES=
-          UPDATEPOFILES=
-          DUMMYPOFILES=
-          for lang in $ALL_LINGUAS; do
-            POFILES="$POFILES $srcdirpre$lang.po"
-            GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
-            UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
-            DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
-          done
-          # CATALOGS depends on both $ac_dir and the user's LINGUAS
-          # environment variable.
-          INST_LINGUAS=
-          if test -n "$ALL_LINGUAS"; then
-            for presentlang in $ALL_LINGUAS; do
-              useit=no
-              if test "%UNSET%" != "$LINGUAS"; then
-                desiredlanguages="$LINGUAS"
-              else
-                desiredlanguages="$ALL_LINGUAS"
-              fi
-              for desiredlang in $desiredlanguages; do
-                # Use the presentlang catalog if desiredlang is
-                #   a. equal to presentlang, or
-                #   b. a variant of presentlang (because in this case,
-                #      presentlang can be used as a fallback for messages
-                #      which are not translated in the desiredlang catalog).
-                case "$desiredlang" in
-                  "$presentlang"*) useit=yes;;
-                esac
-              done
-              if test $useit = yes; then
-                INST_LINGUAS="$INST_LINGUAS $presentlang"
-              fi
-            done
-          fi
-          CATALOGS=
-          if test -n "$INST_LINGUAS"; then
-            for lang in $INST_LINGUAS; do
-              CATALOGS="$CATALOGS $lang.gmo"
-            done
-          fi
-          test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile"
-          sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile"
-          for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do
-            if test -f "$f"; then
-              case "$f" in
-                *.orig | *.bak | *~) ;;
-                *) cat "$f" >> "$ac_dir/Makefile" ;;
-              esac
-            fi
-          done
-        fi
-        ;;
-      esac
-    done],
-   [# Capture the value of obsolete ALL_LINGUAS because we need it to compute
-    # POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES, CATALOGS. But hide it
-    # from automake.
-    eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"'
-    # Capture the value of LINGUAS because we need it to compute CATALOGS.
-    LINGUAS="${LINGUAS-%UNSET%}"
-   ])
-])
-# progtest.m4 serial 3 (gettext-0.12)
-dnl Copyright (C) 1996-2003 Free Software Foundation, Inc.
-dnl This file is free software, distributed under the terms of the GNU
-dnl General Public License.  As a special exception to the GNU General
-dnl Public License, this file may be distributed as part of a program
-dnl that contains a configuration script generated by Autoconf, under
-dnl the same distribution terms as the rest of that program.
-dnl
-dnl This file can can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
-dnl License but which still want to provide support for the GNU gettext
-dnl functionality.
-dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
-dnl gettext package package is covered by the GNU General Public License.
-dnl They are *not* in the public domain.
-
-dnl Authors:
-dnl   Ulrich Drepper <drepper@cygnus.com>, 1996.
-
-# Search path for a program which passes the given test.
-
-dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
-dnl   TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
-AC_DEFUN([AM_PATH_PROG_WITH_TEST],
-[
-# Prepare PATH_SEPARATOR.
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conf$$.sh
-  echo  "exit 0"   >>conf$$.sh
-  chmod +x conf$$.sh
-  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
-    PATH_SEPARATOR=';'
-  else
-    PATH_SEPARATOR=:
-  fi
-  rm -f conf$$.sh
-fi
-
-# Find out how to test for executable files. Don't use a zero-byte file,
-# as systems may use methods other than mode bits to determine executability.
-cat >conf$$.file <<_ASEOF
-#! /bin/sh
-exit 0
-_ASEOF
-chmod +x conf$$.file
-if test -x conf$$.file >/dev/null 2>&1; then
-  ac_executable_p="test -x"
-else
-  ac_executable_p="test -f"
-fi
-rm -f conf$$.file
-
-# Extract the first word of "$2", so it can be a program name with args.
-set dummy $2; ac_word=[$]2
-AC_MSG_CHECKING([for $ac_word])
-AC_CACHE_VAL(ac_cv_path_$1,
-[case "[$]$1" in
-  [[\\/]]* | ?:[[\\/]]*)
-    ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
-    ;;
-  *)
-    ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
-    for ac_dir in ifelse([$5], , $PATH, [$5]); do
-      IFS="$ac_save_IFS"
-      test -z "$ac_dir" && ac_dir=.
-      for ac_exec_ext in '' $ac_executable_extensions; do
-        if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
-          if [$3]; then
-            ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext"
-            break 2
-          fi
-        fi
-      done
-    done
-    IFS="$ac_save_IFS"
-dnl If no 4th arg is given, leave the cache variable unset,
-dnl so AC_PATH_PROGS will keep looking.
-ifelse([$4], , , [  test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
-])dnl
-    ;;
-esac])dnl
-$1="$ac_cv_path_$1"
-if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then
-  AC_MSG_RESULT([$]$1)
-else
-  AC_MSG_RESULT(no)
-fi
-AC_SUBST($1)dnl
-])
-# stdint_h.m4 serial 3 (gettext-0.12)
-dnl Copyright (C) 1997-2003 Free Software Foundation, Inc.
-dnl This file is free software, distributed under the terms of the GNU
-dnl General Public License.  As a special exception to the GNU General
-dnl Public License, this file may be distributed as part of a program
-dnl that contains a configuration script generated by Autoconf, under
-dnl the same distribution terms as the rest of that program.
-
-dnl From Paul Eggert.
-
-# Define HAVE_STDINT_H_WITH_UINTMAX if <stdint.h> exists,
-# doesn't clash with <sys/types.h>, and declares uintmax_t.
-
-AC_DEFUN([jm_AC_HEADER_STDINT_H],
-[
-  AC_CACHE_CHECK([for stdint.h], jm_ac_cv_header_stdint_h,
-  [AC_TRY_COMPILE(
-    [#include <sys/types.h>
-#include <stdint.h>],
-    [uintmax_t i = (uintmax_t) -1;],
-    jm_ac_cv_header_stdint_h=yes,
-    jm_ac_cv_header_stdint_h=no)])
-  if test $jm_ac_cv_header_stdint_h = yes; then
-    AC_DEFINE_UNQUOTED(HAVE_STDINT_H_WITH_UINTMAX, 1,
-      [Define if <stdint.h> exists, doesn't clash with <sys/types.h>,
-       and declares uintmax_t. ])
-  fi
-])
-# uintmax_t.m4 serial 7 (gettext-0.12)
-dnl Copyright (C) 1997-2003 Free Software Foundation, Inc.
-dnl This file is free software, distributed under the terms of the GNU
-dnl General Public License.  As a special exception to the GNU General
-dnl Public License, this file may be distributed as part of a program
-dnl that contains a configuration script generated by Autoconf, under
-dnl the same distribution terms as the rest of that program.
-
-dnl From Paul Eggert.
-
-AC_PREREQ(2.13)
-
-# Define uintmax_t to 'unsigned long' or 'unsigned long long'
-# if it is not already defined in <stdint.h> or <inttypes.h>.
-
-AC_DEFUN([jm_AC_TYPE_UINTMAX_T],
-[
-  AC_REQUIRE([jm_AC_HEADER_INTTYPES_H])
-  AC_REQUIRE([jm_AC_HEADER_STDINT_H])
-  if test $jm_ac_cv_header_inttypes_h = no && test $jm_ac_cv_header_stdint_h = no; then
-    AC_REQUIRE([jm_AC_TYPE_UNSIGNED_LONG_LONG])
-    test $ac_cv_type_unsigned_long_long = yes \
-      && ac_type='unsigned long long' \
-      || ac_type='unsigned long'
-    AC_DEFINE_UNQUOTED(uintmax_t, $ac_type,
-      [Define to unsigned long or unsigned long long
-       if <stdint.h> and <inttypes.h> don't define.])
-  else
-    AC_DEFINE(HAVE_UINTMAX_T, 1,
-      [Define if you have the 'uintmax_t' type in <stdint.h> or <inttypes.h>.])
-  fi
-])
-# ulonglong.m4 serial 2 (fileutils-4.0.32, gettext-0.10.40)
-dnl Copyright (C) 1999-2002 Free Software Foundation, Inc.
-dnl This file is free software, distributed under the terms of the GNU
-dnl General Public License.  As a special exception to the GNU General
-dnl Public License, this file may be distributed as part of a program
-dnl that contains a configuration script generated by Autoconf, under
-dnl the same distribution terms as the rest of that program.
-
-dnl From Paul Eggert.
-
-AC_DEFUN([jm_AC_TYPE_UNSIGNED_LONG_LONG],
-[
-  AC_CACHE_CHECK([for unsigned long long], ac_cv_type_unsigned_long_long,
-  [AC_TRY_LINK([unsigned long long ull = 1; int i = 63;],
-    [unsigned long long ullmax = (unsigned long long) -1;
-     return ull << i | ull >> i | ullmax / ull | ullmax % ull;],
-    ac_cv_type_unsigned_long_long=yes,
-    ac_cv_type_unsigned_long_long=no)])
-  if test $ac_cv_type_unsigned_long_long = yes; then
-    AC_DEFINE(HAVE_UNSIGNED_LONG_LONG, 1,
-      [Define if you have the unsigned long long type.])
-  fi
-])
-
-dnl From gnulib
-AC_DEFUN([BASH_FUNC_FPURGE],
-[
-  AC_CHECK_FUNCS_ONCE([fpurge])
-  AC_CHECK_FUNCS_ONCE([__fpurge])
-  AC_CHECK_DECLS([fpurge], , , [#include <stdio.h>])
-])
-
-AC_DEFUN([BASH_FUNC_SNPRINTF],
-[
-  AC_CHECK_FUNCS_ONCE([snprintf])
-  if test X$ac_cv_func_snprintf = Xyes; then
-    AC_CACHE_CHECK([for standard-conformant snprintf], [bash_cv_func_snprintf],
-      [AC_TRY_RUN([
-#include <stdio.h>
-
-main()
-{
-  int n;
-  n = snprintf (0, 0, "%s", "0123456");
-  exit(n != 7);
-}
-], bash_cv_func_snprintf=yes, bash_cv_func_snprintf=no,
-   [AC_MSG_WARN([cannot check snprintf if cross-compiling])
-    bash_cv_func_snprintf=yes]
-)])
-    if test $bash_cv_func_snprintf = no; then
-      ac_cv_func_snprintf=no
-    fi
-  fi
-  if test $ac_cv_func_snprintf = no; then
-    AC_DEFINE(HAVE_SNPRINTF, 0,
-      [Define if you have a standard-conformant snprintf function.])
-  fi
-])
-
-AC_DEFUN([BASH_FUNC_VSNPRINTF],
-[
-  AC_CHECK_FUNCS_ONCE([vsnprintf])
-  if test X$ac_cv_func_vsnprintf = Xyes; then
-    AC_CACHE_CHECK([for standard-conformant vsnprintf], [bash_cv_func_vsnprintf],
-      [AC_TRY_RUN([
-#if HAVE_STDARG_H
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-#include <stdio.h>
-
-static int
-#if HAVE_STDARG_H
-foo(const char *fmt, ...)
-#else
-foo(format, va_alist)
-     const char *format;
-     va_dcl
-#endif
-{
-  va_list args;
-  int n;
-
-#if HAVE_STDARG_H
-  va_start(args, fmt);
-#else
-  va_start(args);
-#endif
-  n = vsnprintf(0, 0, fmt, args);
-  va_end (args);
-  return n;
-}
-
-main()
-{
-  int n;
-  n = foo("%s", "0123456");
-  exit(n != 7);
-}
-], bash_cv_func_vsnprintf=yes, bash_cv_func_vsnprintf=no,
-   [AC_MSG_WARN([cannot check vsnprintf if cross-compiling])
-    bash_cv_func_vsnprintf=yes]
-)])
-    if test $bash_cv_func_vsnprintf = no; then
-      ac_cv_func_vsnprintf=no
-    fi
-  fi
-  if test $ac_cv_func_vsnprintf = no; then
-    AC_DEFINE(HAVE_VSNPRINTF, 0,
-      [Define if you have a standard-conformant vsnprintf function.])
-  fi
-])
diff --git a/alias.c~ b/alias.c~
deleted file mode 100644 (file)
index 2eedad5..0000000
--- a/alias.c~
+++ /dev/null
@@ -1,574 +0,0 @@
-/* alias.c -- Not a full alias, but just the kind that we use in the
-   shell.  Csh style alias is somewhere else (`over there, in a box'). */
-
-/* Copyright (C) 1987-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/>.
-*/
-
-#include "config.h"
-
-#if defined (ALIAS)
-
-#if defined (HAVE_UNISTD_H)
-#  ifdef _MINIX
-#    include <sys/types.h>
-#  endif
-#  include <unistd.h>
-#endif
-
-#include <stdio.h>
-#include "chartypes.h"
-#include "bashansi.h"
-#include "command.h"
-#include "general.h"
-#include "externs.h"
-#include "alias.h"
-
-#if defined (PROGRAMMABLE_COMPLETION)
-#  include "pcomplete.h"
-#endif
-
-#define ALIAS_HASH_BUCKETS     16      /* must be power of two */
-
-typedef int sh_alias_map_func_t __P((alias_t *));
-
-static void free_alias_data __P((PTR_T));
-static alias_t **map_over_aliases __P((sh_alias_map_func_t *));
-static void sort_aliases __P((alias_t **));
-static int qsort_alias_compare __P((alias_t **, alias_t **));
-
-#if defined (READLINE)
-static int skipquotes __P((char *, int));
-static int skipws __P((char *, int));
-static int rd_token __P((char *, int));
-#endif
-
-/* Non-zero means expand all words on the line.  Otherwise, expand
-   after first expansion if the expansion ends in a space. */
-int alias_expand_all = 0;
-
-/* The list of aliases that we have. */
-HASH_TABLE *aliases = (HASH_TABLE *)NULL;
-
-void
-initialize_aliases ()
-{
-  if (aliases == 0)
-    aliases = hash_create (ALIAS_HASH_BUCKETS);
-}
-
-/* Scan the list of aliases looking for one with NAME.  Return NULL
-   if the alias doesn't exist, else a pointer to the alias_t. */
-alias_t *
-find_alias (name)
-     char *name;
-{
-  BUCKET_CONTENTS *al;
-
-  if (aliases == 0)
-    return ((alias_t *)NULL);
-
-  al = hash_search (name, aliases, 0);
-  return (al ? (alias_t *)al->data : (alias_t *)NULL);
-}
-
-/* Return the value of the alias for NAME, or NULL if there is none. */
-char *
-get_alias_value (name)
-     char *name;
-{
-  alias_t *alias;
-
-  if (aliases == 0)
-    return ((char *)NULL);
-
-  alias = find_alias (name);
-  return (alias ? alias->value : (char *)NULL);
-}
-
-/* Make a new alias from NAME and VALUE.  If NAME can be found,
-   then replace its value. */
-void
-add_alias (name, value)
-     char *name, *value;
-{
-  BUCKET_CONTENTS *elt;
-  alias_t *temp;
-  int n;
-
-  if (!aliases)
-    {
-      initialize_aliases ();
-      temp = (alias_t *)NULL;
-    }
-  else
-    temp = find_alias (name);
-
-  if (temp)
-    {
-      free (temp->value);
-      temp->value = savestring (value);
-      temp->flags &= ~AL_EXPANDNEXT;
-      n = value[strlen (value) - 1];
-      if (n == ' ' || n == '\t')
-       temp->flags |= AL_EXPANDNEXT;
-    }
-  else
-    {
-      temp = (alias_t *)xmalloc (sizeof (alias_t));
-      temp->name = savestring (name);
-      temp->value = savestring (value);
-      temp->flags = 0;
-
-      n = value[strlen (value) - 1];
-      if (n == ' ' || n == '\t')
-       temp->flags |= AL_EXPANDNEXT;
-
-      elt = hash_insert (savestring (name), aliases, HASH_NOSRCH);
-      elt->data = temp;
-#if defined (PROGRAMMABLE_COMPLETION)
-      set_itemlist_dirty (&it_aliases);
-#endif
-    }
-}
-
-/* Delete a single alias structure. */
-static void
-free_alias_data (data)
-     PTR_T data;
-{
-  register alias_t *a;
-
-  a = (alias_t *)data;
-  free (a->value);
-  free (a->name);
-  free (data);
-}
-
-/* Remove the alias with name NAME from the alias table.  Returns
-   the number of aliases left in the table, or -1 if the alias didn't
-   exist. */
-int
-remove_alias (name)
-     char *name;
-{
-  BUCKET_CONTENTS *elt;
-
-  if (aliases == 0)
-    return (-1);
-
-  elt = hash_remove (name, aliases, 0);
-  if (elt)
-    {
-      free_alias_data (elt->data);
-      free (elt->key);         /* alias name */
-      free (elt);              /* XXX */
-#if defined (PROGRAMMABLE_COMPLETION)
-      set_itemlist_dirty (&it_aliases);
-#endif
-      return (aliases->nentries);
-    }
-  return (-1);
-}
-
-/* Delete all aliases. */
-void
-delete_all_aliases ()
-{
-  if (aliases == 0)
-    return;
-
-  hash_flush (aliases, free_alias_data);
-  hash_dispose (aliases);
-  aliases = (HASH_TABLE *)NULL;
-#if defined (PROGRAMMABLE_COMPLETION)
-  set_itemlist_dirty (&it_aliases);
-#endif
-}
-
-/* Return an array of aliases that satisfy the conditions tested by FUNCTION.
-   If FUNCTION is NULL, return all aliases. */
-static alias_t **
-map_over_aliases (function)
-     sh_alias_map_func_t *function;
-{
-  register int i;
-  register BUCKET_CONTENTS *tlist;
-  alias_t *alias, **list;
-  int list_index;
-
-  i = HASH_ENTRIES (aliases);
-  if (i == 0)
-    return ((alias_t **)NULL);
-
-  list = (alias_t **)xmalloc ((i + 1) * sizeof (alias_t *));
-  for (i = list_index = 0; i < aliases->nbuckets; i++)
-    {
-      for (tlist = hash_items (i, aliases); tlist; tlist = tlist->next)
-       {
-         alias = (alias_t *)tlist->data;
-
-         if (!function || (*function) (alias))
-           {
-             list[list_index++] = alias;
-             list[list_index] = (alias_t *)NULL;
-           }
-       }
-    }
-  return (list);
-}
-
-static void
-sort_aliases (array)
-     alias_t **array;
-{
-  qsort (array, strvec_len ((char **)array), sizeof (alias_t *), (QSFUNC *)qsort_alias_compare);
-}
-
-static int
-qsort_alias_compare (as1, as2)
-     alias_t **as1, **as2;
-{
-  int result;
-
-  if ((result = (*as1)->name[0] - (*as2)->name[0]) == 0)
-    result = strcmp ((*as1)->name, (*as2)->name);
-
-  return (result);
-}
-
-/* Return a sorted list of all defined aliases */
-alias_t **
-all_aliases ()
-{
-  alias_t **list;
-
-  if (aliases == 0 || HASH_ENTRIES (aliases) == 0)
-    return ((alias_t **)NULL);
-
-  list = map_over_aliases ((sh_alias_map_func_t *)NULL);
-  if (list)
-    sort_aliases (list);
-  return (list);
-}
-
-char *
-alias_expand_word (s)
-     char *s;
-{
-  alias_t *r;
-
-  r = find_alias (s);
-  return (r ? savestring (r->value) : (char *)NULL);
-}
-
-/* Readline support functions -- expand all aliases in a line. */
-
-#if defined (READLINE)
-
-/* Return non-zero if CHARACTER is a member of the class of characters
-   that are self-delimiting in the shell (this really means that these
-   characters delimit tokens). */
-#define self_delimiting(character) (member ((character), " \t\n\r;|&()"))
-
-/* Return non-zero if CHARACTER is a member of the class of characters
-   that delimit commands in the shell. */
-#define command_separator(character) (member ((character), "\r\n;|&("))
-
-/* If this is 1, we are checking the next token read for alias expansion
-   because it is the first word in a command. */
-static int command_word;
-
-/* This is for skipping quoted strings in alias expansions. */
-#define quote_char(c)  (((c) == '\'') || ((c) == '"'))
-
-/* Consume a quoted string from STRING, starting at string[START] (so
-   string[START] is the opening quote character), and return the index
-   of the closing quote character matching the opening quote character.
-   This handles single matching pairs of unquoted quotes; it could afford
-   to be a little smarter... This skips words between balanced pairs of
-   quotes, words where the first character is quoted with a `\', and other
-   backslash-escaped characters. */
-
-static int
-skipquotes (string, start)
-     char *string;
-     int start;
-{
-  register int i;
-  int delimiter = string[start];
-
-  /* i starts at START + 1 because string[START] is the opening quote
-     character. */
-  for (i = start + 1 ; string[i] ; i++)
-    {
-      if (string[i] == '\\')
-       {
-         i++;          /* skip backslash-quoted quote characters, too */
-         continue;
-       }
-
-      if (string[i] == delimiter)
-       return i;
-    }
-  return (i);
-}
-
-/* Skip the white space and any quoted characters in STRING, starting at
-   START.  Return the new index into STRING, after zero or more characters
-   have been skipped. */
-static int
-skipws (string, start)
-     char *string;
-     int start;
-{
-  register int i;
-  int pass_next, backslash_quoted_word;
-  unsigned char peekc;
-
-  /* skip quoted strings, in ' or ", and words in which a character is quoted
-     with a `\'. */
-  i = backslash_quoted_word = pass_next = 0;
-
-  /* Skip leading whitespace (or separator characters), and quoted words.
-     But save it in the output.  */
-
-  for (i = start; string[i]; i++)
-    {
-      if (pass_next)
-       {
-         pass_next = 0;
-         continue;
-       }
-
-      if (whitespace (string[i]))
-       {
-         backslash_quoted_word = 0; /* we are no longer in a backslash-quoted word */
-         continue;
-       }
-
-      if (string[i] == '\\')
-       {
-         peekc = string[i+1];
-         if (ISLETTER (peekc))
-           backslash_quoted_word++;    /* this is a backslash-quoted word */
-         else
-           pass_next++;
-         continue;
-       }
-
-      /* This only handles single pairs of non-escaped quotes.  This
-        overloads backslash_quoted_word to also mean that a word like
-        ""f is being scanned, so that the quotes will inhibit any expansion
-        of the word. */
-      if (quote_char(string[i]))
-       {
-         i = skipquotes (string, i);
-         /* This could be a line that contains a single quote character,
-            in which case skipquotes () terminates with string[i] == '\0'
-            (the end of the string).  Check for that here. */
-         if (string[i] == '\0')
-           break;
-
-         peekc = string[i + 1];
-         if (ISLETTER (peekc))
-           backslash_quoted_word++;
-         continue;
-       }
-
-      /* If we're in the middle of some kind of quoted word, let it
-        pass through. */
-      if (backslash_quoted_word)
-       continue;
-
-      /* If this character is a shell command separator, then set a hint for
-        alias_expand that the next token is the first word in a command. */
-
-      if (command_separator (string[i]))
-       {
-         command_word++;
-         continue;
-       }
-      break;
-    }
-  return (i);
-}
-
-/* Characters that may appear in a token.  Basically, anything except white
-   space and a token separator. */
-#define token_char(c)  (!((whitespace (string[i]) || self_delimiting (string[i]))))
-
-/* Read from START in STRING until the next separator character, and return
-   the index of that separator.  Skip backslash-quoted characters.  Call
-   skipquotes () for quoted strings in the middle or at the end of tokens,
-   so all characters show up (e.g. foo'' and foo""bar) */
-static int
-rd_token (string, start)
-     char *string;
-     int start;
-{
-  register int i;
-
-  /* From here to next separator character is a token. */
-  for (i = start; string[i] && token_char (string[i]); i++)
-    {
-      if (string[i] == '\\')
-       {
-         i++;  /* skip backslash-escaped character */
-         continue;
-       }
-
-      /* If this character is a quote character, we want to call skipquotes
-        to get the whole quoted portion as part of this word.  That word
-        will not generally match an alias, even if te unquoted word would
-        have.  The presence of the quotes in the token serves then to
-        inhibit expansion. */
-      if (quote_char (string[i]))
-       {
-         i = skipquotes (string, i);
-         /* This could be a line that contains a single quote character,
-            in which case skipquotes () terminates with string[i] == '\0'
-            (the end of the string).  Check for that here. */
-         if (string[i] == '\0')
-           break;
-
-         /* Now string[i] is the matching quote character, and the
-            quoted portion of the token has been scanned. */
-         continue;
-       }
-    }
-  return (i);
-}
-
-/* Return a new line, with any aliases substituted. */
-char *
-alias_expand (string)
-     char *string;
-{
-  register int i, j, start;
-  char *line, *token;
-  int line_len, tl, real_start, expand_next, expand_this_token;
-  alias_t *alias;
-
-  line_len = strlen (string) + 1;
-  line = (char *)xmalloc (line_len);
-  token = (char *)xmalloc (line_len);
-
-  line[0] = i = 0;
-  expand_next = 0;
-  command_word = 1; /* initialized to expand the first word on the line */
-
-  /* Each time through the loop we find the next word in line.  If it
-     has an alias, substitute the alias value.  If the value ends in ` ',
-     then try again with the next word.  Else, if there is no value, or if
-     the value does not end in space, we are done. */
-
-  for (;;)
-    {
-
-      token[0] = 0;
-      start = i;
-
-      /* Skip white space and quoted characters */
-      i = skipws (string, start);
-
-      if (start == i && string[i] == '\0')
-       {
-         free (token);
-         return (line);
-       }
-
-      /* copy the just-skipped characters into the output string,
-        expanding it if there is not enough room. */
-      j = strlen (line);
-      tl = i - start;  /* number of characters just skipped */
-      RESIZE_MALLOCED_BUFFER (line, j, (tl + 1), line_len, (tl + 50));
-      strncpy (line + j, string + start, tl);
-      line[j + tl] = '\0';
-
-      real_start = i;
-
-      command_word = command_word || (command_separator (string[i]));
-      expand_this_token = (command_word || expand_next);
-      expand_next = 0;
-
-      /* Read the next token, and copy it into TOKEN. */
-      start = i;
-      i = rd_token (string, start);
-
-      tl = i - start;  /* token length */
-
-      /* If tl == 0, but we're not at the end of the string, then we have a
-        single-character token, probably a delimiter */
-      if (tl == 0 && string[i] != '\0')
-       {
-         tl = 1;
-         i++;          /* move past it */
-       }
-
-      strncpy (token, string + start, tl);
-      token [tl] = '\0';
-
-      /* If there is a backslash-escaped character quoted in TOKEN,
-        then we don't do alias expansion.  This should check for all
-        other quoting characters, too. */
-      if (xstrchr (token, '\\'))
-       expand_this_token = 0;
-
-      /* If we should be expanding here, if we are expanding all words, or if
-        we are in a location in the string where an expansion is supposed to
-        take place, see if this word has a substitution.  If it does, then do
-        the expansion.  Note that we defer the alias value lookup until we
-        are sure we are expanding this token. */
-
-      if ((token[0]) &&
-         (expand_this_token || alias_expand_all) &&
-         (alias = find_alias (token)))
-       {
-         char *v;
-         int vlen, llen;
-
-         v = alias->value;
-         vlen = strlen (v);
-         llen = strlen (line);
-
-         /* +3 because we possibly add one more character below. */
-         RESIZE_MALLOCED_BUFFER (line, llen, (vlen + 3), line_len, (vlen + 50));
-
-         strcpy (line + llen, v);
-
-         if ((expand_this_token && vlen && whitespace (v[vlen - 1])) ||
-             alias_expand_all)
-           expand_next = 1;
-       }
-      else
-       {
-         int llen, tlen;
-
-         llen = strlen (line);
-         tlen = i - real_start; /* tlen == strlen(token) */
-
-         RESIZE_MALLOCED_BUFFER (line, llen, (tlen + 1), line_len, (llen + tlen + 50));
-
-         strncpy (line + llen, string + real_start, tlen);
-         line[llen + tlen] = '\0';
-       }
-      command_word = 0;
-    }
-}
-#endif /* READLINE */
-#endif /* ALIAS */
diff --git a/array.c~ b/array.c~
deleted file mode 100644 (file)
index 27fe170..0000000
--- a/array.c~
+++ /dev/null
@@ -1,1130 +0,0 @@
-/*
- * array.c - functions to create, destroy, access, and manipulate arrays
- *          of strings.
- *
- * Arrays are sparse doubly-linked lists.  An element's index is stored
- * with it.
- *
- * Chet Ramey
- * chet@ins.cwru.edu
- */
-
-/* Copyright (C) 1997-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/>.
-*/
-
-#include "config.h"
-
-#if defined (ARRAY_VARS)
-
-#if defined (HAVE_UNISTD_H)
-#  ifdef _MINIX
-#    include <sys/types.h>
-#  endif
-#  include <unistd.h>
-#endif
-
-#include <stdio.h>
-#include "bashansi.h"
-
-#include "shell.h"
-#include "array.h"
-#include "builtins/common.h"
-
-#define ADD_BEFORE(ae, new) \
-       do { \
-               ae->prev->next = new; \
-               new->prev = ae->prev; \
-               ae->prev = new; \
-               new->next = ae; \
-       } while(0)
-
-static char *array_to_string_internal __P((ARRAY_ELEMENT *, ARRAY_ELEMENT *, char *, int));
-
-static ARRAY *lastarray = 0;
-static ARRAY_ELEMENT *lastref = 0;
-
-#define IS_LASTREF(a)  ((a) == lastarray)
-
-#define INVALIDATE_LASTREF(a) \
-do { \
-       if ((a) == lastarray) { \
-               lastarray = 0; \
-               lastref = 0; \
-       } \
-} while (0)
-
-#define SET_LASTREF(a, e) \
-do { \
-       lastarray = (a); \
-       lastref = (e); \
-} while (0)
-
-#define UNSET_LASTREF() \
-do { \
-       lastarray = 0; \
-       lastref = 0; \
-} while (0)
-
-ARRAY *
-array_create()
-{
-       ARRAY   *r;
-       ARRAY_ELEMENT   *head;
-
-       r =(ARRAY *)xmalloc(sizeof(ARRAY));
-       r->type = array_indexed;
-       r->max_index = -1;
-       r->num_elements = 0;
-       head = array_create_element(-1, (char *)NULL);  /* dummy head */
-       head->prev = head->next = head;
-       r->head = head;
-       return(r);
-}
-
-void
-array_flush (a)
-ARRAY  *a;
-{
-       register ARRAY_ELEMENT *r, *r1;
-
-       if (a == 0)
-               return;
-       for (r = element_forw(a->head); r != a->head; ) {
-               r1 = element_forw(r);
-               array_dispose_element(r);
-               r = r1;
-       }
-       a->head->next = a->head->prev = a->head;
-       a->max_index = -1;
-       a->num_elements = 0;
-       INVALIDATE_LASTREF(a);
-}
-
-void
-array_dispose(a)
-ARRAY  *a;
-{
-       if (a == 0)
-               return;
-       array_flush (a);
-       array_dispose_element(a->head);
-       free(a);
-}
-
-ARRAY *
-array_copy(a)
-ARRAY  *a;
-{
-       ARRAY   *a1;
-       ARRAY_ELEMENT   *ae, *new;
-
-       if (a == 0)
-               return((ARRAY *) NULL);
-       a1 = array_create();
-       a1->type = a->type;
-       a1->max_index = a->max_index;
-       a1->num_elements = a->num_elements;
-       for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) {
-               new = array_create_element(element_index(ae), element_value(ae));
-               ADD_BEFORE(a1->head, new);
-       }
-       return(a1);
-}
-
-/*
- * Make and return a new array composed of the elements in array A from
- * S to E, inclusive.
- */
-ARRAY *
-array_slice(array, s, e)
-ARRAY          *array;
-ARRAY_ELEMENT  *s, *e;
-{
-       ARRAY   *a;
-       ARRAY_ELEMENT *p, *n;
-       int     i;
-       arrayind_t mi;
-
-       a = array_create ();
-       a->type = array->type;
-
-       for (mi = 0, p = s, i = 0; p != e; p = element_forw(p), i++) {
-               n = array_create_element (element_index(p), element_value(p));
-               ADD_BEFORE(a->head, n);
-               mi = element_index(n);
-       }
-       a->num_elements = i;
-       a->max_index = mi;
-       return a;
-}
-
-/*
- * Walk the array, calling FUNC once for each element, with the array
- * element as the argument.
- */
-void
-array_walk(a, func, udata)
-ARRAY  *a;
-sh_ae_map_func_t *func;
-void   *udata;
-{
-       register ARRAY_ELEMENT *ae;
-
-       if (a == 0 || array_empty(a))
-               return;
-       for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae))
-               if ((*func)(ae, udata) < 0)
-                       return;
-}
-
-/*
- * Shift the array A N elements to the left.  Delete the first N elements
- * and subtract N from the indices of the remaining elements.  If FLAGS
- * does not include AS_DISPOSE, this returns a singly-linked null-terminated
- * list of elements so the caller can dispose of the chain.  If FLAGS
- * includes AS_DISPOSE, this function disposes of the shifted-out elements
- * and returns NULL.
- */
-ARRAY_ELEMENT *
-array_shift(a, n, flags)
-ARRAY  *a;
-int    n, flags;
-{
-       register ARRAY_ELEMENT *ae, *ret;
-       register int i;
-
-       if (a == 0 || array_empty(a) || n <= 0)
-               return ((ARRAY_ELEMENT *)NULL);
-
-       INVALIDATE_LASTREF(a);
-       for (i = 0, ret = ae = element_forw(a->head); ae != a->head && i < n; ae = element_forw(ae), i++)
-               ;
-       if (ae == a->head) {
-               /* Easy case; shifting out all of the elements */
-               if (flags & AS_DISPOSE) {
-                       array_flush (a);
-                       return ((ARRAY_ELEMENT *)NULL);
-               }
-               for (ae = ret; element_forw(ae) != a->head; ae = element_forw(ae))
-                       ;
-               element_forw(ae) = (ARRAY_ELEMENT *)NULL;
-               a->head->next = a->head->prev = a->head;
-               a->max_index = -1;
-               a->num_elements = 0;
-               return ret;
-       }
-       /*
-        * ae now points to the list of elements we want to retain.
-        * ret points to the list we want to either destroy or return.
-        */
-       ae->prev->next = (ARRAY_ELEMENT *)NULL;         /* null-terminate RET */
-
-       a->head->next = ae;             /* slice RET out of the array */
-       ae->prev = a->head;
-
-       for ( ; ae != a->head; ae = element_forw(ae))
-               element_index(ae) -= n; /* renumber retained indices */
-
-       a->num_elements -= n;           /* modify bookkeeping information */
-       a->max_index = element_index(a->head->prev);
-
-       if (flags & AS_DISPOSE) {
-               for (ae = ret; ae; ) {
-                       ret = element_forw(ae);
-                       array_dispose_element(ae);
-                       ae = ret;
-               }
-               return ((ARRAY_ELEMENT *)NULL);
-       }
-
-       return ret;
-}
-
-/*
- * Shift array A right N indices.  If S is non-null, it becomes the value of
- * the new element 0.  Returns the number of elements in the array after the
- * shift.
- */
-int
-array_rshift (a, n, s)
-ARRAY  *a;
-int    n;
-char   *s;
-{
-       register ARRAY_ELEMENT  *ae, *new;
-
-       if (a == 0 || (array_empty(a) && s == 0))
-               return 0;
-       else if (n <= 0)
-               return (a->num_elements);
-
-       ae = element_forw(a->head);
-       if (s) {
-               new = array_create_element(0, s);
-               ADD_BEFORE(ae, new);
-               a->num_elements++;
-               if (array_num_elements(a) == 1) {       /* array was empty */
-                       a->max_index = 0;
-                       return 1;
-               }
-       }
-
-       /*
-        * Renumber all elements in the array except the one we just added.
-        */
-       for ( ; ae != a->head; ae = element_forw(ae))
-               element_index(ae) += n;
-
-       a->max_index = element_index(a->head->prev);
-
-       INVALIDATE_LASTREF(a);
-       return (a->num_elements);
-}
-
-ARRAY_ELEMENT *
-array_unshift_element(a)
-ARRAY  *a;
-{
-       return (array_shift (a, 1, 0));
-}
-
-int
-array_shift_element(a, v)
-ARRAY  *a;
-char   *v;
-{
-       return (array_rshift (a, 1, v));
-}
-
-ARRAY *
-array_quote(array)
-ARRAY  *array;
-{
-       ARRAY_ELEMENT   *a;
-       char    *t;
-
-       if (array == 0 || array_head(array) == 0 || array_empty(array))
-               return (ARRAY *)NULL;
-       for (a = element_forw(array->head); a != array->head; a = element_forw(a)) {
-               t = quote_string (a->value);
-               FREE(a->value);
-               a->value = t;
-       }
-       return array;
-}
-
-ARRAY *
-array_quote_escapes(array)
-ARRAY  *array;
-{
-       ARRAY_ELEMENT   *a;
-       char    *t;
-
-       if (array == 0 || array_head(array) == 0 || array_empty(array))
-               return (ARRAY *)NULL;
-       for (a = element_forw(array->head); a != array->head; a = element_forw(a)) {
-               t = quote_escapes (a->value);
-               FREE(a->value);
-               a->value = t;
-       }
-       return array;
-}
-
-ARRAY *
-array_dequote(array)
-ARRAY  *array;
-{
-       ARRAY_ELEMENT   *a;
-       char    *t;
-
-       if (array == 0 || array_head(array) == 0 || array_empty(array))
-               return (ARRAY *)NULL;
-       for (a = element_forw(array->head); a != array->head; a = element_forw(a)) {
-               t = dequote_string (a->value);
-               FREE(a->value);
-               a->value = t;
-       }
-       return array;
-}
-
-ARRAY *
-array_dequote_escapes(array)
-ARRAY  *array;
-{
-       ARRAY_ELEMENT   *a;
-       char    *t;
-
-       if (array == 0 || array_head(array) == 0 || array_empty(array))
-               return (ARRAY *)NULL;
-       for (a = element_forw(array->head); a != array->head; a = element_forw(a)) {
-               t = dequote_escapes (a->value);
-               FREE(a->value);
-               a->value = t;
-       }
-       return array;
-}
-
-ARRAY *
-array_remove_quoted_nulls(array)
-ARRAY  *array;
-{
-       ARRAY_ELEMENT   *a;
-       char    *t;
-
-       if (array == 0 || array_head(array) == 0 || array_empty(array))
-               return (ARRAY *)NULL;
-       for (a = element_forw(array->head); a != array->head; a = element_forw(a))
-               a->value = remove_quoted_nulls (a->value);
-       return array;
-}
-
-/*
- * Return a string whose elements are the members of array A beginning at
- * index START and spanning NELEM members.  Null elements are counted.
- * Since arrays are sparse, unset array elements are not counted.
- */
-char *
-array_subrange (a, start, nelem, starsub, quoted)
-ARRAY  *a;
-arrayind_t     start, nelem;
-int    starsub, quoted;
-{
-       ARRAY           *a2;
-       ARRAY_ELEMENT   *h, *p;
-       arrayind_t      i;
-       char            *ifs, *sifs, *t;
-       int             slen;
-
-       p = a ? array_head (a) : 0;
-       if (p == 0 || array_empty (a) || start > array_max_index(a))
-               return ((char *)NULL);
-
-       /*
-        * Find element with index START.  If START corresponds to an unset
-        * element (arrays can be sparse), use the first element whose index
-        * is >= START.  If START is < 0, we count START indices back from
-        * the end of A (not elements, even with sparse arrays -- START is an
-        * index).
-        */
-       for (p = element_forw(p); p != array_head(a) && start > element_index(p); p = element_forw(p))
-               ;
-
-       if (p == a->head)
-               return ((char *)NULL);
-
-       /* Starting at P, take NELEM elements, inclusive. */
-       for (i = 0, h = p; p != a->head && i < nelem; i++, p = element_forw(p))
-               ;
-
-       a2 = array_slice(a, h, p);
-
-       if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
-               array_quote(a2);
-       else
-               array_quote_escapes(a2);
-
-       if (starsub && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) {
-               /* ${array[*]} */
-               array_remove_quoted_nulls (a2);
-               sifs = ifs_firstchar ((int *)NULL);
-               t = array_to_string (a2, sifs, 0);
-               free (sifs);
-       } else if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) {
-               /* ${array[@]} */
-               sifs = ifs_firstchar (&slen);
-               ifs = getifs ();
-               if (ifs == 0 || *ifs == 0) {
-                       if (slen < 2)
-                               sifs = xrealloc(sifs, 2);
-                       sifs[0] = ' ';
-                       sifs[1] = '\0';
-               }
-               t = array_to_string (a2, sifs, 0);
-               free (sifs);
-       } else
-               t = array_to_string (a2, " ", 0);
-       array_dispose(a2);
-
-       return t;
-}
-
-char *
-array_patsub (a, pat, rep, mflags)
-ARRAY  *a;
-char   *pat, *rep;
-int    mflags;
-{
-       ARRAY           *a2;
-       ARRAY_ELEMENT   *e;
-       char    *t, *sifs, *ifs;
-       int     slen;
-
-       if (a == 0 || array_head(a) == 0 || array_empty(a))
-               return ((char *)NULL);
-
-       a2 = array_copy(a);
-       for (e = element_forw(a2->head); e != a2->head; e = element_forw(e)) {
-               t = pat_subst(element_value(e), pat, rep, mflags);
-               FREE(element_value(e));
-               e->value = t;
-       }
-
-       if (mflags & MATCH_QUOTED)
-               array_quote(a2);
-       else
-               array_quote_escapes(a2);
-
-       if (mflags & MATCH_STARSUB) {
-               array_remove_quoted_nulls (a2);
-               sifs = ifs_firstchar((int *)NULL);
-               t = array_to_string (a2, sifs, 0);
-               free(sifs);
-       } else if (mflags & MATCH_QUOTED) {
-               /* ${array[@]} */
-               sifs = ifs_firstchar (&slen);
-               ifs = getifs ();
-               if (ifs == 0 || *ifs == 0) {
-                       if (slen < 2)
-                               sifs = xrealloc (sifs, 2);
-                       sifs[0] = ' ';
-                       sifs[1] = '\0';
-               }
-               t = array_to_string (a2, sifs, 0);
-               free(sifs);
-       } else
-               t = array_to_string (a2, " ", 0);
-       array_dispose (a2);
-
-       return t;
-}
-
-char *
-array_modcase (a, pat, modop, mflags)
-ARRAY  *a;
-char   *pat;
-int    modop;
-int    mflags;
-{
-       ARRAY           *a2;
-       ARRAY_ELEMENT   *e;
-       char    *t, *sifs, *ifs;
-       int     slen;
-
-       if (a == 0 || array_head(a) == 0 || array_empty(a))
-               return ((char *)NULL);
-
-       a2 = array_copy(a);
-       for (e = element_forw(a2->head); e != a2->head; e = element_forw(e)) {
-               t = sh_modcase(element_value(e), pat, modop);
-               FREE(element_value(e));
-               e->value = t;
-       }
-
-       if (mflags & MATCH_QUOTED)
-               array_quote(a2);
-       else
-               array_quote_escapes(a2);
-
-       if (mflags & MATCH_STARSUB) {
-               array_remove_quoted_nulls (a2);
-               sifs = ifs_firstchar((int *)NULL);
-               t = array_to_string (a2, sifs, 0);
-               free(sifs);
-       } else if (mflags & MATCH_QUOTED) {
-               /* ${array[@]} */
-               sifs = ifs_firstchar (&slen);
-               ifs = getifs ();
-               if (ifs == 0 || *ifs == 0) {
-                       if (slen < 2)
-                               sifs = xrealloc (sifs, 2);
-                       sifs[0] = ' ';
-                       sifs[1] = '\0';
-               }
-               t = array_to_string (a2, sifs, 0);
-               free(sifs);
-       } else
-               t = array_to_string (a2, " ", 0);
-       array_dispose (a2);
-
-       return t;
-}
-/*
- * Allocate and return a new array element with index INDEX and value
- * VALUE.
- */
-ARRAY_ELEMENT *
-array_create_element(indx, value)
-arrayind_t     indx;
-char   *value;
-{
-       ARRAY_ELEMENT *r;
-
-       r = (ARRAY_ELEMENT *)xmalloc(sizeof(ARRAY_ELEMENT));
-       r->ind = indx;
-       r->value = value ? savestring(value) : (char *)NULL;
-       r->next = r->prev = (ARRAY_ELEMENT *) NULL;
-       return(r);
-}
-
-#ifdef INCLUDE_UNUSED
-ARRAY_ELEMENT *
-array_copy_element(ae)
-ARRAY_ELEMENT  *ae;
-{
-       return(ae ? array_create_element(element_index(ae), element_value(ae))
-                 : (ARRAY_ELEMENT *) NULL);
-}
-#endif
-
-void
-array_dispose_element(ae)
-ARRAY_ELEMENT  *ae;
-{
-       if (ae) {
-               FREE(ae->value);
-               free(ae);
-       }
-}
-
-/*
- * Add a new element with index I and value V to array A (a[i] = v).
- */
-int
-array_insert(a, i, v)
-ARRAY  *a;
-arrayind_t     i;
-char   *v;
-{
-       register ARRAY_ELEMENT *new, *ae;
-
-       if (a == 0)
-               return(-1);
-       new = array_create_element(i, v);
-       if (i > array_max_index(a)) {
-               /*
-                * Hook onto the end.  This also works for an empty array.
-                * Fast path for the common case of allocating arrays
-                * sequentially.
-                */
-               ADD_BEFORE(a->head, new);
-               a->max_index = i;
-               a->num_elements++;
-               SET_LASTREF(a, new);
-               return(0);
-       }
-       /*
-        * Otherwise we search for the spot to insert it.
-        */
-       for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) {
-               if (element_index(ae) == i) {
-                       /*
-                        * Replacing an existing element.
-                        */
-                       array_dispose_element(new);
-                       free(element_value(ae));
-                       ae->value = v ? savestring(v) : (char *)NULL;
-                       SET_LASTREF(a, ae);
-                       return(0);
-               } else if (element_index(ae) > i) {
-                       ADD_BEFORE(ae, new);
-                       a->num_elements++;
-                       SET_LASTREF(a, new);
-                       return(0);
-               }
-       }
-       INVALIDATE_LASTREF(a);
-       return (-1);            /* problem */
-}
-
-/*
- * Delete the element with index I from array A and return it so the
- * caller can dispose of it.
- */
-ARRAY_ELEMENT *
-array_remove(a, i)
-ARRAY  *a;
-arrayind_t     i;
-{
-       register ARRAY_ELEMENT *ae;
-
-       if (a == 0 || array_empty(a))
-               return((ARRAY_ELEMENT *) NULL);
-       for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae))
-               if (element_index(ae) == i) {
-                       ae->next->prev = ae->prev;
-                       ae->prev->next = ae->next;
-                       a->num_elements--;
-                       if (i == array_max_index(a))
-                               a->max_index = element_index(ae->prev);
-                       INVALIDATE_LASTREF(a);
-                       return(ae);
-               }
-       return((ARRAY_ELEMENT *) NULL);
-}
-
-/*
- * Return the value of a[i].
- */
-char *
-array_reference(a, i)
-ARRAY  *a;
-arrayind_t     i;
-{
-       register ARRAY_ELEMENT *ae;
-
-       if (a == 0 || array_empty(a))
-               return((char *) NULL);
-       if (i > array_max_index(a))
-               return((char *)NULL);
-       /* Keep roving pointer into array to optimize sequential access */
-       if (lastref && IS_LASTREF(a))
-               ae = (i >= element_index(lastref)) ? lastref : element_forw(a->head);
-       else
-               ae = element_forw(a->head);
-       for ( ; ae != a->head; ae = element_forw(ae))
-               if (element_index(ae) == i) {
-                       SET_LASTREF(a, ae);
-                       return(element_value(ae));
-               }
-       UNSET_LASTREF();
-       return((char *) NULL);
-}
-
-/* Convenience routines for the shell to translate to and from the form used
-   by the rest of the code. */
-
-WORD_LIST *
-array_to_word_list(a)
-ARRAY  *a;
-{
-       WORD_LIST       *list;
-       ARRAY_ELEMENT   *ae;
-
-       if (a == 0 || array_empty(a))
-               return((WORD_LIST *)NULL);
-       list = (WORD_LIST *)NULL;
-       for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae))
-               list = make_word_list (make_bare_word(element_value(ae)), list);
-       return (REVERSE_LIST(list, WORD_LIST *));
-}
-
-ARRAY *
-array_from_word_list (list)
-WORD_LIST      *list;
-{
-       ARRAY   *a;
-
-       if (list == 0)
-               return((ARRAY *)NULL);
-       a = array_create();
-       return (array_assign_list (a, list));
-}
-
-WORD_LIST *
-array_keys_to_word_list(a)
-ARRAY  *a;
-{
-       WORD_LIST       *list;
-       ARRAY_ELEMENT   *ae;
-       char            *t;
-
-       if (a == 0 || array_empty(a))
-               return((WORD_LIST *)NULL);
-       list = (WORD_LIST *)NULL;
-       for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) {
-               t = itos(element_index(ae));
-               list = make_word_list (make_bare_word(t), list);
-               free(t);
-       }
-       return (REVERSE_LIST(list, WORD_LIST *));
-}
-
-ARRAY *
-array_assign_list (array, list)
-ARRAY  *array;
-WORD_LIST      *list;
-{
-       register WORD_LIST *l;
-       register arrayind_t i;
-
-       for (l = list, i = 0; l; l = l->next, i++)
-               array_insert(array, i, l->word->word);
-       return array;
-}
-
-char **
-array_to_argv (a)
-ARRAY  *a;
-{
-       char            **ret, *t;
-       int             i;
-       ARRAY_ELEMENT   *ae;
-
-       if (a == 0 || array_empty(a))
-               return ((char **)NULL);
-       ret = strvec_create (array_num_elements (a) + 1);
-       i = 0;
-       for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) {
-               t = element_value (ae);
-               ret[i++] = t ? savestring (t) : (char *)NULL;
-       }
-       ret[i] = (char *)NULL;
-       return (ret);
-}
-       
-/*
- * Return a string that is the concatenation of the elements in A from START
- * to END, separated by SEP.
- */
-static char *
-array_to_string_internal (start, end, sep, quoted)
-ARRAY_ELEMENT  *start, *end;
-char   *sep;
-int    quoted;
-{
-       char    *result, *t;
-       ARRAY_ELEMENT *ae;
-       int     slen, rsize, rlen, reg;
-
-       if (start == end)       /* XXX - should not happen */
-               return ((char *)NULL);
-
-       slen = strlen(sep);
-       result = NULL;
-       for (rsize = rlen = 0, ae = start; ae != end; ae = element_forw(ae)) {
-               if (rsize == 0)
-                       result = (char *)xmalloc (rsize = 64);
-               if (element_value(ae)) {
-                       t = quoted ? quote_string(element_value(ae)) : element_value(ae);
-                       reg = strlen(t);
-                       RESIZE_MALLOCED_BUFFER (result, rlen, (reg + slen + 2),
-                                               rsize, rsize);
-                       strcpy(result + rlen, t);
-                       rlen += reg;
-                       if (quoted && t)
-                               free(t);
-                       /*
-                        * Add a separator only after non-null elements.
-                        */
-                       if (element_forw(ae) != end) {
-                               strcpy(result + rlen, sep);
-                               rlen += slen;
-                       }
-               }
-       }
-       if (result)
-         result[rlen] = '\0';  /* XXX */
-       return(result);
-}
-
-char *
-array_to_assign (a, quoted)
-ARRAY  *a;
-int    quoted;
-{
-       char    *result, *valstr, *is;
-       char    indstr[INT_STRLEN_BOUND(intmax_t) + 1];
-       ARRAY_ELEMENT *ae;
-       int     rsize, rlen, elen;
-
-       if (a == 0 || array_empty (a))
-               return((char *)NULL);
-
-       result = (char *)xmalloc (rsize = 128);
-       result[0] = '(';
-       rlen = 1;
-
-       for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) {
-               is = inttostr (element_index(ae), indstr, sizeof(indstr));
-               valstr = element_value (ae) ? sh_double_quote (element_value(ae))
-                                           : (char *)NULL;
-               elen = STRLEN (is) + 8 + STRLEN (valstr);
-               RESIZE_MALLOCED_BUFFER (result, rlen, (elen + 1), rsize, rsize);
-
-               result[rlen++] = '[';
-               strcpy (result + rlen, is);
-               rlen += STRLEN (is);
-               result[rlen++] = ']';
-               result[rlen++] = '=';
-               if (valstr) {
-                       strcpy (result + rlen, valstr);
-                       rlen += STRLEN (valstr);
-               }
-
-               if (element_forw(ae) != a->head)
-                 result[rlen++] = ' ';
-
-               FREE (valstr);
-       }
-       RESIZE_MALLOCED_BUFFER (result, rlen, 1, rsize, 8);
-       result[rlen++] = ')';
-       result[rlen] = '\0';
-       if (quoted) {
-               /* This is not as efficient as it could be... */
-               valstr = sh_single_quote (result);
-               free (result);
-               result = valstr;
-       }
-       return(result);
-}
-
-char *
-array_to_string (a, sep, quoted)
-ARRAY  *a;
-char   *sep;
-int    quoted;
-{
-       if (a == 0)
-               return((char *)NULL);
-       if (array_empty(a))
-               return(savestring(""));
-       return (array_to_string_internal (element_forw(a->head), a->head, sep, quoted));
-}
-
-#if defined (INCLUDE_UNUSED) || defined (TEST_ARRAY)
-/*
- * Return an array consisting of elements in S, separated by SEP
- */
-ARRAY *
-array_from_string(s, sep)
-char   *s, *sep;
-{
-       ARRAY   *a;
-       WORD_LIST *w;
-
-       if (s == 0)
-               return((ARRAY *)NULL);
-       w = list_string (s, sep, 0);
-       if (w == 0)
-               return((ARRAY *)NULL);
-       a = array_from_word_list (w);
-       return (a);
-}
-#endif
-
-#if defined (TEST_ARRAY)
-/*
- * To make a running version, compile -DTEST_ARRAY and link with:
- *     xmalloc.o syntax.o lib/malloc/libmalloc.a lib/sh/libsh.a
- */
-int interrupt_immediately = 0;
-
-int
-signal_is_trapped(s)
-int    s;
-{
-       return 0;
-}
-
-void
-fatal_error(const char *s, ...)
-{
-       fprintf(stderr, "array_test: fatal memory error\n");
-       abort();
-}
-
-void
-programming_error(const char *s, ...)
-{
-       fprintf(stderr, "array_test: fatal programming error\n");
-       abort();
-}
-
-WORD_DESC *
-make_bare_word (s)
-const char     *s;
-{
-       WORD_DESC *w;
-
-       w = (WORD_DESC *)xmalloc(sizeof(WORD_DESC));
-       w->word = s ? savestring(s) : savestring ("");
-       w->flags = 0;
-       return w;
-}
-
-WORD_LIST *
-make_word_list(x, l)
-WORD_DESC      *x;
-WORD_LIST      *l;
-{
-       WORD_LIST *w;
-
-       w = (WORD_LIST *)xmalloc(sizeof(WORD_LIST));
-       w->word = x;
-       w->next = l;
-       return w;
-}
-
-WORD_LIST *
-list_string(s, t, i)
-char   *s, *t;
-int    i;
-{
-       char    *r, *a;
-       WORD_LIST       *wl;
-
-       if (s == 0)
-               return (WORD_LIST *)NULL;
-       r = savestring(s);
-       wl = (WORD_LIST *)NULL;
-       a = strtok(r, t);
-       while (a) {
-               wl = make_word_list (make_bare_word(a), wl);
-               a = strtok((char *)NULL, t);
-       }
-       return (REVERSE_LIST (wl, WORD_LIST *));
-}
-
-GENERIC_LIST *
-list_reverse (list)
-GENERIC_LIST   *list;
-{
-       register GENERIC_LIST *next, *prev;
-
-       for (prev = 0; list; ) {
-               next = list->next;
-               list->next = prev;
-               prev = list;
-               list = next;
-       }
-       return prev;
-}
-
-char *
-pat_subst(s, t, u, i)
-char   *s, *t, *u;
-int    i;
-{
-       return ((char *)NULL);
-}
-
-char *
-quote_string(s)
-char   *s;
-{
-       return savestring(s);
-}
-
-print_element(ae)
-ARRAY_ELEMENT  *ae;
-{
-       char    lbuf[INT_STRLEN_BOUND (intmax_t) + 1];
-
-       printf("array[%s] = %s\n",
-               inttostr (element_index(ae), lbuf, sizeof (lbuf)),
-               element_value(ae));
-}
-
-print_array(a)
-ARRAY  *a;
-{
-       printf("\n");
-       array_walk(a, print_element, (void *)NULL);
-}
-
-main()
-{
-       ARRAY   *a, *new_a, *copy_of_a;
-       ARRAY_ELEMENT   *ae, *aew;
-       char    *s;
-
-       a = array_create();
-       array_insert(a, 1, "one");
-       array_insert(a, 7, "seven");
-       array_insert(a, 4, "four");
-       array_insert(a, 1029, "one thousand twenty-nine");
-       array_insert(a, 12, "twelve");
-       array_insert(a, 42, "forty-two");
-       print_array(a);
-       s = array_to_string (a, " ", 0);
-       printf("s = %s\n", s);
-       copy_of_a = array_from_string(s, " ");
-       printf("copy_of_a:");
-       print_array(copy_of_a);
-       array_dispose(copy_of_a);
-       printf("\n");
-       free(s);
-       ae = array_remove(a, 4);
-       array_dispose_element(ae);
-       ae = array_remove(a, 1029);
-       array_dispose_element(ae);
-       array_insert(a, 16, "sixteen");
-       print_array(a);
-       s = array_to_string (a, " ", 0);
-       printf("s = %s\n", s);
-       copy_of_a = array_from_string(s, " ");
-       printf("copy_of_a:");
-       print_array(copy_of_a);
-       array_dispose(copy_of_a);
-       printf("\n");
-       free(s);
-       array_insert(a, 2, "two");
-       array_insert(a, 1029, "new one thousand twenty-nine");
-       array_insert(a, 0, "zero");
-       array_insert(a, 134, "");
-       print_array(a);
-       s = array_to_string (a, ":", 0);
-       printf("s = %s\n", s);
-       copy_of_a = array_from_string(s, ":");
-       printf("copy_of_a:");
-       print_array(copy_of_a);
-       array_dispose(copy_of_a);
-       printf("\n");
-       free(s);
-       new_a = array_copy(a);
-       print_array(new_a);
-       s = array_to_string (new_a, ":", 0);
-       printf("s = %s\n", s);
-       copy_of_a = array_from_string(s, ":");
-       free(s);
-       printf("copy_of_a:");
-       print_array(copy_of_a);
-       array_shift(copy_of_a, 2, AS_DISPOSE);
-       printf("copy_of_a shifted by two:");
-       print_array(copy_of_a);
-       ae = array_shift(copy_of_a, 2, 0);
-       printf("copy_of_a shifted by two:");
-       print_array(copy_of_a);
-       for ( ; ae; ) {
-               aew = element_forw(ae);
-               array_dispose_element(ae);
-               ae = aew;
-       }
-       array_rshift(copy_of_a, 1, (char *)0);
-       printf("copy_of_a rshift by 1:");
-       print_array(copy_of_a);
-       array_rshift(copy_of_a, 2, "new element zero");
-       printf("copy_of_a rshift again by 2 with new element zero:");
-       print_array(copy_of_a);
-       s = array_to_assign(copy_of_a, 0);
-       printf("copy_of_a=%s\n", s);
-       free(s);
-       ae = array_shift(copy_of_a, array_num_elements(copy_of_a), 0);
-       for ( ; ae; ) {
-               aew = element_forw(ae);
-               array_dispose_element(ae);
-               ae = aew;
-       }
-       array_dispose(copy_of_a);
-       printf("\n");
-       array_dispose(a);
-       array_dispose(new_a);
-}
-
-#endif /* TEST_ARRAY */
-#endif /* ARRAY_VARS */
diff --git a/array.h~ b/array.h~
deleted file mode 100644 (file)
index 1080fc9..0000000
--- a/array.h~
+++ /dev/null
@@ -1,118 +0,0 @@
-/* array.h -- definitions for the interface exported by array.c that allows
-   the rest of the shell to manipulate array variables. */
-
-/* Copyright (C) 1997-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/>.
-*/
-
-
-#ifndef _ARRAY_H_
-#define _ARRAY_H_
-
-#include "stdc.h"
-
-typedef intmax_t       arrayind_t;
-
-enum atype {array_indexed, array_assoc};
-
-typedef struct array {
-       enum atype      type;
-       arrayind_t      max_index, num_elements;
-       struct array_element *head;
-} ARRAY;
-
-typedef struct array_element {
-       arrayind_t      ind;
-       char    *value;
-       struct array_element *next, *prev;
-} ARRAY_ELEMENT;
-
-typedef int sh_ae_map_func_t __P((ARRAY_ELEMENT *, void *));
-
-/* Basic operations on entire arrays */
-extern ARRAY   *array_create __P((void));
-extern void    array_flush __P((ARRAY *));
-extern void    array_dispose __P((ARRAY *));
-extern ARRAY   *array_copy __P((ARRAY *));
-extern ARRAY   *array_slice __P((ARRAY *, ARRAY_ELEMENT *, ARRAY_ELEMENT *));
-extern void    array_walk __P((ARRAY   *, sh_ae_map_func_t *, void *));
-
-extern ARRAY_ELEMENT *array_shift __P((ARRAY *, int, int));
-extern int     array_rshift __P((ARRAY *, int, char *));
-extern ARRAY_ELEMENT *array_unshift_element __P((ARRAY *));
-extern int     array_shift_element __P((ARRAY *, char *));
-
-extern ARRAY   *array_quote __P((ARRAY *));
-extern ARRAY   *array_quote_escapes __P((ARRAY *));
-extern ARRAY   *array_dequote __P((ARRAY *));
-extern ARRAY   *array_dequote_escapes __P((ARRAY *));
-extern ARRAY   *array_remove_quoted_nulls __P((ARRAY *));
-
-extern char    *array_subrange __P((ARRAY *, arrayind_t, arrayind_t, int, int));
-extern char    *array_patsub __P((ARRAY *, char *, char *, int));
-extern char    *array_modcase __P((ARRAY *, char *, int, int));
-
-/* Basic operations on array elements. */
-extern ARRAY_ELEMENT *array_create_element __P((arrayind_t, char *));
-extern ARRAY_ELEMENT *array_copy_element __P((ARRAY_ELEMENT *));
-extern void    array_dispose_element __P((ARRAY_ELEMENT *));
-
-extern int     array_insert __P((ARRAY *, arrayind_t, char *));
-extern ARRAY_ELEMENT *array_remove __P((ARRAY *, arrayind_t));
-extern char    *array_reference __P((ARRAY *, arrayind_t));
-
-/* Converting to and from arrays */
-extern WORD_LIST *array_to_word_list __P((ARRAY *));
-extern ARRAY *array_from_word_list __P((WORD_LIST *));
-extern WORD_LIST *array_keys_to_word_list __P((ARRAY *));
-
-extern ARRAY *array_assign_list __P((ARRAY *, WORD_LIST *));
-
-extern char **array_to_argv __P((ARRAY *));
-
-extern char *array_to_assign __P((ARRAY *, int));
-extern char *array_to_string __P((ARRAY *, char *, int));
-extern ARRAY *array_from_string __P((char *, char *));
-
-/* Flags for array_shift */
-#define AS_DISPOSE     0x01
-
-#define array_num_elements(a)  ((a)->num_elements)
-#define array_max_index(a)     ((a)->max_index)
-#define array_head(a)          ((a)->head)
-#define array_empty(a)         ((a)->num_elements == 0)
-
-#define element_value(ae)      ((ae)->value)
-#define element_index(ae)      ((ae)->ind)
-#define element_forw(ae)       ((ae)->next)
-#define element_back(ae)       ((ae)->prev)
-
-/* Convenience */
-#define array_push(a,v)        \
-  do { array_rshift ((a), 1, (v)); } while (0)
-#define array_pop(a) \
-  do { array_dispose_element (array_shift ((a), 1, 0)); } while (0)
-
-#define GET_ARRAY_FROM_VAR(n, v, a) \
-  do { \
-    (v) = find_variable (n); \
-    (a) = ((v) && array_p ((v))) ? array_cell (v) : (ARRAY *)0; \
-  } while (0)
-
-#define ALL_ELEMENT_SUB(c)     ((c) == '@' || (c) == '*')
-
-#endif /* _ARRAY_H_ */
diff --git a/arrayfunc.c.save b/arrayfunc.c.save
deleted file mode 100644 (file)
index dde33c6..0000000
+++ /dev/null
@@ -1,998 +0,0 @@
-/* arrayfunc.c -- High-level array functions used by other parts of the shell. */
-
-/* Copyright (C) 2001-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/>.
-*/
-
-#include "config.h"
-
-#if defined (ARRAY_VARS)
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-#include <stdio.h>
-
-#include "bashintl.h"
-
-#include "shell.h"
-#include "pathexp.h"
-
-#include "shmbutil.h"
-
-#include "builtins/common.h"
-
-extern char *this_command_name;
-extern int last_command_exit_value;
-extern int array_needs_making;
-
-static SHELL_VAR *bind_array_var_internal __P((SHELL_VAR *, arrayind_t, char *, char *, int));
-
-static char *quote_assign __P((const char *));
-static void quote_array_assignment_chars __P((WORD_LIST *));
-static char *array_value_internal __P((char *, int, int, int *));
-
-/* Standard error message to use when encountering an invalid array subscript */
-const char * const bash_badsub_errmsg = N_("bad array subscript");
-
-/* **************************************************************** */
-/*                                                                 */
-/*  Functions to manipulate array variables and perform assignments */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Convert a shell variable to an array variable.  The original value is
-   saved as array[0]. */
-SHELL_VAR *
-convert_var_to_array (var)
-     SHELL_VAR *var;
-{
-  char *oldval;
-  ARRAY *array;
-
-  oldval = value_cell (var);
-  array = array_create ();
-  if (oldval)
-    array_insert (array, 0, oldval);
-
-  FREE (value_cell (var));
-  var_setarray (var, array);
-
-  /* these aren't valid anymore */
-  var->dynamic_value = (sh_var_value_func_t *)NULL;
-  var->assign_func = (sh_var_assign_func_t *)NULL;
-
-  INVALIDATE_EXPORTSTR (var);
-  if (exported_p (var))
-    array_needs_making++;
-
-  VSETATTR (var, att_array);
-  VUNSETATTR (var, att_invisible);
-
-  return var;
-}
-
-/* Convert a shell variable to an array variable.  The original value is
-   saved as array[0]. */
-SHELL_VAR *
-convert_var_to_assoc (var)
-     SHELL_VAR *var;
-{
-  char *oldval;
-  HASH_TABLE *hash;
-
-  oldval = value_cell (var);
-  hash = assoc_create (0);
-  if (oldval)
-    assoc_insert (hash, "0", oldval);
-
-  FREE (value_cell (var));
-  var_setassoc (var, hash);
-
-  /* these aren't valid anymore */
-  var->dynamic_value = (sh_var_value_func_t *)NULL;
-  var->assign_func = (sh_var_assign_func_t *)NULL;
-
-  INVALIDATE_EXPORTSTR (var);
-  if (exported_p (var))
-    array_needs_making++;
-
-  VSETATTR (var, att_assoc);
-  VUNSETATTR (var, att_invisible);
-
-  return var;
-}
-
-static SHELL_VAR *
-bind_array_var_internal (entry, ind, key, value, flags)
-     SHELL_VAR *entry;
-     arrayind_t ind;
-     char *key;
-     char *value;
-     int flags;
-{
-  SHELL_VAR *dentry;
-  char *newval;
-
-  /* If we're appending, we need the old value of the array reference, so
-     fake out make_variable_value with a dummy SHELL_VAR */
-  if (flags & ASS_APPEND)
-    {
-      dentry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
-      dentry->name = savestring (entry->name);
-      if (assoc_p (entry))
-       newval = assoc_reference (assoc_cell (entry), key);
-      else
-       newval = array_reference (array_cell (entry), ind);
-      if (newval)
-       dentry->value = savestring (newval);
-      else
-       {
-         dentry->value = (char *)xmalloc (1);
-         dentry->value[0] = '\0';
-       }
-      dentry->exportstr = 0;
-      dentry->attributes = entry->attributes & ~(att_array|att_assoc|att_exported);
-      /* Leave the rest of the members uninitialized; the code doesn't look
-        at them. */
-      newval = make_variable_value (dentry, value, flags);      
-      dispose_variable (dentry);
-    }
-  else
-    newval = make_variable_value (entry, value, flags);
-
-  if (entry->assign_func)
-    (*entry->assign_func) (entry, newval, ind, key);
-  else if (assoc_p (entry))
-    assoc_insert (assoc_cell (entry), key, newval);
-  else
-    array_insert (array_cell (entry), ind, newval);
-  FREE (newval);
-
-  return (entry);
-}
-
-/* Perform an array assignment name[ind]=value.  If NAME already exists and
-   is not an array, and IND is 0, perform name=value instead.  If NAME exists
-   and is not an array, and IND is not 0, convert it into an array with the
-   existing value as name[0].
-
-   If NAME does not exist, just create an array variable, no matter what
-   IND's value may be. */
-SHELL_VAR *
-bind_array_variable (name, ind, value, flags)
-     char *name;
-     arrayind_t ind;
-     char *value;
-     int flags;
-{
-  SHELL_VAR *entry;
-
-  entry = var_lookup (name, shell_variables);
-
-  if (entry == (SHELL_VAR *) 0)
-    entry = make_new_array_variable (name);
-  else if (readonly_p (entry) || noassign_p (entry))
-    {
-      if (readonly_p (entry))
-       err_readonly (name);
-      return (entry);
-    }
-  else if (array_p (entry) == 0)
-    entry = convert_var_to_array (entry);
-
-  /* ENTRY is an array variable, and ARRAY points to the value. */
-  return (bind_array_var_internal (entry, ind, 0, value, flags));
-}
-
-SHELL_VAR *
-bind_array_element (entry, ind, value, flags)
-     SHELL_VAR *entry;
-     arrayind_t ind;
-     char *value;
-     int flags;
-{
-  return (bind_array_var_internal (entry, ind, 0, value, flags));
-}
-                    
-SHELL_VAR *
-bind_assoc_variable (entry, name, key, value, flags)
-     SHELL_VAR *entry;
-     char *name;
-     char *key;
-     char *value;
-     int flags;
-{
-  SHELL_VAR *dentry;
-  char *newval;
-
-  if (readonly_p (entry) || noassign_p (entry))
-    {
-      if (readonly_p (entry))
-       err_readonly (name);
-      return (entry);
-    }
-
-  return (bind_array_var_internal (entry, 0, key, value, flags));
-}
-
-/* Parse NAME, a lhs of an assignment statement of the form v[s], and
-   assign VALUE to that array element by calling bind_array_variable(). */
-SHELL_VAR *
-assign_array_element (name, value, flags)
-     char *name, *value;
-     int flags;
-{
-  char *sub, *vname, *akey;
-  arrayind_t ind;
-  int sublen;
-  SHELL_VAR *entry;
-
-  vname = array_variable_name (name, &sub, &sublen);
-
-  if (vname == 0)
-    return ((SHELL_VAR *)NULL);
-
-  if ((ALL_ELEMENT_SUB (sub[0]) && sub[1] == ']') || (sublen <= 1))
-    {
-      free (vname);
-      err_badarraysub (name);
-      return ((SHELL_VAR *)NULL);
-    }
-
-  entry = find_variable (vname);
-
-  if (entry && assoc_p (entry))
-    {
-      sub[sublen-1] = '\0';
-      akey = expand_assignment_string_to_string (sub, 0);      /* [ */
-      sub[sublen-1] = ']';
-      if (akey == 0 || *akey == 0)
-       {
-         free (vname);
-         err_badarraysub (name);
-         return ((SHELL_VAR *)NULL);
-       }
-      entry = bind_assoc_variable (entry, vname, akey, value, flags);
-    }
-  else
-    {
-      ind = array_expand_index (sub, sublen);
-      if (ind < 0)
-       {
-         free (vname);
-         err_badarraysub (name);
-         return ((SHELL_VAR *)NULL);
-       }
-      entry = bind_array_variable (vname, ind, value, flags);
-    }
-
-  free (vname);
-  return (entry);
-}
-
-/* Find the array variable corresponding to NAME.  If there is no variable,
-   create a new array variable.  If the variable exists but is not an array,
-   convert it to an indexed array.  If FLAGS&1 is non-zero, an existing
-   variable is checked for the readonly or noassign attribute in preparation
-   for assignment (e.g., by the `read' builtin).  If FLAGS&2 is non-zero, we
-   create an associative array. */
-SHELL_VAR *
-find_or_make_array_variable (name, flags)
-     char *name;
-     int flags;
-{
-  SHELL_VAR *var;
-
-  var = find_variable (name);
-
-  if (var == 0)
-    var = (flags & 2) ? make_new_assoc_variable (name) : make_new_array_variable (name);
-  else if ((flags & 1) && (readonly_p (var) || noassign_p (var)))
-    {
-      if (readonly_p (var))
-       err_readonly (name);
-      return ((SHELL_VAR *)NULL);
-    }
-  else if ((flags & 2) && array_p (var))
-    {
-      report_error (_("%s: cannot convert indexed to associative array"), name);
-      return ((SHELL_VAR *)NULL);
-    }
-  else if (array_p (var) == 0 && assoc_p (var) == 0)
-    var = convert_var_to_array (var);
-
-  return (var);
-}
-  
-/* Perform a compound assignment statement for array NAME, where VALUE is
-   the text between the parens:  NAME=( VALUE ) */
-SHELL_VAR *
-assign_array_from_string (name, value, flags)
-     char *name, *value;
-     int flags;
-{
-  SHELL_VAR *var;
-  int vflags;
-
-  vflags = 1;
-  if (flags & ASS_MKASSOC)
-    vflags |= 2;
-
-  var = find_or_make_array_variable (name, vflags);
-  if (var == 0)
-    return ((SHELL_VAR *)NULL);
-
-  return (assign_array_var_from_string (var, value, flags));
-}
-
-/* Sequentially assign the indices of indexed array variable VAR from the
-   words in LIST. */
-SHELL_VAR *
-assign_array_var_from_word_list (var, list, flags)
-     SHELL_VAR *var;
-     WORD_LIST *list;
-     int flags;
-{
-  register arrayind_t i;
-  register WORD_LIST *l;
-  ARRAY *a;
-
-  a = array_cell (var);
-  i = (flags & ASS_APPEND) ? array_max_index (a) + 1 : 0;
-
-  for (l = list; l; l = l->next, i++)
-    if (var->assign_func)
-      (*var->assign_func) (var, l->word->word, i, 0);
-    else
-      array_insert (a, i, l->word->word);
-  return var;
-}
-
-WORD_LIST *
-expand_compound_array_assignment (var, value, flags)
-     SHELL_VAR *var;
-     char *value;
-     int flags;
-{
-  WORD_LIST *list, *nlist;
-  char *val;
-  int ni;
-
-  /* I don't believe this condition is ever true any more. */
-  if (*value == '(')   /*)*/
-    {
-      ni = 1;
-      val = extract_array_assignment_list (value, &ni);
-      if (val == 0)
-       return (WORD_LIST *)NULL;
-    }
-  else
-    val = value;
-
-  /* Expand the value string into a list of words, performing all the
-     shell expansions including pathname generation and word splitting. */
-  /* First we split the string on whitespace, using the shell parser
-     (ksh93 seems to do this). */
-  list = parse_string_to_word_list (val, 1, "array assign");
-
-  /* If we're using [subscript]=value, we need to quote each [ and ] to
-     prevent unwanted filename expansion. */
-  if (list)
-    quote_array_assignment_chars (list);
-
-  /* Now that we've split it, perform the shell expansions on each
-     word in the list. */
-  nlist = list ? expand_words_no_vars (list) : (WORD_LIST *)NULL;
-
-  dispose_words (list);
-
-  if (val != value)
-    free (val);
-
-  return nlist;
-}
-
-void
-assign_compound_array_list (var, nlist, flags)
-     SHELL_VAR *var;
-     WORD_LIST *nlist;
-     int flags;
-{
-  ARRAY *a;
-  HASH_TABLE *h;
-  WORD_LIST *list;
-  char *w, *val, *nval;
-  int len, iflags;
-  arrayind_t ind, last_ind;
-  char *akey;
-
-  a = (var && array_p (var)) ? array_cell (var) : (ARRAY *)0;
-  h = (var && assoc_p (var)) ? assoc_cell (var) : (HASH_TABLE *)0;
-
-  akey = (char *)0;
-  ind = 0;
-
-  /* Now that we are ready to assign values to the array, kill the existing
-     value. */
-  if ((flags & ASS_APPEND) == 0)
-    {
-      if (array_p (var) && a)
-       array_flush (a);
-      else if (assoc_p (var) && h)
-       assoc_flush (h);
-    }
-
-  last_ind = (a && (flags & ASS_APPEND)) ? array_max_index (a) + 1 : 0;
-
-  for (list = nlist; list; list = list->next)
-    {
-      iflags = flags;
-      w = list->word->word;
-
-      /* We have a word of the form [ind]=value */
-      if ((list->word->flags & W_ASSIGNMENT) && w[0] == '[')
-       {
-         len = skipsubscript (w, 0);
-
-         /* XXX - changes for `+=' */
-         if (w[len] != ']' || (w[len+1] != '=' && (w[len+1] != '+' || w[len+2] != '=')))
-           {
-             if (assoc_p (var))
-               {
-                 err_badarraysub (w);
-                 continue;
-               }
-             nval = make_variable_value (var, w, flags);
-             if (var->assign_func)
-               (*var->assign_func) (var, nval, last_ind, 0);
-             else
-               array_insert (a, last_ind, nval);
-             FREE (nval);
-             last_ind++;
-             continue;
-           }
-
-         if (len == 1)
-           {
-             err_badarraysub (w);
-             continue;
-           }
-
-         if (ALL_ELEMENT_SUB (w[1]) && len == 2)
-           {
-             if (assoc_p (var))
-               report_error (_("%s: invalid associative array key"), w);
-             else
-               report_error (_("%s: cannot assign to non-numeric index"), w);
-             continue;
-           }
-
-         if (array_p (var))
-           {
-             ind = array_expand_index (w + 1, len);
-             if (ind < 0)
-               {
-                 err_badarraysub (w);
-                 continue;
-               }
-
-             last_ind = ind;
-           }
-         else if (assoc_p (var))
-           {
-             akey = substring (w, 1, len);
-             if (akey == 0 || *akey == 0)
-               {
-                 err_badarraysub (w);
-                 continue;
-               }
-           }
-
-         /* XXX - changes for `+=' -- just accept the syntax.  ksh93 doesn't do this */
-         if (w[len + 1] == '+' && w[len + 2] == '=')
-           {
-             iflags |= ASS_APPEND;
-             val = w + len + 3;
-           }
-         else
-           val = w + len + 2;
-       }
-      else if (assoc_p (var))
-       {
-         report_error (_("%s: %s: must use subscript when assigning associative array"), var->name, w);
-         continue;
-       }
-      else             /* No [ind]=value, just a stray `=' */
-       {
-         ind = last_ind;
-         val = w;
-       }
-
-      if (integer_p (var))
-       this_command_name = (char *)NULL;       /* no command name for errors */
-      bind_array_var_internal (var, ind, akey, val, iflags);
-      last_ind++;
-    }
-}
-
-/* Perform a compound array assignment:  VAR->name=( VALUE ).  The
-   VALUE has already had the parentheses stripped. */
-SHELL_VAR *
-assign_array_var_from_string (var, value, flags)
-     SHELL_VAR *var;
-     char *value;
-     int flags;
-{
-  WORD_LIST *nlist;
-
-  if (value == 0)
-    return var;
-
-  nlist = expand_compound_array_assignment (var, value, flags);
-  assign_compound_array_list (var, nlist, flags);
-
-  if (nlist)
-    dispose_words (nlist);
-  return (var);
-}
-
-/* Quote globbing chars and characters in $IFS before the `=' in an assignment
-   statement (usually a compound array assignment) to protect them from
-   unwanted filename expansion or word splitting. */
-static char *
-quote_assign (string)
-     const char *string;
-{
-  size_t slen;
-  int saw_eq;
-  char *temp, *t;
-  const char *s, *send;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string);
-  send = string + slen;
-
-  t = temp = (char *)xmalloc (slen * 2 + 1);
-  saw_eq = 0;
-  for (s = string; *s; )
-    {
-      if (*s == '=')
-       saw_eq = 1;
-      if (saw_eq == 0 && (glob_char_p (s) || isifs (*s)))
-       *t++ = '\\';
-
-      COPY_CHAR_P (t, s, send);
-    }
-  *t = '\0';
-  return temp;
-}
-
-/* For each word in a compound array assignment, if the word looks like
-   [ind]=value, quote globbing chars and characters in $IFS before the `='. */
-static void
-quote_array_assignment_chars (list)
-     WORD_LIST *list;
-{
-  char *nword;
-  WORD_LIST *l;
-
-  for (l = list; l; l = l->next)
-    {
-      if (l->word == 0 || l->word->word == 0 || l->word->word[0] == '\0')
-       continue;       /* should not happen, but just in case... */
-      /* Don't bother if it doesn't look like [ind]=value */
-      if (l->word->word[0] != '[' || mbschr (l->word->word, '=') == 0) /* ] */
-       continue;
-      nword = quote_assign (l->word->word);
-      free (l->word->word);
-      l->word->word = nword;
-    }
-}
-
-/* skipsubscript moved to subst.c to use private functions. 2009/02/24. */
-
-/* This function is called with SUB pointing to just after the beginning
-   `[' of an array subscript and removes the array element to which SUB
-   expands from array VAR.  A subscript of `*' or `@' unsets the array. */
-int
-unbind_array_element (var, sub)
-     SHELL_VAR *var;
-     char *sub;
-{
-  int len;
-  arrayind_t ind;
-  char *akey;
-  ARRAY_ELEMENT *ae;
-
-  len = skipsubscript (sub, 0);
-  if (sub[len] != ']' || len == 0)
-    {
-      builtin_error ("%s[%s: %s", var->name, sub, _(bash_badsub_errmsg));
-      return -1;
-    }
-  sub[len] = '\0';
-
-  if (ALL_ELEMENT_SUB (sub[0]) && sub[1] == 0)
-    {
-      unbind_variable (var->name);
-      return (0);
-    }
-
-  if (assoc_p (var))
-    {
-      akey = expand_assignment_string_to_string (sub, 0);     /* [ */
-      if (akey == 0 || *akey == 0)
-       {
-         builtin_error ("[%s]: %s", sub, _(bash_badsub_errmsg));
-         return -1;
-       }
-      assoc_remove (assoc_cell (var), akey);
-    }
-  else
-    {
-      ind = array_expand_index (sub, len+1);
-      if (ind < 0)
-       {
-         builtin_error ("[%s]: %s", sub, _(bash_badsub_errmsg));
-         return -1;
-       }
-      ae = array_remove (array_cell (var), ind);
-      if (ae)
-       array_dispose_element (ae);
-    }
-
-  return 0;
-}
-
-/* Format and output an array assignment in compound form VAR=(VALUES),
-   suitable for re-use as input. */
-void
-print_array_assignment (var, quoted)
-     SHELL_VAR *var;
-     int quoted;
-{
-  char *vstr;
-
-  vstr = array_to_assign (array_cell (var), quoted);
-
-  if (vstr == 0)
-    printf ("%s=%s\n", var->name, quoted ? "'()'" : "()");
-  else
-    {
-      printf ("%s=%s\n", var->name, vstr);
-      free (vstr);
-    }
-}
-
-/* Format and output an associative array assignment in compound form
-   VAR=(VALUES), suitable for re-use as input. */
-void
-print_assoc_assignment (var, quoted)
-     SHELL_VAR *var;
-     int quoted;
-{
-  char *vstr;
-
-  vstr = assoc_to_assign (assoc_cell (var), quoted);
-
-  if (vstr == 0)
-    printf ("%s=%s\n", var->name, quoted ? "'()'" : "()");
-  else
-    {
-      printf ("%s=%s\n", var->name, vstr);
-      free (vstr);
-    }
-}
-
-/***********************************************************************/
-/*                                                                    */
-/* Utility functions to manage arrays and their contents for expansion */
-/*                                                                    */
-/***********************************************************************/
-
-/* Return 1 if NAME is a properly-formed array reference v[sub]. */
-int
-valid_array_reference (name)
-     char *name;
-{
-  char *t;
-  int r, len;
-
-  t = mbschr (name, '[');      /* ] */
-  if (t)
-    {
-      *t = '\0';
-      r = legal_identifier (name);
-      *t = '[';
-      if (r == 0)
-       return 0;
-      /* Check for a properly-terminated non-blank subscript. */
-      len = skipsubscript (t, 0);
-      if (t[len] != ']' || len == 1)
-       return 0;
-      for (r = 1; r < len; r++)
-       if (whitespace (t[r]) == 0)
-         return 1;
-      return 0;
-    }
-  return 0;
-}
-
-/* Expand the array index beginning at S and extending LEN characters. */
-arrayind_t
-array_expand_index (s, len)
-     char *s;
-     int len;
-{
-  char *exp, *t;
-  int expok;
-  arrayind_t val;
-
-  exp = (char *)xmalloc (len);
-  strncpy (exp, s, len - 1);
-  exp[len - 1] = '\0';
-  t = expand_arith_string (exp, 0);
-  this_command_name = (char *)NULL;
-  val = evalexp (t, &expok);
-  free (t);
-  free (exp);
-  if (expok == 0)
-    {
-      last_command_exit_value = EXECUTION_FAILURE;
-
-      top_level_cleanup ();      
-      jump_to_top_level (DISCARD);
-    }
-  return val;
-}
-
-/* Return the name of the variable specified by S without any subscript.
-   If SUBP is non-null, return a pointer to the start of the subscript
-   in *SUBP. If LENP is non-null, the length of the subscript is returned
-   in *LENP.  This returns newly-allocated memory. */
-char *
-array_variable_name (s, subp, lenp)
-     char *s, **subp;
-     int *lenp;
-{
-  char *t, *ret;
-  int ind, ni;
-
-  t = mbschr (s, '[');
-  if (t == 0)
-    {
-      if (subp)
-       *subp = t;
-      if (lenp)
-       *lenp = 0;
-      return ((char *)NULL);
-    }
-  ind = t - s;
-  ni = skipsubscript (s, ind);
-  if (ni <= ind + 1 || s[ni] != ']')
-    {
-      err_badarraysub (s);
-      if (subp)
-       *subp = t;
-      if (lenp)
-       *lenp = 0;
-      return ((char *)NULL);
-    }
-
-  *t = '\0';
-  ret = savestring (s);
-  *t++ = '[';          /* ] */
-
-  if (subp)
-    *subp = t;
-  if (lenp)
-    *lenp = ni - ind;
-
-  return ret;
-}
-
-/* Return the variable specified by S without any subscript.  If SUBP is
-   non-null, return a pointer to the start of the subscript in *SUBP.
-   If LENP is non-null, the length of the subscript is returned in *LENP. */
-SHELL_VAR *
-array_variable_part (s, subp, lenp)
-     char *s, **subp;
-     int *lenp;
-{
-  char *t;
-  SHELL_VAR *var;
-
-  t = array_variable_name (s, subp, lenp);
-  if (t == 0)
-    return ((SHELL_VAR *)NULL);
-  var = find_variable (t);
-
-  free (t);
-  return (var == 0 || invisible_p (var)) ? (SHELL_VAR *)0 : var;
-}
-
-/* Return a string containing the elements in the array and subscript
-   described by S.  If the subscript is * or @, obeys quoting rules akin
-   to the expansion of $* and $@ including double quoting.  If RTYPE
-   is non-null it gets 1 if the array reference is name[*], 2 if the
-   reference is name[@], and 0 otherwise. */
-static char *
-array_value_internal (s, quoted, allow_all, rtype)
-     char *s;
-     int quoted, allow_all, *rtype;
-{
-  int len;
-  arrayind_t ind;
-  char *akey;
-  char *retval, *t, *temp;
-  WORD_LIST *l;
-  SHELL_VAR *var;
-
-  var = array_variable_part (s, &t, &len);
-
-  /* Expand the index, even if the variable doesn't exist, in case side
-     effects are needed, like ${w[i++]} where w is unset. */
-#if 0
-  if (var == 0)
-    return (char *)NULL;
-#endif
-
-  if (len == 0)
-    return ((char *)NULL);     /* error message already printed */
-
-  /* [ */
-  if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']')
-    {
-      if (rtype)
-       *rtype = (t[0] == '*') ? 1 : 2;
-      if (allow_all == 0)
-       {
-         err_badarraysub (s);
-         return ((char *)NULL);
-       }
-      else if (var == 0 || value_cell (var) == 0)
-       return ((char *)NULL);
-      else if (array_p (var) == 0 && assoc_p (var) == 0)
-       l = add_string_to_list (value_cell (var), (WORD_LIST *)NULL);
-      else if (assoc_p (var))
-       {
-         l = assoc_to_word_list (assoc_cell (var));
-         if (l == (WORD_LIST *)NULL)
-           return ((char *)NULL);
-       }
-      else
-       {
-         l = array_to_word_list (array_cell (var));
-         if (l == (WORD_LIST *)NULL)
-           return ((char *) NULL);
-       }
-
-      if (t[0] == '*' && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-       {
-         temp = string_list_dollar_star (l);
-         retval = quote_string (temp);
-         free (temp);
-       }
-      else     /* ${name[@]} or unquoted ${name[*]} */
-       retval = string_list_dollar_at (l, quoted);
-
-      dispose_words (l);
-    }
-  else
-    {
-      if (rtype)
-       *rtype = 0;
-      if (var == 0 || array_p (var) || assoc_p (var) == 0)
-       {
-         ind = array_expand_index (t, len);
-         if (ind < 0)
-           {
-index_error:
-             if (var)
-               err_badarraysub (var->name);
-             else
-               {
-                 t[-1] = '\0';
-                 err_badarraysub (s);
-                 t[-1] = '[';  /* ] */
-               }
-             return ((char *)NULL);
-           }
-       }
-      else if (assoc_p (var))
-       {
-         t[len - 1] = '\0';
-         akey = expand_assignment_string_to_string (t, 0);     /* [ */
-         t[len - 1] = ']';
-         if (akey == 0 || *akey == 0)
-           goto index_error;
-       }
-     
-      if (var == 0)
-       return ((char *)NULL);
-      if (array_p (var) == 0 && assoc_p (var) == 0)
-       return (ind == 0 ? value_cell (var) : (char *)NULL);
-      else if (assoc_p (var))
-       retval = assoc_reference (assoc_cell (var), akey);
-      else
-       retval = array_reference (array_cell (var), ind);
-    }
-
-  return retval;
-}
-
-/* Return a string containing the elements described by the array and
-   subscript contained in S, obeying quoting for subscripts * and @. */
-char *
-array_value (s, quoted, rtype)
-     char *s;
-     int quoted, *rtype;
-{
-  return (array_value_internal (s, quoted, 1, rtype));
-}
-
-/* Return the value of the array indexing expression S as a single string.
-   If ALLOW_ALL is 0, do not allow `@' and `*' subscripts.  This is used
-   by other parts of the shell such as the arithmetic expression evaluator
-   in expr.c. */
-char *
-get_array_value (s, allow_all, rtype)
-     char *s;
-     int allow_all, *rtype;
-{
-  return (array_value_internal (s, 0, allow_all, rtype));
-}
-
-char *
-array_keys (s, quoted)
-     char *s;
-     int quoted;
-{
-  int len;
-  char *retval, *t, *temp;
-  WORD_LIST *l;
-  SHELL_VAR *var;
-
-  var = array_variable_part (s, &t, &len);
-
-  /* [ */
-  if (var == 0 || ALL_ELEMENT_SUB (t[0]) == 0 || t[1] != ']')
-    return (char *)NULL;
-
-  if (array_p (var) == 0 && assoc_p (var) == 0)
-    l = add_string_to_list ("0", (WORD_LIST *)NULL);
-  else if (assoc_p (var))
-    l = assoc_keys_to_word_list (assoc_cell (var));
-  else
-    l = array_keys_to_word_list (array_cell (var));
-  if (l == (WORD_LIST *)NULL)
-    return ((char *) NULL);
-
-  if (t[0] == '*' && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-    {
-      temp = string_list_dollar_star (l);
-      retval = quote_string (temp);
-      free (temp);
-    }
-  else /* ${!name[@]} or unquoted ${!name[*]} */
-    retval = string_list_dollar_at (l, quoted);
-
-  dispose_words (l);
-  return retval;
-}
-#endif /* ARRAY_VARS */
diff --git a/arrayfunc.c~ b/arrayfunc.c~
deleted file mode 100644 (file)
index 06e40a5..0000000
+++ /dev/null
@@ -1,1013 +0,0 @@
-/* arrayfunc.c -- High-level array functions used by other parts of the shell. */
-
-/* Copyright (C) 2001-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/>.
-*/
-
-#include "config.h"
-
-#if defined (ARRAY_VARS)
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-#include <stdio.h>
-
-#include "bashintl.h"
-
-#include "shell.h"
-#include "pathexp.h"
-
-#include "shmbutil.h"
-
-#include "builtins/common.h"
-
-extern char *this_command_name;
-extern int last_command_exit_value;
-extern int array_needs_making;
-
-static SHELL_VAR *bind_array_var_internal __P((SHELL_VAR *, arrayind_t, char *, char *, int));
-
-static char *quote_assign __P((const char *));
-static void quote_array_assignment_chars __P((WORD_LIST *));
-static char *array_value_internal __P((char *, int, int, int *));
-
-/* Standard error message to use when encountering an invalid array subscript */
-const char * const bash_badsub_errmsg = N_("bad array subscript");
-
-/* **************************************************************** */
-/*                                                                 */
-/*  Functions to manipulate array variables and perform assignments */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Convert a shell variable to an array variable.  The original value is
-   saved as array[0]. */
-SHELL_VAR *
-convert_var_to_array (var)
-     SHELL_VAR *var;
-{
-  char *oldval;
-  ARRAY *array;
-
-  oldval = value_cell (var);
-  array = array_create ();
-  if (oldval)
-    array_insert (array, 0, oldval);
-
-  FREE (value_cell (var));
-  var_setarray (var, array);
-
-  /* these aren't valid anymore */
-  var->dynamic_value = (sh_var_value_func_t *)NULL;
-  var->assign_func = (sh_var_assign_func_t *)NULL;
-
-  INVALIDATE_EXPORTSTR (var);
-  if (exported_p (var))
-    array_needs_making++;
-
-  VSETATTR (var, att_array);
-  VUNSETATTR (var, att_invisible);
-
-  return var;
-}
-
-/* Convert a shell variable to an array variable.  The original value is
-   saved as array[0]. */
-SHELL_VAR *
-convert_var_to_assoc (var)
-     SHELL_VAR *var;
-{
-  char *oldval;
-  HASH_TABLE *hash;
-
-  oldval = value_cell (var);
-  hash = assoc_create (0);
-  if (oldval)
-    assoc_insert (hash, savestring ("0"), oldval);
-
-  FREE (value_cell (var));
-  var_setassoc (var, hash);
-
-  /* these aren't valid anymore */
-  var->dynamic_value = (sh_var_value_func_t *)NULL;
-  var->assign_func = (sh_var_assign_func_t *)NULL;
-
-  INVALIDATE_EXPORTSTR (var);
-  if (exported_p (var))
-    array_needs_making++;
-
-  VSETATTR (var, att_assoc);
-  VUNSETATTR (var, att_invisible);
-
-  return var;
-}
-
-static SHELL_VAR *
-bind_array_var_internal (entry, ind, key, value, flags)
-     SHELL_VAR *entry;
-     arrayind_t ind;
-     char *key;
-     char *value;
-     int flags;
-{
-  SHELL_VAR *dentry;
-  char *newval;
-
-  /* If we're appending, we need the old value of the array reference, so
-     fake out make_variable_value with a dummy SHELL_VAR */
-  if (flags & ASS_APPEND)
-    {
-      dentry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
-      dentry->name = savestring (entry->name);
-      if (assoc_p (entry))
-       newval = assoc_reference (assoc_cell (entry), key);
-      else
-       newval = array_reference (array_cell (entry), ind);
-      if (newval)
-       dentry->value = savestring (newval);
-      else
-       {
-         dentry->value = (char *)xmalloc (1);
-         dentry->value[0] = '\0';
-       }
-      dentry->exportstr = 0;
-      dentry->attributes = entry->attributes & ~(att_array|att_assoc|att_exported);
-      /* Leave the rest of the members uninitialized; the code doesn't look
-        at them. */
-      newval = make_variable_value (dentry, value, flags);      
-      dispose_variable (dentry);
-    }
-  else
-    newval = make_variable_value (entry, value, flags);
-
-  if (entry->assign_func)
-    (*entry->assign_func) (entry, newval, ind, key);
-  else if (assoc_p (entry))
-    assoc_insert (assoc_cell (entry), key, newval);
-  else
-    array_insert (array_cell (entry), ind, newval);
-  FREE (newval);
-
-  return (entry);
-}
-
-/* Perform an array assignment name[ind]=value.  If NAME already exists and
-   is not an array, and IND is 0, perform name=value instead.  If NAME exists
-   and is not an array, and IND is not 0, convert it into an array with the
-   existing value as name[0].
-
-   If NAME does not exist, just create an array variable, no matter what
-   IND's value may be. */
-SHELL_VAR *
-bind_array_variable (name, ind, value, flags)
-     char *name;
-     arrayind_t ind;
-     char *value;
-     int flags;
-{
-  SHELL_VAR *entry;
-
-  entry = var_lookup (name, shell_variables);
-
-  if (entry == (SHELL_VAR *) 0)
-    entry = make_new_array_variable (name);
-  else if (readonly_p (entry) || noassign_p (entry))
-    {
-      if (readonly_p (entry))
-       err_readonly (name);
-      return (entry);
-    }
-  else if (array_p (entry) == 0)
-    entry = convert_var_to_array (entry);
-
-  /* ENTRY is an array variable, and ARRAY points to the value. */
-  return (bind_array_var_internal (entry, ind, 0, value, flags));
-}
-
-SHELL_VAR *
-bind_array_element (entry, ind, value, flags)
-     SHELL_VAR *entry;
-     arrayind_t ind;
-     char *value;
-     int flags;
-{
-  return (bind_array_var_internal (entry, ind, 0, value, flags));
-}
-                    
-SHELL_VAR *
-bind_assoc_variable (entry, name, key, value, flags)
-     SHELL_VAR *entry;
-     char *name;
-     char *key;
-     char *value;
-     int flags;
-{
-  SHELL_VAR *dentry;
-  char *newval;
-
-  if (readonly_p (entry) || noassign_p (entry))
-    {
-      if (readonly_p (entry))
-       err_readonly (name);
-      return (entry);
-    }
-
-  return (bind_array_var_internal (entry, 0, key, value, flags));
-}
-
-/* Parse NAME, a lhs of an assignment statement of the form v[s], and
-   assign VALUE to that array element by calling bind_array_variable(). */
-SHELL_VAR *
-assign_array_element (name, value, flags)
-     char *name, *value;
-     int flags;
-{
-  char *sub, *vname, *akey;
-  arrayind_t ind;
-  int sublen;
-  SHELL_VAR *entry;
-
-  vname = array_variable_name (name, &sub, &sublen);
-
-  if (vname == 0)
-    return ((SHELL_VAR *)NULL);
-
-  if ((ALL_ELEMENT_SUB (sub[0]) && sub[1] == ']') || (sublen <= 1))
-    {
-      free (vname);
-      err_badarraysub (name);
-      return ((SHELL_VAR *)NULL);
-    }
-
-  entry = find_variable (vname);
-
-  if (entry && assoc_p (entry))
-    {
-      sub[sublen-1] = '\0';
-      akey = expand_assignment_string_to_string (sub, 0);      /* [ */
-      sub[sublen-1] = ']';
-      if (akey == 0 || *akey == 0)
-       {
-         free (vname);
-         err_badarraysub (name);
-         return ((SHELL_VAR *)NULL);
-       }
-      entry = bind_assoc_variable (entry, vname, akey, value, flags);
-    }
-  else
-    {
-      ind = array_expand_index (sub, sublen);
-      if (ind < 0)
-       {
-         free (vname);
-         err_badarraysub (name);
-         return ((SHELL_VAR *)NULL);
-       }
-      entry = bind_array_variable (vname, ind, value, flags);
-    }
-
-  free (vname);
-  return (entry);
-}
-
-/* Find the array variable corresponding to NAME.  If there is no variable,
-   create a new array variable.  If the variable exists but is not an array,
-   convert it to an indexed array.  If FLAGS&1 is non-zero, an existing
-   variable is checked for the readonly or noassign attribute in preparation
-   for assignment (e.g., by the `read' builtin).  If FLAGS&2 is non-zero, we
-   create an associative array. */
-SHELL_VAR *
-find_or_make_array_variable (name, flags)
-     char *name;
-     int flags;
-{
-  SHELL_VAR *var;
-
-  var = find_variable (name);
-
-  if (var == 0)
-    var = (flags & 2) ? make_new_assoc_variable (name) : make_new_array_variable (name);
-  else if ((flags & 1) && (readonly_p (var) || noassign_p (var)))
-    {
-      if (readonly_p (var))
-       err_readonly (name);
-      return ((SHELL_VAR *)NULL);
-    }
-  else if ((flags & 2) && array_p (var))
-    {
-      report_error (_("%s: cannot convert indexed to associative array"), name);
-      return ((SHELL_VAR *)NULL);
-    }
-  else if (array_p (var) == 0 && assoc_p (var) == 0)
-    var = convert_var_to_array (var);
-
-  return (var);
-}
-  
-/* Perform a compound assignment statement for array NAME, where VALUE is
-   the text between the parens:  NAME=( VALUE ) */
-SHELL_VAR *
-assign_array_from_string (name, value, flags)
-     char *name, *value;
-     int flags;
-{
-  SHELL_VAR *var;
-  int vflags;
-
-  vflags = 1;
-  if (flags & ASS_MKASSOC)
-    vflags |= 2;
-
-  var = find_or_make_array_variable (name, vflags);
-  if (var == 0)
-    return ((SHELL_VAR *)NULL);
-
-  return (assign_array_var_from_string (var, value, flags));
-}
-
-/* Sequentially assign the indices of indexed array variable VAR from the
-   words in LIST. */
-SHELL_VAR *
-assign_array_var_from_word_list (var, list, flags)
-     SHELL_VAR *var;
-     WORD_LIST *list;
-     int flags;
-{
-  register arrayind_t i;
-  register WORD_LIST *l;
-  ARRAY *a;
-
-  a = array_cell (var);
-  i = (flags & ASS_APPEND) ? array_max_index (a) + 1 : 0;
-
-  for (l = list; l; l = l->next, i++)
-    if (var->assign_func)
-      (*var->assign_func) (var, l->word->word, i, 0);
-    else
-      array_insert (a, i, l->word->word);
-  return var;
-}
-
-WORD_LIST *
-expand_compound_array_assignment (var, value, flags)
-     SHELL_VAR *var;
-     char *value;
-     int flags;
-{
-  WORD_LIST *list, *nlist;
-  char *val;
-  int ni;
-
-  /* I don't believe this condition is ever true any more. */
-  if (*value == '(')   /*)*/
-    {
-      ni = 1;
-      val = extract_array_assignment_list (value, &ni);
-      if (val == 0)
-       return (WORD_LIST *)NULL;
-    }
-  else
-    val = value;
-
-  /* Expand the value string into a list of words, performing all the
-     shell expansions including pathname generation and word splitting. */
-  /* First we split the string on whitespace, using the shell parser
-     (ksh93 seems to do this). */
-  list = parse_string_to_word_list (val, 1, "array assign");
-
-  /* If we're using [subscript]=value, we need to quote each [ and ] to
-     prevent unwanted filename expansion. */
-  if (list)
-    quote_array_assignment_chars (list);
-
-  /* Now that we've split it, perform the shell expansions on each
-     word in the list. */
-  nlist = list ? expand_words_no_vars (list) : (WORD_LIST *)NULL;
-
-  dispose_words (list);
-
-  if (val != value)
-    free (val);
-
-  return nlist;
-}
-
-void
-assign_compound_array_list (var, nlist, flags)
-     SHELL_VAR *var;
-     WORD_LIST *nlist;
-     int flags;
-{
-  ARRAY *a;
-  HASH_TABLE *h;
-  WORD_LIST *list;
-  char *w, *val, *nval;
-  int len, iflags;
-  arrayind_t ind, last_ind;
-  char *akey;
-
-  a = (var && array_p (var)) ? array_cell (var) : (ARRAY *)0;
-  h = (var && assoc_p (var)) ? assoc_cell (var) : (HASH_TABLE *)0;
-
-  akey = (char *)0;
-  ind = 0;
-
-  /* Now that we are ready to assign values to the array, kill the existing
-     value. */
-  if ((flags & ASS_APPEND) == 0)
-    {
-      if (a && array_p (var))
-       array_flush (a);
-      else if (h && assoc_p (var))
-       assoc_flush (h);
-    }
-
-  last_ind = (a && (flags & ASS_APPEND)) ? array_max_index (a) + 1 : 0;
-
-  for (list = nlist; list; list = list->next)
-    {
-      iflags = flags;
-      w = list->word->word;
-
-      /* We have a word of the form [ind]=value */
-      if ((list->word->flags & W_ASSIGNMENT) && w[0] == '[')
-       {
-         len = skipsubscript (w, 0, (var && assoc_p (var) != 0));
-
-         /* XXX - changes for `+=' */
-         if (w[len] != ']' || (w[len+1] != '=' && (w[len+1] != '+' || w[len+2] != '=')))
-           {
-             if (assoc_p (var))
-               {
-                 err_badarraysub (w);
-                 continue;
-               }
-             nval = make_variable_value (var, w, flags);
-             if (var->assign_func)
-               (*var->assign_func) (var, nval, last_ind, 0);
-             else
-               array_insert (a, last_ind, nval);
-             FREE (nval);
-             last_ind++;
-             continue;
-           }
-
-         if (len == 1)
-           {
-             err_badarraysub (w);
-             continue;
-           }
-
-         if (ALL_ELEMENT_SUB (w[1]) && len == 2)
-           {
-             if (assoc_p (var))
-               report_error (_("%s: invalid associative array key"), w);
-             else
-               report_error (_("%s: cannot assign to non-numeric index"), w);
-             continue;
-           }
-
-         if (array_p (var))
-           {
-             ind = array_expand_index (w + 1, len);
-             if (ind < 0)
-               {
-                 err_badarraysub (w);
-                 continue;
-               }
-
-             last_ind = ind;
-           }
-         else if (assoc_p (var))
-           {
-             akey = substring (w, 1, len);
-             if (akey == 0 || *akey == 0)
-               {
-                 err_badarraysub (w);
-                 continue;
-               }
-           }
-
-         /* XXX - changes for `+=' -- just accept the syntax.  ksh93 doesn't do this */
-         if (w[len + 1] == '+' && w[len + 2] == '=')
-           {
-             iflags |= ASS_APPEND;
-             val = w + len + 3;
-           }
-         else
-           val = w + len + 2;
-       }
-      else if (assoc_p (var))
-       {
-         report_error (_("%s: %s: must use subscript when assigning associative array"), var->name, w);
-         continue;
-       }
-      else             /* No [ind]=value, just a stray `=' */
-       {
-         ind = last_ind;
-         val = w;
-       }
-
-      if (integer_p (var))
-       this_command_name = (char *)NULL;       /* no command name for errors */
-      bind_array_var_internal (var, ind, akey, val, iflags);
-      last_ind++;
-    }
-}
-
-/* Perform a compound array assignment:  VAR->name=( VALUE ).  The
-   VALUE has already had the parentheses stripped. */
-SHELL_VAR *
-assign_array_var_from_string (var, value, flags)
-     SHELL_VAR *var;
-     char *value;
-     int flags;
-{
-  WORD_LIST *nlist;
-
-  if (value == 0)
-    return var;
-
-  nlist = expand_compound_array_assignment (var, value, flags);
-  assign_compound_array_list (var, nlist, flags);
-
-  if (nlist)
-    dispose_words (nlist);
-  return (var);
-}
-
-/* Quote globbing chars and characters in $IFS before the `=' in an assignment
-   statement (usually a compound array assignment) to protect them from
-   unwanted filename expansion or word splitting. */
-static char *
-quote_assign (string)
-     const char *string;
-{
-  size_t slen;
-  int saw_eq;
-  char *temp, *t, *subs;
-  const char *s, *send;
-  int ss, se;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string);
-  send = string + slen;
-
-  t = temp = (char *)xmalloc (slen * 2 + 1);
-  saw_eq = 0;
-  for (s = string; *s; )
-    {
-      if (*s == '=')
-       saw_eq = 1;
-      if (saw_eq == 0 && *s == '[')            /* looks like a subscript */
-       {
-         ss = s - string;
-         se = skipsubscript (string, ss, 0);
-         subs = substring (s, ss, se);
-         *t++ = '\\';
-         strcpy (t, subs);
-         t += se - ss;
-         *t++ = '\\';
-         *t++ = ']';
-         s += se + 1;
-         free (subs);
-         continue;
-       }
-      if (saw_eq == 0 && (glob_char_p (s) || isifs (*s)))
-       *t++ = '\\';
-
-      COPY_CHAR_P (t, s, send);
-    }
-  *t = '\0';
-  return temp;
-}
-
-/* For each word in a compound array assignment, if the word looks like
-   [ind]=value, quote globbing chars and characters in $IFS before the `='. */
-static void
-quote_array_assignment_chars (list)
-     WORD_LIST *list;
-{
-  char *nword;
-  WORD_LIST *l;
-
-  for (l = list; l; l = l->next)
-    {
-      if (l->word == 0 || l->word->word == 0 || l->word->word[0] == '\0')
-       continue;       /* should not happen, but just in case... */
-      /* Don't bother if it doesn't look like [ind]=value */
-      if (l->word->word[0] != '[' || mbschr (l->word->word, '=') == 0) /* ] */
-       continue;
-      nword = quote_assign (l->word->word);
-      free (l->word->word);
-      l->word->word = nword;
-    }
-}
-
-/* skipsubscript moved to subst.c to use private functions. 2009/02/24. */
-
-/* This function is called with SUB pointing to just after the beginning
-   `[' of an array subscript and removes the array element to which SUB
-   expands from array VAR.  A subscript of `*' or `@' unsets the array. */
-int
-unbind_array_element (var, sub)
-     SHELL_VAR *var;
-     char *sub;
-{
-  int len;
-  arrayind_t ind;
-  char *akey;
-  ARRAY_ELEMENT *ae;
-
-  len = skipsubscript (sub, 0, 0);
-  if (sub[len] != ']' || len == 0)
-    {
-      builtin_error ("%s[%s: %s", var->name, sub, _(bash_badsub_errmsg));
-      return -1;
-    }
-  sub[len] = '\0';
-
-  if (ALL_ELEMENT_SUB (sub[0]) && sub[1] == 0)
-    {
-      unbind_variable (var->name);
-      return (0);
-    }
-
-  if (assoc_p (var))
-    {
-      akey = expand_assignment_string_to_string (sub, 0);     /* [ */
-      if (akey == 0 || *akey == 0)
-       {
-         builtin_error ("[%s]: %s", sub, _(bash_badsub_errmsg));
-         return -1;
-       }
-      assoc_remove (assoc_cell (var), akey);
-    }
-  else
-    {
-      ind = array_expand_index (sub, len+1);
-      if (ind < 0)
-       {
-         builtin_error ("[%s]: %s", sub, _(bash_badsub_errmsg));
-         return -1;
-       }
-      ae = array_remove (array_cell (var), ind);
-      if (ae)
-       array_dispose_element (ae);
-    }
-
-  return 0;
-}
-
-/* Format and output an array assignment in compound form VAR=(VALUES),
-   suitable for re-use as input. */
-void
-print_array_assignment (var, quoted)
-     SHELL_VAR *var;
-     int quoted;
-{
-  char *vstr;
-
-  vstr = array_to_assign (array_cell (var), quoted);
-
-  if (vstr == 0)
-    printf ("%s=%s\n", var->name, quoted ? "'()'" : "()");
-  else
-    {
-      printf ("%s=%s\n", var->name, vstr);
-      free (vstr);
-    }
-}
-
-/* Format and output an associative array assignment in compound form
-   VAR=(VALUES), suitable for re-use as input. */
-void
-print_assoc_assignment (var, quoted)
-     SHELL_VAR *var;
-     int quoted;
-{
-  char *vstr;
-
-  vstr = assoc_to_assign (assoc_cell (var), quoted);
-
-  if (vstr == 0)
-    printf ("%s=%s\n", var->name, quoted ? "'()'" : "()");
-  else
-    {
-      printf ("%s=%s\n", var->name, vstr);
-      free (vstr);
-    }
-}
-
-/***********************************************************************/
-/*                                                                    */
-/* Utility functions to manage arrays and their contents for expansion */
-/*                                                                    */
-/***********************************************************************/
-
-/* Return 1 if NAME is a properly-formed array reference v[sub]. */
-int
-valid_array_reference (name)
-     char *name;
-{
-  char *t;
-  int r, len;
-
-  t = mbschr (name, '[');      /* ] */
-  if (t)
-    {
-      *t = '\0';
-      r = legal_identifier (name);
-      *t = '[';
-      if (r == 0)
-       return 0;
-      /* Check for a properly-terminated non-blank subscript. */
-      len = skipsubscript (t, 0, 0);
-      if (t[len] != ']' || len == 1)
-       return 0;
-      for (r = 1; r < len; r++)
-       if (whitespace (t[r]) == 0)
-         return 1;
-      return 0;
-    }
-  return 0;
-}
-
-/* Expand the array index beginning at S and extending LEN characters. */
-arrayind_t
-array_expand_index (s, len)
-     char *s;
-     int len;
-{
-  char *exp, *t;
-  int expok;
-  arrayind_t val;
-
-  exp = (char *)xmalloc (len);
-  strncpy (exp, s, len - 1);
-  exp[len - 1] = '\0';
-  t = expand_arith_string (exp, 0);
-  this_command_name = (char *)NULL;
-  val = evalexp (t, &expok);
-  free (t);
-  free (exp);
-  if (expok == 0)
-    {
-      last_command_exit_value = EXECUTION_FAILURE;
-
-      top_level_cleanup ();      
-      jump_to_top_level (DISCARD);
-    }
-  return val;
-}
-
-/* Return the name of the variable specified by S without any subscript.
-   If SUBP is non-null, return a pointer to the start of the subscript
-   in *SUBP. If LENP is non-null, the length of the subscript is returned
-   in *LENP.  This returns newly-allocated memory. */
-char *
-array_variable_name (s, subp, lenp)
-     char *s, **subp;
-     int *lenp;
-{
-  char *t, *ret;
-  int ind, ni;
-
-  t = mbschr (s, '[');
-  if (t == 0)
-    {
-      if (subp)
-       *subp = t;
-      if (lenp)
-       *lenp = 0;
-      return ((char *)NULL);
-    }
-  ind = t - s;
-  ni = skipsubscript (s, ind, 0);
-  if (ni <= ind + 1 || s[ni] != ']')
-    {
-      err_badarraysub (s);
-      if (subp)
-       *subp = t;
-      if (lenp)
-       *lenp = 0;
-      return ((char *)NULL);
-    }
-
-  *t = '\0';
-  ret = savestring (s);
-  *t++ = '[';          /* ] */
-
-  if (subp)
-    *subp = t;
-  if (lenp)
-    *lenp = ni - ind;
-
-  return ret;
-}
-
-/* Return the variable specified by S without any subscript.  If SUBP is
-   non-null, return a pointer to the start of the subscript in *SUBP.
-   If LENP is non-null, the length of the subscript is returned in *LENP. */
-SHELL_VAR *
-array_variable_part (s, subp, lenp)
-     char *s, **subp;
-     int *lenp;
-{
-  char *t;
-  SHELL_VAR *var;
-
-  t = array_variable_name (s, subp, lenp);
-  if (t == 0)
-    return ((SHELL_VAR *)NULL);
-  var = find_variable (t);
-
-  free (t);
-  return (var == 0 || invisible_p (var)) ? (SHELL_VAR *)0 : var;
-}
-
-/* Return a string containing the elements in the array and subscript
-   described by S.  If the subscript is * or @, obeys quoting rules akin
-   to the expansion of $* and $@ including double quoting.  If RTYPE
-   is non-null it gets 1 if the array reference is name[*], 2 if the
-   reference is name[@], and 0 otherwise. */
-static char *
-array_value_internal (s, quoted, allow_all, rtype)
-     char *s;
-     int quoted, allow_all, *rtype;
-{
-  int len;
-  arrayind_t ind;
-  char *akey;
-  char *retval, *t, *temp;
-  WORD_LIST *l;
-  SHELL_VAR *var;
-
-  var = array_variable_part (s, &t, &len);
-
-  /* Expand the index, even if the variable doesn't exist, in case side
-     effects are needed, like ${w[i++]} where w is unset. */
-#if 0
-  if (var == 0)
-    return (char *)NULL;
-#endif
-
-  if (len == 0)
-    return ((char *)NULL);     /* error message already printed */
-
-  /* [ */
-  if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']')
-    {
-      if (rtype)
-       *rtype = (t[0] == '*') ? 1 : 2;
-      if (allow_all == 0)
-       {
-         err_badarraysub (s);
-         return ((char *)NULL);
-       }
-      else if (var == 0 || value_cell (var) == 0)
-       return ((char *)NULL);
-      else if (array_p (var) == 0 && assoc_p (var) == 0)
-       l = add_string_to_list (value_cell (var), (WORD_LIST *)NULL);
-      else if (assoc_p (var))
-       {
-         l = assoc_to_word_list (assoc_cell (var));
-         if (l == (WORD_LIST *)NULL)
-           return ((char *)NULL);
-       }
-      else
-       {
-         l = array_to_word_list (array_cell (var));
-         if (l == (WORD_LIST *)NULL)
-           return ((char *) NULL);
-       }
-
-      if (t[0] == '*' && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-       {
-         temp = string_list_dollar_star (l);
-         retval = quote_string (temp);
-         free (temp);
-       }
-      else     /* ${name[@]} or unquoted ${name[*]} */
-       retval = string_list_dollar_at (l, quoted);
-
-      dispose_words (l);
-    }
-  else
-    {
-      if (rtype)
-       *rtype = 0;
-      if (var == 0 || array_p (var) || assoc_p (var) == 0)
-       {
-         ind = array_expand_index (t, len);
-         if (ind < 0)
-           {
-index_error:
-             if (var)
-               err_badarraysub (var->name);
-             else
-               {
-                 t[-1] = '\0';
-                 err_badarraysub (s);
-                 t[-1] = '[';  /* ] */
-               }
-             return ((char *)NULL);
-           }
-       }
-      else if (assoc_p (var))
-       {
-         t[len - 1] = '\0';
-         akey = expand_assignment_string_to_string (t, 0);     /* [ */
-         t[len - 1] = ']';
-         if (akey == 0 || *akey == 0)
-           goto index_error;
-       }
-     
-      if (var == 0)
-       return ((char *)NULL);
-      if (array_p (var) == 0 && assoc_p (var) == 0)
-       return (ind == 0 ? value_cell (var) : (char *)NULL);
-      else if (assoc_p (var))
-       retval = assoc_reference (assoc_cell (var), akey);
-      else
-       retval = array_reference (array_cell (var), ind);
-    }
-
-  return retval;
-}
-
-/* Return a string containing the elements described by the array and
-   subscript contained in S, obeying quoting for subscripts * and @. */
-char *
-array_value (s, quoted, rtype)
-     char *s;
-     int quoted, *rtype;
-{
-  return (array_value_internal (s, quoted, 1, rtype));
-}
-
-/* Return the value of the array indexing expression S as a single string.
-   If ALLOW_ALL is 0, do not allow `@' and `*' subscripts.  This is used
-   by other parts of the shell such as the arithmetic expression evaluator
-   in expr.c. */
-char *
-get_array_value (s, allow_all, rtype)
-     char *s;
-     int allow_all, *rtype;
-{
-  return (array_value_internal (s, 0, allow_all, rtype));
-}
-
-char *
-array_keys (s, quoted)
-     char *s;
-     int quoted;
-{
-  int len;
-  char *retval, *t, *temp;
-  WORD_LIST *l;
-  SHELL_VAR *var;
-
-  var = array_variable_part (s, &t, &len);
-
-  /* [ */
-  if (var == 0 || ALL_ELEMENT_SUB (t[0]) == 0 || t[1] != ']')
-    return (char *)NULL;
-
-  if (array_p (var) == 0 && assoc_p (var) == 0)
-    l = add_string_to_list ("0", (WORD_LIST *)NULL);
-  else if (assoc_p (var))
-    l = assoc_keys_to_word_list (assoc_cell (var));
-  else
-    l = array_keys_to_word_list (array_cell (var));
-  if (l == (WORD_LIST *)NULL)
-    return ((char *) NULL);
-
-  if (t[0] == '*' && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-    {
-      temp = string_list_dollar_star (l);
-      retval = quote_string (temp);
-      free (temp);
-    }
-  else /* ${!name[@]} or unquoted ${!name[*]} */
-    retval = string_list_dollar_at (l, quoted);
-
-  dispose_words (l);
-  return retval;
-}
-#endif /* ARRAY_VARS */
diff --git a/assoc.c~ b/assoc.c~
deleted file mode 100644 (file)
index 0b1a228..0000000
--- a/assoc.c~
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * assoc.c - functions to manipulate associative arrays
- *
- * Associative arrays are standard shell hash tables.
- *
- * Chet Ramey
- * chet@ins.cwru.edu
- */
-
-/* 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/>.
-*/
-
-#include "config.h"
-
-#if defined (ARRAY_VARS)
-
-#if defined (HAVE_UNISTD_H)
-#  ifdef _MINIX
-#    include <sys/types.h>
-#  endif
-#  include <unistd.h>
-#endif
-
-#include <stdio.h>
-#include "bashansi.h"
-
-#include "shell.h"
-#include "array.h"
-#include "assoc.h"
-#include "builtins/common.h"
-
-static WORD_LIST *assoc_to_word_list_internal __P((HASH_TABLE *, int));
-
-/* assoc_create == hash_create */
-
-void
-assoc_dispose (hash)
-     HASH_TABLE *hash;
-{
-  if (hash)
-    {
-      hash_flush (hash, 0);
-      hash_dispose (hash);
-    }
-}
-
-void
-assoc_flush (hash)
-     HASH_TABLE *hash;
-{
-  hash_flush (hash, 0);
-}
-     
-int
-assoc_insert (hash, key, value)
-     HASH_TABLE *hash;
-     char *key;
-     char *value;
-{
-  BUCKET_CONTENTS *b;
-
-  b = hash_search (key, hash, HASH_CREATE);
-  if (b == 0)
-    return -1;
-  FREE (b->data);
-  b->data = value ? savestring (value) : (char *)0;
-  return (0);
-}
-
-void
-assoc_remove (hash, string)
-     HASH_TABLE *hash;
-     char *string;
-{
-  BUCKET_CONTENTS *b;
-
-  b = hash_remove (string, hash, 0);
-  if (b)
-    {
-      free ((char *)b->data);
-      free (b->key);
-      free (b);
-    }
-}
-
-char *
-assoc_reference (hash, string)
-     HASH_TABLE *hash;
-     char *string;
-{
-  BUCKET_CONTENTS *b;
-
-  if (hash == 0)
-    return (char *)0;
-
-  b = hash_search (string, hash, 0);
-  return (b ? (char *)b->data : 0);
-}
-
-/* Quote the data associated with each element of the hash table ASSOC,
-   using quote_string */
-HASH_TABLE *
-assoc_quote (h)
-     HASH_TABLE *h;
-{
-  int i;
-  BUCKET_CONTENTS *tlist;
-  char *t;
-
-  if (h == 0 || assoc_empty (h))
-    return ((HASH_TABLE *)NULL);
-  
-  for (i = 0; i < h->nbuckets; i++)
-    for (tlist = hash_items (i, h); tlist; tlist = tlist->next)
-      {
-       t = quote_string ((char *)tlist->data);
-       FREE (tlist->data);
-       tlist->data = t;
-      }
-
-  return h;
-}
-
-/* Quote escape characters in the data associated with each element
-   of the hash table ASSOC, using quote_escapes */
-HASH_TABLE *
-assoc_quote_escapes (h)
-     HASH_TABLE *h;
-{
-  int i;
-  BUCKET_CONTENTS *tlist;
-  char *t;
-
-  if (h == 0 || assoc_empty (h))
-    return ((HASH_TABLE *)NULL);
-  
-  for (i = 0; i < h->nbuckets; i++)
-    for (tlist = hash_items (i, h); tlist; tlist = tlist->next)
-      {
-       t = quote_escapes ((char *)tlist->data);
-       FREE (tlist->data);
-       tlist->data = t;
-      }
-
-  return h;
-}
-
-HASH_TABLE *
-assoc_dequote (h)
-     HASH_TABLE *h;
-{
-  int i;
-  BUCKET_CONTENTS *tlist;
-  char *t;
-
-  if (h == 0 || assoc_empty (h))
-    return ((HASH_TABLE *)NULL);
-  
-  for (i = 0; i < h->nbuckets; i++)
-    for (tlist = hash_items (i, h); tlist; tlist = tlist->next)
-      {
-       t = dequote_string ((char *)tlist->data);
-       FREE (tlist->data);
-       tlist->data = t;
-      }
-
-  return h;
-}
-
-HASH_TABLE *
-assoc_dequote_escapes (h)
-     HASH_TABLE *h;
-{
-  int i;
-  BUCKET_CONTENTS *tlist;
-  char *t;
-
-  if (h == 0 || assoc_empty (h))
-    return ((HASH_TABLE *)NULL);
-  
-  for (i = 0; i < h->nbuckets; i++)
-    for (tlist = hash_items (i, h); tlist; tlist = tlist->next)
-      {
-       t = dequote_escapes ((char *)tlist->data);
-       FREE (tlist->data);
-       tlist->data = t;
-      }
-
-  return h;
-}
-
-HASH_TABLE *
-assoc_remove_quoted_nulls (h)
-     HASH_TABLE *h;
-{
-  int i;
-  BUCKET_CONTENTS *tlist;
-  char *t;
-
-  if (h == 0 || assoc_empty (h))
-    return ((HASH_TABLE *)NULL);
-  
-  for (i = 0; i < h->nbuckets; i++)
-    for (tlist = hash_items (i, h); tlist; tlist = tlist->next)
-      {
-       t = remove_quoted_nulls ((char *)tlist->data);
-       tlist->data = t;
-      }
-
-  return h;
-}
-
-/*
- * Return a string whose elements are the members of array H beginning at
- * the STARTth element and spanning NELEM members.  Null elements are counted.
- */
-char *
-assoc_subrange (hash, start, nelem, starsub, quoted)
-HASH_TABLE *hash;
-arrayind_t start, nelem;
-int starsub, quoted;
-{
-  WORD_LIST *l, *save, *h, *t;
-  int i, j;
-  char *ret;
-
-  if (assoc_empty (hash))
-    return ((char *)NULL);
-
-  save = l = assoc_to_word_list (hash);
-  if (save == 0)
-    return ((char *)NULL);
-
-  for (i = 1; l && i < start; i++)
-    l = l->next;
-  if (l == 0)
-    return ((char *)NULL);
-  for (j = 0,h = t = l; l && j < nelem; j++)
-    {
-      t = l;
-      l = l->next;
-    }
-
-  t->next = (WORD_LIST *)NULL;
-
-  ret = string_list_pos_params (starsub ? '*' : '@', h, quoted);
-
-  if (t != l)
-    t->next = l;
-
-  dispose_words (save);
-  return (ret);
-
-}
-
-char *
-assoc_patsub (h, pat, rep, mflags)
-     HASH_TABLE *h;
-     char *pat, *rep;
-     int mflags;
-{
-  BUCKET_CONTENTS *tlist;
-  int i, slen;
-  HASH_TABLE *h2;
-  char *t, *sifs, *ifs;
-
-  if (h == 0 || assoc_empty (h))
-    return ((char *)NULL);
-
-  h2 = assoc_copy (h);
-  for (i = 0; i < h2->nbuckets; i++)
-    for (tlist = hash_items (i, h2); tlist; tlist = tlist->next)
-      {
-       t = pat_subst ((char *)tlist->data, pat, rep, mflags);
-       FREE (tlist->data);
-       tlist->data = t;
-      }
-
-  if (mflags & MATCH_QUOTED)
-    assoc_quote (h2);
-  else
-    assoc_quote_escapes (h2);
-
-  if (mflags & MATCH_STARSUB)
-    {
-      assoc_remove_quoted_nulls (h2);
-      sifs = ifs_firstchar ((int *)NULL);
-      t = assoc_to_string (h2, sifs, 0);
-      free (sifs);
-    }
-  else if (mflags & MATCH_QUOTED)
-    {
-      /* ${array[@]} */
-      sifs = ifs_firstchar (&slen);
-      ifs = getifs ();
-      if (ifs == 0 || *ifs == 0)
-       {
-         if (slen < 2)
-           sifs = xrealloc (sifs, 2);
-         sifs[0] = ' ';
-         sifs[1] = '\0';
-       }
-      t = assoc_to_string (h2, sifs, 0);
-      free(sifs);
-    }
-  else
-    t = assoc_to_string (h2, " ", 0);
-
-  assoc_dispose (h2);
-
-  return t;
-}
-
-char *
-assoc_modcase (h, pat, modop, mflags)
-     HASH_TABLE *h;
-     char *pat;
-     int modop;
-     int mflags;
-{
-  BUCKET_CONTENTS *tlist;
-  int i, slen;
-  HASH_TABLE *h2;
-  char *t, *sifs, *ifs;
-
-  if (h == 0 || assoc_empty (h))
-    return ((char *)NULL);
-
-  h2 = assoc_copy (h);
-  for (i = 0; i < h2->nbuckets; i++)
-    for (tlist = hash_items (i, h2); tlist; tlist = tlist->next)
-      {
-       t = sh_modcase ((char *)tlist->data, pat, modop);
-       FREE (tlist->data);
-       tlist->data = t;
-      }
-
-  if (mflags & MATCH_QUOTED)
-    assoc_quote (h2);
-  else
-    assoc_quote_escapes (h2);
-
-  if (mflags & MATCH_STARSUB)
-    {
-      assoc_remove_quoted_nulls (h2);
-      sifs = ifs_firstchar ((int *)NULL);
-      t = assoc_to_string (h2, sifs, 0);
-      free (sifs);
-    }
-  else if (mflags & MATCH_QUOTED)
-    {
-      /* ${array[@]} */
-      sifs = ifs_firstchar (&slen);
-      ifs = getifs ();
-      if (ifs == 0 || *ifs == 0)
-       {
-         if (slen < 2)
-           sifs = xrealloc (sifs, 2);
-         sifs[0] = ' ';
-         sifs[1] = '\0';
-       }
-      t = assoc_to_string (h2, sifs, 0);
-      free(sifs);
-    }
-  else
-    t = assoc_to_string (h2, " ", 0);
-
-  assoc_dispose (h2);
-
-  return t;
-}
-
-char *
-assoc_to_assign (hash, quoted)
-     HASH_TABLE *hash;
-     int quoted;
-{
-  char *ret;
-  char *istr, *vstr;
-  int i, rsize, rlen, elen;
-  BUCKET_CONTENTS *tlist;
-
-  if (hash == 0 || assoc_empty (hash))
-    return (char *)0;
-
-  ret = xmalloc (rsize = 128);
-  ret[0] = '(';
-  rlen = 1;
-
-  for (i = 0; i < hash->nbuckets; i++)
-    for (tlist = hash_items (i, hash); tlist; tlist = tlist->next)
-      {
-#if 0
-       istr = sh_single_quote (tlist->key);
-#else
-       istr = tlist->key;
-#endif
-       vstr = tlist->data ? sh_double_quote ((char *)tlist->data) : (char *)0;
-
-       elen = STRLEN (istr) + 8 + STRLEN (vstr);
-       RESIZE_MALLOCED_BUFFER (ret, rlen, (elen+1), rsize, rsize);
-
-       ret[rlen++] = '[';
-       strcpy (ret+rlen, istr);
-       rlen += STRLEN (istr);
-       ret[rlen++] = ']';
-       ret[rlen++] = '=';
-       if (vstr)
-         {
-           strcpy (ret + rlen, vstr);
-           rlen += STRLEN (vstr);
-         }
-       ret[rlen++] = ' ';
-
-#if 0
-       FREE (istr);
-#endif
-       FREE (vstr);
-    }
-
-  RESIZE_MALLOCED_BUFFER (ret, rlen, 1, rsize, 8);
-  ret[rlen++] = ')';
-  ret[rlen] = '\0';
-
-  if (quoted)
-    {
-      vstr = sh_single_quote (ret);
-      free (ret);
-      ret = vstr;
-    }
-
-  return ret;
-}
-
-static WORD_LIST *
-assoc_to_word_list_internal (h, t)
-     HASH_TABLE *h;
-     int t;
-{
-  WORD_LIST *list;
-  int i;
-  BUCKET_CONTENTS *tlist;
-  char *w;
-
-  if (h == 0 || assoc_empty (h))
-    return((WORD_LIST *)NULL);
-  list = (WORD_LIST *)NULL;
-  
-  for (i = 0; i < h->nbuckets; i++)
-    for (tlist = hash_items (i, h); tlist; tlist = tlist->next)
-      {
-       w = (t == 0) ? (char *)tlist->data : (char *)tlist->key;
-       list = make_word_list (make_bare_word(w), list);
-      }
-  return (REVERSE_LIST(list, WORD_LIST *));
-}
-
-WORD_LIST *
-assoc_to_word_list (h)
-     HASH_TABLE *h;
-{
-  return (assoc_to_word_list_internal (h, 0));
-}
-
-WORD_LIST *
-assoc_keys_to_word_list (h)
-     HASH_TABLE *h;
-{
-  return (assoc_to_word_list_internal (h, 1));
-}
-
-char *
-assoc_to_string (h, sep, quoted)
-     HASH_TABLE *h;
-     char *sep;
-     int quoted;
-{
-  BUCKET_CONTENTS *tlist;
-  int i;
-  char *result, *t, *w;
-  WORD_LIST *list, *l;
-
-  if (h == 0)
-    return ((char *)NULL);
-  if (assoc_empty (h))
-    return (savestring (""));
-
-  result = NULL;
-  list = NULL;
-  /* This might be better implemented directly, but it's simple to implement
-     by converting to a word list first, possibly quoting the data, then
-     using list_string */
-  for (i = 0; i < h->nbuckets; i++)
-    for (tlist = hash_items (i, h); tlist; tlist = tlist->next)
-      {
-       w = (char *)tlist->data;
-       if (w == 0)
-         continue;
-       t = quoted ? quote_string (w) : savestring (w);
-       list = make_word_list (make_bare_word(t), list);
-       FREE (t);
-      }
-
-  l = REVERSE_LIST(list, WORD_LIST *);
-
-  result = l ? string_list_internal (l, sep) : savestring ("");
-  return result;
-}
-
-#endif /* ARRAY_VARS */
diff --git a/bashhist.c~ b/bashhist.c~
deleted file mode 100644 (file)
index 30c8108..0000000
+++ /dev/null
@@ -1,898 +0,0 @@
-/* bashhist.c -- bash interface to the GNU history library. */
-
-/* Copyright (C) 1993-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/>.
-*/
-
-#include "config.h"
-
-#if defined (HISTORY)
-
-#if defined (HAVE_UNISTD_H)
-#  ifdef _MINIX
-#    include <sys/types.h>
-#  endif
-#  include <unistd.h>
-#endif
-
-#include "bashtypes.h"
-#include <stdio.h>
-#include <errno.h>
-#include "bashansi.h"
-#include "posixstat.h"
-#include "filecntl.h"
-
-#include "bashintl.h"
-
-#if defined (SYSLOG_HISTORY)
-#  include <syslog.h>
-#endif
-
-#include "shell.h"
-#include "flags.h"
-#include "input.h"
-#include "parser.h"    /* for the struct dstack stuff. */
-#include "pathexp.h"   /* for the struct ignorevar stuff */
-#include "bashhist.h"  /* matching prototypes and declarations */
-#include "builtins/common.h"
-
-#include <readline/history.h>
-#include <glob/glob.h>
-#include <glob/strmatch.h>
-
-#if defined (READLINE)
-#  include "bashline.h"
-extern int rl_done, rl_dispatching;    /* should really include readline.h */
-#endif
-
-#if !defined (errno)
-extern int errno;
-#endif
-
-static int histignore_item_func __P((struct ign *));
-static int check_history_control __P((char *));
-static void hc_erasedups __P((char *));
-static void really_add_history __P((char *));
-
-static struct ignorevar histignore =
-{
-  "HISTIGNORE",
-  (struct ign *)0,
-  0,
-  (char *)0,
-  (sh_iv_item_func_t *)histignore_item_func,
-};
-
-#define HIGN_EXPAND 0x01
-
-/* Declarations of bash history variables. */
-/* Non-zero means to remember lines typed to the shell on the history
-   list.  This is different than the user-controlled behaviour; this
-   becomes zero when we read lines from a file, for example. */
-int remember_on_history = 1;
-int enable_history_list = 1;   /* value for `set -o history' */
-
-/* The number of lines that Bash has added to this history session.  The
-   difference between the number of the top element in the history list
-   (offset from history_base) and the number of lines in the history file.
-   Appending this session's history to the history file resets this to 0. */
-int history_lines_this_session;
-
-/* The number of lines that Bash has read from the history file. */
-int history_lines_in_file;
-
-#if defined (BANG_HISTORY)
-/* Non-zero means do no history expansion on this line, regardless
-   of what history_expansion says. */
-int history_expansion_inhibited;
-#endif
-
-/* With the old default, every line was saved in the history individually.
-   I.e., if the user enters:
-       bash$ for i in a b c
-       > do
-       > echo $i
-       > done
-   Each line will be individually saved in the history.
-       bash$ history
-       10  for i in a b c
-       11  do
-       12  echo $i
-       13  done
-       14  history
-   If the variable command_oriented_history is set, multiple lines
-   which form one command will be saved as one history entry.
-       bash$ for i in a b c
-       > do
-       > echo $i
-       > done
-       bash$ history
-       10  for i in a b c
-    do
-    echo $i
-    done
-       11  history
-   The user can then recall the whole command all at once instead
-   of just being able to recall one line at a time.
-
-   This is now enabled by default.
-   */
-int command_oriented_history = 1;
-
-/* Set to 1 if the first line of a possibly-multi-line command was saved
-   in the history list.  Managed by maybe_add_history(), but global so
-   the history-manipluating builtins can see it. */
-int current_command_first_line_saved = 0;
-
-/* Non-zero means to store newlines in the history list when using
-   command_oriented_history rather than trying to use semicolons. */
-int literal_history;
-
-/* Non-zero means to append the history to the history file at shell
-   exit, even if the history has been stifled. */
-int force_append_history;
-
-/* A nit for picking at history saving.  Flags have the following values:
-
-   Value == 0 means save all lines parsed by the shell on the history.
-   Value & HC_IGNSPACE means save all lines that do not start with a space.
-   Value & HC_IGNDUPS means save all lines that do not match the last
-   line saved.
-   Value & HC_ERASEDUPS means to remove all other matching lines from the
-   history list before saving the latest line. */
-int history_control;
-
-/* Set to 1 if the last command was added to the history list successfully
-   as a separate history entry; set to 0 if the line was ignored or added
-   to a previous entry as part of command-oriented-history processing. */
-int hist_last_line_added;
-
-/* Set to 1 if builtins/history.def:push_history added the last history
-   entry. */
-int hist_last_line_pushed;
-
-#if defined (READLINE)
-/* If non-zero, and readline is being used, the user is offered the
-   chance to re-edit a failed history expansion. */
-int history_reediting;
-
-/* If non-zero, and readline is being used, don't directly execute a
-   line with history substitution.  Reload it into the editing buffer
-   instead and let the user further edit and confirm with a newline. */
-int hist_verify;
-
-#endif /* READLINE */
-
-/* Non-zero means to not save function definitions in the history list. */
-int dont_save_function_defs;
-
-/* Variables declared in other files used here. */
-extern int current_command_line_count;
-
-extern struct dstack dstack;
-
-static int bash_history_inhibit_expansion __P((char *, int));
-#if defined (READLINE)
-static void re_edit __P((char *));
-#endif
-static int history_expansion_p __P((char *));
-static int shell_comment __P((char *));
-static int should_expand __P((char *));
-static HIST_ENTRY *last_history_entry __P((void));
-static char *expand_histignore_pattern __P((char *));
-static int history_should_ignore __P((char *));
-
-/* Is the history expansion starting at string[i] one that should not
-   be expanded? */
-static int
-bash_history_inhibit_expansion (string, i)
-     char *string;
-     int i;
-{
-  /* The shell uses ! as a pattern negation character in globbing [...]
-     expressions, so let those pass without expansion. */
-  if (i > 0 && (string[i - 1] == '[') && member (']', string + i + 1))
-    return (1);
-  /* The shell uses ! as the indirect expansion character, so let those
-     expansions pass as well. */
-  else if (i > 1 && string[i - 1] == '{' && string[i - 2] == '$' &&
-            member ('}', string + i + 1))
-    return (1);
-#if defined (EXTENDED_GLOB)
-  else if (extended_glob && i > 1 && string[i+1] == '(' && member (')', string + i + 2))
-    return (1);
-#endif
-  else
-    return (0);
-}
-
-void
-bash_initialize_history ()
-{
-  history_quotes_inhibit_expansion = 1;
-  history_search_delimiter_chars = ";&()|<>";
-  history_inhibit_expansion_function = bash_history_inhibit_expansion;
-#if defined (BANG_HISTORY)
-  sv_histchars ("histchars");
-#endif
-}
-
-void
-bash_history_reinit (interact)
-     int interact;
-{
-#if defined (BANG_HISTORY)
-  history_expansion = interact != 0;
-  history_expansion_inhibited = 1;
-#endif
-  remember_on_history = enable_history_list = interact != 0;
-  history_inhibit_expansion_function = bash_history_inhibit_expansion;
-}
-
-void
-bash_history_disable ()
-{
-  remember_on_history = 0;
-#if defined (BANG_HISTORY)
-  history_expansion_inhibited = 1;
-#endif
-}
-
-void
-bash_history_enable ()
-{
-  remember_on_history = 1;
-#if defined (BANG_HISTORY)
-  history_expansion_inhibited = 0;
-#endif
-  history_inhibit_expansion_function = bash_history_inhibit_expansion;
-  sv_history_control ("HISTCONTROL");
-  sv_histignore ("HISTIGNORE");
-}
-
-/* Load the history list from the history file. */
-void
-load_history ()
-{
-  char *hf;
-
-  /* Truncate history file for interactive shells which desire it.
-     Note that the history file is automatically truncated to the
-     size of HISTSIZE if the user does not explicitly set the size
-     differently. */
-  set_if_not ("HISTSIZE", "500");
-  sv_histsize ("HISTSIZE");
-
-  set_if_not ("HISTFILESIZE", get_string_value ("HISTSIZE"));
-  sv_histsize ("HISTFILESIZE");
-
-  /* Read the history in HISTFILE into the history list. */
-  hf = get_string_value ("HISTFILE");
-
-  if (hf && *hf && file_exists (hf))
-    {
-      read_history (hf);
-      using_history ();
-      history_lines_in_file = where_history ();
-    }
-}
-
-void
-bash_clear_history ()
-{
-  clear_history ();
-  history_lines_this_session = 0;
-}
-
-/* Delete and free the history list entry at offset I. */
-int
-bash_delete_histent (i)
-     int i;
-{
-  HIST_ENTRY *discard;
-
-  discard = remove_history (i);
-  if (discard)
-    free_history_entry (discard);
-  history_lines_this_session--;
-
-  return 1;
-}
-
-int
-bash_delete_last_history ()
-{
-  register int i;
-  HIST_ENTRY **hlist, *histent;
-  int r;
-
-  hlist = history_list ();
-  if (hlist == NULL)
-    return 0;
-
-  for (i = 0; hlist[i]; i++)
-    ;
-  i--;
-
-  /* History_get () takes a parameter that must be offset by history_base. */
-  histent = history_get (history_base + i);    /* Don't free this */
-  if (histent == NULL)
-    return 0;
-
-  r = bash_delete_histent (i);
-
-  if (where_history () > history_length)
-    history_set_pos (history_length);
-
-  return r;
-}
-
-#ifdef INCLUDE_UNUSED
-/* Write the existing history out to the history file. */
-void
-save_history ()
-{
-  char *hf;
-
-  hf = get_string_value ("HISTFILE");
-  if (hf && *hf && file_exists (hf))
-    {
-      /* Append only the lines that occurred this session to
-        the history file. */
-      using_history ();
-
-      if (history_lines_this_session < where_history () || force_append_history)
-       append_history (history_lines_this_session, hf);
-      else
-       write_history (hf);
-      sv_histsize ("HISTFILESIZE");
-    }
-}
-#endif
-
-int
-maybe_append_history (filename)
-     char *filename;
-{
-  int fd, result;
-  struct stat buf;
-
-  result = EXECUTION_SUCCESS;
-  if (history_lines_this_session && (history_lines_this_session < where_history ()))
-    {
-      /* If the filename was supplied, then create it if necessary. */
-      if (stat (filename, &buf) == -1 && errno == ENOENT)
-       {
-         fd = open (filename, O_WRONLY|O_CREAT, 0600);
-         if (fd < 0)
-           {
-             builtin_error (_("%s: cannot create: %s"), filename, strerror (errno));
-             return (EXECUTION_FAILURE);
-           }
-         close (fd);
-       }
-      result = append_history (history_lines_this_session, filename);
-      history_lines_in_file += history_lines_this_session;
-      history_lines_this_session = 0;
-    }
-  return (result);
-}
-
-/* If this is an interactive shell, then append the lines executed
-   this session to the history file. */
-int
-maybe_save_shell_history ()
-{
-  int result;
-  char *hf;
-
-  result = 0;
-  if (history_lines_this_session)
-    {
-      hf = get_string_value ("HISTFILE");
-
-      if (hf && *hf)
-       {
-         /* If the file doesn't exist, then create it. */
-         if (file_exists (hf) == 0)
-           {
-             int file;
-             file = open (hf, O_CREAT | O_TRUNC | O_WRONLY, 0600);
-             if (file != -1)
-               close (file);
-           }
-
-         /* Now actually append the lines if the history hasn't been
-            stifled.  If the history has been stifled, rewrite the
-            history file. */
-         using_history ();
-         if (history_lines_this_session <= where_history () || force_append_history)
-           {
-             result = append_history (history_lines_this_session, hf);
-             history_lines_in_file += history_lines_this_session;
-           }
-         else
-           {
-             result = write_history (hf);
-             history_lines_in_file = history_lines_this_session;
-           }
-         history_lines_this_session = 0;
-
-         sv_histsize ("HISTFILESIZE");
-       }
-    }
-  return (result);
-}
-
-#if defined (READLINE)
-/* Tell readline () that we have some text for it to edit. */
-static void
-re_edit (text)
-     char *text;
-{
-  if (bash_input.type == st_stdin)
-    bash_re_edit (text);
-}
-#endif /* READLINE */
-
-/* Return 1 if this line needs history expansion. */
-static int
-history_expansion_p (line)
-     char *line;
-{
-  register char *s;
-
-  for (s = line; *s; s++)
-    if (*s == history_expansion_char || *s == history_subst_char)
-      return 1;
-  return 0;
-}
-
-/* Do pre-processing on LINE.  If PRINT_CHANGES is non-zero, then
-   print the results of expanding the line if there were any changes.
-   If there is an error, return NULL, otherwise the expanded line is
-   returned.  If ADDIT is non-zero the line is added to the history
-   list after history expansion.  ADDIT is just a suggestion;
-   REMEMBER_ON_HISTORY can veto, and does.
-   Right now this does history expansion. */
-char *
-pre_process_line (line, print_changes, addit)
-     char *line;
-     int print_changes, addit;
-{
-  char *history_value;
-  char *return_value;
-  int expanded;
-
-  return_value = line;
-  expanded = 0;
-
-#  if defined (BANG_HISTORY)
-  /* History expand the line.  If this results in no errors, then
-     add that line to the history if ADDIT is non-zero. */
-  if (!history_expansion_inhibited && history_expansion && history_expansion_p (line))
-    {
-      expanded = history_expand (line, &history_value);
-
-      if (expanded)
-       {
-         if (print_changes)
-           {
-             if (expanded < 0)
-               internal_error ("%s", history_value);
-#if defined (READLINE)
-             else if (hist_verify == 0 || expanded == 2)
-#else
-             else
-#endif
-               fprintf (stderr, "%s\n", history_value);
-           }
-
-         /* If there was an error, return NULL. */
-         if (expanded < 0 || expanded == 2)    /* 2 == print only */
-           {
-#    if defined (READLINE)
-             if (expanded == 2 && rl_dispatching == 0 && *history_value)
-#    else            
-             if (expanded == 2 && *history_value)
-#    endif /* !READLINE */
-               maybe_add_history (history_value);
-
-             free (history_value);
-
-#    if defined (READLINE)
-             /* New hack.  We can allow the user to edit the
-                failed history expansion. */
-             if (history_reediting && expanded < 0 && rl_done)
-               re_edit (line);
-#    endif /* READLINE */
-             return ((char *)NULL);
-           }
-
-#    if defined (READLINE)
-         if (hist_verify && expanded == 1)
-           {
-             re_edit (history_value);
-             return ((char *)NULL);
-           }
-#    endif
-       }
-
-      /* Let other expansions know that return_value can be free'ed,
-        and that a line has been added to the history list.  Note
-        that we only add lines that have something in them. */
-      expanded = 1;
-      return_value = history_value;
-    }
-#  endif /* BANG_HISTORY */
-
-  if (addit && remember_on_history && *return_value)
-    maybe_add_history (return_value);
-
-#if 0
-  if (expanded == 0)
-    return_value = savestring (line);
-#endif
-
-  return (return_value);
-}
-
-/* Return 1 if the first non-whitespace character in LINE is a `#', indicating
- * that the line is a shell comment. */
-static int
-shell_comment (line)
-     char *line;
-{
-  char *p;
-
-  for (p = line; p && *p && whitespace (*p); p++)
-    ;
-  return (p && *p == '#');
-}
-
-#ifdef INCLUDE_UNUSED
-/* Remove shell comments from LINE.  A `#' and anything after it is a comment.
-   This isn't really useful yet, since it doesn't handle quoting. */
-static char *
-filter_comments (line)
-     char *line;
-{
-  char *p;
-
-  for (p = line; p && *p && *p != '#'; p++)
-    ;
-  if (p && *p == '#')
-    *p = '\0';
-  return (line);
-}
-#endif
-
-/* Check LINE against what HISTCONTROL says to do.  Returns 1 if the line
-   should be saved; 0 if it should be discarded. */
-static int
-check_history_control (line)
-     char *line;
-{
-  HIST_ENTRY *temp;
-  int r;
-
-  if (history_control == 0)
-    return 1;
-
-  /* ignorespace or ignoreboth */
-  if ((history_control & HC_IGNSPACE) && *line == ' ')
-    return 0;
-
-  /* ignoredups or ignoreboth */
-  if (history_control & HC_IGNDUPS)
-    {
-      using_history ();
-      temp = previous_history ();
-
-      r = (temp == 0 || STREQ (temp->line, line) == 0);
-
-      using_history ();
-
-      if (r == 0)
-       return r;
-    }
-
-  return 1;
-}
-
-/* Remove all entries matching LINE from the history list.  Triggered when
-   HISTCONTROL includes `erasedups'. */
-static void
-hc_erasedups (line)
-     char *line;
-{
-  HIST_ENTRY *temp;
-  int r;
-
-  using_history ();
-  while (temp = previous_history ())
-    {
-      if (STREQ (temp->line, line))
-       {
-         r = where_history ();
-         remove_history (r);
-       }
-    }
-  using_history ();
-}
-
-/* Add LINE to the history list, handling possibly multi-line compound
-   commands.  We note whether or not we save the first line of each command
-   (which is usually the entire command and history entry), and don't add
-   the second and subsequent lines of a multi-line compound command if we
-   didn't save the first line.  We don't usually save shell comment lines in
-   compound commands in the history, because they could have the effect of
-   commenting out the rest of the command when the entire command is saved as
-   a single history entry (when COMMAND_ORIENTED_HISTORY is enabled).  If
-   LITERAL_HISTORY is set, we're saving lines in the history with embedded
-   newlines, so it's OK to save comment lines.  We also make sure to save
-   multiple-line quoted strings or other constructs. */
-void
-maybe_add_history (line)
-     char *line;
-{
-  hist_last_line_added = 0;
-
-  /* Don't use the value of history_control to affect the second
-     and subsequent lines of a multi-line command (old code did
-     this only when command_oriented_history is enabled). */
-  if (current_command_line_count > 1)
-    {
-      if (current_command_first_line_saved &&
-         (literal_history || dstack.delimiter_depth != 0 || shell_comment (line) == 0))
-       bash_add_history (line);
-      return;
-    }
-
-  /* This is the first line of a (possible multi-line) command.  Note whether
-     or not we should save the first line and remember it. */
-  current_command_first_line_saved = check_add_history (line, 0);
-}
-
-/* Just check LINE against HISTCONTROL and HISTIGNORE and add it to the
-   history if it's OK.  Used by `history -s' as well as maybe_add_history().
-   Returns 1 if the line was saved in the history, 0 otherwise. */
-int
-check_add_history (line, force)
-     char *line;
-     int force;
-{
-  if (check_history_control (line) && history_should_ignore (line) == 0)
-    {
-      /* We're committed to saving the line.  If the user has requested it,
-        remove other matching lines from the history. */
-      if (history_control & HC_ERASEDUPS)
-       hc_erasedups (line);
-        
-      if (force)
-       {
-         really_add_history (line);
-         using_history ();
-       }
-      else
-       bash_add_history (line);
-      return 1;
-    }
-  return 0;
-}
-
-#if defined (SYSLOG_HISTORY)
-#define SYSLOG_MAXLEN 600
-
-void
-bash_syslog_history (line)
-     const char *line;
-{
-  char trunc[SYSLOG_MAXLEN];
-
-  if (strlen(line) < SYSLOG_MAXLEN)
-    syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "HISTORY: PID=%d UID=%d %s", getpid(), current_user.uid, line);
-  else
-    {
-      strcpy (trunc, line, SYSLOG_MAXLEN);
-      trunc[SYSLOG_MAXLEN - 1] = '\0';
-      syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "HISTORY (TRUNCATED): PID=%d UID=%d %s", getpid(), current_user.uid, trunc);
-    }
-}
-#endif
-       
-/* Add a line to the history list.
-   The variable COMMAND_ORIENTED_HISTORY controls the style of history
-   remembering;  when non-zero, and LINE is not the first line of a
-   complete parser construct, append LINE to the last history line instead
-   of adding it as a new line. */
-void
-bash_add_history (line)
-     char *line;
-{
-  int add_it, offset, curlen;
-  HIST_ENTRY *current, *old;
-  char *chars_to_add, *new_line;
-
-  add_it = 1;
-  if (command_oriented_history && current_command_line_count > 1)
-    {
-      chars_to_add = literal_history ? "\n" : history_delimiting_chars ();
-
-      using_history ();
-      current = previous_history ();
-
-      if (current)
-       {
-         /* If the previous line ended with an escaped newline (escaped
-            with backslash, but otherwise unquoted), then remove the quoted
-            newline, since that is what happens when the line is parsed. */
-         curlen = strlen (current->line);
-
-         if (dstack.delimiter_depth == 0 && current->line[curlen - 1] == '\\' &&
-             current->line[curlen - 2] != '\\')
-           {
-             current->line[curlen - 1] = '\0';
-             curlen--;
-             chars_to_add = "";
-           }
-
-         new_line = (char *)xmalloc (1
-                                     + curlen
-                                     + strlen (line)
-                                     + strlen (chars_to_add));
-         sprintf (new_line, "%s%s%s", current->line, chars_to_add, line);
-         offset = where_history ();
-         old = replace_history_entry (offset, new_line, current->data);
-         free (new_line);
-
-         if (old)
-           free_history_entry (old);
-
-         add_it = 0;
-       }
-    }
-
-  if (add_it)
-    really_add_history (line);
-
-#if defined (SYSLOG_HISTORY)
-  bash_syslog_history (line);
-#endif
-
-  using_history ();
-}
-
-static void
-really_add_history (line)
-     char *line;
-{
-  hist_last_line_added = 1;
-  hist_last_line_pushed = 0;
-  add_history (line);
-  history_lines_this_session++;
-}
-
-int
-history_number ()
-{
-  using_history ();
-  return (remember_on_history ? history_base + where_history () : 1);
-}
-
-static int
-should_expand (s)
-     char *s;
-{
-  char *p;
-
-  for (p = s; p && *p; p++)
-    {
-      if (*p == '\\')
-       p++;
-      else if (*p == '&')
-       return 1;
-    }
-  return 0;
-}
-
-static int
-histignore_item_func (ign)
-     struct ign *ign;
-{
-  if (should_expand (ign->val))
-    ign->flags |= HIGN_EXPAND;
-  return (0);
-}
-
-void
-setup_history_ignore (varname)
-     char *varname;
-{
-  setup_ignore_patterns (&histignore);
-}
-
-static HIST_ENTRY *
-last_history_entry ()
-{
-  HIST_ENTRY *he;
-
-  using_history ();
-  he = previous_history ();
-  using_history ();
-  return he;
-}
-
-char *
-last_history_line ()
-{
-  HIST_ENTRY *he;
-
-  he = last_history_entry ();
-  if (he == 0)
-    return ((char *)NULL);
-  return he->line;
-}
-
-static char *
-expand_histignore_pattern (pat)
-     char *pat;
-{
-  HIST_ENTRY *phe;
-  char *ret;
-
-  phe = last_history_entry ();
-
-  if (phe == (HIST_ENTRY *)0)
-    return (savestring (pat));
-
-  ret = strcreplace (pat, '&', phe->line, 1);
-
-  return ret;
-}
-
-/* Return 1 if we should not put LINE into the history according to the
-   patterns in HISTIGNORE. */
-static int
-history_should_ignore (line)
-     char *line;
-{
-  register int i, match;
-  char *npat;
-
-  if (histignore.num_ignores == 0)
-    return 0;
-
-  for (i = match = 0; i < histignore.num_ignores; i++)
-    {
-      if (histignore.ignores[i].flags & HIGN_EXPAND)
-       npat = expand_histignore_pattern (histignore.ignores[i].val);
-      else
-       npat = histignore.ignores[i].val;
-
-      match = strmatch (npat, line, FNMATCH_EXTFLAG) != FNM_NOMATCH;
-
-      if (histignore.ignores[i].flags & HIGN_EXPAND)
-       free (npat);
-
-      if (match)
-       break;
-    }
-
-  return match;
-}
-#endif /* HISTORY */
diff --git a/bashline.c~ b/bashline.c~
deleted file mode 100644 (file)
index d7a309c..0000000
+++ /dev/null
@@ -1,3662 +0,0 @@
-/* bashline.c -- Bash's interface to the readline library. */
-
-/* Copyright (C) 1987-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/>.
-*/
-
-#include "config.h"
-
-#if defined (READLINE)
-
-#include "bashtypes.h"
-#include "posixstat.h"
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#if defined (HAVE_GRP_H)
-#  include <grp.h>
-#endif
-
-#if defined (HAVE_NETDB_H)
-#  include <netdb.h>
-#endif
-
-#include <stdio.h>
-#include "chartypes.h"
-#include "bashansi.h"
-#include "bashintl.h"
-
-#include "shell.h"
-#include "input.h"
-#include "builtins.h"
-#include "bashhist.h"
-#include "bashline.h"
-#include "execute_cmd.h"
-#include "findcmd.h"
-#include "pathexp.h"
-#include "shmbutil.h"
-
-#include "builtins/common.h"
-
-#include <readline/rlconf.h>
-#include <readline/readline.h>
-#include <readline/history.h>
-
-#include <glob/glob.h>
-
-#if defined (ALIAS)
-#  include "alias.h"
-#endif
-
-#if defined (PROGRAMMABLE_COMPLETION)
-#  include "pcomplete.h"
-#endif
-
-/* These should agree with the defines for emacs_mode and vi_mode in
-   rldefs.h, even though that's not a public readline header file. */
-#ifndef EMACS_EDITING_MODE
-#  define NO_EDITING_MODE      -1
-#  define EMACS_EDITING_MODE    1
-#  define VI_EDITING_MODE       0
-#endif
-
-#define RL_BOOLEAN_VARIABLE_VALUE(s)   ((s)[0] == 'o' && (s)[1] == 'n' && (s)[2] == '\0')
-
-#if defined (BRACE_COMPLETION)
-extern int bash_brace_completion __P((int, int));
-#endif /* BRACE_COMPLETION */
-
-/* To avoid including curses.h/term.h/termcap.h and that whole mess. */
-extern int tputs __P((const char *string, int nlines, int (*outx)(int)));
-
-/* Forward declarations */
-
-/* Functions bound to keys in Readline for Bash users. */
-static int shell_expand_line __P((int, int));
-static int display_shell_version __P((int, int));
-static int operate_and_get_next __P((int, int));
-
-static int bash_ignore_filenames __P((char **));
-static int bash_ignore_everything __P((char **));
-
-#if defined (BANG_HISTORY)
-static char *history_expand_line_internal __P((char *));
-static int history_expand_line __P((int, int));
-static int tcsh_magic_space __P((int, int));
-#endif /* BANG_HISTORY */
-#ifdef ALIAS
-static int alias_expand_line __P((int, int));
-#endif
-#if defined (BANG_HISTORY) && defined (ALIAS)
-static int history_and_alias_expand_line __P((int, int));
-#endif
-
-static int bash_forward_shellword __P((int, int));
-static int bash_backward_shellword __P((int, int));
-static int bash_kill_shellword __P((int, int));
-static int bash_backward_kill_shellword __P((int, int));
-
-/* Helper functions for Readline. */
-static char *restore_tilde __P((char *, char *));
-
-static char *bash_filename_rewrite_hook __P((char *, int));
-static void bash_directory_expansion __P((char **));
-static int bash_directory_completion_hook __P((char **));
-static int filename_completion_ignore __P((char **));
-static int bash_push_line __P((void));
-
-static void cleanup_expansion_error __P((void));
-static void maybe_make_readline_line __P((char *));
-static void set_up_new_line __P((char *));
-
-static int check_redir __P((int));
-static char **attempt_shell_completion __P((const char *, int, int));
-static char *variable_completion_function __P((const char *, int));
-static char *hostname_completion_function __P((const char *, int));
-static char *command_subst_completion_function __P((const char *, int));
-
-static void build_history_completion_array __P((void));
-static char *history_completion_generator __P((const char *, int));
-static int dynamic_complete_history __P((int, int));
-static int bash_dabbrev_expand __P((int, int));
-
-static void initialize_hostname_list __P((void));
-static void add_host_name __P((char *));
-static void snarf_hosts_from_file __P((char *));
-static char **hostnames_matching __P((char *));
-
-static void _ignore_completion_names __P((char **, sh_ignore_func_t *));
-static int name_is_acceptable __P((const char *));
-static int test_for_directory __P((const char *));
-static int return_zero __P((const char *));
-
-static char *bash_dequote_filename __P((char *, int));
-static char *quote_word_break_chars __P((char *));
-static char *bash_quote_filename __P((char *, int, char *));
-
-static int putx __P((int));
-static int bash_execute_unix_command __P((int, int));
-static void init_unix_command_map __P((void));
-static int isolate_sequence __P((char *, int, int, int *));
-
-static int set_saved_history __P((void));
-
-#if defined (ALIAS)
-static int posix_edit_macros __P((int, int));
-#endif
-
-#if defined (PROGRAMMABLE_COMPLETION)
-static int find_cmd_start __P((int));
-static int find_cmd_end __P((int));
-static char *find_cmd_name __P((int));
-static char *prog_complete_return __P((const char *, int));
-
-static char **prog_complete_matches;
-#endif
-
-/* Variables used here but defined in other files. */
-#if defined (BANG_HISTORY)
-extern int hist_verify;
-#endif
-
-extern int current_command_line_count, last_command_exit_value;
-extern int array_needs_making;
-extern int posixly_correct, no_symbolic_links;
-extern char *current_prompt_string, *ps1_prompt;
-extern STRING_INT_ALIST word_token_alist[];
-extern sh_builtin_func_t *last_shell_builtin, *this_shell_builtin;
-
-/* SPECIFIC_COMPLETION_FUNCTIONS specifies that we have individual
-   completion functions which indicate what type of completion should be
-   done (at or before point) that can be bound to key sequences with
-   the readline library. */
-#define SPECIFIC_COMPLETION_FUNCTIONS
-
-#if defined (SPECIFIC_COMPLETION_FUNCTIONS)
-static int bash_specific_completion __P((int, rl_compentry_func_t *));
-
-static int bash_complete_filename_internal __P((int));
-static int bash_complete_username_internal __P((int));
-static int bash_complete_hostname_internal __P((int));
-static int bash_complete_variable_internal __P((int));
-static int bash_complete_command_internal __P((int));
-
-static int bash_complete_filename __P((int, int));
-static int bash_possible_filename_completions __P((int, int));
-static int bash_complete_username __P((int, int));
-static int bash_possible_username_completions __P((int, int));
-static int bash_complete_hostname __P((int, int));
-static int bash_possible_hostname_completions __P((int, int));
-static int bash_complete_variable __P((int, int));
-static int bash_possible_variable_completions __P((int, int));
-static int bash_complete_command __P((int, int));
-static int bash_possible_command_completions __P((int, int));
-
-static char *glob_complete_word __P((const char *, int));
-static int bash_glob_completion_internal __P((int));
-static int bash_glob_complete_word __P((int, int));
-static int bash_glob_expand_word __P((int, int));
-static int bash_glob_list_expansions __P((int, int));
-
-#endif /* SPECIFIC_COMPLETION_FUNCTIONS */
-
-static int edit_and_execute_command __P((int, int, int, char *));
-#if defined (VI_MODE)
-static int vi_edit_and_execute_command __P((int, int));
-static int bash_vi_complete __P((int, int));
-#endif
-static int emacs_edit_and_execute_command __P((int, int));
-
-/* Non-zero once initalize_readline () has been called. */
-int bash_readline_initialized = 0;
-
-/* If non-zero, we do hostname completion, breaking words at `@' and
-   trying to complete the stuff after the `@' from our own internal
-   host list. */
-int perform_hostname_completion = 1;
-
-/* If non-zero, we don't do command completion on an empty line. */
-int no_empty_command_completion;
-
-/* Set FORCE_FIGNORE if you want to honor FIGNORE even if it ignores the
-   only possible matches.  Set to 0 if you want to match filenames if they
-   are the only possible matches, even if FIGNORE says to. */
-int force_fignore = 1;
-
-/* Perform spelling correction on directory names during word completion */
-int dircomplete_spelling = 0;
-
-static char *bash_completer_word_break_characters = " \t\n\"'@><=;|&(:";
-static char *bash_nohostname_word_break_characters = " \t\n\"'><=;|&(:";
-/* )) */
-
-static rl_hook_func_t *old_rl_startup_hook = (rl_hook_func_t *)NULL;
-
-static int dot_in_path = 0;
-
-/* Set to non-zero when dabbrev-expand is running */
-static int dabbrev_expand_active = 0;
-
-/* What kind of quoting is performed by bash_quote_filename:
-       COMPLETE_DQUOTE = double-quoting the filename
-       COMPLETE_SQUOTE = single_quoting the filename
-       COMPLETE_BSQUOTE = backslash-quoting special chars in the filename
-*/
-#define COMPLETE_DQUOTE  1
-#define COMPLETE_SQUOTE  2
-#define COMPLETE_BSQUOTE 3
-static int completion_quoting_style = COMPLETE_BSQUOTE;
-
-/* Flag values for the final argument to bash_default_completion */
-#define DEFCOMP_CMDPOS         1
-
-/* Change the readline VI-mode keymaps into or out of Posix.2 compliance.
-   Called when the shell is put into or out of `posix' mode. */
-void
-posix_readline_initialize (on_or_off)
-     int on_or_off;
-{
-  if (on_or_off)
-    rl_variable_bind ("comment-begin", "#");
-#if defined (VI_MODE)
-  rl_bind_key_in_map (CTRL ('I'), on_or_off ? rl_insert : rl_complete, vi_insertion_keymap);
-#endif
-}
-
-void
-reset_completer_word_break_chars ()
-{
-  rl_completer_word_break_characters = perform_hostname_completion ? savestring (bash_completer_word_break_characters) : savestring (bash_nohostname_word_break_characters);
-}
-
-/* When this function returns, rl_completer_word_break_characters points to
-   dynamically allocated memory. */
-int
-enable_hostname_completion (on_or_off)
-     int on_or_off;
-{
-  int old_value;
-  char *at, *nv, *nval;
-
-  old_value = perform_hostname_completion;
-
-  if (on_or_off)
-    {
-      perform_hostname_completion = 1;
-      rl_special_prefixes = "$@";
-    }
-  else
-    {
-      perform_hostname_completion = 0;
-      rl_special_prefixes = "$";
-    }
-
-  /* Now we need to figure out how to appropriately modify and assign
-     rl_completer_word_break_characters depending on whether we want
-     hostname completion on or off. */
-
-  /* If this is the first time this has been called
-     (bash_readline_initialized == 0), use the sames values as before, but
-     allocate new memory for rl_completer_word_break_characters. */
-
-  if (bash_readline_initialized == 0 &&
-      (rl_completer_word_break_characters == 0 || 
-       rl_completer_word_break_characters == rl_basic_word_break_characters))
-    {
-      if (on_or_off)
-       rl_completer_word_break_characters = savestring (bash_completer_word_break_characters);
-      else
-       rl_completer_word_break_characters = savestring (bash_nohostname_word_break_characters);
-    }
-  else
-    {
-      /* See if we have anything to do. */
-      at = strchr (rl_completer_word_break_characters, '@');
-      if ((at == 0 && on_or_off == 0) || (at != 0 && on_or_off != 0))
-        return old_value;
-
-      /* We have something to do.  Do it. */
-      nval = (char *)xmalloc (strlen (rl_completer_word_break_characters) + 1 + on_or_off);
-
-      if (on_or_off == 0)
-       {
-         /* Turn it off -- just remove `@' from word break chars.  We want
-            to remove all occurrences of `@' from the char list, so we loop
-            rather than just copy the rest of the list over AT. */
-         for (nv = nval, at = rl_completer_word_break_characters; *at; )
-           if (*at != '@')
-             *nv++ = *at++;
-           else
-             at++;
-         *nv = '\0';
-       }
-      else
-       {
-         nval[0] = '@';
-         strcpy (nval + 1, rl_completer_word_break_characters);
-        }
-
-      free (rl_completer_word_break_characters);
-      rl_completer_word_break_characters = nval;
-    }
-
-  return (old_value);
-}
-
-/* Called once from parse.y if we are going to use readline. */
-void
-initialize_readline ()
-{
-  rl_command_func_t *func;
-  char kseq[2];
-
-  if (bash_readline_initialized)
-    return;
-
-  rl_terminal_name = get_string_value ("TERM");
-  rl_instream = stdin;
-  rl_outstream = stderr;
-
-  /* Allow conditional parsing of the ~/.inputrc file. */
-  rl_readline_name = "Bash";
-
-  /* Add bindable names before calling rl_initialize so they may be
-     referenced in the various inputrc files. */
-  rl_add_defun ("shell-expand-line", shell_expand_line, -1);
-#ifdef BANG_HISTORY
-  rl_add_defun ("history-expand-line", history_expand_line, -1);
-  rl_add_defun ("magic-space", tcsh_magic_space, -1);
-#endif
-
-  rl_add_defun ("shell-forward-word", bash_forward_shellword, -1);
-  rl_add_defun ("shell-backward-word", bash_backward_shellword, -1);
-  rl_add_defun ("shell-kill-word", bash_kill_shellword, -1);
-  rl_add_defun ("shell-backward-kill-word", bash_backward_kill_shellword, -1);
-
-#ifdef ALIAS
-  rl_add_defun ("alias-expand-line", alias_expand_line, -1);
-#  ifdef BANG_HISTORY
-  rl_add_defun ("history-and-alias-expand-line", history_and_alias_expand_line, -1);
-#  endif
-#endif
-
-  /* Backwards compatibility. */
-  rl_add_defun ("insert-last-argument", rl_yank_last_arg, -1);
-
-  rl_add_defun ("operate-and-get-next", operate_and_get_next, -1);
-  rl_add_defun ("display-shell-version", display_shell_version, -1);
-  rl_add_defun ("edit-and-execute-command", emacs_edit_and_execute_command, -1);
-
-#if defined (BRACE_COMPLETION)
-  rl_add_defun ("complete-into-braces", bash_brace_completion, -1);
-#endif
-
-#if defined (SPECIFIC_COMPLETION_FUNCTIONS)
-  rl_add_defun ("complete-filename", bash_complete_filename, -1);
-  rl_add_defun ("possible-filename-completions", bash_possible_filename_completions, -1);
-  rl_add_defun ("complete-username", bash_complete_username, -1);
-  rl_add_defun ("possible-username-completions", bash_possible_username_completions, -1);
-  rl_add_defun ("complete-hostname", bash_complete_hostname, -1);
-  rl_add_defun ("possible-hostname-completions", bash_possible_hostname_completions, -1);
-  rl_add_defun ("complete-variable", bash_complete_variable, -1);
-  rl_add_defun ("possible-variable-completions", bash_possible_variable_completions, -1);
-  rl_add_defun ("complete-command", bash_complete_command, -1);
-  rl_add_defun ("possible-command-completions", bash_possible_command_completions, -1);
-  rl_add_defun ("glob-complete-word", bash_glob_complete_word, -1);
-  rl_add_defun ("glob-expand-word", bash_glob_expand_word, -1);
-  rl_add_defun ("glob-list-expansions", bash_glob_list_expansions, -1);
-#endif
-
-  rl_add_defun ("dynamic-complete-history", dynamic_complete_history, -1);
-  rl_add_defun ("dabbrev-expand", bash_dabbrev_expand, -1);
-
-  /* Bind defaults before binding our custom shell keybindings. */
-  if (RL_ISSTATE(RL_STATE_INITIALIZED) == 0)
-    rl_initialize ();
-
-  /* Bind up our special shell functions. */
-  rl_bind_key_if_unbound_in_map (CTRL('E'), shell_expand_line, emacs_meta_keymap);
-
-#ifdef BANG_HISTORY
-  rl_bind_key_if_unbound_in_map ('^', history_expand_line, emacs_meta_keymap);
-#endif
-
-  rl_bind_key_if_unbound_in_map (CTRL ('O'), operate_and_get_next, emacs_standard_keymap);
-  rl_bind_key_if_unbound_in_map (CTRL ('V'), display_shell_version, emacs_ctlx_keymap);
-
-  /* In Bash, the user can switch editing modes with "set -o [vi emacs]",
-     so it is not necessary to allow C-M-j for context switching.  Turn
-     off this occasionally confusing behaviour. */
-  kseq[0] = CTRL('J');
-  kseq[1] = '\0';
-  func = rl_function_of_keyseq (kseq, emacs_meta_keymap, (int *)NULL);
-  if (func == rl_vi_editing_mode)
-    rl_unbind_key_in_map (CTRL('J'), emacs_meta_keymap);
-  kseq[0] = CTRL('M');
-  func = rl_function_of_keyseq (kseq, emacs_meta_keymap, (int *)NULL);
-  if (func == rl_vi_editing_mode)
-    rl_unbind_key_in_map (CTRL('M'), emacs_meta_keymap);
-#if defined (VI_MODE)
-  rl_unbind_key_in_map (CTRL('E'), vi_movement_keymap);
-#endif
-
-#if defined (BRACE_COMPLETION)
-  rl_bind_key_if_unbound_in_map ('{', bash_brace_completion, emacs_meta_keymap); /*}*/
-#endif /* BRACE_COMPLETION */
-
-#if defined (SPECIFIC_COMPLETION_FUNCTIONS)
-  rl_bind_key_if_unbound_in_map ('/', bash_complete_filename, emacs_meta_keymap);
-  rl_bind_key_if_unbound_in_map ('/', bash_possible_filename_completions, emacs_ctlx_keymap);
-
-  /* Have to jump through hoops here because there is a default binding for
-     M-~ (rl_tilde_expand) */
-  kseq[0] = '~';
-  kseq[1] = '\0';
-  func = rl_function_of_keyseq (kseq, emacs_meta_keymap, (int *)NULL);
-  if (func == 0 || func == rl_tilde_expand)
-    rl_bind_keyseq_in_map (kseq, bash_complete_username, emacs_meta_keymap);
-
-  rl_bind_key_if_unbound_in_map ('~', bash_possible_username_completions, emacs_ctlx_keymap);
-
-  rl_bind_key_if_unbound_in_map ('@', bash_complete_hostname, emacs_meta_keymap);
-  rl_bind_key_if_unbound_in_map ('@', bash_possible_hostname_completions, emacs_ctlx_keymap);
-
-  rl_bind_key_if_unbound_in_map ('$', bash_complete_variable, emacs_meta_keymap);
-  rl_bind_key_if_unbound_in_map ('$', bash_possible_variable_completions, emacs_ctlx_keymap);
-
-  rl_bind_key_if_unbound_in_map ('!', bash_complete_command, emacs_meta_keymap);
-  rl_bind_key_if_unbound_in_map ('!', bash_possible_command_completions, emacs_ctlx_keymap);
-
-  rl_bind_key_if_unbound_in_map ('g', bash_glob_complete_word, emacs_meta_keymap);
-  rl_bind_key_if_unbound_in_map ('*', bash_glob_expand_word, emacs_ctlx_keymap);
-  rl_bind_key_if_unbound_in_map ('g', bash_glob_list_expansions, emacs_ctlx_keymap);
-
-#endif /* SPECIFIC_COMPLETION_FUNCTIONS */
-
-  kseq[0] = TAB;
-  kseq[1] = '\0';
-  func = rl_function_of_keyseq (kseq, emacs_meta_keymap, (int *)NULL);
-  if (func == 0 || func == rl_tab_insert)
-    rl_bind_key_in_map (TAB, dynamic_complete_history, emacs_meta_keymap);
-
-  /* Tell the completer that we want a crack first. */
-  rl_attempted_completion_function = attempt_shell_completion;
-
-  /* Tell the completer that we might want to follow symbolic links or
-     do other expansion on directory names. */
-  rl_directory_completion_hook = bash_directory_completion_hook;
-
-  rl_filename_rewrite_hook = bash_filename_rewrite_hook;
-
-  /* Tell the filename completer we want a chance to ignore some names. */
-  rl_ignore_some_completions_function = filename_completion_ignore;
-
-  /* Bind C-xC-e to invoke emacs and run result as commands. */
-  rl_bind_key_if_unbound_in_map (CTRL ('E'), emacs_edit_and_execute_command, emacs_ctlx_keymap);
-#if defined (VI_MODE)
-  rl_bind_key_if_unbound_in_map ('v', vi_edit_and_execute_command, vi_movement_keymap);
-#  if defined (ALIAS)
-  rl_bind_key_if_unbound_in_map ('@', posix_edit_macros, vi_movement_keymap);
-#  endif
-
-  rl_bind_key_in_map ('\\', bash_vi_complete, vi_movement_keymap);
-  rl_bind_key_in_map ('*', bash_vi_complete, vi_movement_keymap);
-  rl_bind_key_in_map ('=', bash_vi_complete, vi_movement_keymap);
-#endif
-
-  rl_completer_quote_characters = "'\"";
-
-  /* This sets rl_completer_word_break_characters and rl_special_prefixes
-     to the appropriate values, depending on whether or not hostname
-     completion is enabled. */
-  enable_hostname_completion (perform_hostname_completion);
-
-  /* characters that need to be quoted when appearing in filenames. */
-#if 0
-  rl_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:{";       /*}*/
-#else
-  rl_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:{~";      /*}*/
-#endif
-  rl_filename_quoting_function = bash_quote_filename;
-  rl_filename_dequoting_function = bash_dequote_filename;
-  rl_char_is_quoted_p = char_is_quoted;
-
-#if 0
-  /* This is superfluous and makes it impossible to use tab completion in
-     vi mode even when explicitly binding it in ~/.inputrc.  sv_strict_posix()
-     should already have called posix_readline_initialize() when
-     posixly_correct was set. */
-  if (posixly_correct)
-    posix_readline_initialize (1);
-#endif
-
-  bash_readline_initialized = 1;
-}
-
-void
-bashline_reinitialize ()
-{
-  bash_readline_initialized = 0;
-}
-
-/* On Sun systems at least, rl_attempted_completion_function can end up
-   getting set to NULL, and rl_completion_entry_function set to do command
-   word completion if Bash is interrupted while trying to complete a command
-   word.  This just resets all the completion functions to the right thing.
-   It's called from throw_to_top_level(). */
-void
-bashline_reset ()
-{
-  tilde_initialize ();
-  rl_attempted_completion_function = attempt_shell_completion;
-  rl_completion_entry_function = NULL;
-  rl_directory_completion_hook = bash_directory_completion_hook;
-  rl_ignore_some_completions_function = filename_completion_ignore;
-}
-
-/* Contains the line to push into readline. */
-static char *push_to_readline = (char *)NULL;
-
-/* Push the contents of push_to_readline into the
-   readline buffer. */
-static int
-bash_push_line ()
-{
-  if (push_to_readline)
-    {
-      rl_insert_text (push_to_readline);
-      free (push_to_readline);
-      push_to_readline = (char *)NULL;
-      rl_startup_hook = old_rl_startup_hook;
-    }
-  return 0;
-}
-
-/* Call this to set the initial text for the next line to read
-   from readline. */
-int
-bash_re_edit (line)
-     char *line;
-{
-  FREE (push_to_readline);
-
-  push_to_readline = savestring (line);
-  old_rl_startup_hook = rl_startup_hook;
-  rl_startup_hook = bash_push_line;
-
-  return (0);
-}
-
-static int
-display_shell_version (count, c)
-     int count, c;
-{
-  rl_crlf ();
-  show_shell_version (0);
-  putc ('\r', rl_outstream);
-  fflush (rl_outstream);
-  rl_on_new_line ();
-  rl_redisplay ();
-  return 0;
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*                          Readline Stuff                         */
-/*                                                                 */
-/* **************************************************************** */
-
-/* If the user requests hostname completion, then simply build a list
-   of hosts, and complete from that forever more, or at least until
-   HOSTFILE is unset. */
-
-/* THIS SHOULD BE A STRINGLIST. */
-/* The kept list of hostnames. */
-static char **hostname_list = (char **)NULL;
-
-/* The physical size of the above list. */
-static int hostname_list_size;
-
-/* The number of hostnames in the above list. */
-static int hostname_list_length;
-
-/* Whether or not HOSTNAME_LIST has been initialized. */
-int hostname_list_initialized = 0;
-
-/* Initialize the hostname completion table. */
-static void
-initialize_hostname_list ()
-{
-  char *temp;
-
-  temp = get_string_value ("HOSTFILE");
-  if (temp == 0)
-    temp = get_string_value ("hostname_completion_file");
-  if (temp == 0)
-    temp = DEFAULT_HOSTS_FILE;
-
-  snarf_hosts_from_file (temp);
-
-  if (hostname_list)
-    hostname_list_initialized++;
-}
-
-/* Add NAME to the list of hosts. */
-static void
-add_host_name (name)
-     char *name;
-{
-  if (hostname_list_length + 2 > hostname_list_size)
-    {
-      hostname_list_size = (hostname_list_size + 32) - (hostname_list_size % 32);
-      hostname_list = strvec_resize (hostname_list, hostname_list_size);
-    }
-
-  hostname_list[hostname_list_length++] = savestring (name);
-  hostname_list[hostname_list_length] = (char *)NULL;
-}
-
-#define cr_whitespace(c) ((c) == '\r' || (c) == '\n' || whitespace(c))
-
-static void
-snarf_hosts_from_file (filename)
-     char *filename;
-{
-  FILE *file;
-  char *temp, buffer[256], name[256];
-  register int i, start;
-
-  file = fopen (filename, "r");
-  if (file == 0)
-    return;
-
-  while (temp = fgets (buffer, 255, file))
-    {
-      /* Skip to first character. */
-      for (i = 0; buffer[i] && cr_whitespace (buffer[i]); i++)
-       ;
-
-      /* If comment or blank line, ignore. */
-      if (buffer[i] == '\0' || buffer[i] == '#')
-       continue;
-
-      /* If `preprocessor' directive, do the include. */
-      if (strncmp (buffer + i, "$include ", 9) == 0)
-       {
-         char *incfile, *t;
-
-         /* Find start of filename. */
-         for (incfile = buffer + i + 9; *incfile && whitespace (*incfile); incfile++)
-           ;
-
-         /* Find end of filename. */
-         for (t = incfile; *t && cr_whitespace (*t) == 0; t++)
-           ;
-
-         *t = '\0';
-
-         snarf_hosts_from_file (incfile);
-         continue;
-       }
-
-      /* Skip internet address if present. */
-      if (DIGIT (buffer[i]))
-       for (; buffer[i] && cr_whitespace (buffer[i]) == 0; i++);
-
-      /* Gobble up names.  Each name is separated with whitespace. */
-      while (buffer[i])
-       {
-         for (; cr_whitespace (buffer[i]); i++)
-           ;
-         if (buffer[i] == '\0' || buffer[i] ==  '#')
-           break;
-
-         /* Isolate the current word. */
-         for (start = i; buffer[i] && cr_whitespace (buffer[i]) == 0; i++)
-           ;
-         if (i == start)
-           continue;
-         strncpy (name, buffer + start, i - start);
-         name[i - start] = '\0';
-         add_host_name (name);
-       }
-    }
-  fclose (file);
-}
-
-/* Return the hostname list. */
-char **
-get_hostname_list ()
-{
-  if (hostname_list_initialized == 0)
-    initialize_hostname_list ();
-  return (hostname_list);
-}
-
-void
-clear_hostname_list ()
-{
-  register int i;
-
-  if (hostname_list_initialized == 0)
-    return;
-  for (i = 0; i < hostname_list_length; i++)
-    free (hostname_list[i]);
-  hostname_list_length = hostname_list_initialized = 0;
-}
-
-/* Return a NULL terminated list of hostnames which begin with TEXT.
-   Initialize the hostname list the first time if neccessary.
-   The array is malloc ()'ed, but not the individual strings. */
-static char **
-hostnames_matching (text)
-     char *text;
-{
-  register int i, len, nmatch, rsize;
-  char **result;
-
-  if (hostname_list_initialized == 0)
-    initialize_hostname_list ();
-
-  if (hostname_list_initialized == 0)
-    return ((char **)NULL);
-
-  /* Special case.  If TEXT consists of nothing, then the whole list is
-     what is desired. */
-  if (*text == '\0')
-    {
-      result = strvec_create (1 + hostname_list_length);
-      for (i = 0; i < hostname_list_length; i++)
-       result[i] = hostname_list[i];
-      result[i] = (char *)NULL;
-      return (result);
-    }
-
-  /* Scan until found, or failure. */
-  len = strlen (text);
-  result = (char **)NULL;
-  for (i = nmatch = rsize = 0; i < hostname_list_length; i++)
-    {
-      if (STREQN (text, hostname_list[i], len) == 0)
-       continue;
-
-      /* OK, it matches.  Add it to the list. */
-      if (nmatch >= (rsize - 1))
-       {
-         rsize = (rsize + 16) - (rsize % 16);
-         result = strvec_resize (result, rsize);
-       }
-
-      result[nmatch++] = hostname_list[i];
-    }
-  if (nmatch)
-    result[nmatch] = (char *)NULL;
-  return (result);
-}
-
-/* The equivalent of the Korn shell C-o operate-and-get-next-history-line
-   editing command. */
-static int saved_history_line_to_use = -1;
-
-static int
-set_saved_history ()
-{
-  if (saved_history_line_to_use >= 0)
-    rl_get_previous_history (history_length - saved_history_line_to_use, 0);
-  saved_history_line_to_use = -1;
-  rl_startup_hook = old_rl_startup_hook;
-  return (0);
-}
-
-static int
-operate_and_get_next (count, c)
-     int count, c;
-{
-  int where;
-
-  /* Accept the current line. */
-  rl_newline (1, c);
-
-  /* Find the current line, and find the next line to use. */
-  where = where_history ();
-
-  if ((history_is_stifled () && (history_length >= history_max_entries)) ||
-      (where >= history_length - 1))
-    saved_history_line_to_use = where;
-  else
-    saved_history_line_to_use = where + 1;
-
-  old_rl_startup_hook = rl_startup_hook;
-  rl_startup_hook = set_saved_history;
-
-  return 0;
-}
-
-/* This vi mode command causes VI_EDIT_COMMAND to be run on the current
-   command being entered (if no explicit argument is given), otherwise on
-   a command from the history file. */
-
-#define VI_EDIT_COMMAND                "fc -e \"${VISUAL:-${EDITOR:-vi}}\""
-#define EMACS_EDIT_COMMAND     "fc -e \"${VISUAL:-${EDITOR:-emacs}}\""
-#define POSIX_VI_EDIT_COMMAND  "fc -e vi"
-
-static int
-edit_and_execute_command (count, c, editing_mode, edit_command)
-     int count, c, editing_mode;
-     char *edit_command;
-{
-  char *command, *metaval;
-  int r, cclc, rrs, metaflag;
-
-  rrs = rl_readline_state;
-  cclc = current_command_line_count;
-
-  /* Accept the current line. */
-  rl_newline (1, c);
-
-  if (rl_explicit_arg)
-    {
-      command = (char *)xmalloc (strlen (edit_command) + 8);
-      sprintf (command, "%s %d", edit_command, count);
-    }
-  else
-    {
-      /* Take the command we were just editing, add it to the history file,
-        then call fc to operate on it.  We have to add a dummy command to
-        the end of the history because fc ignores the last command (assumes
-        it's supposed to deal with the command before the `fc'). */
-      using_history ();
-      bash_add_history (rl_line_buffer);
-      bash_add_history ("");
-      history_lines_this_session++;
-      using_history ();
-      command = savestring (edit_command);
-    }
-
-  metaval = rl_variable_value ("input-meta");
-  metaflag = RL_BOOLEAN_VARIABLE_VALUE (metaval);
-  
-  /* Now, POSIX.1-2001 and SUSv3 say that the commands executed from the
-     temporary file should be placed into the history.  We don't do that
-     yet. */
-  if (rl_deprep_term_function)
-    (*rl_deprep_term_function) ();
-  r = parse_and_execute (command, (editing_mode == VI_EDITING_MODE) ? "v" : "C-xC-e", SEVAL_NOHIST);
-  if (rl_prep_term_function)
-    (*rl_prep_term_function) (metaflag);
-
-  current_command_line_count = cclc;
-
-  /* Now erase the contents of the current line and undo the effects of the
-     rl_accept_line() above.  We don't even want to make the text we just
-     executed available for undoing. */
-  rl_line_buffer[0] = '\0';    /* XXX */
-  rl_point = rl_end = 0;
-  rl_done = 0;
-  rl_readline_state = rrs;
-
-  rl_forced_update_display ();
-
-  return r;
-}
-
-#if defined (VI_MODE)
-static int
-vi_edit_and_execute_command (count, c)
-     int count, c;
-{
-  if (posixly_correct)
-    return (edit_and_execute_command (count, c, VI_EDITING_MODE, POSIX_VI_EDIT_COMMAND));
-  else
-    return (edit_and_execute_command (count, c, VI_EDITING_MODE, VI_EDIT_COMMAND));
-}
-#endif /* VI_MODE */
-
-static int
-emacs_edit_and_execute_command (count, c)
-     int count, c;
-{
-  return (edit_and_execute_command (count, c, EMACS_EDITING_MODE, EMACS_EDIT_COMMAND));
-}
-
-#if defined (ALIAS)
-static int
-posix_edit_macros (count, key)
-     int count, key;
-{
-  int c;
-  char alias_name[3], *alias_value, *macro;
-
-  c = rl_read_key ();
-  alias_name[0] = '_';
-  alias_name[1] = c;
-  alias_name[2] = '\0';
-
-  alias_value = get_alias_value (alias_name);
-  if (alias_value && *alias_value)
-    {
-      macro = savestring (alias_value);
-      rl_push_macro_input (macro);
-    }
-  return 0;
-}
-#endif
-
-/* Bindable commands that move `shell-words': that is, sequences of
-   non-unquoted-metacharacters. */
-
-#define WORDDELIM(c)   (shellmeta(c) || shellblank(c))
-
-static int
-bash_forward_shellword (count, key)
-     int count, key;
-{
-  size_t slen;
-  int sindex, c, p;
-  DECLARE_MBSTATE;
-
-  if (count < 0)
-    return (bash_backward_shellword (-count, key));
-
-  /* The tricky part of this is deciding whether or not the first character
-     we're on is an unquoted metacharacter.  Not completely handled yet. */
-  /* XXX - need to test this stuff with backslash-escaped shell
-     metacharacters and unclosed single- and double-quoted strings. */
-
-  p = rl_point;
-  slen = rl_end;
-
-  while (count)
-    {
-      if (p == rl_end)
-       {
-         rl_point = rl_end;
-         return 0;
-       }
-
-      /* Move forward until we hit a non-metacharacter. */
-      while (p < rl_end && (c = rl_line_buffer[p]) && WORDDELIM (c))
-       {
-         switch (c)
-           {
-           default:
-             ADVANCE_CHAR (rl_line_buffer, slen, p);
-             continue;         /* straight back to loop, don't increment p */
-           case '\\':
-             if (p < rl_end && rl_line_buffer[p])
-               ADVANCE_CHAR (rl_line_buffer, slen, p);
-             break;
-           case '\'':
-             p = skip_to_delim (rl_line_buffer, ++p, "'", SD_NOJMP);
-             break;
-           case '"':
-             p = skip_to_delim (rl_line_buffer, ++p, "\"", SD_NOJMP);
-             break;
-           }
-
-         if (p < rl_end)
-           p++;
-       }
-
-      if (rl_line_buffer[p] == 0 || p == rl_end)
-        {
-         rl_point = rl_end;
-         rl_ding ();
-         return 0;
-        }
-       
-      /* Now move forward until we hit a non-quoted metacharacter or EOL */
-      while (p < rl_end && (c = rl_line_buffer[p]) && WORDDELIM (c) == 0)
-       {
-         switch (c)
-           {
-           default:
-             ADVANCE_CHAR (rl_line_buffer, slen, p);
-             continue;         /* straight back to loop, don't increment p */
-           case '\\':
-             if (p < rl_end && rl_line_buffer[p])
-               ADVANCE_CHAR (rl_line_buffer, slen, p);
-             break;
-           case '\'':
-             p = skip_to_delim (rl_line_buffer, ++p, "'", SD_NOJMP);
-             break;
-           case '"':
-             p = skip_to_delim (rl_line_buffer, ++p, "\"", SD_NOJMP);
-             break;
-           }
-
-         if (p < rl_end)
-           p++;
-       }
-
-      if (p == rl_end || rl_line_buffer[p] == 0)
-       {
-         rl_point = rl_end;
-         return (0);
-       }
-
-      count--;      
-    }
-
-  rl_point = p;
-  return (0);
-}
-
-static int
-bash_backward_shellword (count, key)
-     int count, key;
-{
-  size_t slen;
-  int sindex, c, p;
-  DECLARE_MBSTATE;
-  
-  if (count < 0)
-    return (bash_forward_shellword (-count, key));
-
-  p = rl_point;
-  slen = rl_end;
-  
-  while (count)
-    {
-      if (p == 0)
-       {
-         rl_point = 0;
-         return 0;
-       }
-
-      /* Move backward until we hit a non-metacharacter. */
-      while (p > 0)
-       {
-         c = rl_line_buffer[p];
-         if (WORDDELIM (c) && char_is_quoted (rl_line_buffer, p) == 0)
-           BACKUP_CHAR (rl_line_buffer, slen, p);
-         break;
-       }
-
-      if (p == 0)
-       {
-         rl_point = 0;
-         return 0;
-       }
-
-      /* Now move backward until we hit a metacharacter or BOL. */
-      while (p > 0)
-       {
-         c = rl_line_buffer[p];
-         if (WORDDELIM (c) && char_is_quoted (rl_line_buffer, p) == 0)
-           break;
-         BACKUP_CHAR (rl_line_buffer, slen, p);
-       }
-
-      count--;
-    }
-
-  rl_point = p;
-  return 0;
-}
-
-static int
-bash_kill_shellword (count, key)
-     int count, key;
-{
-  int p;
-
-  if (count < 0)
-    return (bash_backward_kill_shellword (-count, key));
-
-  p = rl_point;
-  bash_forward_shellword (count, key);
-
-  if (rl_point != p)
-    rl_kill_text (p, rl_point);
-
-  rl_point = p;
-  if (rl_editing_mode == 1)    /* 1 == emacs_mode */
-    rl_mark = rl_point;
-
-  return 0;
-}
-
-static int
-bash_backward_kill_shellword (count, key)
-     int count, key;
-{
-  int p;
-
-  if (count < 0)
-    return (bash_kill_shellword (-count, key));
-
-  p = rl_point;
-  bash_backward_shellword (count, key);
-
-  if (rl_point != p)
-    rl_kill_text (p, rl_point);
-
-  if (rl_editing_mode == 1)    /* 1 == emacs_mode */
-    rl_mark = rl_point;
-
-  return 0;
-}
-
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     How To Do Shell Completion                  */
-/*                                                                 */
-/* **************************************************************** */
-
-#define COMMAND_SEPARATORS ";|&{(`"
-/* )} */ 
-
-static int
-check_redir (ti)
-     int ti;
-{
-  register int this_char, prev_char;
-
-  /* Handle the two character tokens `>&', `<&', and `>|'.
-     We are not in a command position after one of these. */
-  this_char = rl_line_buffer[ti];
-  prev_char = rl_line_buffer[ti - 1];
-
-  if ((this_char == '&' && (prev_char == '<' || prev_char == '>')) ||
-      (this_char == '|' && prev_char == '>'))
-    return (1);
-  else if ((this_char == '{' && prev_char == '$') || /* } */
-          (char_is_quoted (rl_line_buffer, ti)))
-    return (1);
-  return (0);
-}
-
-#if defined (PROGRAMMABLE_COMPLETION)
-/*
- * XXX - because of the <= start test, and setting os = s+1, this can
- * potentially return os > start.  This is probably not what we want to
- * happen, but fix later after 2.05a-release.
- */
-static int
-find_cmd_start (start)
-     int start;
-{
-  register int s, os;
-
-  os = 0;
-  while (((s = skip_to_delim (rl_line_buffer, os, COMMAND_SEPARATORS, SD_NOJMP|SD_NOSKIPCMD)) <= start) &&
-        rl_line_buffer[s])
-    os = s+1;
-  return os;
-}
-
-static int
-find_cmd_end (end)
-     int end;
-{
-  register int e;
-
-  e = skip_to_delim (rl_line_buffer, end, COMMAND_SEPARATORS, SD_NOJMP);
-  return e;
-}
-
-static char *
-find_cmd_name (start)
-     int start;
-{
-  char *name;
-  register int s, e;
-
-  for (s = start; whitespace (rl_line_buffer[s]); s++)
-    ;
-
-  /* skip until a shell break character */
-  e = skip_to_delim (rl_line_buffer, s, "()<>;&| \t\n", SD_NOJMP);
-
-  name = substring (rl_line_buffer, s, e);
-
-  return (name);
-}
-
-static char *
-prog_complete_return (text, matchnum)
-     const char *text;
-     int matchnum;
-{
-  static int ind;
-
-  if (matchnum == 0)
-    ind = 0;
-
-  if (prog_complete_matches == 0 || prog_complete_matches[ind] == 0)
-    return (char *)NULL;
-  return (prog_complete_matches[ind++]);
-}
-
-#endif /* PROGRAMMABLE_COMPLETION */
-
-/* Do some completion on TEXT.  The indices of TEXT in RL_LINE_BUFFER are
-   at START and END.  Return an array of matches, or NULL if none. */
-static char **
-attempt_shell_completion (text, start, end)
-     const char *text;
-     int start, end;
-{
-  int in_command_position, ti, saveti, qc, dflags;
-  char **matches, *command_separator_chars;
-
-  command_separator_chars = COMMAND_SEPARATORS;
-  matches = (char **)NULL;
-  rl_ignore_some_completions_function = filename_completion_ignore;
-
-  /* Determine if this could be a command word.  It is if it appears at
-     the start of the line (ignoring preceding whitespace), or if it
-     appears after a character that separates commands.  It cannot be a
-     command word if we aren't at the top-level prompt. */
-  ti = start - 1;
-  saveti = qc = -1;
-
-  while ((ti > -1) && (whitespace (rl_line_buffer[ti])))
-    ti--;
-
-#if 1
-  /* If this is an open quote, maybe we're trying to complete a quoted
-     command name. */
-  if (ti >= 0 && (rl_line_buffer[ti] == '"' || rl_line_buffer[ti] == '\''))
-    {
-      qc = rl_line_buffer[ti];
-      saveti = ti--;
-      while (ti > -1 && (whitespace (rl_line_buffer[ti])))
-       ti--;
-    }
-#endif
-      
-  in_command_position = 0;
-  if (ti < 0)
-    {
-      /* Only do command completion at the start of a line when we
-        are prompting at the top level. */
-      if (current_prompt_string == ps1_prompt)
-       in_command_position++;
-    }
-  else if (member (rl_line_buffer[ti], command_separator_chars))
-    {
-      in_command_position++;
-
-      if (check_redir (ti) == 1)
-       in_command_position = 0;
-    }
-  else
-    {
-      /* This still could be in command position.  It is possible
-        that all of the previous words on the line are variable
-        assignments. */
-    }
-
-  /* Check that we haven't incorrectly flagged a closed command substitution
-     as indicating we're in a command position. */
-  if (in_command_position && ti >= 0 && rl_line_buffer[ti] == '`' &&
-       *text != '`' && unclosed_pair (rl_line_buffer, end, "`") == 0)
-    in_command_position = 0;
-
-  /* Special handling for command substitution.  If *TEXT is a backquote,
-     it can be the start or end of an old-style command substitution, or
-     unmatched.  If it's unmatched, both calls to unclosed_pair will
-     succeed.  */
-  if (*text == '`' && 
-       (in_command_position || (unclosed_pair (rl_line_buffer, start, "`") &&
-                                unclosed_pair (rl_line_buffer, end, "`"))))
-    matches = rl_completion_matches (text, command_subst_completion_function);
-
-#if defined (PROGRAMMABLE_COMPLETION)
-  /* Attempt programmable completion. */
-  if (matches == 0 && (in_command_position == 0 || text[0] == '\0') &&
-      prog_completion_enabled && (progcomp_size () > 0) &&
-      current_prompt_string == ps1_prompt)
-    {
-      int s, e, foundcs;
-      char *n;
-
-      /* XXX - don't free the members */
-      if (prog_complete_matches)
-       free (prog_complete_matches);
-      prog_complete_matches = (char **)NULL;
-
-      s = find_cmd_start (start);
-      e = find_cmd_end (end);
-      n = find_cmd_name (s);
-      if (e == 0 && e == s && text[0] == '\0')
-        prog_complete_matches = programmable_completions ("_EmptycmD_", text, s, e, &foundcs);
-      else if (e > s && assignment (n, 0) == 0)
-       prog_complete_matches = programmable_completions (n, text, s, e, &foundcs);
-      else
-       foundcs = 0;
-      FREE (n);
-      /* XXX - if we found a COMPSPEC for the command, just return whatever
-        the programmable completion code returns, and disable the default
-        filename completion that readline will do unless the COPT_DEFAULT
-        option has been set with the `-o default' option to complete or
-        compopt. */
-      if (foundcs)
-       {
-         pcomp_set_readline_variables (foundcs, 1);
-         /* Turn what the programmable completion code returns into what
-            readline wants.  I should have made compute_lcd_of_matches
-            external... */
-         matches = rl_completion_matches (text, prog_complete_return);
-         if ((foundcs & COPT_DEFAULT) == 0)
-           rl_attempted_completion_over = 1;   /* no default */
-         if (matches || ((foundcs & COPT_BASHDEFAULT) == 0))
-           return (matches);
-       }
-    }
-#endif
-
-  if (matches == 0)
-    {
-      dflags = 0;
-      if (in_command_position)
-       dflags |= DEFCOMP_CMDPOS;
-      matches = bash_default_completion (text, start, end, qc, dflags);
-    }
-
-  return matches;
-}
-
-char **
-bash_default_completion (text, start, end, qc, compflags)
-     const char *text;
-     int start, end, qc, compflags;
-{
-  char **matches;
-
-  matches = (char **)NULL;
-
-  /* New posix-style command substitution or variable name? */
-  if (!matches && *text == '$')
-    {
-      if (qc != '\'' && text[1] == '(') /* ) */
-       matches = rl_completion_matches (text, command_subst_completion_function);
-      else
-       matches = rl_completion_matches (text, variable_completion_function);
-    }
-
-  /* If the word starts in `~', and there is no slash in the word, then
-     try completing this word as a username. */
-  if (matches ==0 && *text == '~' && mbschr (text, '/') == 0)
-    matches = rl_completion_matches (text, rl_username_completion_function);
-
-  /* Another one.  Why not?  If the word starts in '@', then look through
-     the world of known hostnames for completion first. */
-  if (!matches && perform_hostname_completion && *text == '@')
-    matches = rl_completion_matches (text, hostname_completion_function);
-
-  /* And last, (but not least) if this word is in a command position, then
-     complete over possible command names, including aliases, functions,
-     and command names. */
-  if (matches == 0 && (compflags & DEFCOMP_CMDPOS))
-    {
-      /* If END == START and text[0] == 0, we are trying to complete an empty
-        command word. */
-      if (no_empty_command_completion && end == start && text[0] == '\0')
-       {
-         matches = (char **)NULL;
-         rl_ignore_some_completions_function = bash_ignore_everything;
-       }
-      else
-       {
-#define CMD_IS_DIR(x)  (absolute_pathname(x) == 0 && absolute_program(x) == 0 && *(x) != '~' && test_for_directory (x))
-
-         dot_in_path = 0;
-         matches = rl_completion_matches (text, command_word_completion_function);
-
-         /* If we are attempting command completion and nothing matches, we
-            do not want readline to perform filename completion for us.  We
-            still want to be able to complete partial pathnames, so set the
-            completion ignore function to something which will remove
-            filenames and leave directories in the match list. */
-         if (matches == (char **)NULL)
-           rl_ignore_some_completions_function = bash_ignore_filenames;
-         else if (matches[1] == 0 && CMD_IS_DIR(matches[0]) && dot_in_path == 0)
-           /* If we found a single match, without looking in the current
-              directory (because it's not in $PATH), but the found name is
-              also a command in the current directory, suppress appending any
-              terminating character, since it's ambiguous. */
-           {
-             rl_completion_suppress_append = 1;
-             rl_filename_completion_desired = 0;
-           }
-         else if (matches[0] && matches[1] && STREQ (matches[0], matches[1]) && CMD_IS_DIR (matches[0]))
-           /* There are multiple instances of the same match (duplicate
-              completions haven't yet been removed).  In this case, all of
-              the matches will be the same, and the duplicate removal code
-              will distill them all down to one.  We turn on
-              rl_completion_suppress_append for the same reason as above.
-              Remember: we only care if there's eventually a single unique
-              completion.  If there are multiple completions this won't
-              make a difference and the problem won't occur. */
-           {
-             rl_completion_suppress_append = 1;
-             rl_filename_completion_desired = 0;
-           }
-       }
-    }
-
-  /* This could be a globbing pattern, so try to expand it using pathname
-     expansion. */
-  if (!matches && glob_pattern_p (text))
-    {
-      matches = rl_completion_matches (text, glob_complete_word);
-      /* A glob expression that matches more than one filename is problematic.
-        If we match more than one filename, punt. */
-      if (matches && matches[1] && rl_completion_type == TAB)
-       {
-         strvec_dispose (matches);
-         matches = (char **)0;
-       }
-    }
-
-  return (matches);
-}
-
-/* This is the function to call when the word to complete is in a position
-   where a command word can be found.  It grovels $PATH, looking for commands
-   that match.  It also scans aliases, function names, and the shell_builtin
-   table. */
-char *
-command_word_completion_function (hint_text, state)
-     const char *hint_text;
-     int state;
-{
-  static char *hint = (char *)NULL;
-  static char *path = (char *)NULL;
-  static char *val = (char *)NULL;
-  static char *filename_hint = (char *)NULL;
-  static char *dequoted_hint = (char *)NULL;
-  static char *directory_part = (char *)NULL;
-  static char **glob_matches = (char **)NULL;
-  static int path_index, hint_len, dequoted_len, istate, igncase;
-  static int mapping_over, local_index, searching_path, hint_is_dir;
-  static int old_glob_ignore_case, globpat;
-  static SHELL_VAR **varlist = (SHELL_VAR **)NULL;
-#if defined (ALIAS)
-  static alias_t **alias_list = (alias_t **)NULL;
-#endif /* ALIAS */
-  char *temp;
-
-  /* We have to map over the possibilities for command words.  If we have
-     no state, then make one just for that purpose. */
-  if (state == 0)
-    {
-      if (dequoted_hint && dequoted_hint != hint)
-       free (dequoted_hint);
-      if (hint)
-       free (hint);
-
-      mapping_over = searching_path = 0;
-      hint_is_dir = CMD_IS_DIR (hint_text);
-      val = (char *)NULL;
-
-      temp = rl_variable_value ("completion-ignore-case");
-      igncase = RL_BOOLEAN_VARIABLE_VALUE (temp);
-
-      if (glob_matches)
-       {
-         free (glob_matches);
-         glob_matches = (char **)NULL;
-       }
-
-      globpat = glob_pattern_p (hint_text);
-
-      /* If this is an absolute program name, do not check it against
-        aliases, reserved words, functions or builtins.  We must check
-        whether or not it is unique, and, if so, whether that filename
-        is executable. */
-      if (globpat || absolute_program (hint_text))
-       {
-         /* Perform tilde expansion on what's passed, so we don't end up
-            passing filenames with tildes directly to stat(). */
-         if (*hint_text == '~')
-           {
-             hint = bash_tilde_expand (hint_text, 0);
-             directory_part = savestring (hint_text);
-             temp = strchr (directory_part, '/');
-             if (temp)
-               *temp = 0;
-             else
-               {
-                 free (directory_part);
-                 directory_part = (char *)NULL;
-               }
-           }
-         else
-           hint = savestring (hint_text);
-
-         dequoted_hint = hint;
-         /* If readline's completer found a quote character somewhere, but
-            didn't set the quote character, there must have been a quote
-            character embedded in the filename.  It can't be at the start of
-            the filename, so we need to dequote the filename before we look
-            in the file system for it. */
-         if (rl_completion_found_quote && rl_completion_quote_character == 0)
-           {
-             dequoted_hint = bash_dequote_filename (hint, 0);
-             free (hint);
-             hint = dequoted_hint;
-           }
-         dequoted_len = hint_len = strlen (hint);
-
-         if (filename_hint)
-           free (filename_hint);
-
-         filename_hint = savestring (hint);
-
-         istate = 0;
-
-         if (globpat)
-           {
-             mapping_over = 5;
-             goto globword;
-           }
-         else
-           {
-             mapping_over = 4;
-             goto inner;
-           }
-       }
-
-      dequoted_hint = hint = savestring (hint_text);
-      dequoted_len = hint_len = strlen (hint);
-
-      if (rl_completion_found_quote && rl_completion_quote_character == 0)
-       {
-         dequoted_hint = bash_dequote_filename (hint, 0);
-         dequoted_len = strlen (dequoted_hint);
-       }
-      
-      path = get_string_value ("PATH");
-      path_index = dot_in_path = 0;
-
-      /* Initialize the variables for each type of command word. */
-      local_index = 0;
-
-      if (varlist)
-       free (varlist);
-
-      varlist = all_visible_functions ();
-
-#if defined (ALIAS)
-      if (alias_list)
-       free (alias_list);
-
-      alias_list = all_aliases ();
-#endif /* ALIAS */
-    }
-
-  /* mapping_over says what we are currently hacking.  Note that every case
-     in this list must fall through when there are no more possibilities. */
-
-  switch (mapping_over)
-    {
-    case 0:                    /* Aliases come first. */
-#if defined (ALIAS)
-      while (alias_list && alias_list[local_index])
-       {
-         register char *alias;
-
-         alias = alias_list[local_index++]->name;
-
-         if (STREQN (alias, hint, hint_len))
-           return (savestring (alias));
-       }
-#endif /* ALIAS */
-      local_index = 0;
-      mapping_over++;
-
-    case 1:                    /* Then shell reserved words. */
-      {
-       while (word_token_alist[local_index].word)
-         {
-           register char *reserved_word;
-
-           reserved_word = word_token_alist[local_index++].word;
-
-           if (STREQN (reserved_word, hint, hint_len))
-             return (savestring (reserved_word));
-         }
-       local_index = 0;
-       mapping_over++;
-      }
-
-    case 2:                    /* Then function names. */
-      while (varlist && varlist[local_index])
-       {
-         register char *varname;
-
-         varname = varlist[local_index++]->name;
-
-         if (STREQN (varname, hint, hint_len))
-           return (savestring (varname));
-       }
-      local_index = 0;
-      mapping_over++;
-
-    case 3:                    /* Then shell builtins. */
-      for (; local_index < num_shell_builtins; local_index++)
-       {
-         /* Ignore it if it doesn't have a function pointer or if it
-            is not currently enabled. */
-         if (!shell_builtins[local_index].function ||
-             (shell_builtins[local_index].flags & BUILTIN_ENABLED) == 0)
-           continue;
-
-         if (STREQN (shell_builtins[local_index].name, hint, hint_len))
-           {
-             int i = local_index++;
-
-             return (savestring (shell_builtins[i].name));
-           }
-       }
-      local_index = 0;
-      mapping_over++;
-    }
-
-globword:
-  /* Limited support for completing command words with globbing chars.  Only
-     a single match (multiple matches that end up reducing the number of
-     characters in the common prefix are bad) will ever be returned on
-     regular completion. */
-  if (glob_pattern_p (hint))
-    {
-      if (state == 0)
-       {
-         glob_ignore_case = igncase;
-         glob_matches = shell_glob_filename (hint);
-         glob_ignore_case = old_glob_ignore_case;
-
-         if (GLOB_FAILED (glob_matches) || glob_matches == 0)
-           {
-             glob_matches = (char **)NULL;
-             return ((char *)NULL);
-           }
-
-         local_index = 0;
-               
-         if (glob_matches[1] && rl_completion_type == TAB)     /* multiple matches are bad */
-           return ((char *)NULL);
-       }
-
-      while (val = glob_matches[local_index++])
-        {
-         if (executable_or_directory (val))
-           {
-             if (*hint_text == '~')
-               {
-                 temp = restore_tilde (val, directory_part);
-                 free (val);
-                 val = temp;
-               }
-             return (val);
-           }
-         free (val);
-        }
-
-      glob_ignore_case = old_glob_ignore_case;
-      return ((char *)NULL);
-    }
-
-  /* If the text passed is a directory in the current directory, return it
-     as a possible match.  Executables in directories in the current
-     directory can be specified using relative pathnames and successfully
-     executed even when `.' is not in $PATH. */
-  if (hint_is_dir)
-    {
-      hint_is_dir = 0; /* only return the hint text once */
-      return (savestring (hint_text));
-    }
-    
-  /* Repeatedly call filename_completion_function while we have
-     members of PATH left.  Question:  should we stat each file?
-     Answer: we call executable_file () on each file. */
- outer:
-
-  istate = (val != (char *)NULL);
-
-  if (istate == 0)
-    {
-      char *current_path;
-
-      /* Get the next directory from the path.  If there is none, then we
-        are all done. */
-      if (path == 0 || path[path_index] == 0 ||
-         (current_path = extract_colon_unit (path, &path_index)) == 0)
-       return ((char *)NULL);
-
-      searching_path = 1;
-      if (*current_path == 0)
-       {
-         free (current_path);
-         current_path = savestring (".");
-       }
-
-      if (*current_path == '~')
-       {
-         char *t;
-
-         t = bash_tilde_expand (current_path, 0);
-         free (current_path);
-         current_path = t;
-       }
-
-      if (current_path[0] == '.' && current_path[1] == '\0')
-       dot_in_path = 1;
-
-      if (filename_hint)
-       free (filename_hint);
-
-      filename_hint = sh_makepath (current_path, hint, 0);
-      free (current_path);             /* XXX */
-    }
-
- inner:
-  val = rl_filename_completion_function (filename_hint, istate);
-  istate = 1;
-
-  if (val == 0)
-    {
-      /* If the hint text is an absolute program, then don't bother
-        searching through PATH. */
-      if (absolute_program (hint))
-       return ((char *)NULL);
-
-      goto outer;
-    }
-  else
-    {
-      int match, freetemp;
-
-      if (absolute_program (hint))
-       {
-         if (igncase == 0)
-           match = strncmp (val, hint, hint_len) == 0;
-         else
-           match = strncasecmp (val, hint, hint_len) == 0;
-
-         /* If we performed tilde expansion, restore the original
-            filename. */
-         if (*hint_text == '~')
-           temp = restore_tilde (val, directory_part);
-         else
-           temp = savestring (val);
-         freetemp = 1;
-       }
-      else
-       {
-         temp = strrchr (val, '/');
-
-         if (temp)
-           {
-             temp++;
-             if (igncase == 0)
-               freetemp = match = strncmp (temp, hint, hint_len) == 0;
-             else
-               freetemp = match = strncasecmp (temp, hint, hint_len) == 0;
-             if (match)
-               temp = savestring (temp);
-           }
-         else
-           freetemp = match = 0;
-       }
-
-#if 0
-      /* If we have found a match, and it is an executable file or a
-        directory name, return it. */
-      if (match && executable_or_directory (val))
-#else
-      /* If we have found a match, and it is an executable file, return it.
-        We don't return directory names when searching $PATH, since the
-        bash execution code won't find executables in directories which
-        appear in directories in $PATH when they're specified using
-        relative pathnames. */
-      if (match && (searching_path ? executable_file (val) : executable_or_directory (val)))
-#endif
-       {
-         free (val);
-         val = "";             /* So it won't be NULL. */
-         return (temp);
-       }
-      else
-       {
-         if (freetemp)
-           free (temp);
-         free (val);
-         goto inner;
-       }
-    }
-}
-
-/* Completion inside an unterminated command substitution. */
-static char *
-command_subst_completion_function (text, state)
-     const char *text;
-     int state;
-{
-  static char **matches = (char **)NULL;
-  static const char *orig_start;
-  static char *filename_text = (char *)NULL;
-  static int cmd_index, start_len;
-  char *value;
-
-  if (state == 0)
-    {
-      if (filename_text)
-       free (filename_text);
-      orig_start = text;
-      if (*text == '`')
-       text++;
-      else if (*text == '$' && text[1] == '(') /* ) */
-       text += 2;
-      /* If the text was quoted, suppress any quote character that the
-        readline completion code would insert. */
-      rl_completion_suppress_quote = 1;
-      start_len = text - orig_start;
-      filename_text = savestring (text);
-      if (matches)
-       free (matches);
-
-      /*
-       * At this point we can entertain the idea of re-parsing
-       * `filename_text' into a (possibly incomplete) command name and
-       * arguments, and doing completion based on that.  This is
-       * currently very rudimentary, but it is a small improvement.
-       */
-      for (value = filename_text + strlen (filename_text) - 1; value > filename_text; value--)
-        if (whitespace (*value) || member (*value, COMMAND_SEPARATORS))
-          break;
-      if (value <= filename_text)
-       matches = rl_completion_matches (filename_text, command_word_completion_function);
-      else
-       {
-         value++;
-         start_len += value - filename_text;
-         if (whitespace (value[-1]))
-           matches = rl_completion_matches (value, rl_filename_completion_function);
-         else
-           matches = rl_completion_matches (value, command_word_completion_function);
-       }
-
-      /* If there is more than one match, rl_completion_matches has already
-        put the lcd in matches[0].  Skip over it. */
-      cmd_index = matches && matches[0] && matches[1];
-
-      /* If there's a single match and it's a directory, set the append char
-        to the expected `/'.  Otherwise, don't append anything. */
-      if (matches && matches[0] && matches[1] == 0 && test_for_directory (matches[0]))
-       rl_completion_append_character = '/';
-      else
-       rl_completion_suppress_append = 1;
-    }
-
-  if (!matches || !matches[cmd_index])
-    {
-      rl_filename_quoting_desired = 0; /* disable quoting */
-      return ((char *)NULL);
-    }
-  else
-    {
-      value = (char *)xmalloc (1 + start_len + strlen (matches[cmd_index]));
-
-      if (start_len == 1)
-       value[0] = *orig_start;
-      else
-       strncpy (value, orig_start, start_len);
-
-      strcpy (value + start_len, matches[cmd_index]);
-
-      cmd_index++;
-      return (value);
-    }
-}
-
-/* Okay, now we write the entry_function for variable completion. */
-static char *
-variable_completion_function (text, state)
-     const char *text;
-     int state;
-{
-  static char **varlist = (char **)NULL;
-  static int varlist_index;
-  static char *varname = (char *)NULL;
-  static int namelen;
-  static int first_char, first_char_loc;
-
-  if (!state)
-    {
-      if (varname)
-       free (varname);
-
-      first_char_loc = 0;
-      first_char = text[0];
-
-      if (first_char == '$')
-       first_char_loc++;
-
-      if (text[first_char_loc] == '{')
-       first_char_loc++;
-
-      varname = savestring (text + first_char_loc);
-
-      namelen = strlen (varname);
-      if (varlist)
-       strvec_dispose (varlist);
-
-      varlist = all_variables_matching_prefix (varname);
-      varlist_index = 0;
-    }
-
-  if (!varlist || !varlist[varlist_index])
-    {
-      return ((char *)NULL);
-    }
-  else
-    {
-      char *value;
-
-      value = (char *)xmalloc (4 + strlen (varlist[varlist_index]));
-
-      if (first_char_loc)
-       {
-         value[0] = first_char;
-         if (first_char_loc == 2)
-           value[1] = '{';
-       }
-
-      strcpy (value + first_char_loc, varlist[varlist_index]);
-      if (first_char_loc == 2)
-       strcat (value, "}");
-
-      varlist_index++;
-      return (value);
-    }
-}
-
-/* How about a completion function for hostnames? */
-static char *
-hostname_completion_function (text, state)
-     const char *text;
-     int state;
-{
-  static char **list = (char **)NULL;
-  static int list_index = 0;
-  static int first_char, first_char_loc;
-
-  /* If we don't have any state, make some. */
-  if (state == 0)
-    {
-      FREE (list);
-
-      list = (char **)NULL;
-
-      first_char_loc = 0;
-      first_char = *text;
-
-      if (first_char == '@')
-       first_char_loc++;
-
-      list = hostnames_matching ((char *)text+first_char_loc);
-      list_index = 0;
-    }
-
-  if (list && list[list_index])
-    {
-      char *t;
-
-      t = (char *)xmalloc (2 + strlen (list[list_index]));
-      *t = first_char;
-      strcpy (t + first_char_loc, list[list_index]);
-      list_index++;
-      return (t);
-    }
-
-  return ((char *)NULL);
-}
-
-/*
- * A completion function for service names from /etc/services (or wherever).
- */
-char *
-bash_servicename_completion_function (text, state)
-     const char *text;
-     int state;
-{
-#if defined (__WIN32__) || defined (__OPENNT) || !defined (HAVE_GETSERVENT)
-  return ((char *)NULL);
-#else
-  static char *sname = (char *)NULL;
-  static struct servent *srvent;
-  static int snamelen, firstc;
-  char *value;
-  char **alist, *aentry;
-  int afound;
-
-  if (state == 0)
-    {
-      FREE (sname);
-      firstc = *text;
-
-      sname = savestring (text);
-      snamelen = strlen (sname);
-      setservent (0);
-    }
-
-  while (srvent = getservent ())
-    {
-      afound = 0;
-      if (snamelen == 0 || (STREQN (sname, srvent->s_name, snamelen)))
-       break;
-      /* Not primary, check aliases */
-      for (alist = srvent->s_aliases; *alist; alist++)
-       {
-         aentry = *alist;
-         if (STREQN (sname, aentry, snamelen))
-           {
-             afound = 1;
-             break;
-           }
-       }
-
-      if (afound)
-       break;
-    }
-
-  if (srvent == 0)
-    {
-      endservent ();
-      return ((char *)NULL);
-    }
-
-  value = afound ? savestring (aentry) : savestring (srvent->s_name);
-  return value;
-#endif
-}
-
-/*
- * A completion function for group names from /etc/group (or wherever).
- */
-char *
-bash_groupname_completion_function (text, state)
-     const char *text;
-     int state;
-{
-#if defined (__WIN32__) || defined (__OPENNT) || !defined (HAVE_GRP_H)
-  return ((char *)NULL);
-#else
-  static char *gname = (char *)NULL;
-  static struct group *grent;
-  static int gnamelen;
-  char *value;
-
-  if (state == 0)
-    {
-      FREE (gname);
-      gname = savestring (text);
-      gnamelen = strlen (gname);
-
-      setgrent ();
-    }
-
-  while (grent = getgrent ())
-    {
-      if (gnamelen == 0 || (STREQN (gname, grent->gr_name, gnamelen)))
-        break;
-    }
-
-  if (grent == 0)
-    {
-      endgrent ();
-      return ((char *)NULL);
-    }
-
-  value = savestring (grent->gr_name);
-  return (value);
-#endif
-}
-
-/* Functions to perform history and alias expansions on the current line. */
-
-#if defined (BANG_HISTORY)
-/* Perform history expansion on the current line.  If no history expansion
-   is done, pre_process_line() returns what it was passed, so we need to
-   allocate a new line here. */
-static char *
-history_expand_line_internal (line)
-     char *line;
-{
-  char *new_line;
-  int old_verify;
-
-  old_verify = hist_verify;
-  hist_verify = 0;
-  new_line = pre_process_line (line, 0, 0);
-  hist_verify = old_verify;
-
-  return (new_line == line) ? savestring (line) : new_line;
-}
-#endif
-
-/* There was an error in expansion.  Let the preprocessor print
-   the error here. */
-static void
-cleanup_expansion_error ()
-{
-  char *to_free;
-#if defined (BANG_HISTORY)
-  int old_verify;
-
-  old_verify = hist_verify;
-  hist_verify = 0;
-#endif
-
-  fprintf (rl_outstream, "\r\n");
-  to_free = pre_process_line (rl_line_buffer, 1, 0);
-#if defined (BANG_HISTORY)
-  hist_verify = old_verify;
-#endif
-  if (to_free != rl_line_buffer)
-    FREE (to_free);
-  putc ('\r', rl_outstream);
-  rl_forced_update_display ();
-}
-
-/* If NEW_LINE differs from what is in the readline line buffer, add an
-   undo record to get from the readline line buffer contents to the new
-   line and make NEW_LINE the current readline line. */
-static void
-maybe_make_readline_line (new_line)
-     char *new_line;
-{
-  if (strcmp (new_line, rl_line_buffer) != 0)
-    {
-      rl_point = rl_end;
-
-      rl_add_undo (UNDO_BEGIN, 0, 0, 0);
-      rl_delete_text (0, rl_point);
-      rl_point = rl_end = rl_mark = 0;
-      rl_insert_text (new_line);
-      rl_add_undo (UNDO_END, 0, 0, 0);
-    }
-}
-
-/* Make NEW_LINE be the current readline line.  This frees NEW_LINE. */
-static void
-set_up_new_line (new_line)
-     char *new_line;
-{
-  int old_point, at_end;
-
-  old_point = rl_point;
-  at_end = rl_point == rl_end;
-
-  /* If the line was history and alias expanded, then make that
-     be one thing to undo. */
-  maybe_make_readline_line (new_line);
-  free (new_line);
-
-  /* Place rl_point where we think it should go. */
-  if (at_end)
-    rl_point = rl_end;
-  else if (old_point < rl_end)
-    {
-      rl_point = old_point;
-      if (!whitespace (rl_line_buffer[rl_point]))
-       rl_forward_word (1, 0);
-    }
-}
-
-#if defined (ALIAS)
-/* Expand aliases in the current readline line. */
-static int
-alias_expand_line (count, ignore)
-     int count, ignore;
-{
-  char *new_line;
-
-  new_line = alias_expand (rl_line_buffer);
-
-  if (new_line)
-    {
-      set_up_new_line (new_line);
-      return (0);
-    }
-  else
-    {
-      cleanup_expansion_error ();
-      return (1);
-    }
-}
-#endif
-
-#if defined (BANG_HISTORY)
-/* History expand the line. */
-static int
-history_expand_line (count, ignore)
-     int count, ignore;
-{
-  char *new_line;
-
-  new_line = history_expand_line_internal (rl_line_buffer);
-
-  if (new_line)
-    {
-      set_up_new_line (new_line);
-      return (0);
-    }
-  else
-    {
-      cleanup_expansion_error ();
-      return (1);
-    }
-}
-
-/* Expand history substitutions in the current line and then insert a
-   space (hopefully close to where we were before). */
-static int
-tcsh_magic_space (count, ignore)
-     int count, ignore;
-{
-  int dist_from_end, old_point;
-
-  old_point = rl_point;
-  dist_from_end = rl_end - rl_point;
-  if (history_expand_line (count, ignore) == 0)
-    {
-      /* Try a simple heuristic from Stephen Gildea <gildea@intouchsys.com>.
-        This works if all expansions were before rl_point or if no expansions
-        were performed. */
-      rl_point = (old_point == 0) ? old_point : rl_end - dist_from_end;
-      rl_insert (1, ' ');
-      return (0);
-    }
-  else
-    return (1);
-}
-#endif /* BANG_HISTORY */
-
-/* History and alias expand the line. */
-static int
-history_and_alias_expand_line (count, ignore)
-     int count, ignore;
-{
-  char *new_line;
-
-  new_line = 0;
-#if defined (BANG_HISTORY)
-  new_line = history_expand_line_internal (rl_line_buffer);
-#endif
-
-#if defined (ALIAS)
-  if (new_line)
-    {
-      char *alias_line;
-
-      alias_line = alias_expand (new_line);
-      free (new_line);
-      new_line = alias_line;
-    }
-#endif /* ALIAS */
-
-  if (new_line)
-    {
-      set_up_new_line (new_line);
-      return (0);
-    }
-  else
-    {
-      cleanup_expansion_error ();
-      return (1);
-    }
-}
-
-/* History and alias expand the line, then perform the shell word
-   expansions by calling expand_string.  This can't use set_up_new_line()
-   because we want the variable expansions as a separate undo'able
-   set of operations. */
-static int
-shell_expand_line (count, ignore)
-     int count, ignore;
-{
-  char *new_line;
-  WORD_LIST *expanded_string;
-
-  new_line = 0;
-#if defined (BANG_HISTORY)
-  new_line = history_expand_line_internal (rl_line_buffer);
-#endif
-
-#if defined (ALIAS)
-  if (new_line)
-    {
-      char *alias_line;
-
-      alias_line = alias_expand (new_line);
-      free (new_line);
-      new_line = alias_line;
-    }
-#endif /* ALIAS */
-
-  if (new_line)
-    {
-      int old_point = rl_point;
-      int at_end = rl_point == rl_end;
-
-      /* If the line was history and alias expanded, then make that
-        be one thing to undo. */
-      maybe_make_readline_line (new_line);
-      free (new_line);
-
-      /* If there is variable expansion to perform, do that as a separate
-        operation to be undone. */
-      new_line = savestring (rl_line_buffer);
-      expanded_string = expand_string (new_line, 0);
-      FREE (new_line);
-      if (expanded_string == 0)
-       {
-         new_line = (char *)xmalloc (1);
-         new_line[0] = '\0';
-       }
-      else
-       {
-         new_line = string_list (expanded_string);
-         dispose_words (expanded_string);
-       }
-
-      maybe_make_readline_line (new_line);
-      free (new_line);
-
-      /* Place rl_point where we think it should go. */
-      if (at_end)
-       rl_point = rl_end;
-      else if (old_point < rl_end)
-       {
-         rl_point = old_point;
-         if (!whitespace (rl_line_buffer[rl_point]))
-           rl_forward_word (1, 0);
-       }
-      return 0;
-    }
-  else
-    {
-      cleanup_expansion_error ();
-      return 1;
-    }
-}
-
-/* If FIGNORE is set, then don't match files with the given suffixes when
-   completing filenames.  If only one of the possibilities has an acceptable
-   suffix, delete the others, else just return and let the completer
-   signal an error.  It is called by the completer when real
-   completions are done on filenames by the completer's internal
-   function, not for completion lists (M-?) and not on "other"
-   completion types, such as hostnames or commands. */
-
-static struct ignorevar fignore =
-{
-  "FIGNORE",
-  (struct ign *)0,
-  0,
-  (char *)0,
-  (sh_iv_item_func_t *) 0,
-};
-
-static void
-_ignore_completion_names (names, name_func)
-     char **names;
-     sh_ignore_func_t *name_func;
-{
-  char **newnames;
-  int idx, nidx;
-  char **oldnames;
-  int oidx;
-
-  /* If there is only one completion, see if it is acceptable.  If it is
-     not, free it up.  In any case, short-circuit and return.  This is a
-     special case because names[0] is not the prefix of the list of names
-     if there is only one completion; it is the completion itself. */
-  if (names[1] == (char *)0)
-    {
-      if (force_fignore)
-       if ((*name_func) (names[0]) == 0)
-         {
-           free (names[0]);
-           names[0] = (char *)NULL;
-         }
-
-      return;
-    }
-
-  /* Allocate space for array to hold list of pointers to matching
-     filenames.  The pointers are copied back to NAMES when done. */
-  for (nidx = 1; names[nidx]; nidx++)
-    ;
-  newnames = strvec_create (nidx + 1);
-
-  if (force_fignore == 0)
-    {
-      oldnames = strvec_create (nidx - 1);
-      oidx = 0;
-    }
-
-  newnames[0] = names[0];
-  for (idx = nidx = 1; names[idx]; idx++)
-    {
-      if ((*name_func) (names[idx]))
-       newnames[nidx++] = names[idx];
-      else if (force_fignore == 0)
-       oldnames[oidx++] = names[idx];
-      else
-       free (names[idx]);
-    }
-
-  newnames[nidx] = (char *)NULL;
-
-  /* If none are acceptable then let the completer handle it. */
-  if (nidx == 1)
-    {
-      if (force_fignore)
-       {
-         free (names[0]);
-         names[0] = (char *)NULL;
-       }
-      else
-       free (oldnames);
-
-      free (newnames);
-      return;
-    }
-
-  if (force_fignore == 0)
-    {
-      while (oidx)
-       free (oldnames[--oidx]);
-      free (oldnames);
-    }
-
-  /* If only one is acceptable, copy it to names[0] and return. */
-  if (nidx == 2)
-    {
-      free (names[0]);
-      names[0] = newnames[1];
-      names[1] = (char *)NULL;
-      free (newnames);
-      return;
-    }
-
-  /* Copy the acceptable names back to NAMES, set the new array end,
-     and return. */
-  for (nidx = 1; newnames[nidx]; nidx++)
-    names[nidx] = newnames[nidx];
-  names[nidx] = (char *)NULL;
-  free (newnames);
-}
-
-static int
-name_is_acceptable (name)
-     const char *name;
-{
-  struct ign *p;
-  int nlen;
-
-  for (nlen = strlen (name), p = fignore.ignores; p->val; p++)
-    {
-      if (nlen > p->len && p->len > 0 && STREQ (p->val, &name[nlen - p->len]))
-       return (0);
-    }
-
-  return (1);
-}
-
-#if 0
-static int
-ignore_dot_names (name)
-     char *name;
-{
-  return (name[0] != '.');
-}
-#endif
-
-static int
-filename_completion_ignore (names)
-     char **names;
-{
-#if 0
-  if (glob_dot_filenames == 0)
-    _ignore_completion_names (names, ignore_dot_names);
-#endif
-
-  setup_ignore_patterns (&fignore);
-
-  if (fignore.num_ignores == 0)
-    return 0;
-
-  _ignore_completion_names (names, name_is_acceptable);
-
-  return 0;
-}
-
-/* Return 1 if NAME is a directory.  NAME undergoes tilde expansion. */
-static int
-test_for_directory (name)
-     const char *name;
-{
-  char *fn;
-  int r;
-
-  fn = bash_tilde_expand (name, 0);
-  r = file_isdir (fn);
-  free (fn);
-
-  return (r);
-}
-
-/* Remove files from NAMES, leaving directories. */
-static int
-bash_ignore_filenames (names)
-     char **names;
-{
-  _ignore_completion_names (names, test_for_directory);
-  return 0;
-}
-
-static int
-return_zero (name)
-     const char *name;
-{
-  return 0;
-}
-
-static int
-bash_ignore_everything (names)
-     char **names;
-{
-  _ignore_completion_names (names, return_zero);
-  return 0;
-}
-
-/* Replace a tilde-prefix in VAL with a `~', assuming the user typed it.  VAL
-   is an expanded filename.  DIRECTORY_PART is the tilde-prefix portion
-   of the un-tilde-expanded version of VAL (what the user typed). */
-static char *
-restore_tilde (val, directory_part)
-     char *val, *directory_part;
-{
-  int l, vl, dl2, xl;
-  char *dh2, *expdir, *ret;
-
-  vl = strlen (val);
-
-  /* We need to duplicate the expansions readline performs on the directory
-     portion before passing it to our completion function. */
-  dh2 = directory_part ? bash_dequote_filename (directory_part, 0) : 0;
-  bash_directory_expansion (&dh2);
-  dl2 = strlen (dh2);
-
-  expdir = bash_tilde_expand (directory_part, 0);
-  xl = strlen (expdir);
-  free (expdir);
-
-  /*
-     dh2 = unexpanded but dequoted tilde-prefix
-     dl2 = length of tilde-prefix
-     expdir = tilde-expanded tilde-prefix
-     xl = length of expanded tilde-prefix
-     l = length of remainder after tilde-prefix
-  */
-  l = (vl - xl) + 1;
-
-  ret = (char *)xmalloc (dl2 + 2 + l);
-  strcpy (ret, dh2);
-  strcpy (ret + dl2, val + xl);
-
-  free (dh2);
-  return (ret);
-}
-
-/* Simulate the expansions that will be performed by
-   rl_filename_completion_function.  This must be called with the address of
-   a pointer to malloc'd memory. */
-static void
-bash_directory_expansion (dirname)
-     char **dirname;
-{
-  char *d, *nd;
-
-  d = savestring (*dirname);
-
-  if (rl_directory_rewrite_hook)
-    (*rl_directory_rewrite_hook) (&d);
-
-  if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&d))
-    {
-      free (*dirname);
-      *dirname = d;
-    }
-  else if (rl_completion_found_quote)
-    {
-      nd = bash_dequote_filename (d, rl_completion_quote_character);
-      free (*dirname);
-      free (d);
-      *dirname = nd;
-    }
-}
-
-/* If necessary, rewrite directory entry */
-static char *
-bash_filename_rewrite_hook (fname, fnlen)
-     char *fname;
-     int fnlen;
-{
-  char *conv;
-
-  conv = fnx_fromfs (fname, fnlen);
-  if (conv != fname)
-    conv = savestring (conv);
-  return conv;
-}
-
-/* Handle symbolic link references and other directory name
-   expansions while hacking completion. */
-static int
-bash_directory_completion_hook (dirname)
-     char **dirname;
-{
-  char *local_dirname, *new_dirname, *t;
-  int return_value, should_expand_dirname;
-  WORD_LIST *wl;
-  struct stat sb;
-
-  return_value = should_expand_dirname = 0;
-  local_dirname = *dirname;
-
-  if (mbschr (local_dirname, '$'))
-    should_expand_dirname = 1;
-  else
-    {
-      t = mbschr (local_dirname, '`');
-      if (t && unclosed_pair (local_dirname, strlen (local_dirname), "`") == 0)
-       should_expand_dirname = 1;
-    }
-
-#if defined (HAVE_LSTAT)
-  if (should_expand_dirname && lstat (local_dirname, &sb) == 0)
-#else
-  if (should_expand_dirname && stat (local_dirname, &sb) == 0)
-#endif
-    should_expand_dirname = 0;
-
-  if (should_expand_dirname)  
-    {
-      new_dirname = savestring (local_dirname);
-      wl = expand_prompt_string (new_dirname, 0, W_NOCOMSUB);  /* does the right thing */
-      if (wl)
-       {
-         *dirname = string_list (wl);
-         /* Tell the completer to replace the directory name only if we
-            actually expanded something. */
-         return_value = STREQ (local_dirname, *dirname) == 0;
-         free (local_dirname);
-         free (new_dirname);
-         dispose_words (wl);
-         local_dirname = *dirname;
-       }
-      else
-       {
-         free (new_dirname);
-         free (local_dirname);
-         *dirname = (char *)xmalloc (1);
-         **dirname = '\0';
-         return 1;
-       }
-    }
-  else 
-    {
-      /* Dequote the filename even if we don't expand it. */
-      new_dirname = bash_dequote_filename (local_dirname, rl_completion_quote_character);
-      free (local_dirname);
-      local_dirname = *dirname = new_dirname;
-    }
-
-  if (no_symbolic_links == 0 && (local_dirname[0] != '.' || local_dirname[1]))
-    {
-      char *temp1, *temp2;
-      int len1, len2;
-
-      t = get_working_directory ("symlink-hook");
-      temp1 = make_absolute (local_dirname, t);
-      free (t);
-      temp2 = sh_canonpath (temp1, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
-
-      /* Try spelling correction if initial canonicalization fails. */
-      if (temp2 == 0 && dircomplete_spelling)
-       {
-         temp2 = dirspell (temp1);
-         if (temp2)
-           {
-             free (temp1);
-             temp1 = temp2;
-             temp2 = sh_canonpath (temp1, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
-             return_value = temp2 != 0;
-           }
-       }
-      /* If we can't canonicalize, bail. */
-      if (temp2 == 0)
-       {
-         free (temp1);
-         return 1;
-       }
-      len1 = strlen (temp1);
-      if (temp1[len1 - 1] == '/')
-       {
-         len2 = strlen (temp2);
-         if (len2 > 2)         /* don't append `/' to `/' or `//' */
-           {
-             temp2 = (char *)xrealloc (temp2, len2 + 2);
-             temp2[len2] = '/';
-             temp2[len2 + 1] = '\0';
-           }
-       }
-      free (local_dirname);
-      *dirname = temp2;
-      free (temp1);
-    }
-  return (return_value);
-}
-
-static char **history_completion_array = (char **)NULL;
-static int harry_size;
-static int harry_len;
-
-static void
-build_history_completion_array ()
-{
-  register int i, j;
-  HIST_ENTRY **hlist;
-  char **tokens;
-
-  /* First, clear out the current dynamic history completion list. */
-  if (harry_size)
-    {
-      strvec_dispose (history_completion_array);
-      history_completion_array = (char **)NULL;
-      harry_size = 0;
-      harry_len = 0;
-    }
-
-  /* Next, grovel each line of history, making each shell-sized token
-     a separate entry in the history_completion_array. */
-  hlist = history_list ();
-
-  if (hlist)
-    {
-      for (i = 0; hlist[i]; i++)
-       ;
-      for ( --i; i >= 0; i--)
-       {
-         /* Separate each token, and place into an array. */
-         tokens = history_tokenize (hlist[i]->line);
-
-         for (j = 0; tokens && tokens[j]; j++)
-           {
-             if (harry_len + 2 > harry_size)
-               history_completion_array = strvec_resize (history_completion_array, harry_size += 10);
-
-             history_completion_array[harry_len++] = tokens[j];
-             history_completion_array[harry_len] = (char *)NULL;
-           }
-         free (tokens);
-       }
-
-      /* Sort the complete list of tokens. */
-      if (dabbrev_expand_active == 0)
-        qsort (history_completion_array, harry_len, sizeof (char *), (QSFUNC *)strvec_strcmp);
-    }
-}
-
-static char *
-history_completion_generator (hint_text, state)
-     const char *hint_text;
-     int state;
-{
-  static int local_index, len;
-  static const char *text;
-
-  /* If this is the first call to the generator, then initialize the
-     list of strings to complete over. */
-  if (state == 0)
-    {
-      if (dabbrev_expand_active)       /* This is kind of messy */
-       rl_completion_suppress_append = 1;
-      local_index = 0;
-      build_history_completion_array ();
-      text = hint_text;
-      len = strlen (text);
-    }
-
-  while (history_completion_array && history_completion_array[local_index])
-    {
-      if (strncmp (text, history_completion_array[local_index++], len) == 0)
-       return (savestring (history_completion_array[local_index - 1]));
-    }
-  return ((char *)NULL);
-}
-
-static int
-dynamic_complete_history (count, key)
-     int count, key;
-{
-  int r;
-  rl_compentry_func_t *orig_func;
-  rl_completion_func_t *orig_attempt_func;
-
-  orig_func = rl_completion_entry_function;
-  orig_attempt_func = rl_attempted_completion_function;
-
-  rl_completion_entry_function = history_completion_generator;
-  rl_attempted_completion_function = (rl_completion_func_t *)NULL;
-
-  /* XXX - use rl_completion_mode here? */
-  if (rl_last_func == dynamic_complete_history)
-    r = rl_complete_internal ('?');
-  else
-    r = rl_complete_internal (TAB);
-
-  rl_completion_entry_function = orig_func;
-  rl_attempted_completion_function = orig_attempt_func;
-  return r;
-}
-
-static int
-bash_dabbrev_expand (count, key)
-     int count, key;
-{
-  int r, orig_suppress, orig_sort;
-  rl_compentry_func_t *orig_func;
-  rl_completion_func_t *orig_attempt_func;
-
-  orig_func = rl_menu_completion_entry_function;
-  orig_attempt_func = rl_attempted_completion_function;
-  orig_suppress = rl_completion_suppress_append;
-  orig_sort = rl_sort_completion_matches;
-
-  rl_menu_completion_entry_function = history_completion_generator;
-  rl_attempted_completion_function = (rl_completion_func_t *)NULL;
-  rl_filename_completion_desired = 0;
-  rl_completion_suppress_append = 1;
-  rl_sort_completion_matches = 0;
-
-  /* XXX - use rl_completion_mode here? */
-  dabbrev_expand_active = 1;
-  if (rl_last_func == bash_dabbrev_expand)
-    rl_last_func = rl_menu_complete;
-  r = rl_menu_complete (count, key);
-  dabbrev_expand_active = 0;
-
-  rl_last_func = bash_dabbrev_expand;
-  rl_menu_completion_entry_function = orig_func;
-  rl_attempted_completion_function = orig_attempt_func;
-  rl_completion_suppress_append = orig_suppress;
-  rl_sort_completion_matches = orig_sort;
-
-  return r;
-}
-
-#if defined (SPECIFIC_COMPLETION_FUNCTIONS)
-static int
-bash_complete_username (ignore, ignore2)
-     int ignore, ignore2;
-{
-  return bash_complete_username_internal (rl_completion_mode (bash_complete_username));
-}
-
-static int
-bash_possible_username_completions (ignore, ignore2)
-     int ignore, ignore2;
-{
-  return bash_complete_username_internal ('?');
-}
-
-static int
-bash_complete_username_internal (what_to_do)
-     int what_to_do;
-{
-  return bash_specific_completion (what_to_do, rl_username_completion_function);
-}
-
-static int
-bash_complete_filename (ignore, ignore2)
-     int ignore, ignore2;
-{
-  return bash_complete_filename_internal (rl_completion_mode (bash_complete_filename));
-}
-
-static int
-bash_possible_filename_completions (ignore, ignore2)
-     int ignore, ignore2;
-{
-  return bash_complete_filename_internal ('?');
-}
-
-static int
-bash_complete_filename_internal (what_to_do)
-     int what_to_do;
-{
-  rl_compentry_func_t *orig_func;
-  rl_completion_func_t *orig_attempt_func;
-  rl_icppfunc_t *orig_dir_func;
-  /*const*/ char *orig_rl_completer_word_break_characters;
-  int r;
-
-  orig_func = rl_completion_entry_function;
-  orig_attempt_func = rl_attempted_completion_function;
-  orig_dir_func = rl_directory_completion_hook;
-  orig_rl_completer_word_break_characters = rl_completer_word_break_characters;
-  rl_completion_entry_function = rl_filename_completion_function;
-  rl_attempted_completion_function = (rl_completion_func_t *)NULL;
-  rl_directory_completion_hook = (rl_icppfunc_t *)NULL;
-  rl_completer_word_break_characters = " \t\n\"\'";
-
-  r = rl_complete_internal (what_to_do);
-
-  rl_completion_entry_function = orig_func;
-  rl_attempted_completion_function = orig_attempt_func;
-  rl_directory_completion_hook = orig_dir_func;
-  rl_completer_word_break_characters = orig_rl_completer_word_break_characters;
-
-  return r;
-}
-
-static int
-bash_complete_hostname (ignore, ignore2)
-     int ignore, ignore2;
-{
-  return bash_complete_hostname_internal (rl_completion_mode (bash_complete_hostname));
-}
-
-static int
-bash_possible_hostname_completions (ignore, ignore2)
-     int ignore, ignore2;
-{
-  return bash_complete_hostname_internal ('?');
-}
-
-static int
-bash_complete_variable (ignore, ignore2)
-     int ignore, ignore2;
-{
-  return bash_complete_variable_internal (rl_completion_mode (bash_complete_variable));
-}
-
-static int
-bash_possible_variable_completions (ignore, ignore2)
-     int ignore, ignore2;
-{
-  return bash_complete_variable_internal ('?');
-}
-
-static int
-bash_complete_command (ignore, ignore2)
-     int ignore, ignore2;
-{
-  return bash_complete_command_internal (rl_completion_mode (bash_complete_command));
-}
-
-static int
-bash_possible_command_completions (ignore, ignore2)
-     int ignore, ignore2;
-{
-  return bash_complete_command_internal ('?');
-}
-
-static int
-bash_complete_hostname_internal (what_to_do)
-     int what_to_do;
-{
-  return bash_specific_completion (what_to_do, hostname_completion_function);
-}
-
-static int
-bash_complete_variable_internal (what_to_do)
-     int what_to_do;
-{
-  return bash_specific_completion (what_to_do, variable_completion_function);
-}
-
-static int
-bash_complete_command_internal (what_to_do)
-     int what_to_do;
-{
-  return bash_specific_completion (what_to_do, command_word_completion_function);
-}
-
-static char *globtext;
-static char *globorig;
-
-static char *
-glob_complete_word (text, state)
-     const char *text;
-     int state;
-{
-  static char **matches = (char **)NULL;
-  static int ind;
-  int glen;
-  char *ret, *ttext;
-
-  if (state == 0)
-    {
-      rl_filename_completion_desired = 1;
-      FREE (matches);
-      if (globorig != globtext)
-       FREE (globorig);
-      FREE (globtext);
-
-      ttext = bash_tilde_expand (text, 0);
-
-      if (rl_explicit_arg)
-       {
-         globorig = savestring (ttext);
-         glen = strlen (ttext);
-         globtext = (char *)xmalloc (glen + 2);
-         strcpy (globtext, ttext);
-         globtext[glen] = '*';
-         globtext[glen+1] = '\0';
-       }
-      else
-        globtext = globorig = savestring (ttext);
-
-      if (ttext != text)
-       free (ttext);
-
-      matches = shell_glob_filename (globtext);
-      if (GLOB_FAILED (matches))
-       matches = (char **)NULL;
-      ind = 0;
-    }
-
-  ret = matches ? matches[ind] : (char *)NULL;
-  ind++;
-  return ret;
-}
-
-static int
-bash_glob_completion_internal (what_to_do)
-     int what_to_do;
-{
-  return bash_specific_completion (what_to_do, glob_complete_word);
-}
-
-/* A special quoting function so we don't end up quoting globbing characters
-   in the word if there are no matches or multiple matches. */
-static char *
-bash_glob_quote_filename (s, rtype, qcp)
-     char *s;
-     int rtype;
-     char *qcp;
-{
-  if (globorig && qcp && *qcp == '\0' && STREQ (s, globorig))
-    return (savestring (s));
-  else
-    return (bash_quote_filename (s, rtype, qcp));
-}
-
-static int
-bash_glob_complete_word (count, key)
-     int count, key;
-{
-  int r;
-  rl_quote_func_t *orig_quoting_function;
-
-  if (rl_editing_mode == EMACS_EDITING_MODE)
-    rl_explicit_arg = 1;       /* force `*' append */
-  orig_quoting_function = rl_filename_quoting_function;
-  rl_filename_quoting_function = bash_glob_quote_filename;
-  
-  r = bash_glob_completion_internal (rl_completion_mode (bash_glob_complete_word));
-
-  rl_filename_quoting_function = orig_quoting_function;
-  return r;
-}
-
-static int
-bash_glob_expand_word (count, key)
-     int count, key;
-{
-  return bash_glob_completion_internal ('*');
-}
-
-static int
-bash_glob_list_expansions (count, key)
-     int count, key;
-{
-  return bash_glob_completion_internal ('?');
-}
-
-static int
-bash_specific_completion (what_to_do, generator)
-     int what_to_do;
-     rl_compentry_func_t *generator;
-{
-  rl_compentry_func_t *orig_func;
-  rl_completion_func_t *orig_attempt_func;
-  int r;
-
-  orig_func = rl_completion_entry_function;
-  orig_attempt_func = rl_attempted_completion_function;
-  rl_completion_entry_function = generator;
-  rl_attempted_completion_function = NULL;
-
-  r = rl_complete_internal (what_to_do);
-
-  rl_completion_entry_function = orig_func;
-  rl_attempted_completion_function = orig_attempt_func;
-
-  return r;
-}
-
-#endif /* SPECIFIC_COMPLETION_FUNCTIONS */
-
-#if defined (VI_MODE)
-/* Completion, from vi mode's point of view.  This is a modified version of
-   rl_vi_complete which uses the bash globbing code to implement what POSIX
-   specifies, which is to append a `*' and attempt filename generation (which
-   has the side effect of expanding any globbing characters in the word). */
-static int
-bash_vi_complete (count, key)
-     int count, key;
-{
-#if defined (SPECIFIC_COMPLETION_FUNCTIONS)
-  int p, r;
-  char *t;
-
-  if ((rl_point < rl_end) && (!whitespace (rl_line_buffer[rl_point])))
-    {
-      if (!whitespace (rl_line_buffer[rl_point + 1]))
-       rl_vi_end_word (1, 'E');
-      rl_point++;
-    }
-
-  /* Find boundaries of current word, according to vi definition of a
-     `bigword'. */
-  t = 0;
-  if (rl_point > 0)
-    {
-      p = rl_point;
-      rl_vi_bWord (1, 'B');
-      r = rl_point;
-      rl_point = p;
-      p = r;
-
-      t = substring (rl_line_buffer, p, rl_point);
-    }      
-
-  if (t && glob_pattern_p (t) == 0)
-    rl_explicit_arg = 1;       /* XXX - force glob_complete_word to append `*' */
-  FREE (t);
-
-  if (key == '*')      /* Expansion and replacement. */
-    r = bash_glob_expand_word (count, key);
-  else if (key == '=') /* List possible completions. */
-    r = bash_glob_list_expansions (count, key);
-  else if (key == '\\')        /* Standard completion */
-    r = bash_glob_complete_word (count, key);
-  else
-    r = rl_complete (0, key);
-
-  if (key == '*' || key == '\\')
-    rl_vi_start_inserting (key, 1, 1);
-
-  return (r);
-#else
-  return rl_vi_complete (count, key);
-#endif /* !SPECIFIC_COMPLETION_FUNCTIONS */
-}
-#endif /* VI_MODE */
-
-/* Filename quoting for completion. */
-/* A function to strip unquoted quote characters (single quotes, double
-   quotes, and backslashes).  It allows single quotes to appear
-   within double quotes, and vice versa.  It should be smarter. */
-static char *
-bash_dequote_filename (text, quote_char)
-     char *text;
-     int quote_char;
-{
-  char *ret, *p, *r;
-  int l, quoted;
-
-  l = strlen (text);
-  ret = (char *)xmalloc (l + 1);
-  for (quoted = quote_char, p = text, r = ret; p && *p; p++)
-    {
-      /* Allow backslash-escaped characters to pass through unscathed. */
-      if (*p == '\\')
-       {
-         /* Backslashes are preserved within single quotes. */
-         if (quoted == '\'')
-           *r++ = *p;
-         /* Backslashes are preserved within double quotes unless the
-            character is one that is defined to be escaped */
-         else if (quoted == '"' && ((sh_syntaxtab[p[1]] & CBSDQUOTE) == 0))
-           *r++ = *p;
-
-         *r++ = *++p;
-         if (*p == '\0')
-           return ret;         /* XXX - was break; */
-         continue;
-       }
-      /* Close quote. */
-      if (quoted && *p == quoted)
-       {
-         quoted = 0;
-         continue;
-       }
-      /* Open quote. */
-      if (quoted == 0 && (*p == '\'' || *p == '"'))
-       {
-         quoted = *p;
-         continue;
-       }
-      *r++ = *p;
-    }
-  *r = '\0';
-  return ret;
-}
-
-/* Quote characters that the readline completion code would treat as
-   word break characters with backslashes.  Pass backslash-quoted
-   characters through without examination. */
-static char *
-quote_word_break_chars (text)
-     char *text;
-{
-  char *ret, *r, *s;
-  int l;
-
-  l = strlen (text);
-  ret = (char *)xmalloc ((2 * l) + 1);
-  for (s = text, r = ret; *s; s++)
-    {
-      /* Pass backslash-quoted characters through, including the backslash. */
-      if (*s == '\\')
-       {
-         *r++ = '\\';
-         *r++ = *++s;
-         if (*s == '\0')
-           break;
-         continue;
-       }
-      /* OK, we have an unquoted character.  Check its presence in
-        rl_completer_word_break_characters. */
-      if (mbschr (rl_completer_word_break_characters, *s))
-       *r++ = '\\';
-      /* XXX -- check for standalone tildes here and backslash-quote them */
-      if (s == text && *s == '~' && file_exists (text))
-        *r++ = '\\';
-      *r++ = *s;
-    }
-  *r = '\0';
-  return ret;
-}
-
-/* Quote a filename using double quotes, single quotes, or backslashes
-   depending on the value of completion_quoting_style.  If we're
-   completing using backslashes, we need to quote some additional
-   characters (those that readline treats as word breaks), so we call
-   quote_word_break_chars on the result.  This returns newly-allocated
-   memory. */
-static char *
-bash_quote_filename (s, rtype, qcp)
-     char *s;
-     int rtype;
-     char *qcp;
-{
-  char *rtext, *mtext, *ret;
-  int rlen, cs;
-
-  rtext = (char *)NULL;
-
-  /* If RTYPE == MULT_MATCH, it means that there is
-     more than one match.  In this case, we do not add
-     the closing quote or attempt to perform tilde
-     expansion.  If RTYPE == SINGLE_MATCH, we try
-     to perform tilde expansion, because single and double
-     quotes inhibit tilde expansion by the shell. */
-
-  cs = completion_quoting_style;
-  /* Might need to modify the default completion style based on *qcp,
-     since it's set to any user-provided opening quote.  We also change
-     to single-quoting if there is no user-provided opening quote and
-     the word being completed contains newlines, since those are not
-     quoted correctly using backslashes (a backslash-newline pair is
-     special to the shell parser). */
-  if (*qcp == '\0' && cs == COMPLETE_BSQUOTE && mbschr (s, '\n'))
-    cs = COMPLETE_SQUOTE;
-  else if (*qcp == '"')
-    cs = COMPLETE_DQUOTE;
-  else if (*qcp == '\'')
-    cs = COMPLETE_SQUOTE;
-#if defined (BANG_HISTORY)
-  else if (*qcp == '\0' && history_expansion && cs == COMPLETE_DQUOTE &&
-          history_expansion_inhibited == 0 && mbschr (s, '!'))
-    cs = COMPLETE_BSQUOTE;
-
-  if (*qcp == '"' && history_expansion && cs == COMPLETE_DQUOTE &&
-       history_expansion_inhibited == 0 && mbschr (s, '!'))
-    {
-      cs = COMPLETE_BSQUOTE;
-      *qcp = '\0';
-    }
-#endif
-
-  /* Don't tilde-expand backslash-quoted filenames, since only single and
-     double quotes inhibit tilde expansion. */
-  mtext = s;
-  if (mtext[0] == '~' && rtype == SINGLE_MATCH && cs != COMPLETE_BSQUOTE)
-    mtext = bash_tilde_expand (s, 0);
-
-  switch (cs)
-    {
-    case COMPLETE_DQUOTE:
-      rtext = sh_double_quote (mtext);
-      break;
-    case COMPLETE_SQUOTE:
-      rtext = sh_single_quote (mtext);
-      break;
-    case COMPLETE_BSQUOTE:
-      rtext = sh_backslash_quote (mtext);
-      break;
-    }
-
-  if (mtext != s)
-    free (mtext);
-
-  /* We may need to quote additional characters: those that readline treats
-     as word breaks that are not quoted by backslash_quote. */
-  if (rtext && cs == COMPLETE_BSQUOTE)
-    {
-      mtext = quote_word_break_chars (rtext);
-      free (rtext);
-      rtext = mtext;
-    }
-
-  /* Leave the opening quote intact.  The readline completion code takes
-     care of avoiding doubled opening quotes. */
-  rlen = strlen (rtext);
-  ret = (char *)xmalloc (rlen + 1);
-  strcpy (ret, rtext);
-
-  /* If there are multiple matches, cut off the closing quote. */
-  if (rtype == MULT_MATCH && cs != COMPLETE_BSQUOTE)
-    ret[rlen - 1] = '\0';
-  free (rtext);
-  return ret;
-}
-
-/* Support for binding readline key sequences to Unix commands. */
-static Keymap cmd_xmap;
-
-static int
-putx(c)
-     int c;
-{
-  putc (c, rl_outstream);
-}
-  
-static int
-bash_execute_unix_command (count, key)
-     int count;        /* ignored */
-     int key;
-{
-  Keymap ckmap;                /* current keymap */
-  Keymap xkmap;                /* unix command executing keymap */
-  register int i, r;
-  intmax_t mi;
-  sh_parser_state_t ps;
-  char *cmd, *value, *l, *l1, *ce;
-  SHELL_VAR *v;
-  char ibuf[INT_STRLEN_BOUND(int) + 1];
-
-  /* First, we need to find the right command to execute.  This is tricky,
-     because we might have already indirected into another keymap. */
-  ckmap = rl_get_keymap ();
-  if (ckmap != rl_executing_keymap)
-    {
-      /* bogus.  we have to search.  only handle one level of indirection. */
-      for (i = 0; i < KEYMAP_SIZE; i++)
-       {
-         if (ckmap[i].type == ISKMAP && (Keymap)ckmap[i].function == rl_executing_keymap)
-           break;
-       }
-      if (i < KEYMAP_SIZE)
-       xkmap = (Keymap)cmd_xmap[i].function;
-      else
-       {
-         rl_crlf ();
-         internal_error (_("bash_execute_unix_command: cannot find keymap for command"));
-         rl_forced_update_display ();
-         return 1;
-       }
-    }
-  else
-    xkmap = cmd_xmap;
-
-  cmd = (char *)xkmap[key].function;
-
-  if (cmd == 0)
-    {
-      rl_ding ();
-      return 1;
-    }
-
-  ce = rl_get_termcap ("ce");
-  if (ce)      /* clear current line */
-    {
-      fprintf (rl_outstream, "\r");
-      tputs (ce, 1, putx);
-      fflush (rl_outstream);
-    }
-  else
-    rl_crlf ();        /* move to a new line */
-
-  v = bind_variable ("READLINE_LINE", rl_line_buffer, 0);
-  if (v)
-    VSETATTR (v, att_exported);
-  l = v ? value_cell (v) : 0;
-  value = inttostr (rl_point, ibuf, sizeof (ibuf));
-  v = bind_int_variable ("READLINE_POINT", value);
-  if (v)
-    VSETATTR (v, att_exported);
-  array_needs_making = 1;
-
-  save_parser_state (&ps);
-  r = parse_and_execute (cmd, "bash_execute_unix_command", SEVAL_NOHIST|SEVAL_NOFREE);
-  restore_parser_state (&ps);
-
-  v = find_variable ("READLINE_LINE");
-  l1 = v ? value_cell (v) : 0;
-  if (l1 != l)
-    maybe_make_readline_line (value_cell (v));
-  v = find_variable ("READLINE_POINT");
-  if (v && legal_number (value_cell (v), &mi))
-    {
-      i = mi;
-      if (i != rl_point)
-       {
-         rl_point = i;
-         if (rl_point > rl_end)
-           rl_point = rl_end;
-         else if (rl_point < 0)
-           rl_point = 0;
-       }
-    }      
-
-  unbind_variable ("READLINE_LINE");
-  unbind_variable ("READLINE_POINT");
-  array_needs_making = 1;
-
-  /* and restore the readline buffer and display after command execution. */
-  rl_forced_update_display ();
-  return 0;
-}
-
-static void
-init_unix_command_map ()
-{
-  cmd_xmap = rl_make_bare_keymap ();
-}
-
-static int
-isolate_sequence (string, ind, need_dquote, startp)
-     char *string;
-     int ind, need_dquote, *startp;
-{
-  register int i;
-  int c, passc, delim;
-
-  for (i = ind; string[i] && whitespace (string[i]); i++)
-    ;
-  /* NEED_DQUOTE means that the first non-white character *must* be `"'. */
-  if (need_dquote && string[i] != '"')
-    {
-      builtin_error (_("%s: first non-whitespace character is not `\"'"), string);
-      return -1;
-    }
-
-  /* We can have delimited strings even if NEED_DQUOTE == 0, like the command
-     string to bind the key sequence to. */
-  delim = (string[i] == '"' || string[i] == '\'') ? string[i] : 0;
-    
-  if (startp)
-    *startp = delim ? ++i : i;
-
-  for (passc = 0; c = string[i]; i++)
-    {
-      if (passc)
-       {
-         passc = 0;
-         continue;
-       }
-      if (c == '\\')
-       {
-         passc++;
-         continue;
-       }
-      if (c == delim)
-       break;
-    }
-
-  if (delim && string[i] != delim)
-    {
-      builtin_error (_("no closing `%c' in %s"), delim, string);
-      return -1;
-    }
-
-  return i;
-}
-
-int
-bind_keyseq_to_unix_command (line)
-     char *line;
-{
-  Keymap kmap;
-  char *kseq, *value;
-  int i, kstart;
-
-  if (cmd_xmap == 0)
-    init_unix_command_map ();
-
-  kmap = rl_get_keymap ();
-
-  /* We duplicate some of the work done by rl_parse_and_bind here, but
-     this code only has to handle `"keyseq": ["]command["]' and can
-     generate an error for anything else. */
-  i = isolate_sequence (line, 0, 1, &kstart);
-  if (i < 0)
-    return -1;
-
-  /* Create the key sequence string to pass to rl_generic_bind */
-  kseq = substring (line, kstart, i);
-
-  for ( ; line[i] && line[i] != ':'; i++)
-    ;
-  if (line[i] != ':')
-    {
-      builtin_error (_("%s: missing colon separator"), line);
-      return -1;
-    }
-
-  i = isolate_sequence (line, i + 1, 0, &kstart);
-  if (i < 0)
-    return -1;
-
-  /* Create the value string containing the command to execute. */
-  value = substring (line, kstart, i);
-
-  /* Save the command to execute and the key sequence in the CMD_XMAP */
-  rl_generic_bind (ISMACR, kseq, value, cmd_xmap);
-
-  /* and bind the key sequence in the current keymap to a function that
-     understands how to execute from CMD_XMAP */
-  rl_bind_keyseq_in_map (kseq, bash_execute_unix_command, kmap);
-  
-  return 0;
-}
-
-/* Used by the programmable completion code.  Complete TEXT as a filename,
-   but return only directories as matches.  Dequotes the filename before
-   attempting to find matches. */
-char **
-bash_directory_completion_matches (text)
-     const char *text;
-{
-  char **m1;
-  char *dfn;
-  int qc;
-
-  qc = rl_dispatching ? rl_completion_quote_character : 0;  
-  dfn = bash_dequote_filename ((char *)text, qc);
-  m1 = rl_completion_matches (dfn, rl_filename_completion_function);
-  free (dfn);
-
-  if (m1 == 0 || m1[0] == 0)
-    return m1;
-  /* We don't bother recomputing the lcd of the matches, because it will just
-     get thrown away by the programmable completion code and recomputed
-     later. */
-  (void)bash_ignore_filenames (m1);
-  return m1;
-}
-
-char *
-bash_dequote_text (text)
-     const char *text;
-{
-  char *dtxt;
-  int qc;
-
-  qc = (text[0] == '"' || text[0] == '\'') ? text[0] : 0;
-  dtxt = bash_dequote_filename ((char *)text, qc);
-  return (dtxt);
-}
-#endif /* READLINE */
diff --git a/bashtypes.h~ b/bashtypes.h~
deleted file mode 100644 (file)
index f773652..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/* bashtypes.h -- Bash system types. */
-
-/* Copyright (C) 1993-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 (_BASHTYPES_H_)
-#  define _BASHTYPES_H_
-
-#if defined (CRAY)
-#  define word __word
-#endif
-
-#include <sys/types.h>
-
-#if defined (CRAY)
-#  undef word
-#endif
-
-#if defined (HAVE_INTTYPES_H)
-#  include <inttypes.h>
-#endif
-
-#endif /* _BASHTYPES_H_ */
diff --git a/braces.c~ b/braces.c~
deleted file mode 100644 (file)
index 6b034ac..0000000
--- a/braces.c~
+++ /dev/null
@@ -1,682 +0,0 @@
-/* braces.c -- code for doing word expansion in curly braces. */
-
-/* Copyright (C) 1987-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/>.
-*/
-
-/* Stuff in curly braces gets expanded before all other shell expansions. */
-
-#include "config.h"
-
-#if defined (BRACE_EXPANSION)
-
-#if defined (HAVE_UNISTD_H)
-#  ifdef _MINIX
-#    include <sys/types.h>
-#  endif
-#  include <unistd.h>
-#endif
-
-#include "bashansi.h"
-
-#if defined (SHELL)
-#  include "shell.h"
-#endif /* SHELL */
-
-#include "general.h"
-#include "shmbutil.h"
-#include "chartypes.h"
-
-#define brace_whitespace(c) (!(c) || (c) == ' ' || (c) == '\t' || (c) == '\n')
-
-#define BRACE_SEQ_SPECIFIER    ".."
-
-extern int asprintf __P((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3)));
-
-/* Basic idea:
-
-   Segregate the text into 3 sections: preamble (stuff before an open brace),
-   postamble (stuff after the matching close brace) and amble (stuff after
-   preamble, and before postamble).  Expand amble, and then tack on the
-   expansions to preamble.  Expand postamble, and tack on the expansions to
-   the result so far.
- */
-
-/* The character which is used to separate arguments. */
-static const int brace_arg_separator = ',';
-
-#if defined (__P)
-static int brace_gobbler __P((char *, size_t, int *, int));
-static char **expand_amble __P((char *, size_t, int));
-static char **expand_seqterm __P((char *, size_t));
-static char **mkseq __P((int, int, int, int, int));
-static char **array_concat __P((char **, char **));
-#else
-static int brace_gobbler ();
-static char **expand_amble ();
-static char **expand_seqterm ();
-static char **mkseq();
-static char **array_concat ();
-#endif
-
-#if 0
-static void
-dump_result (a)
-     char **a;
-{
-  int i;
-
-  for (i = 0; a[i]; i++)
-    printf ("dump_result: a[%d] = -%s-\n", i, a[i]);
-}
-#endif
-
-/* Return an array of strings; the brace expansion of TEXT. */
-char **
-brace_expand (text)
-     char *text;
-{
-  register int start;
-  size_t tlen;
-  char *preamble, *postamble, *amble;
-  size_t alen;
-  char **tack, **result;
-  int i, j, c, c1;
-
-  DECLARE_MBSTATE;
-
-  /* Find the text of the preamble. */
-  tlen = strlen (text);
-  i = 0;
-#if defined (CSH_BRACE_COMPAT)
-  c = brace_gobbler (text, tlen, &i, '{');     /* } */
-#else
-  /* Make sure that when we exit this loop, c == 0 or text[i] begins a
-     valid brace expansion sequence. */
-  do
-    {
-      c = brace_gobbler (text, tlen, &i, '{'); /* } */
-      c1 = c;
-      /* Verify that c begins a valid brace expansion word.  If it doesn't, we
-        go on.  Loop stops when there are no more open braces in the word. */
-      if (c)
-       {
-         start = j = i + 1;    /* { */
-         c = brace_gobbler (text, tlen, &j, '}');
-         if (c == 0)           /* it's not */
-           {
-             i++;
-             c = c1;
-             continue;
-           }
-         else                  /* it is */
-           {
-             c = c1;
-             break;
-           }
-       }
-      else
-       break;
-    }
-  while (c);
-#endif /* !CSH_BRACE_COMPAT */
-
-  preamble = (char *)xmalloc (i + 1);
-  strncpy (preamble, text, i);
-  preamble[i] = '\0';
-
-  result = (char **)xmalloc (2 * sizeof (char *));
-  result[0] = preamble;
-  result[1] = (char *)NULL;
-
-  /* Special case.  If we never found an exciting character, then
-     the preamble is all of the text, so just return that. */
-  if (c != '{')
-    return (result);
-
-  /* Find the amble.  This is the stuff inside this set of braces. */
-  start = ++i;
-  c = brace_gobbler (text, tlen, &i, '}');
-
-  /* What if there isn't a matching close brace? */
-  if (c == 0)
-    {
-#if defined (NOTDEF)
-      /* Well, if we found an unquoted BRACE_ARG_SEPARATOR between START
-        and I, then this should be an error.  Otherwise, it isn't. */
-      j = start;
-      while (j < i)
-       {
-         if (text[j] == '\\')
-           {
-             j++;
-             ADVANCE_CHAR (text, tlen, j);
-             continue;
-           }
-
-         if (text[j] == brace_arg_separator)
-           {   /* { */
-             strvec_dispose (result);
-             report_error ("no closing `%c' in %s", '}', text);
-             throw_to_top_level ();
-           }
-         ADVANCE_CHAR (text, tlen, j);
-       }
-#endif
-      free (preamble);         /* Same as result[0]; see initialization. */
-      result[0] = savestring (text);
-      return (result);
-    }
-
-#if defined (SHELL)
-  amble = substring (text, start, i);
-  alen = i - start;
-#else
-  amble = (char *)xmalloc (1 + (i - start));
-  strncpy (amble, &text[start], (i - start));
-  alen = i - start;
-  amble[alen] = '\0';
-#endif
-
-#if defined (SHELL)
-  INITIALIZE_MBSTATE;
-
-  /* If the amble does not contain an unquoted BRACE_ARG_SEPARATOR, then
-     just return without doing any expansion.  */
-  j = 0;
-  while (amble[j])
-    {
-      if (amble[j] == '\\')
-       {
-         j++;
-         ADVANCE_CHAR (amble, alen, j);
-         continue;
-       }
-
-      if (amble[j] == brace_arg_separator)
-       break;
-
-      ADVANCE_CHAR (amble, alen, j);
-    }
-
-  if (amble[j] == 0)
-    {
-      tack = expand_seqterm (amble, alen);
-      if (tack)
-       goto add_tack;
-      else
-       {
-         free (amble);
-         free (preamble);
-         result[0] = savestring (text);
-         return (result);
-       }
-    }
-#endif /* SHELL */
-
-  tack = expand_amble (amble, alen, 0);
-add_tack:
-  result = array_concat (result, tack);
-  free (amble);
-  strvec_dispose (tack);
-
-  postamble = text + i + 1;
-
-  tack = brace_expand (postamble);
-  result = array_concat (result, tack);
-  strvec_dispose (tack);
-
-  return (result);
-}
-
-/* Expand the text found inside of braces.  We simply try to split the
-   text at BRACE_ARG_SEPARATORs into separate strings.  We then brace
-   expand each slot which needs it, until there are no more slots which
-   need it. */
-static char **
-expand_amble (text, tlen, flags)
-     char *text;
-     size_t tlen;
-     int flags;
-{
-  char **result, **partial;
-  char *tem;
-  int start, i, c;
-
-  DECLARE_MBSTATE;
-
-  result = (char **)NULL;
-
-  start = i = 0;
-  c = 1;
-  while (c)
-    {
-      c = brace_gobbler (text, tlen, &i, brace_arg_separator);
-#if defined (SHELL)
-      tem = substring (text, start, i);
-#else
-      tem = (char *)xmalloc (1 + (i - start));
-      strncpy (tem, &text[start], (i - start));
-      tem[i- start] = '\0';
-#endif
-
-      partial = brace_expand (tem);
-
-      if (!result)
-       result = partial;
-      else
-       {
-         register int lr, lp, j;
-
-         lr = strvec_len (result);
-         lp = strvec_len (partial);
-
-         result = strvec_resize (result, lp + lr + 1);
-
-         for (j = 0; j < lp; j++)
-           result[lr + j] = partial[j];
-
-         result[lr + j] = (char *)NULL;
-         free (partial);
-       }
-      free (tem);
-      ADVANCE_CHAR (text, tlen, i);
-      start = i;
-    }
-  return (result);
-}
-
-#define ST_BAD 0
-#define ST_INT 1
-#define ST_CHAR        2
-#define ST_ZINT        3
-
-static char **
-mkseq (start, end, incr, type, width)
-     int start, end, incr, type, width;
-{
-  int n, i;
-  char **result, *t;
-
-  n = abs (end - start) + 1;
-  result = strvec_create (n + 1);
-
-  if (incr == 0)
-    incr = 1;
-  
-  if (start > end && incr > 0)
-    incr = -incr;
-  else if (start < end && incr < 0)
-    incr = -incr;
-
-  /* Make sure we go through the loop at least once, so {3..3} prints `3' */
-  i = 0;
-  n = start;
-  do
-    {
-#if defined (SHELL)
-      QUIT;            /* XXX - memory leak here */
-#endif
-      if (type == ST_INT)
-       result[i++] = itos (n);
-      else if (type == ST_ZINT)
-       {
-         int len;
-         len = asprintf (&t, "%0*d", width, n);
-         result[i++] = t;
-       }
-      else
-       {
-         t = (char *)xmalloc (2);
-         t[0] = n;
-         t[1] = '\0';
-         result[i++] = t;
-       }
-      n += incr;
-      if ((incr < 0 && n < end) || (incr > 0 && n > end))
-       break;
-    }
-  while (1);
-
-  result[i] = (char *)0;
-  return (result);
-}
-
-static char **
-expand_seqterm (text, tlen)
-     char *text;
-     size_t tlen;
-{
-  char *t, *lhs, *rhs;
-  int i, lhs_t, rhs_t, lhs_v, rhs_v, incr, lhs_l, rhs_l, width;
-  intmax_t tl, tr;
-  char **result, *ep, *oep;
-
-  t = strstr (text, BRACE_SEQ_SPECIFIER);
-  if (t == 0)
-    return ((char **)NULL);
-
-  lhs_l = t - text;            /* index of start of BRACE_SEQ_SPECIFIER */
-  lhs = substring (text, 0, lhs_l);
-  rhs = substring (text, lhs_l + sizeof(BRACE_SEQ_SPECIFIER) - 1, tlen);
-
-  if (lhs[0] == 0 || rhs[0] == 0)
-    {
-      free (lhs);
-      free (rhs);
-      return ((char **)NULL);
-    }
-
-  /* Now figure out whether LHS and RHS are integers or letters.  Both
-     sides have to match. */
-  lhs_t = (legal_number (lhs, &tl)) ? ST_INT :
-               ((ISALPHA (lhs[0]) && lhs[1] == 0) ?  ST_CHAR : ST_BAD);
-
-  /* Decide on rhs and whether or not it looks like the user specified
-     an increment */
-  ep = 0;
-  if (ISDIGIT (rhs[0]) || ((rhs[0] == '+' || rhs[0] == '-') && ISDIGIT (rhs[1])))
-    {
-      rhs_t = ST_INT;
-      tr = strtoimax (rhs, &ep, 10);
-      if (ep && *ep != 0 && *ep != '.')
-       rhs_t = ST_BAD;                 /* invalid */
-    }
-  else if (ISALPHA (rhs[0]) && (rhs[1] == 0 || rhs[1] == '.'))
-    {
-      rhs_t = ST_CHAR;
-      ep = rhs + 1;
-    }
-  else
-    {
-      rhs_t = ST_BAD;
-      ep = 0;
-    }
-
-  incr = 1;
-  if (rhs_t != ST_BAD)
-    {
-      oep = ep;
-      if (ep && *ep == '.' && ep[1] == '.' && ep[2])
-       incr = strtoimax (ep + 2, &ep, 10);
-      if (*ep != 0)
-       rhs_t = ST_BAD;                 /* invalid incr */
-      tlen -= ep - oep;
-    }
-
-  if (lhs_t != rhs_t || lhs_t == ST_BAD || rhs_t == ST_BAD)
-    {
-      free (lhs);
-      free (rhs);
-      return ((char **)NULL);
-    }
-
-  /* OK, we have something.  It's either a sequence of integers, ascending
-     or descending, or a sequence or letters, ditto.  Generate the sequence,
-     put it into a string vector, and return it. */
-  
-  if (lhs_t == ST_CHAR)
-    {
-      lhs_v = (unsigned char)lhs[0];
-      rhs_v = (unsigned char)rhs[0];
-      width = 1;
-    }
-  else
-    {
-      lhs_v = tl;              /* integer truncation */
-      rhs_v = tr;
-
-      /* Decide whether or not the terms need zero-padding */
-      rhs_l = tlen - lhs_l - sizeof (BRACE_SEQ_SPECIFIER) + 1;
-      width = 0;
-      if (lhs_l > 1 && lhs[0] == '0')
-       width = lhs_l, lhs_t = ST_ZINT;
-      if (lhs_l > 2 && lhs[0] == '-' && lhs[1] == '0')
-       width = lhs_l, lhs_t = ST_ZINT;
-      if (rhs_l > 1 && rhs[0] == '0' && width < rhs_l)
-       width = rhs_l, lhs_t = ST_ZINT;
-      if (rhs_l > 2 && rhs[0] == '-' && rhs[1] == '0' && width < rhs_l)
-       width = rhs_l, lhs_t = ST_ZINT;
-    }
-
-  result = mkseq (lhs_v, rhs_v, incr, lhs_t, width);
-
-  free (lhs);
-  free (rhs);
-
-  return (result);
-}
-
-/* Start at INDEX, and skip characters in TEXT. Set INDEX to the
-   index of the character matching SATISFY.  This understands about
-   quoting.  Return the character that caused us to stop searching;
-   this is either the same as SATISFY, or 0. */
-/* If SATISFY is `}', we are looking for a brace expression, so we
-   should enforce the rules that govern valid brace expansions:
-       1) to count as an arg separator, a comma or `..' has to be outside
-          an inner set of braces.       
-*/
-static int
-brace_gobbler (text, tlen, indx, satisfy)
-     char *text;
-     size_t tlen;
-     int *indx;
-     int satisfy;
-{
-  register int i, c, quoted, level, commas, pass_next;
-#if defined (SHELL)
-  int si;
-  char *t;
-#endif
-  DECLARE_MBSTATE;
-
-  level = quoted = pass_next = 0;
-#if defined (CSH_BRACE_COMPAT)
-  commas = 1;
-#else
-  commas = (satisfy == '}') ? 0 : 1;
-#endif
-
-  i = *indx;
-  while (c = text[i])
-    {
-      if (pass_next)
-       {
-         pass_next = 0;
-         ADVANCE_CHAR (text, tlen, i);
-         continue;
-       }
-
-      /* A backslash escapes the next character.  This allows backslash to
-        escape the quote character in a double-quoted string. */
-      if (c == '\\' && (quoted == 0 || quoted == '"' || quoted == '`'))
-       {
-         pass_next = 1;
-         i++;
-         continue;
-       }
-
-#if defined (SHELL)
-      /* If compiling for the shell, treat ${...} like \{...} */
-      if (c == '$' && text[i+1] == '{' && quoted != '\'')              /* } */
-       {
-         pass_next = 1;
-         i++;
-         if (quoted == 0)
-           level++;
-         continue;
-       }
-#endif
-
-      if (quoted)
-       {
-         if (c == quoted)
-           quoted = 0;
-         ADVANCE_CHAR (text, tlen, i);
-         continue;
-       }
-
-      if (c == '"' || c == '\'' || c == '`')
-       {
-         quoted = c;
-         i++;
-         continue;
-       }
-
-#if defined (SHELL)
-      /* Pass new-style command and process substitutions through unchanged. */
-      if ((c == '$' || c == '<' || c == '>') && text[i+1] == '(')                      /* ) */
-       {
-         si = i + 2;
-         t = extract_command_subst (text, &si, 0);
-         i = si;
-         free (t);
-         i++;
-         continue;
-       }
-#endif
-
-      if (c == satisfy && level == 0 && quoted == 0 && commas > 0)
-       {
-         /* We ignore an open brace surrounded by whitespace, and also
-            an open brace followed immediately by a close brace preceded
-            by whitespace.  */
-         if (c == '{' &&
-             ((!i || brace_whitespace (text[i - 1])) &&
-              (brace_whitespace (text[i + 1]) || text[i + 1] == '}')))
-           {
-             i++;
-             continue;
-           }
-
-           break;
-       }
-
-      if (c == '{')
-       level++;
-      else if (c == '}' && level)
-       level--;
-#if !defined (CSH_BRACE_COMPAT)
-      else if (satisfy == '}' && c == brace_arg_separator && level == 0)
-       commas++;
-      else if (satisfy == '}' && STREQN (text+i, BRACE_SEQ_SPECIFIER, 2) &&
-               text[i+2] != satisfy && level == 0)
-       commas++;
-#endif
-
-      ADVANCE_CHAR (text, tlen, i);
-    }
-
-  *indx = i;
-  return (c);
-}
-
-/* Return a new array of strings which is the result of appending each
-   string in ARR2 to each string in ARR1.  The resultant array is
-   len (arr1) * len (arr2) long.  For convenience, ARR1 (and its contents)
-   are free ()'ed.  ARR1 can be NULL, in that case, a new version of ARR2
-   is returned. */
-static char **
-array_concat (arr1, arr2)
-     char **arr1, **arr2;
-{
-  register int i, j, len, len1, len2;
-  register char **result;
-
-  if (arr1 == 0)
-    return (strvec_copy (arr2));
-
-  if (arr2 == 0)
-    return (strvec_copy (arr1));
-
-  len1 = strvec_len (arr1);
-  len2 = strvec_len (arr2);
-
-  result = (char **)xmalloc ((1 + (len1 * len2)) * sizeof (char *));
-
-  len = 0;
-  for (i = 0; i < len1; i++)
-    {
-      int strlen_1 = strlen (arr1[i]);
-
-      for (j = 0; j < len2; j++)
-       {
-         result[len] = (char *)xmalloc (1 + strlen_1 + strlen (arr2[j]));
-         strcpy (result[len], arr1[i]);
-         strcpy (result[len] + strlen_1, arr2[j]);
-         len++;
-       }
-      free (arr1[i]);
-    }
-  free (arr1);
-
-  result[len] = (char *)NULL;
-  return (result);
-}
-
-#if defined (TEST)
-#include <stdio.h>
-
-fatal_error (format, arg1, arg2)
-     char *format, *arg1, *arg2;
-{
-  report_error (format, arg1, arg2);
-  exit (1);
-}
-
-report_error (format, arg1, arg2)
-     char *format, *arg1, *arg2;
-{
-  fprintf (stderr, format, arg1, arg2);
-  fprintf (stderr, "\n");
-}
-
-main ()
-{
-  char example[256];
-
-  for (;;)
-    {
-      char **result;
-      int i;
-
-      fprintf (stderr, "brace_expand> ");
-
-      if ((!fgets (example, 256, stdin)) ||
-         (strncmp (example, "quit", 4) == 0))
-       break;
-
-      if (strlen (example))
-       example[strlen (example) - 1] = '\0';
-
-      result = brace_expand (example);
-
-      for (i = 0; result[i]; i++)
-       printf ("%s\n", result[i]);
-
-      free_array (result);
-    }
-}
-\f
-/*
- * Local variables:
- * compile-command: "gcc -g -Bstatic -DTEST -o brace_expand braces.c general.o"
- * end:
- */
-
-#endif /* TEST */
-#endif /* BRACE_EXPANSION */
diff --git a/builtins/Makefile.in~ b/builtins/Makefile.in~
deleted file mode 100644 (file)
index 921f64f..0000000
+++ /dev/null
@@ -1,659 +0,0 @@
-# This Makefile for building libbuiltins.a is in -*- text -*- for Emacs.
-#
-# Copyright (C) 1996-2009 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
-
-PACKAGE = @PACKAGE_NAME@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-
-#
-SHELL = @MAKE_SHELL@
-RANLIB = @RANLIB@
-CC = @CC@
-CC_FOR_BUILD = @CC_FOR_BUILD@
-AR = @AR@
-ARFLAGS = @ARFLAGS@
-RM = rm -f
-CP = cp
-
-EXEEXT = @EXEEXT@
-
-prefix = @prefix@
-
-srcdir = @srcdir@
-VPATH = .:@srcdir@
-topdir = @top_srcdir@
-
-datarootdir = @datarootdir@
-
-includedir = @includedir@
-datadir = @datadir@
-localedir = @localedir@
-
-# Support an alternate destination root directory for package building
-DESTDIR =
-
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-BUILD_DIR = @BUILD_DIR@
-
-LIBBUILD = ${BUILD_DIR}/lib
-
-PROFILE_FLAGS = @PROFILE_FLAGS@
-CFLAGS = @CFLAGS@
-CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ @CROSS_COMPILE@
-CPPFLAGS = @CPPFLAGS@
-CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@
-LOCAL_CFLAGS = @LOCAL_CFLAGS@ ${DEBUG}
-DEFS = @DEFS@
-LOCAL_DEFS = @LOCAL_DEFS@
-
-LIBS = @LIBS@
-LDFLAGS = @LDFLAGS@ $(LOCAL_LDFLAGS) $(CFLAGS)
-LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@ $(LOCAL_LDFLAGS) $(CFLAGS_FOR_BUILD)
-LOCAL_LDFLAGS = @LOCAL_LDFLAGS@
-#LIBS_FOR_BUILD = @LIBS_FOR_BUILD@
-LIBS_FOR_BUILD = $(LIBS)
-
-BASHINCDIR = ${topdir}/include
-
-RL_INCLUDEDIR = @RL_INCLUDEDIR@
-
-INTL_LIBSRC = ${topdir}/lib/intl
-INTL_BUILDDIR = ${LIBBUILD}/intl
-INTL_LIBDIR = ${INTL_BUILDDIR}
-INTL_LIBRARY = ${INTL_BUILDDIR}/libintl.a
-INTL_INC = @INTL_INC@
-INTL_DEP = @INTL_DEP@
-LIBINTL_H = @LIBINTL_H@
-
-HELPDIR = @HELPDIR@
-MKDIRS = ${topdir}/support/mkdirs
-
-INCLUDES = -I. -I.. @RL_INCLUDE@ -I$(topdir) -I$(BASHINCDIR) -I$(topdir)/lib -I$(srcdir) ${INTL_INC}
-
-BASE_CCFLAGS = ${PROFILE_FLAGS} $(DEFS) $(LOCAL_DEFS) $(SYSTEM_FLAGS) \
-        ${INCLUDES} $(LOCAL_CFLAGS)
-
-CCFLAGS = $(BASE_CCFLAGS) $(CPPFLAGS) $(CFLAGS)
-
-CCFLAGS_FOR_BUILD = $(BASE_CCFLAGS) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD)
-
-GCC_LINT_FLAGS = -Wall -Wshadow -Wpointer-arith -Wcast-qual \
-                -Wcast-align -Wstrict-prototypes -Wconversion \
-                -Wmissing-prototypes -Wtraditional -Wredundant-decls -pedantic
-
-MKBUILTINS = mkbuiltins$(EXEEXT)
-DIRECTDEFINE = -D $(srcdir)
-HELPDIRDEFINE = @HELPDIRDEFINE@
-HELPSTRINGS = @HELPSTRINGS@
-
-# xxx this is bad style
-RL_LIBSRC = $(topdir)/lib/readline
-
-.SUFFIXES:
-.SUFFIXES: .def .c .o
-# How to make a .o file from a .def file.
-.def.o:
-       $(RM) $@
-       ./$(MKBUILTINS) $(DIRECTDEFINE) $<
-       $(CC) -c $(CCFLAGS) $*.c || ( $(RM) $*.c ; exit 1 )
-       $(RM) $*.c
-
-# How to make a .c file from a .def file.
-.def.c:
-       $(RM) $@
-       ./$(MKBUILTINS) $(DIRECTDEFINE) $<
-
-# default rule for making a .o file from a .c file
-.c.o:
-       $(RM) $@
-       $(CC) -c $(CCFLAGS) $<
-
-DEFSRC =  $(srcdir)/alias.def $(srcdir)/bind.def $(srcdir)/break.def \
-         $(srcdir)/builtin.def $(srcdir)/caller.def \
-         $(srcdir)/cd.def $(srcdir)/colon.def \
-         $(srcdir)/command.def $(srcdir)/declare.def $(srcdir)/echo.def \
-         $(srcdir)/enable.def $(srcdir)/eval.def $(srcdir)/getopts.def \
-         $(srcdir)/exec.def $(srcdir)/exit.def $(srcdir)/fc.def \
-         $(srcdir)/fg_bg.def $(srcdir)/hash.def $(srcdir)/help.def \
-         $(srcdir)/history.def $(srcdir)/jobs.def $(srcdir)/kill.def \
-         $(srcdir)/let.def $(srcdir)/read.def $(srcdir)/return.def \
-         $(srcdir)/set.def $(srcdir)/setattr.def $(srcdir)/shift.def \
-         $(srcdir)/source.def $(srcdir)/suspend.def $(srcdir)/test.def \
-         $(srcdir)/times.def $(srcdir)/trap.def $(srcdir)/type.def \
-         $(srcdir)/ulimit.def $(srcdir)/umask.def $(srcdir)/wait.def \
-         $(srcdir)/reserved.def $(srcdir)/pushd.def $(srcdir)/shopt.def \
-         $(srcdir)/printf.def $(srcdir)/complete.def $(srcdir)/mapfile.def
-
-STATIC_SOURCE = common.c evalstring.c evalfile.c getopt.c bashgetopt.c \
-               getopt.h 
-
-OFILES = builtins.o \
-       alias.o bind.o break.o builtin.o caller.o cd.o colon.o command.o \
-       common.o declare.o echo.o enable.o eval.o evalfile.o \
-       evalstring.o exec.o exit.o fc.o fg_bg.o hash.o help.o history.o \
-       jobs.o kill.o let.o mapfile.o \
-       pushd.o read.o return.o set.o setattr.o shift.o source.o \
-       suspend.o test.o times.o trap.o type.o ulimit.o umask.o \
-       wait.o getopts.o shopt.o printf.o getopt.o bashgetopt.o complete.o
-
-CREATED_FILES = builtext.h builtins.c psize.aux pipesize.h
-
-all: $(MKBUILTINS) libbuiltins.a
-
-libbuiltins.a: $(MKBUILTINS) $(OFILES) builtins.o
-       $(RM) $@
-       $(AR) $(ARFLAGS) $@ $(OFILES)
-       -$(RANLIB) $@
-
-builtext.h builtins.c: $(MKBUILTINS) $(DEFSRC)
-       @-if test -f builtins.c; then mv -f builtins.c old-builtins.c; fi
-       @-if test -f builtext.h; then mv -f builtext.h old-builtext.h; fi
-       ./$(MKBUILTINS) -externfile builtext.h -structfile builtins.c \
-           -noproduction $(DIRECTDEFINE) $(HELPDIRDEFINE) $(HELPSTRINGS) $(DEFSRC)
-       @-if cmp -s old-builtext.h builtext.h 2>/dev/null; then \
-               mv old-builtext.h builtext.h; \
-        else \
-               $(RM) old-builtext.h; \
-        fi
-       @-if cmp -s old-builtins.c builtins.c 2>/dev/null; then \
-               mv old-builtins.c builtins.c; \
-        else \
-               $(RM) old-builtins.c; \
-        fi
-
-helpdoc:       $(MKBUILTINS) $(DEFSRC)
-       ./$(MKBUILTINS) ${HELPDIRDEFINE} -noproduction $(DIRECTDEFINE) $(DEFSRC)
-
-install-help:
-       @-if test -n "${HELPDIR}" && test -d helpfiles ; then \
-               test -d $(DESTDIR)${HELPDIR} || ${SHELL} ${MKDIRS} $(DESTDIR)$(HELPDIR) ;\
-               ( for f in helpfiles/*; do \
-                       echo installing $$f; \
-                       ${INSTALL_DATA} $$f $(DESTDIR)$(HELPDIR); \
-                 done; ) ; \
-       fi
-
-install:       @HELPINSTALL@
-
-mkbuiltins.o: ../config.h
-mkbuiltins.o: mkbuiltins.c
-       $(RM) $@
-       $(CC_FOR_BUILD) -c $(CCFLAGS_FOR_BUILD) $<
-
-mkbuiltins$(EXEEXT): mkbuiltins.o
-       $(CC_FOR_BUILD) $(LDFLAGS_FOR_BUILD) -o $(MKBUILTINS) mkbuiltins.o $(LIBS_FOR_BUILD)
-
-# rules for deficient makes, like SunOS
-mkbuiltins.o: mkbuiltins.c
-builtins.o: builtins.c
-common.o: common.c
-bashgetopt.o: bashgetopt.c
-getopt.o: getopt.c
-evalstring.o: evalstring.c          
-evalfile.o: evalfile.c  
-
-ulimit.o: pipesize.h
-
-pipesize.h:    psize.aux
-       $(SHELL) $(srcdir)/psize.sh > $@
-
-psize.aux:     psize.c
-       $(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ $(srcdir)/psize.c
-
-documentation: builtins.texi
-
-builtins.texi: $(MKBUILTINS)
-       ./$(MKBUILTINS) -documentonly $(DEFSRC)
-
-clean:
-       $(RM) $(OFILES) $(CREATED_FILES) $(MKBUILTINS) mkbuiltins.o libbuiltins.a
-       -test -d helpfiles && $(RM) -r helpfiles
-
-mostlyclean: 
-       $(RM) $(OFILES) libbuiltins.a
-
-distclean maintainer-clean: clean
-       $(RM) Makefile
-
-$(OFILES):     $(MKBUILTINS) ../config.h
-
-../version.h: ../config.h ../Makefile Makefile
-       -( cd ${BUILD_DIR} && ${MAKE} ${MFLAGS} version.h )
-
-# maintainer special - for now
-po:    builtins.c
-       xgettext -L C -o $(topdir)/po/builtins.pot --keyword='N_' builtins.c 2>/dev/null
-
-${LIBINTL_H}:
-       @echo making $@ in ${INTL_BUILDDIR}
-       @(cd ${INTL_BUILDDIR} && \
-               $(MAKE) $(MFLAGS) libintl.h) || exit 1
-
-# dependencies
-
-alias.o: alias.def
-bind.o: bind.def
-break.o: break.def
-builtin.o: builtin.def
-caller.o: caller.def
-cd.o: cd.def
-colon.o: colon.def
-command.o: command.def
-declare.o: declare.def
-echo.o: echo.def
-enable.o: enable.def
-eval.o: eval.def
-exec.o: exec.def
-exit.o: exit.def
-fc.o: fc.def
-fg_bg.o: fg_bg.def
-hash.o: hash.def
-help.o: help.def
-history.o: history.def
-jobs.o: jobs.def
-kill.o: kill.def
-let.o: let.def
-mapfile.o: mapfile.def
-printf.o: printf.def
-pushd.o: pushd.def
-read.o: read.def
-return.o: return.def
-set.o: set.def
-setattr.o: setattr.def
-shift.o: shift.def
-shopt.o: shopt.def
-source.o: source.def
-suspend.o: suspend.def
-test.o: test.def
-times.o: times.def
-trap.o: trap.def
-type.o: type.def
-ulimit.o: ulimit.def
-umask.o: umask.def
-wait.o: wait.def
-getopts.o: getopts.def
-reserved.o: reserved.def
-complete.o: complete.def
-
-# C files
-bashgetopt.o: ../config.h $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h
-bashgetopt.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/bashjmp.h
-bashgetopt.o: $(topdir)/command.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/error.h
-bashgetopt.o: $(topdir)/variables.h $(topdir)/conftypes.h $(topdir)/quit.h $(BASHINCDIR)/maxpath.h
-bashgetopt.o: $(topdir)/unwind_prot.h $(topdir)/dispose_cmd.h
-bashgetopt.o: $(topdir)/make_cmd.h $(topdir)/subst.h $(topdir)/sig.h
-bashgetopt.o: ../pathnames.h $(topdir)/externs.h $(srcdir)/common.h
-bashgetopt.o: $(BASHINCDIR)/chartypes.h
-common.o: $(topdir)/bashtypes.h $(BASHINCDIR)/posixstat.h $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h
-common.o: $(topdir)/shell.h $(topdir)/syntax.h ../config.h $(topdir)/bashjmp.h $(BASHINCDIR)/posixjmp.h
-common.o: $(topdir)/sig.h $(topdir)/command.h
-common.o: $(topdir)/general.h $(topdir)/xmalloc.h $(BASHINCDIR)/stdc.h $(BASHINCDIR)/memalloc.h
-common.o: $(topdir)/variables.h $(topdir)/conftypes.h $(topdir)/input.h
-common.o: $(topdir)/siglist.h $(topdir)/bashhist.h $(topdir)/quit.h
-common.o: $(topdir)/unwind_prot.h $(BASHINCDIR)/maxpath.h $(topdir)/jobs.h
-common.o: $(topdir)/builtins.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-common.o: $(topdir)/subst.h $(topdir)/execute_cmd.h $(topdir)/error.h
-common.o: $(topdir)/externs.h ../pathnames.h ./builtext.h
-common.o: $(BASHINCDIR)/chartypes.h
-evalfile.o: $(topdir)/bashtypes.h $(BASHINCDIR)/posixstat.h ${BASHINCDIR}/filecntl.h
-evalfile.o: $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h
-evalfile.o: $(topdir)/shell.h $(topdir)/syntax.h ../config.h $(topdir)/bashjmp.h
-evalfile.o: $(topdir)/command.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/error.h
-evalfile.o: $(topdir)/variables.h $(topdir)/conftypes.h $(topdir)/quit.h $(BASHINCDIR)/maxpath.h
-evalfile.o: $(topdir)/unwind_prot.h $(topdir)/dispose_cmd.h
-evalfile.o: $(topdir)/make_cmd.h $(topdir)/subst.h $(topdir)/sig.h
-evalfile.o: ../pathnames.h $(topdir)/externs.h
-evalfile.o: $(topdir)/jobs.h $(topdir)/builtins.h $(topdir)/flags.h
-evalfile.o: $(topdir)/input.h $(topdir)/execute_cmd.h
-evalfile.o: $(topdir)/bashhist.h $(srcdir)/common.h
-evalstring.o: ../config.h $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h
-evalstring.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/bashjmp.h $(BASHINCDIR)/posixjmp.h
-evalstring.o: $(topdir)/sig.h $(topdir)/command.h $(topdir)/siglist.h
-evalstring.o: $(BASHINCDIR)/memalloc.h $(topdir)/variables.h $(topdir)/conftypes.h $(topdir)/input.h
-evalstring.o: $(topdir)/quit.h $(topdir)/unwind_prot.h
-evalstring.o: $(BASHINCDIR)/maxpath.h $(topdir)/jobs.h $(topdir)/builtins.h
-evalstring.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
-evalstring.o: $(topdir)/externs.h $(topdir)/jobs.h $(topdir)/builtins.h
-evalstring.o: $(topdir)/flags.h $(topdir)/input.h $(topdir)/execute_cmd.h
-evalstring.o: $(topdir)/bashhist.h $(srcdir)/common.h
-evalstring.o: $(topdir)/trap.h $(topdir)/redir.h ../pathnames.h
-getopt.o: ../config.h $(BASHINCDIR)/memalloc.h
-getopt.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/bashjmp.h $(topdir)/command.h
-getopt.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/error.h $(topdir)/variables.h $(topdir)/conftypes.h
-getopt.o: $(topdir)/quit.h $(BASHINCDIR)/maxpath.h $(topdir)/unwind_prot.h
-getopt.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
-getopt.o: $(topdir)/sig.h ../pathnames.h $(topdir)/externs.h
-getopt.o: $(srcdir)/getopt.h 
-mkbuiltins.o: ../config.h $(topdir)/bashtypes.h $(BASHINCDIR)/posixstat.h
-mkbuiltins.o: ${BASHINCDIR}/filecntl.h
-mkbuiltins.o: $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h
-
-# def files
-alias.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-alias.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(BASHINCDIR)/maxpath.h
-alias.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-alias.o: $(topdir)/subst.h $(topdir)/externs.h $(srcdir)/common.h
-alias.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-alias.o: ../pathnames.h
-bind.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
-bind.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-bind.o: $(topdir)/subst.h $(topdir)/externs.h $(srcdir)/bashgetopt.h
-bind.o: $(topdir)/general.h $(topdir)/xmalloc.h $(BASHINCDIR)/maxpath.h $(topdir)/bashline.h
-bind.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h 
-bind.o: ../pathnames.h
-break.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h 
-break.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-break.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-break.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
-break.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-break.o: ../pathnames.h
-builtin.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-builtin.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/externs.h
-builtin.o: $(topdir)/quit.h $(srcdir)/common.h $(BASHINCDIR)/maxpath.h
-builtin.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
-builtin.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h 
-builtin.o: $(srcdir)/bashgetopt.h ../pathnames.h
-caller.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
-caller.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/quit.h $(topdir)/dispose_cmd.h
-caller.o: $(topdir)/make_cmd.h $(topdir)/subst.h $(topdir)/externs.h
-caller.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-caller.o: $(srcdir)/common.h $(BASHINCDIR)/maxpath.h ./builtext.h
-caller.o: ${BASHINCDIR}/chartypes.h $(topdir)/bashtypes.h ../pathnames.h
-cd.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
-cd.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/quit.h $(topdir)/dispose_cmd.h
-cd.o: $(topdir)/make_cmd.h $(topdir)/subst.h $(topdir)/externs.h
-cd.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-cd.o: $(srcdir)/common.h $(BASHINCDIR)/maxpath.h ../pathnames.h
-command.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-command.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/externs.h
-command.o: $(topdir)/quit.h $(srcdir)/bashgetopt.h $(BASHINCDIR)/maxpath.h
-command.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
-command.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h 
-command.o: ../pathnames.h
-declare.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-declare.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-declare.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-declare.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
-declare.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-declare.o: $(topdir)/arrayfunc.h $(srcdir)/bashgetopt.h
-declare.o: ./builtext.h ../pathnames.h
-echo.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
-echo.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/subst.h $(topdir)/externs.h
-echo.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-echo.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-echo.o: $(BASHINCDIR)/maxpath.h ../pathnames.h
-enable.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-enable.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-enable.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-enable.o: $(topdir)/subst.h $(topdir)/externs.h
-enable.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-enable.o: $(BASHINCDIR)/maxpath.h ../pathnames.h
-enable.o: $(topdir)/pcomplete.h
-eval.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-eval.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-eval.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-eval.o: $(topdir)/subst.h $(topdir)/externs.h 
-eval.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-eval.o: $(BASHINCDIR)/maxpath.h ../pathnames.h
-exec.o: $(topdir)/bashtypes.h
-exec.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-exec.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-exec.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-exec.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/flags.h
-exec.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-exec.o: $(srcdir)/common.h $(topdir)/execute_cmd.h $(BASHINCDIR)/maxpath.h
-exec.o: $(topdir)/findcmd.h $(topdir)/jobs.h ../pathnames.h
-exit.o: $(topdir)/bashtypes.h
-exit.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-exit.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-exit.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-exit.o: $(topdir)/subst.h $(topdir)/externs.h  $(topdir)/jobs.h
-exit.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-exit.o: $(BASHINCDIR)/maxpath.h ./builtext.h ../pathnames.h
-fc.o: $(topdir)/bashtypes.h $(BASHINCDIR)/posixstat.h
-fc.o: $(topdir)/builtins.h $(topdir)/command.h $(srcdir)/bashgetopt.h
-fc.o: $(topdir)/bashhist.h
-fc.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
-fc.o: $(topdir)/general.h $(topdir)/xmalloc.h $(BASHINCDIR)/maxpath.h
-fc.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-fc.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/shell.h $(topdir)/syntax.h
-fc.o: $(topdir)/flags.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-fc.o: $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h $(BASHINCDIR)/chartypes.h
-fc.o: ../pathnames.h
-fg_bg.o: $(topdir)/bashtypes.h $(srcdir)/bashgetopt.h
-fg_bg.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-fg_bg.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-fg_bg.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-fg_bg.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
-fg_bg.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-fg_bg.o: $(topdir)/jobs.h ../pathnames.h
-getopts.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-getopts.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-getopts.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-getopts.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
-getopts.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-getopts.o: ../pathnames.h
-hash.o: $(topdir)/builtins.h $(topdir)/command.h $(topdir)/quit.h
-hash.o: $(topdir)/findcmd.h $(topdir)/hashlib.h
-hash.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-hash.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-hash.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-hash.o: $(srcdir)/common.h $(BASHINCDIR)/maxpath.h ../pathnames.h
-help.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-help.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-help.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-help.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
-help.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-help.o: ${srcdir}/common.h ../pathnames.h
-history.o: $(topdir)/bashtypes.h
-history.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-history.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-history.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-history.o: $(topdir)/subst.h $(topdir)/externs.h 
-history.o: ${BASHINCDIR}/filecntl.h $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h
-history.o: $(topdir)/variables.h $(topdir)/conftypes.h $(topdir)/bashhist.h $(BASHINCDIR)/maxpath.h
-history.o: ../pathnames.h
-inlib.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-inlib.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-inlib.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-inlib.o: $(BASHINCDIR)/maxpath.h $(topdir)/subst.h $(topdir)/externs.h
-inlib.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h ../pathnames.h
-jobs.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
-jobs.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/quit.h $(srcdir)/bashgetopt.h
-jobs.o: $(BASHINCDIR)/maxpath.h $(topdir)/externs.h $(topdir)/jobs.h
-jobs.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
-jobs.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h 
-jobs.o: ../pathnames.h
-kill.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
-kill.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/subst.h $(topdir)/externs.h
-kill.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-kill.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/trap.h $(topdir)/unwind_prot.h
-kill.o: $(topdir)/variables.h $(topdir)/conftypes.h $(BASHINCDIR)/maxpath.h
-kill.o: $(topdir)/jobs.h ../pathnames.h
-let.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-let.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-let.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-let.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
-let.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-let.o: ../pathnames.h
-printf.o: ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/bashjmp.h
-printf.o: $(topdir)/command.h $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-printf.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-printf.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/sig.h
-printf.o: ../pathnames.h $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h
-printf.o: $(topdir)/variables.h $(topdir)/conftypes.h $(BASHINCDIR)/stdc.h $(srcdir)/bashgetopt.h
-printf.o: $(topdir)/bashtypes.h ${srcdir}/common.h $(BASHINCDIR)/chartypes.h
-printf.o: ../pathnames.h
-pushd.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-pushd.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-pushd.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-pushd.o: $(topdir)/subst.h $(topdir)/externs.h 
-pushd.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-pushd.o: $(BASHINCDIR)/maxpath.h $(srcdir)/common.h ./builtext.h
-pushd.o: ../pathnames.h
-read.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-read.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-read.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-read.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
-read.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-read.o: $(BASHINCDIR)/shtty.h
-read.o: $(topdir)/arrayfunc.h ../pathnames.h
-return.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-return.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-return.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-return.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
-return.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-return.o: ../pathnames.h
-set.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-set.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/subst.h $(topdir)/externs.h
-set.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-set.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-set.o: $(BASHINCDIR)/maxpath.h $(topdir)/error.h
-set.o: $(topdir)/arrayfunc.h ../pathnames.h
-setattr.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-setattr.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(BASHINCDIR)/maxpath.h
-setattr.o: $(topdir)/quit.h $(srcdir)/common.h $(srcdir)/bashgetopt.h
-setattr.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
-setattr.o: $(topdir)/externs.h 
-setattr.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h 
-setattr.o: $(topdir)/arrayfunc.h ../pathnames.h
-shift.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-shift.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-shift.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-shift.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
-shift.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-shift.o: ../pathnames.h
-shopt.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-shopt.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h 
-shopt.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-shopt.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
-shopt.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-shopt.o: $(srcdir)/common.h $(srcdir)/bashgetopt.h ../pathnames.h
-shopt.o: $(srcdir)/bashhist.h
-source.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-source.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/findcmd.h
-source.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-source.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
-source.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-source.o: $(srcdir)/bashgetopt.h $(topdir)/flags.h $(topdir)/trap.h
-source.o: ../pathnames.h
-suspend.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-suspend.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-suspend.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-suspend.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
-suspend.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-suspend.o: $(topdir)/jobs.h ../pathnames.h
-test.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-test.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-test.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-test.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
-test.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-test.o: $(topdir)/test.h ../pathnames.h
-times.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-times.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-times.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-times.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
-times.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-times.o: $(BASHINCDIR)/posixtime.h ../pathnames.h
-trap.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-trap.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/externs.h
-trap.o: $(topdir)/quit.h $(srcdir)/common.h $(BASHINCDIR)/maxpath.h
-trap.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
-trap.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-trap.o: $(topdir)/findcmd.h ../pathnames.h
-type.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-type.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-type.o: $(topdir)/quit.h $(srcdir)/common.h $(BASHINCDIR)/maxpath.h
-type.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
-type.o: $(topdir)/externs.h $(topdir)/hashcmd.h ../pathnames.h
-type.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h 
-ulimit.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-ulimit.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-ulimit.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-ulimit.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
-ulimit.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-ulimit.o: ../pathnames.h
-umask.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-umask.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-umask.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-umask.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
-umask.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-umask.o: $(BASHINCDIR)/chartypes.h ../pathnames.h
-wait.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-wait.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-wait.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-wait.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
-wait.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-wait.o: $(topdir)/jobs.h
-wait.o: $(BASHINCDIR)/chartypes.h ../pathnames.h
-
-complete.o: ../config.h ../pathnames.h
-complete.o: ${topdir}/shell.h $(topdir)/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h ${topdir}/sig.h  
-complete.o: ${topdir}/unwind_prot.h ${topdir}/variables.h
-complete.o: ${topdir}/bashtypes.h ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-complete.o: ${topdir}/builtins.h
-complete.o: ${topdir}/pcomplete.h
-complete.o: ${srcdir}/common.h ${srcdir}/bashgetopt.h
-mapfile.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
-mapfile.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
-mapfile.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
-mapfile.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
-mapfile.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/variables.h $(topdir)/conftypes.h
-mapfile.o: $(topdir)/arrayfunc.h ../pathnames.h
-
-#bind.o: $(RL_LIBSRC)chardefs.h $(RL_LIBSRC)readline.h $(RL_LIBSRC)keymaps.h
-
-# libintl dependencies
-bind.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-break.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-caller.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-cd.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-common.c: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-complete.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-declare.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-enable.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-evalfile.c: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-exec.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-exit.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-fc.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-fg_bg.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-getopt.c: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-hash.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-help.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-history.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-inlib.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-jobs.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-kill.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-let.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-mapfile.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-mkbuiltins.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-printf.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-pushd.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-read.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-return.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-set.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-setattr.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-shift.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-shopt.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-source.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-suspend.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-type.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-ulimit.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-umask.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
diff --git a/builtins/alias.def~ b/builtins/alias.def~
deleted file mode 100644 (file)
index 539f773..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-This file is alias.def, from which is created alias.c
-It implements the builtins "alias" and "unalias" in Bash.
-
-Copyright (C) 1987-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/>.
-
-$BUILTIN alias
-$FUNCTION alias_builtin
-$DEPENDS_ON ALIAS
-$PRODUCES alias.c
-$SHORT_DOC alias [-p] [name[=value] ... ]
-Define or display aliases.
-
-Without arguments, `alias' prints the list of aliases in the reusable
-form `alias NAME=VALUE' on standard output.
-
-Otherwise, an alias is defined for each NAME whose VALUE is given.
-A trailing space in VALUE causes the next word to be checked for
-alias substitution when the alias is expanded.
-
-Options:
-  -p   Print all defined aliases in a reusable format
-
-Exit Status:
-alias returns true unless a NAME is supplied for which no alias has been
-defined.
-$END
-
-#include <config.h>
-
-#if defined (ALIAS)
-
-#if defined (HAVE_UNISTD_H)
-#  ifdef _MINIX
-#    include <sys/types.h>
-#  endif
-#  include <unistd.h>
-#endif
-
-#  include "../bashansi.h"
-#  include "../bashintl.h"
-
-#  include <stdio.h>
-#  include "../shell.h"
-#  include "../alias.h"
-#  include "common.h"
-#  include "bashgetopt.h"
-
-/* Flags for print_alias */
-#define AL_REUSABLE    0x01
-
-static void print_alias __P((alias_t *, int));
-
-extern int posixly_correct;
-
-/* Hack the alias command in a Korn shell way. */
-int
-alias_builtin (list)
-     WORD_LIST *list;
-{
-  int any_failed, offset, pflag, dflags;
-  alias_t **alias_list, *t;
-  char *name, *value;
-
-itrace("alias_builtin");
-  dflags = posixly_correct ? 0 : AL_REUSABLE;
-  pflag = 0;
-  reset_internal_getopt ();
-  while ((offset = internal_getopt (list, "p")) != -1)
-    {
-      switch (offset)
-       {
-       case 'p':
-         pflag = 1;
-         dflags |= AL_REUSABLE;
-         break;
-       default:
-         builtin_usage ();
-         return (EX_USAGE);
-       }
-    }
-
-  list = loptend;
-
-  if (list == 0 || pflag)
-    {
-      if (aliases == 0)
-       return (EXECUTION_SUCCESS);
-
-      alias_list = all_aliases ();
-
-      if (alias_list == 0)
-       return (EXECUTION_SUCCESS);
-
-      for (offset = 0; alias_list[offset]; offset++)
-       print_alias (alias_list[offset], dflags);
-
-      free (alias_list);       /* XXX - Do not free the strings. */
-
-      if (list == 0)
-       return (sh_chkwrite (EXECUTION_SUCCESS));
-    }
-
-  any_failed = 0;
-  while (list)
-    {
-      name = list->word->word;
-
-      for (offset = 0; name[offset] && name[offset] != '='; offset++)
-       ;
-
-      if (offset && name[offset] == '=')
-       {
-         name[offset] = '\0';
-         value = name + offset + 1;
-
-         if (legal_alias_name (name, 0) == 0)
-           {
-             builtin_error (_("`%s': invalid alias name"), name);
-             any_failed++;
-           }
-         else
-           add_alias (name, value);
-       }
-      else
-       {
-         t = find_alias (name);
-         if (t)
-           print_alias (t, dflags);
-         else
-           {
-             sh_notfound (name);
-             any_failed++;
-           }
-       }
-      list = list->next;
-    }
-
-  return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
-}
-#endif /* ALIAS */
-
-$BUILTIN unalias
-$FUNCTION unalias_builtin
-$DEPENDS_ON ALIAS
-$SHORT_DOC unalias [-a] name [name ...]
-Remove each NAME from the list of defined aliases.
-
-Options:
-  -a   remove all alias definitions.
-
-Return success unless a NAME is not an existing alias.
-$END
-
-#if defined (ALIAS)
-/* Remove aliases named in LIST from the aliases database. */
-int
-unalias_builtin (list)
-     register WORD_LIST *list;
-{
-  register alias_t *alias;
-  int opt, aflag;
-
-  aflag = 0;
-  reset_internal_getopt ();
-  while ((opt = internal_getopt (list, "a")) != -1)
-    {
-      switch (opt)
-       {
-       case 'a':
-         aflag = 1;
-         break;
-       default:
-         builtin_usage ();
-         return (EX_USAGE);
-       }
-    }
-
-  list = loptend;
-
-  if (aflag)
-    {
-      delete_all_aliases ();
-      return (EXECUTION_SUCCESS);
-    }
-
-  if (list == 0)
-    {
-      builtin_usage ();
-      return (EX_USAGE);
-    }
-
-  aflag = 0;
-  while (list)
-    {
-      alias = find_alias (list->word->word);
-
-      if (alias)
-       remove_alias (alias->name);
-      else
-       {
-         sh_notfound (list->word->word);
-         aflag++;
-       }
-
-      list = list->next;
-    }
-
-  return (aflag ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
-}
-
-/* Output ALIAS in such a way as to allow it to be read back in. */
-static void
-print_alias (alias, flags)
-     alias_t *alias;
-     int flags;
-{
-  char *value;
-
-  value = sh_single_quote (alias->value);
-  if (flags & AL_REUSABLE)
-    printf ("alias ");
-  printf ("%s=%s\n", alias->name, value);
-  free (value);
-
-  fflush (stdout);
-}
-#endif /* ALIAS */
diff --git a/builtins/bind.def~ b/builtins/bind.def~
deleted file mode 100644 (file)
index fcc3bbb..0000000
+++ /dev/null
@@ -1,332 +0,0 @@
-This file is bind.def, from which is created bind.c.
-It implements the builtin "bind" in Bash.
-
-Copyright (C) 1987-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/>.
-
-$PRODUCES bind.c
-
-#include <config.h>
-
-$BUILTIN bind
-$DEPENDS_ON READLINE
-$FUNCTION bind_builtin
-$SHORT_DOC bind [-lpvsPVS] [-m keymap] [-f filename] [-q name] [-u name] [-r keyseq] [-x keyseq:shell-command] [keyseq:readline-function or readline-command]
-Set Readline key bindings and variables.
-
-Bind a key sequence to a Readline function or a macro, or set a
-Readline variable.  The non-option argument syntax is equivalent to
-that found in ~/.inputrc, but must be passed as a single argument:
-e.g., bind '"\C-x\C-r": re-read-init-file'.
-
-Options:
-  -m  keymap         Use KEYMAP as the keymap for the duration of this
-                     command.  Acceptable keymap names are emacs,
-                     emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move,
-                     vi-command, and vi-insert.
-  -l                 List names of functions.
-  -P                 List function names and bindings.
-  -p                 List functions and bindings in a form that can be
-                     reused as input.
-  -S                 List key sequences that invoke macros and their values
-  -s                 List key sequences that invoke macros and their values
-                     in a form that can be reused as input.
-  -V                 List variable names and values
-  -v                 List variable names and values in a form that can
-                     be reused as input.
-  -q  function-name  Query about which keys invoke the named function.
-  -u  function-name  Unbind all keys which are bound to the named function.
-  -r  keyseq         Remove the binding for KEYSEQ.
-  -f  filename       Read key bindings from FILENAME.
-  -x  keyseq:shell-command     Cause SHELL-COMMAND to be executed when
-                               KEYSEQ is entered.
-
-Exit Status:
-bind returns 0 unless an unrecognized option is given or an error occurs.
-$END
-
-#if defined (READLINE)
-
-#if defined (HAVE_UNISTD_H)
-#  ifdef _MINIX
-#    include <sys/types.h>
-#  endif
-#  include <unistd.h>
-#endif
-
-#include <stdio.h>
-#include <errno.h>
-#if !defined (errno)
-extern int errno;
-#endif /* !errno */
-
-#include <readline/readline.h>
-#include <readline/history.h>
-
-#include "../bashintl.h"
-
-#include "../shell.h"
-#include "../bashline.h"
-#include "bashgetopt.h"
-#include "common.h"
-
-static int query_bindings __P((char *));
-static int unbind_command __P((char *));
-
-extern int no_line_editing;
-
-#define BIND_RETURN(x)  do { return_code = x; goto bind_exit; } while (0)
-
-#define LFLAG  0x0001
-#define PFLAG  0x0002
-#define FFLAG  0x0004
-#define VFLAG  0x0008
-#define QFLAG  0x0010
-#define MFLAG  0x0020
-#define RFLAG  0x0040
-#define PPFLAG 0x0080
-#define VVFLAG 0x0100
-#define SFLAG   0x0200
-#define SSFLAG  0x0400
-#define UFLAG  0x0800
-#define XFLAG  0x1000
-
-int
-bind_builtin (list)
-     WORD_LIST *list;
-{
-  int return_code;
-  Keymap kmap, saved_keymap;
-  int flags, opt;
-  char *initfile, *map_name, *fun_name, *unbind_name, *remove_seq, *cmd_seq;
-
-  if (no_line_editing)
-    {
-#if 0
-      builtin_error (_("line editing not enabled"));
-      return (EXECUTION_FAILURE);
-#else
-      builtin_warning (_("line editing not enabled"));
-#endif
-    }
-
-  kmap = saved_keymap = (Keymap) NULL;
-  flags = 0;
-  initfile = map_name = fun_name = unbind_name = remove_seq = (char *)NULL;
-  return_code = EXECUTION_SUCCESS;
-
-  if (bash_readline_initialized == 0)
-    initialize_readline ();
-
-  begin_unwind_frame ("bind_builtin");
-  unwind_protect_var (rl_outstream);
-
-  rl_outstream = stdout;
-
-  reset_internal_getopt ();  
-  while ((opt = internal_getopt (list, "lvpVPsSf:q:u:m:r:x:")) != EOF)
-    {
-      switch (opt)
-       {
-       case 'l':
-         flags |= LFLAG;
-         break;
-       case 'v':
-         flags |= VFLAG;
-         break;
-       case 'p':
-         flags |= PFLAG;
-         break;
-       case 'f':
-         flags |= FFLAG;
-         initfile = list_optarg;
-         break;
-       case 'm':
-         flags |= MFLAG;
-         map_name = list_optarg;
-         break;
-       case 'q':
-         flags |= QFLAG;
-         fun_name = list_optarg;
-         break;
-       case 'u':
-         flags |= UFLAG;
-         unbind_name = list_optarg;
-         break;
-       case 'r':
-         flags |= RFLAG;
-         remove_seq = list_optarg;
-         break;
-       case 'V':
-         flags |= VVFLAG;
-         break;
-       case 'P':
-         flags |= PPFLAG;
-         break;
-       case 's':
-         flags |= SFLAG;
-         break;
-       case 'S':
-         flags |= SSFLAG;
-         break;
-       case 'x':
-         flags |= XFLAG;
-         cmd_seq = list_optarg;
-         break;
-       default:
-         builtin_usage ();
-         BIND_RETURN (EX_USAGE);
-       }
-    }
-
-  list = loptend;
-
-  /* First, see if we need to install a special keymap for this
-     command.  Then start on the arguments. */
-
-  if ((flags & MFLAG) && map_name)
-    {
-      kmap = rl_get_keymap_by_name (map_name);
-      if (!kmap)
-       {
-         builtin_error (_("`%s': invalid keymap name"), map_name);
-         BIND_RETURN (EXECUTION_FAILURE);
-       }
-    }
-
-  if (kmap)
-    {
-      saved_keymap = rl_get_keymap ();
-      rl_set_keymap (kmap);
-    }
-
-  /* XXX - we need to add exclusive use tests here.  It doesn't make sense
-     to use some of these options together. */
-  /* Now hack the option arguments */
-  if (flags & LFLAG)
-    rl_list_funmap_names ();
-
-  if (flags & PFLAG)
-    rl_function_dumper (1);
-
-  if (flags & PPFLAG)
-    rl_function_dumper (0);
-
-  if (flags & SFLAG)
-    rl_macro_dumper (1);
-
-  if (flags & SSFLAG)
-    rl_macro_dumper (0);
-
-  if (flags & VFLAG)
-    rl_variable_dumper (1);
-
-  if (flags & VVFLAG)
-    rl_variable_dumper (0);
-
-  if ((flags & FFLAG) && initfile)
-    {
-      if (rl_read_init_file (initfile) != 0)
-       {
-         builtin_error (_("%s: cannot read: %s"), initfile, strerror (errno));
-         BIND_RETURN (EXECUTION_FAILURE);
-       }
-    }
-
-  if ((flags & QFLAG) && fun_name)
-    return_code = query_bindings (fun_name);
-
-  if ((flags & UFLAG) && unbind_name)
-    return_code = unbind_command (unbind_name);
-
-  if ((flags & RFLAG) && remove_seq)
-    {
-      if (rl_set_key (remove_seq, (rl_command_func_t *)NULL, rl_get_keymap ()) != 0)
-       {
-         builtin_error (_("`%s': cannot unbind"), remove_seq);
-         BIND_RETURN (EXECUTION_FAILURE);
-       }
-    }
-
-  if (flags & XFLAG)
-    return_code = bind_keyseq_to_unix_command (cmd_seq);
-
-  /* Process the rest of the arguments as binding specifications. */
-  while (list)
-    {
-      rl_parse_and_bind (list->word->word);
-      list = list->next;
-    }
-
- bind_exit:
-  if (saved_keymap)
-    rl_set_keymap (saved_keymap);
-
-  run_unwind_frame ("bind_builtin");
-
-  return (sh_chkwrite (return_code));
-}
-
-static int
-query_bindings (name)
-     char *name;
-{
-  rl_command_func_t *function;
-  char **keyseqs;
-  int j;
-
-  function = rl_named_function (name);
-  if (function == 0)
-    {
-      builtin_error (_("`%s': unknown function name"), name);
-      return EXECUTION_FAILURE;
-    }
-
-  keyseqs = rl_invoking_keyseqs (function);
-
-  if (!keyseqs)
-    {
-      printf (_("%s is not bound to any keys.\n"), name);
-      return EXECUTION_FAILURE;
-    }
-
-  printf (_("%s can be invoked via "), name);
-  for (j = 0; j < 5 && keyseqs[j]; j++)
-    printf ("\"%s\"%s", keyseqs[j], keyseqs[j + 1] ? ", " : ".\n");
-  if (keyseqs[j])
-    printf ("...\n");
-  strvec_dispose (keyseqs);
-  return EXECUTION_SUCCESS;
-}
-
-static int
-unbind_command (name)
-     char *name;
-{
-  rl_command_func_t *function;
-
-  function = rl_named_function (name);
-  if (function == 0)
-    {
-      builtin_error (_("`%s': unknown function name"), name);
-      return EXECUTION_FAILURE;
-    }
-
-  rl_unbind_function_in_map (function, rl_get_keymap ());
-  return EXECUTION_SUCCESS;
-}
-#endif /* READLINE */
diff --git a/builtins/common.c~ b/builtins/common.c~
deleted file mode 100644 (file)
index 6ba641b..0000000
+++ /dev/null
@@ -1,890 +0,0 @@
-/* common.c - utility functions for all builtins */
-
-/* Copyright (C) 1987-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/>.
-*/
-
-#include <config.h>
-
-#if defined (HAVE_UNISTD_H)
-#  ifdef _MINIX
-#    include <sys/types.h>
-#  endif
-#  include <unistd.h>
-#endif
-
-#include <stdio.h>
-#include <chartypes.h>
-#include "../bashtypes.h"
-#include "posixstat.h"
-#include <signal.h>
-
-#include <errno.h>
-
-#if defined (PREFER_STDARG)
-#  include <stdarg.h>
-#else
-#  include <varargs.h>
-#endif
-
-#include "../bashansi.h"
-#include "../bashintl.h"
-
-#define NEED_FPURGE_DECL
-
-#include "../shell.h"
-#include "maxpath.h"
-#include "../flags.h"
-#include "../jobs.h"
-#include "../builtins.h"
-#include "../input.h"
-#include "../execute_cmd.h"
-#include "../trap.h"
-#include "bashgetopt.h"
-#include "common.h"
-#include "builtext.h"
-#include <tilde/tilde.h>
-
-#if defined (HISTORY)
-#  include "../bashhist.h"
-#endif
-
-#if !defined (errno)
-extern int errno;   
-#endif /* !errno */
-
-extern int indirection_level, subshell_environment;
-extern int line_number;
-extern int last_command_exit_value;
-extern int running_trap;
-extern int posixly_correct;
-extern char *this_command_name, *shell_name;
-extern const char * const bash_getcwd_errstr;
-
-/* Used by some builtins and the mainline code. */
-sh_builtin_func_t *last_shell_builtin = (sh_builtin_func_t *)NULL;
-sh_builtin_func_t *this_shell_builtin = (sh_builtin_func_t *)NULL;
-
-/* **************************************************************** */
-/*                                                                 */
-/*          Error reporting, usage, and option processing          */
-/*                                                                 */
-/* **************************************************************** */
-
-/* This is a lot like report_error (), but it is for shell builtins
-   instead of shell control structures, and it won't ever exit the
-   shell. */
-
-static void
-builtin_error_prolog ()
-{
-  char *name;
-
-  name = get_name_for_error ();
-  fprintf (stderr, "%s: ", name);
-
-  if (interactive_shell == 0)
-    fprintf (stderr, _("line %d: "), executing_line_number ());
-
-  if (this_command_name && *this_command_name)
-    fprintf (stderr, "%s: ", this_command_name);
-}
-
-void
-#if defined (PREFER_STDARG)
-builtin_error (const char *format, ...)
-#else
-builtin_error (format, va_alist)
-     const char *format;
-     va_dcl
-#endif
-{
-  va_list args;
-
-  builtin_error_prolog ();
-
-  SH_VA_START (args, format);
-
-  vfprintf (stderr, format, args);
-  va_end (args);
-  fprintf (stderr, "\n");
-}
-
-void
-#if defined (PREFER_STDARG)
-builtin_warning (const char *format, ...)
-#else
-builtin_warning (format, va_alist)
-     const char *format;
-     va_dcl
-#endif
-{
-  va_list args;
-
-  builtin_error_prolog ();
-  fprintf (stderr, _("warning: "));
-
-  SH_VA_START (args, format);
-
-  vfprintf (stderr, format, args);
-  va_end (args);
-  fprintf (stderr, "\n");
-}
-
-/* Print a usage summary for the currently-executing builtin command. */
-void
-builtin_usage ()
-{
-  if (this_command_name && *this_command_name)
-    fprintf (stderr, _("%s: usage: "), this_command_name);
-  fprintf (stderr, "%s\n", current_builtin->short_doc);
-  fflush (stderr);
-}
-
-/* Return if LIST is NULL else barf and jump to top_level.  Used by some
-   builtins that do not accept arguments. */
-void
-no_args (list)
-     WORD_LIST *list;
-{
-  if (list)
-    {
-      builtin_error (_("too many arguments"));
-      top_level_cleanup ();
-      jump_to_top_level (DISCARD);
-    }
-}
-
-/* Check that no options were given to the currently-executing builtin,
-   and return 0 if there were options. */
-int
-no_options (list)
-     WORD_LIST *list;
-{
-  reset_internal_getopt ();
-  if (internal_getopt (list, "") != -1)
-    {
-      builtin_usage ();
-      return (1);
-    }
-  return (0);
-}
-
-void
-sh_needarg (s)
-     char *s;
-{
-  builtin_error (_("%s: option requires an argument"), s);
-}
-
-void
-sh_neednumarg (s)
-     char *s;
-{
-  builtin_error (_("%s: numeric argument required"), s);
-}
-
-void
-sh_notfound (s)
-     char *s;
-{
-  builtin_error (_("%s: not found"), s);
-}
-
-/* Function called when one of the builtin commands detects an invalid
-   option. */
-void
-sh_invalidopt (s)
-     char *s;
-{
-  builtin_error (_("%s: invalid option"), s);
-}
-
-void
-sh_invalidoptname (s)
-     char *s;
-{
-  builtin_error (_("%s: invalid option name"), s);
-}
-
-void
-sh_invalidid (s)
-     char *s;
-{
-  builtin_error (_("`%s': not a valid identifier"), s);
-}
-
-void
-sh_invalidnum (s)
-     char *s;
-{
-  char *msg;
-
-  if (*s == '0' && isdigit (s[1]))
-    msg = _("invalid octal number");
-  else if (*s == '0' && s[1] == 'x')
-    msg = _("invalid hex number");
-  else
-    msg = _("invalid number");
-  builtin_error ("%s: %s", s, msg);
-}
-
-void
-sh_invalidsig (s)
-     char *s;
-{
-  builtin_error (_("%s: invalid signal specification"), s);
-}
-
-void
-sh_badpid (s)
-     char *s;
-{
-  builtin_error (_("`%s': not a pid or valid job spec"), s);
-}
-
-void
-sh_readonly (s)
-     const char *s;
-{
-  builtin_error (_("%s: readonly variable"), s);
-}
-
-void
-sh_erange (s, desc)
-     char *s, *desc;
-{
-  if (s)
-    builtin_error (_("%s: %s out of range"), s, desc ? desc : _("argument"));
-  else
-    builtin_error (_("%s out of range"), desc ? desc : _("argument"));
-}
-
-#if defined (JOB_CONTROL)
-void
-sh_badjob (s)
-     char *s;
-{
-  builtin_error (_("%s: no such job"), s);
-}
-
-void
-sh_nojobs (s)
-     char *s;
-{
-  if (s)
-    builtin_error (_("%s: no job control"), s);
-  else
-    builtin_error (_("no job control"));
-}
-#endif
-
-#if defined (RESTRICTED_SHELL)
-void
-sh_restricted (s)
-     char *s;
-{
-  if (s)
-    builtin_error (_("%s: restricted"), s);
-  else
-    builtin_error (_("restricted"));
-}
-#endif
-
-void
-sh_notbuiltin (s)
-     char *s;
-{
-  builtin_error (_("%s: not a shell builtin"), s);
-}
-
-void
-sh_wrerror ()
-{
-#if defined (DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS) && defined (EPIPE)
-  if (errno != EPIPE)
-#endif /* DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS && EPIPE */
-  builtin_error (_("write error: %s"), strerror (errno));
-}
-
-void
-sh_ttyerror (set)
-     int set;
-{
-  if (set)
-    builtin_error (_("error setting terminal attributes: %s"), strerror (errno));
-  else
-    builtin_error (_("error getting terminal attributes: %s"), strerror (errno));
-}
-
-int
-sh_chkwrite (s)
-     int s;
-{
-  fflush (stdout);
-  if (ferror (stdout))
-    {
-      sh_wrerror ();
-      fpurge (stdout);
-      clearerr (stdout);
-      return (EXECUTION_FAILURE);
-    }
-  return (s);
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*          Shell positional parameter manipulation                */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Convert a WORD_LIST into a C-style argv.  Return the number of elements
-   in the list in *IP, if IP is non-null.  A convenience function for
-   loadable builtins; also used by `test'. */
-char **
-make_builtin_argv (list, ip)
-     WORD_LIST *list;
-     int *ip;
-{
-  char **argv;
-
-  argv = strvec_from_word_list (list, 0, 1, ip);
-  argv[0] = this_command_name;
-  return argv;
-}
-
-/* Remember LIST in $0 ... $9, and REST_OF_ARGS.  If DESTRUCTIVE is
-   non-zero, then discard whatever the existing arguments are, else
-   only discard the ones that are to be replaced. */
-void
-remember_args (list, destructive)
-     WORD_LIST *list;
-     int destructive;
-{
-  register int i;
-
-  for (i = 1; i < 10; i++)
-    {
-      if ((destructive || list) && dollar_vars[i])
-       {
-         free (dollar_vars[i]);
-         dollar_vars[i] = (char *)NULL;
-       }
-
-      if (list)
-       {
-         dollar_vars[i] = savestring (list->word->word);
-         list = list->next;
-       }
-    }
-
-  /* If arguments remain, assign them to REST_OF_ARGS.
-     Note that copy_word_list (NULL) returns NULL, and
-     that dispose_words (NULL) does nothing. */
-  if (destructive || list)
-    {
-      dispose_words (rest_of_args);
-      rest_of_args = copy_word_list (list);
-    }
-
-  if (destructive)
-    set_dollar_vars_changed ();
-}
-
-static int changed_dollar_vars;
-
-/* Have the dollar variables been reset to new values since we last
-   checked? */
-int
-dollar_vars_changed ()
-{
-  return (changed_dollar_vars);
-}
-
-void
-set_dollar_vars_unchanged ()
-{
-  changed_dollar_vars = 0;
-}
-
-void
-set_dollar_vars_changed ()
-{
-  if (variable_context)
-    changed_dollar_vars |= ARGS_FUNC;
-  else if (this_shell_builtin == set_builtin)
-    changed_dollar_vars |= ARGS_SETBLTIN;
-  else
-    changed_dollar_vars |= ARGS_INVOC;
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*             Validating numeric input and arguments              */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Read a numeric arg for this_command_name, the name of the shell builtin
-   that wants it.  LIST is the word list that the arg is to come from.
-   Accept only the numeric argument; report an error if other arguments
-   follow.  If FATAL is 1, call throw_to_top_level, which exits the
-   shell; if it's 2, call jump_to_top_level (DISCARD), which aborts the
-   current command; if FATAL is 0, return an indication of an invalid
-   number by setting *NUMOK == 0 and return -1. */
-int
-get_numeric_arg (list, fatal, count)
-     WORD_LIST *list;
-     int fatal;
-     intmax_t *count;
-{
-  char *arg;
-
-  if (count)
-    *count = 1;
-
-  if (list && list->word && ISOPTION (list->word->word, '-'))
-    list = list->next;
-
-  if (list)
-    {
-      arg = list->word->word;
-      if (arg == 0 || (legal_number (arg, count) == 0))
-       {
-         sh_neednumarg (list->word->word ? list->word->word : "`'");
-         if (fatal == 0)
-           return 0;
-         else if (fatal == 1)          /* fatal == 1; abort */
-           throw_to_top_level ();
-         else                          /* fatal == 2; discard current command */
-           {
-             top_level_cleanup ();
-             jump_to_top_level (DISCARD);
-           }
-       }
-      no_args (list->next);
-    }
-
-  return (1);
-}
-
-/* Get an eight-bit status value from LIST */
-int
-get_exitstat (list)
-     WORD_LIST *list;
-{
-  int status;
-  intmax_t sval;
-  char *arg;
-
-  if (list && list->word && ISOPTION (list->word->word, '-'))
-    list = list->next;
-
-  if (list == 0)
-    return (last_command_exit_value);      
-
-  arg = list->word->word;
-  if (arg == 0 || legal_number (arg, &sval) == 0)
-    {
-      sh_neednumarg (list->word->word ? list->word->word : "`'");
-      return 255;
-    }
-  no_args (list->next);
-
-  status = sval & 255;
-  return status;
-}
-
-/* Return the octal number parsed from STRING, or -1 to indicate
-   that the string contained a bad number. */
-int
-read_octal (string)
-     char *string;
-{
-  int result, digits;
-
-  result = digits = 0;
-  while (*string && ISOCTAL (*string))
-    {
-      digits++;
-      result = (result * 8) + (*string++ - '0');
-      if (result > 0777)
-       return -1;
-    }
-
-  if (digits == 0 || *string)
-    result = -1;
-
-  return (result);
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*          Manipulating the current working directory             */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Return a consed string which is the current working directory.
-   FOR_WHOM is the name of the caller for error printing.  */
-char *the_current_working_directory = (char *)NULL;
-
-char *
-get_working_directory (for_whom)
-     char *for_whom;
-{
-  if (no_symbolic_links)
-    {
-      FREE (the_current_working_directory);
-      the_current_working_directory = (char *)NULL;
-    }
-
-  if (the_current_working_directory == 0)
-    {
-#if defined (GETCWD_BROKEN)
-      the_current_working_directory = getcwd (0, PATH_MAX);
-#else
-      the_current_working_directory = getcwd (0, 0);
-#endif
-      if (the_current_working_directory == 0)
-       {
-         fprintf (stderr, _("%s: error retrieving current directory: %s: %s\n"),
-                  (for_whom && *for_whom) ? for_whom : get_name_for_error (),
-                  _(bash_getcwd_errstr), strerror (errno));
-         return (char *)NULL;
-       }
-    }
-
-  return (savestring (the_current_working_directory));
-}
-
-/* Make NAME our internal idea of the current working directory. */
-void
-set_working_directory (name)
-     char *name;
-{
-  FREE (the_current_working_directory);
-  the_current_working_directory = savestring (name);
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*             Job control support functions                       */
-/*                                                                 */
-/* **************************************************************** */
-
-#if defined (JOB_CONTROL)
-int
-get_job_by_name (name, flags)
-     const char *name;
-     int flags;
-{
-  register int i, wl, cl, match, job;
-  register PROCESS *p;
-  register JOB *j;
-
-  job = NO_JOB;
-  wl = strlen (name);
-  for (i = js.j_jobslots - 1; i >= 0; i--)
-    {
-      j = get_job_by_jid (i);
-      if (j == 0 || ((flags & JM_STOPPED) && J_JOBSTATE(j) != JSTOPPED))
-        continue;
-
-      p = j->pipe;
-      do
-        {
-         if (flags & JM_EXACT)
-           {
-             cl = strlen (p->command);
-             match = STREQN (p->command, name, cl);
-           }
-         else if (flags & JM_SUBSTRING)
-           match = strindex (p->command, name) != (char *)0;
-         else
-           match = STREQN (p->command, name, wl);
-
-         if (match == 0)
-           {
-             p = p->next;
-             continue;
-           }
-         else if (flags & JM_FIRSTMATCH)
-           return i;           /* return first match */
-         else if (job != NO_JOB)
-           {
-             if (this_shell_builtin)
-               builtin_error (_("%s: ambiguous job spec"), name);
-             else
-               report_error (_("%s: ambiguous job spec"), name);
-             return (DUP_JOB);
-           }
-         else
-           job = i;
-        }
-      while (p != j->pipe);
-    }
-
-  return (job);
-}
-
-/* Return the job spec found in LIST. */
-int
-get_job_spec (list)
-     WORD_LIST *list;
-{
-  register char *word;
-  int job, jflags;
-
-  if (list == 0)
-    return (js.j_current);
-
-  word = list->word->word;
-
-  if (*word == '\0')
-    return (NO_JOB);
-
-  if (*word == '%')
-    word++;
-
-  if (DIGIT (*word) && all_digits (word))
-    {
-      job = atoi (word);
-      return (job > js.j_jobslots ? NO_JOB : job - 1);
-    }
-
-  jflags = 0;
-  switch (*word)
-    {
-    case 0:
-    case '%':
-    case '+':
-      return (js.j_current);
-
-    case '-':
-      return (js.j_previous);
-
-    case '?':                  /* Substring search requested. */
-      jflags |= JM_SUBSTRING;
-      word++;
-      /* FALLTHROUGH */
-
-    default:
-      return get_job_by_name (word, jflags);
-    }
-}
-#endif /* JOB_CONTROL */
-
-/*
- * NOTE:  `kill' calls this function with forcecols == 0
- */
-int
-display_signal_list (list, forcecols)
-     WORD_LIST *list;
-     int forcecols;
-{
-  register int i, column;
-  char *name;
-  int result, signum, dflags;
-  intmax_t lsignum;
-
-  result = EXECUTION_SUCCESS;
-  if (!list)
-    {
-      for (i = 1, column = 0; i < NSIG; i++)
-       {
-         name = signal_name (i);
-         if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
-           continue;
-
-         if (posixly_correct && !forcecols)
-           {
-             /* This is for the kill builtin.  POSIX.2 says the signal names
-                are displayed without the `SIG' prefix. */
-             if (STREQN (name, "SIG", 3))
-               name += 3;
-             printf ("%s%s", name, (i == NSIG - 1) ? "" : " ");
-           }
-         else
-           {
-             printf ("%2d) %s", i, name);
-
-             if (++column < 5)
-               printf ("\t");
-             else
-               {
-                 printf ("\n");
-                 column = 0;
-               }
-           }
-       }
-
-      if ((posixly_correct && !forcecols) || column != 0)
-       printf ("\n");
-      return result;
-    }
-
-  /* List individual signal names or numbers. */
-  while (list)
-    {
-      if (legal_number (list->word->word, &lsignum))
-       {
-         /* This is specified by Posix.2 so that exit statuses can be
-            mapped into signal numbers. */
-         if (lsignum > 128)
-           lsignum -= 128;
-         if (lsignum < 0 || lsignum >= NSIG)
-           {
-             sh_invalidsig (list->word->word);
-             result = EXECUTION_FAILURE;
-             list = list->next;
-             continue;
-           }
-
-         signum = lsignum;
-         name = signal_name (signum);
-         if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
-           {
-             list = list->next;
-             continue;
-           }
-#if defined (JOB_CONTROL)
-         /* POSIX.2 says that `kill -l signum' prints the signal name without
-            the `SIG' prefix. */
-         printf ("%s\n", (this_shell_builtin == kill_builtin) ? name + 3 : name);
-#else
-         printf ("%s\n", name);
-#endif
-       }
-      else
-       {
-         dflags = DSIG_NOCASE;
-         if (posixly_correct == 0 || this_shell_builtin != kill_builtin)
-           dflags |= DSIG_SIGPREFIX;
-         signum = decode_signal (list->word->word, dflags);
-         if (signum == NO_SIG)
-           {
-             sh_invalidsig (list->word->word);
-             result = EXECUTION_FAILURE;
-             list = list->next;
-             continue;
-           }
-         printf ("%d\n", signum);
-       }
-      list = list->next;
-    }
-  return (result);
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*         Finding builtin commands and their functions            */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Perform a binary search and return the address of the builtin function
-   whose name is NAME.  If the function couldn't be found, or the builtin
-   is disabled or has no function associated with it, return NULL.
-   Return the address of the builtin.
-   DISABLED_OKAY means find it even if the builtin is disabled. */
-struct builtin *
-builtin_address_internal (name, disabled_okay)
-     char *name;
-     int disabled_okay;
-{
-  int hi, lo, mid, j;
-
-  hi = num_shell_builtins - 1;
-  lo = 0;
-
-  while (lo <= hi)
-    {
-      mid = (lo + hi) / 2;
-
-      j = shell_builtins[mid].name[0] - name[0];
-
-      if (j == 0)
-       j = strcmp (shell_builtins[mid].name, name);
-
-      if (j == 0)
-       {
-         /* It must have a function pointer.  It must be enabled, or we
-            must have explicitly allowed disabled functions to be found,
-            and it must not have been deleted. */
-         if (shell_builtins[mid].function &&
-             ((shell_builtins[mid].flags & BUILTIN_DELETED) == 0) &&
-             ((shell_builtins[mid].flags & BUILTIN_ENABLED) || disabled_okay))
-           return (&shell_builtins[mid]);
-         else
-           return ((struct builtin *)NULL);
-       }
-      if (j > 0)
-       hi = mid - 1;
-      else
-       lo = mid + 1;
-    }
-  return ((struct builtin *)NULL);
-}
-
-/* Return the pointer to the function implementing builtin command NAME. */
-sh_builtin_func_t *
-find_shell_builtin (name)
-     char *name;
-{
-  current_builtin = builtin_address_internal (name, 0);
-  return (current_builtin ? current_builtin->function : (sh_builtin_func_t *)NULL);
-}
-
-/* Return the address of builtin with NAME, whether it is enabled or not. */
-sh_builtin_func_t *
-builtin_address (name)
-     char *name;
-{
-  current_builtin = builtin_address_internal (name, 1);
-  return (current_builtin ? current_builtin->function : (sh_builtin_func_t *)NULL);
-}
-
-/* Return the function implementing the builtin NAME, but only if it is a
-   POSIX.2 special builtin. */
-sh_builtin_func_t *
-find_special_builtin (name)
-     char *name;
-{
-  current_builtin = builtin_address_internal (name, 0);
-  return ((current_builtin && (current_builtin->flags & SPECIAL_BUILTIN)) ?
-                       current_builtin->function :
-                       (sh_builtin_func_t *)NULL);
-}
-  
-static int
-shell_builtin_compare (sbp1, sbp2)
-     struct builtin *sbp1, *sbp2;
-{
-  int result;
-
-  if ((result = sbp1->name[0] - sbp2->name[0]) == 0)
-    result = strcmp (sbp1->name, sbp2->name);
-
-  return (result);
-}
-
-/* Sort the table of shell builtins so that the binary search will work
-   in find_shell_builtin. */
-void
-initialize_shell_builtins ()
-{
-  qsort (shell_builtins, num_shell_builtins, sizeof (struct builtin),
-    (QSFUNC *)shell_builtin_compare);
-}
diff --git a/builtins/common.h~ b/builtins/common.h~
deleted file mode 100644 (file)
index 182083a..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/* common.h -- extern declarations for functions defined in common.c. */
-
-/* Copyright (C) 1993-2004 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 (__COMMON_H)
-#  define __COMMON_H
-
-#include "stdc.h"
-
-#define ISOPTION(s, c) (s[0] == '-' && !s[2] && s[1] == c)
-
-/* Flag values for parse_and_execute () */
-#define SEVAL_NONINT   0x001
-#define SEVAL_INTERACT 0x002
-#define SEVAL_NOHIST   0x004
-#define SEVAL_NOFREE   0x008
-#define SEVAL_RESETLINE        0x010
-#define SEVAL_PARSEONLY        0x020
-#define SEVAL_NOLONGJMP 0x040
-
-/* Flags for describe_command, shared between type.def and command.def */
-#define CDESC_ALL              0x001   /* type -a */
-#define CDESC_SHORTDESC                0x002   /* command -V */
-#define CDESC_REUSABLE         0x004   /* command -v */
-#define CDESC_TYPE             0x008   /* type -t */
-#define CDESC_PATH_ONLY                0x010   /* type -p */
-#define CDESC_FORCE_PATH       0x020   /* type -ap or type -P */
-#define CDESC_NOFUNCS          0x040   /* type -f */
-#define CDESC_ABSPATH          0x080   /* convert to absolute path, no ./ */
-
-/* Flags for get_job_by_name */
-#define JM_PREFIX              0x01    /* prefix of job name */
-#define JM_SUBSTRING           0x02    /* substring of job name */
-#define JM_EXACT               0x04    /* match job name exactly */
-#define JM_STOPPED             0x08    /* match stopped jobs only */
-#define JM_FIRSTMATCH          0x10    /* return first matching job */
-
-/* Flags for remember_args and value of changed_dollar_vars */
-#define ARGS_NONE              0x0
-#define ARGS_INVOC             0x01
-#define ARGS_FUNC              0x02
-#define ARGS_SETBLTIN          0x04
-
-/* Functions from common.c */
-extern void builtin_error __P((const char *, ...))  __attribute__((__format__ (printf, 1, 2)));
-extern void builtin_warning __P((const char *, ...))  __attribute__((__format__ (printf, 1, 2)));
-extern void builtin_usage __P((void));
-extern void no_args __P((WORD_LIST *));
-extern int no_options __P((WORD_LIST *));
-
-/* common error message functions */
-extern void sh_needarg __P((char *));
-extern void sh_neednumarg __P((char *));
-extern void sh_notfound __P((char *));
-extern void sh_invalidopt __P((char *));
-extern void sh_invalidoptname __P((char *));
-extern void sh_invalidid __P((char *));
-extern void sh_invalidnum __P((char *));
-extern void sh_invalidsig __P((char *));
-extern void sh_erange __P((char *, char *));
-extern void sh_badpid __P((char *));
-extern void sh_badjob __P((char *));
-extern void sh_readonly __P((const char *));
-extern void sh_nojobs __P((char *));
-extern void sh_restricted __P((char *));
-extern void sh_notbuiltin __P((char *));
-extern void sh_wrerror __P((void));
-extern void sh_ttyerror __P((int));
-extern int sh_chkwrite __P((int));
-
-extern char **make_builtin_argv __P((WORD_LIST *, int *));
-extern void remember_args __P((WORD_LIST *, int));
-
-extern int dollar_vars_changed __P((void));
-extern void set_dollar_vars_unchanged __P((void));
-extern void set_dollar_vars_changed __P((void));
-
-extern int get_numeric_arg __P((WORD_LIST *, int, intmax_t *));
-extern int get_exitstat __P((WORD_LIST *));
-extern int read_octal __P((char *));
-
-/* Keeps track of the current working directory. */
-extern char *the_current_working_directory;
-extern char *get_working_directory __P((char *));
-extern void set_working_directory __P((char *));
-
-#if defined (JOB_CONTROL)
-extern int get_job_by_name __P((const char *, int));
-extern int get_job_spec __P((WORD_LIST *));
-#endif
-extern int display_signal_list __P((WORD_LIST *, int));
-
-/* It's OK to declare a function as returning a Function * without
-   providing a definition of what a `Function' is. */
-extern struct builtin *builtin_address_internal __P((char *, int));
-extern sh_builtin_func_t *find_shell_builtin __P((char *));
-extern sh_builtin_func_t *builtin_address __P((char *));
-extern sh_builtin_func_t *find_special_builtin __P((char *));
-extern void initialize_shell_builtins __P((void));
-
-/* Functions from exit.def */
-extern void bash_logout __P((void));
-
-/* Functions from getopts.def */
-extern void getopts_reset __P((int));
-
-/* Functions from set.def */
-extern int minus_o_option_value __P((char *));
-extern void list_minus_o_opts __P((int, int));
-extern char **get_minus_o_opts __P((void));
-extern int set_minus_o_option __P((int, char *));
-
-extern void set_shellopts __P((void));
-extern void parse_shellopts __P((char *));
-extern void initialize_shell_options __P((int));
-
-extern void reset_shell_options __P((void));
-
-/* Functions from shopt.def */
-extern void reset_shopt_options __P((void));
-extern char **get_shopt_options __P((void));
-
-extern int shopt_setopt __P((char *, int));
-extern int shopt_listopt __P((char *, int));
-
-extern int set_login_shell __P((int));
-
-extern void set_bashopts __P((void));
-extern void parse_bashopts __P((void));
-extern void intialize_bashopts __P((int));
-
-/* Functions from type.def */
-extern int describe_command __P((char *, int));
-
-/* Functions from setattr.def */
-extern int set_or_show_attributes __P((WORD_LIST *, int, int));
-extern int show_all_var_attributes __P((int, int));
-extern int show_var_attributes __P((SHELL_VAR *, int, int));
-extern int show_name_attributes __P((char *, int));
-extern void set_var_attribute __P((char *, int, int));
-
-/* Functions from pushd.def */
-extern char *get_dirstack_from_string __P((char *));
-extern char *get_dirstack_element __P((intmax_t, int));
-extern void set_dirstack_element __P((intmax_t, int, char *));
-extern WORD_LIST *get_directory_stack __P((int));
-
-/* Functions from evalstring.c */
-extern int parse_and_execute __P((char *, const char *, int));
-extern void parse_and_execute_cleanup __P((void));
-extern int parse_string __P((char *, const char *, int, char **));
-
-/* Functions from evalfile.c */
-extern int maybe_execute_file __P((const char *, int));
-extern int source_file __P((const char *, int));
-extern int fc_execute_file __P((const char *));
-
-#endif /* !__COMMON_H */
diff --git a/builtins/declare.def~ b/builtins/declare.def~
deleted file mode 100644 (file)
index bef8ec2..0000000
+++ /dev/null
@@ -1,557 +0,0 @@
-This file is declare.def, from which is created declare.c.
-It implements the builtins "declare" and "local" in Bash.
-
-Copyright (C) 1987-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/>.
-
-$PRODUCES declare.c
-
-$BUILTIN declare
-$FUNCTION declare_builtin
-$SHORT_DOC declare [-aAfFilrtux] [-p] [name[=value] ...]
-Set variable values and attributes.
-
-Declare variables and give them attributes.  If no NAMEs are given,
-display the attributes and values of all variables.
-
-Options:
-  -f   restrict action or display to function names and definitions
-  -F   restrict display to function names only (plus line number and
-       source file when debugging)
-  -p   display the attributes and value of each NAME
-
-Options which set attributes:
-  -a   to make NAMEs indexed arrays (if supported)
-  -A   to make NAMEs associative arrays (if supported)
-  -i   to make NAMEs have the `integer' attribute
-  -l   to convert NAMEs to lower case on assignment
-  -r   to make NAMEs readonly
-  -t   to make NAMEs have the `trace' attribute
-  -u   to convert NAMEs to upper case on assignment
-  -x   to make NAMEs export
-
-Using `+' instead of `-' turns off the given attribute.
-
-Variables with the integer attribute have arithmetic evaluation (see
-the `let' command) performed when the variable is assigned a value.
-
-When used in a function, `declare' makes NAMEs local, as with the `local'
-command.
-
-Exit Status:
-Returns success unless an invalid option is supplied or an error occurs.
-$END
-
-$BUILTIN typeset
-$FUNCTION declare_builtin
-$SHORT_DOC typeset [-aAfFilrtux] [-p] name[=value] ...
-Set variable values and attributes.
-
-Obsolete.  See `help declare'.
-$END
-
-#include <config.h>
-
-#if defined (HAVE_UNISTD_H)
-#  ifdef _MINIX
-#    include <sys/types.h>
-#  endif
-#  include <unistd.h>
-#endif
-
-#include <stdio.h>
-
-#include "../bashansi.h"
-#include "../bashintl.h"
-
-#include "../shell.h"
-#include "common.h"
-#include "builtext.h"
-#include "bashgetopt.h"
-
-extern int array_needs_making;
-extern int posixly_correct;
-
-static int declare_internal __P((register WORD_LIST *, int));
-
-/* Declare or change variable attributes. */
-int
-declare_builtin (list)
-     register WORD_LIST *list;
-{
-  return (declare_internal (list, 0));
-}
-
-$BUILTIN local
-$FUNCTION local_builtin
-$SHORT_DOC local [option] name[=value] ...
-Define local variables.
-
-Create a local variable called NAME, and give it VALUE.  OPTION can
-be any option accepted by `declare'.
-
-Local variables can only be used within a function; they are visible
-only to the function where they are defined and its children.
-
-Exit Status:
-Returns success unless an invalid option is supplied, an error occurs,
-or the shell is not executing a function.
-$END
-int
-local_builtin (list)
-     register WORD_LIST *list;
-{
-  if (variable_context)
-    return (declare_internal (list, 1));
-  else
-    {
-      builtin_error (_("can only be used in a function"));
-      return (EXECUTION_FAILURE);
-    }
-}
-
-#if defined (ARRAY_VARS)
-#  define DECLARE_OPTS "+acfilprtuxAF"
-#else
-#  define DECLARE_OPTS "+cfilprtuxF"
-#endif
-
-/* The workhorse function. */
-static int
-declare_internal (list, local_var)
-     register WORD_LIST *list;
-     int local_var;
-{
-  int flags_on, flags_off, *flags;
-  int any_failed, assign_error, pflag, nodefs, opt;
-  char *t, *subscript_start;
-  SHELL_VAR *var;
-  FUNCTION_DEF *shell_fn;
-
-  flags_on = flags_off = any_failed = assign_error = pflag = nodefs = 0;
-  reset_internal_getopt ();
-  while ((opt = internal_getopt (list, DECLARE_OPTS)) != EOF)
-    {
-      flags = list_opttype == '+' ? &flags_off : &flags_on;
-
-      switch (opt)
-       {
-       case 'a':
-#if defined (ARRAY_VARS)
-         *flags |= att_array;
-         break;
-#else
-         builtin_usage ();
-         return (EX_USAGE);
-#endif
-       case 'A':
-#if defined (ARRAY_VARS)
-         *flags |= att_assoc;
-         break;
-#else
-         builtin_usage ();
-         return (EX_USAGE);
-#endif
-       case 'p':
-         if (local_var == 0)
-           pflag++;
-         break;
-        case 'F':
-         nodefs++;
-         *flags |= att_function;
-         break;
-       case 'f':
-         *flags |= att_function;
-         break;
-       case 'i':
-         *flags |= att_integer;
-         break;
-       case 'r':
-         *flags |= att_readonly;
-         break;
-       case 't':
-         *flags |= att_trace;
-         break;
-       case 'x':
-         *flags |= att_exported;
-         array_needs_making = 1;
-         break;
-#if defined (CASEMOD_ATTRS)
-#  if defined (CASEMOD_CAPCASE)
-        case 'c':
-         *flags |= att_capcase;
-         if (flags == &flags_on)
-           flags_off |= att_uppercase|att_lowercase;
-         break;
-#  endif
-       case 'l':
-         *flags |= att_lowercase;
-         if (flags == &flags_on)
-           flags_off |= att_capcase|att_uppercase;
-         break;
-       case 'u':
-         *flags |= att_uppercase;
-         if (flags == &flags_on)
-           flags_off |= att_capcase|att_lowercase;
-         break;
-#endif /* CASEMOD_ATTRS */
-       default:
-         builtin_usage ();
-         return (EX_USAGE);
-       }
-    }
-
-  list = loptend;
-
-  /* If there are no more arguments left, then we just want to show
-     some variables. */
-  if (list == 0)       /* declare -[aAfFirtx] */
-    {
-      /* Show local variables defined at this context level if this is
-        the `local' builtin. */
-      if (local_var)
-       {
-         register SHELL_VAR **vlist;
-         register int i;
-
-         vlist = all_local_variables ();
-
-         if (vlist)
-           {
-             for (i = 0; vlist[i]; i++)
-               print_assignment (vlist[i]);
-
-             free (vlist);
-           }
-       }
-      else if (pflag && (flags_on == 0 || flags_on == att_function))
-       show_all_var_attributes (flags_on == 0, nodefs);
-      else if (flags_on == 0)
-       return (set_builtin ((WORD_LIST *)NULL));
-      else
-       set_or_show_attributes ((WORD_LIST *)NULL, flags_on, nodefs);
-
-      return (sh_chkwrite (EXECUTION_SUCCESS));
-    }
-
-  if (pflag)   /* declare -p [-aAfFirtx] name [name...] */
-    {
-      for (any_failed = 0; list; list = list->next)
-       {
-         pflag = show_name_attributes (list->word->word, nodefs);
-         if (pflag)
-           {
-             sh_notfound (list->word->word);
-             any_failed++;
-           }
-       }
-      return (sh_chkwrite (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS));
-    }
-
-#define NEXT_VARIABLE() free (name); list = list->next; continue
-
-  /* There are arguments left, so we are making variables. */
-  while (list)         /* declare [-aAfFirx] name [name ...] */
-    {
-      char *value, *name;
-      int offset, aflags;
-#if defined (ARRAY_VARS)
-      int making_array_special, compound_array_assign, simple_array_assign;
-#endif
-
-      name = savestring (list->word->word);
-      offset = assignment (name, 0);
-      aflags = 0;
-
-      if (offset)      /* declare [-aAfFirx] name=value */
-       {
-         name[offset] = '\0';
-         value = name + offset + 1;
-         if (name[offset - 1] == '+')
-           {
-             aflags |= ASS_APPEND;
-             name[offset - 1] = '\0';
-           }
-       }
-      else
-       value = "";
-
-#if defined (ARRAY_VARS)
-      compound_array_assign = simple_array_assign = 0;
-      subscript_start = (char *)NULL;
-      if (t = strchr (name, '['))      /* ] */
-       {
-         /* If offset != 0 we have already validated any array reference */
-         if (offset == 0 && valid_array_reference (name) == 0)
-           {
-             sh_invalidid (name);
-             assign_error++;
-             NEXT_VARIABLE ();
-           }
-         subscript_start = t;
-         *t = '\0';
-         making_array_special = 1;
-       }
-      else
-       making_array_special = 0;
-#endif
-
-      /* If we're in posix mode or not looking for a shell function (since
-        shell function names don't have to be valid identifiers when the
-        shell's not in posix mode), check whether or not the argument is a
-        valid, well-formed shell identifier. */
-      if ((posixly_correct || (flags_on & att_function) == 0) && legal_identifier (name) == 0)
-       {
-         sh_invalidid (name);
-         assign_error++;
-         NEXT_VARIABLE ();
-       }
-
-      /* If VARIABLE_CONTEXT has a non-zero value, then we are executing
-        inside of a function.  This means we should make local variables,
-        not global ones. */
-
-      /* XXX - this has consequences when we're making a local copy of a
-              variable that was in the temporary environment.  Watch out
-              for this. */
-      if (variable_context && ((flags_on & att_function) == 0))
-       {
-#if defined (ARRAY_VARS)
-         if (flags_on & att_assoc)
-           var = make_local_assoc_variable (name);
-         else if ((flags_on & att_array) || making_array_special)
-           var = make_local_array_variable (name);
-         else
-#endif
-         var = make_local_variable (name);
-         if (var == 0)
-           {
-             any_failed++;
-             NEXT_VARIABLE ();
-           }
-       }
-      else
-       var = (SHELL_VAR *)NULL;
-
-      /* If we are declaring a function, then complain about it in some way.
-        We don't let people make functions by saying `typeset -f foo=bar'. */
-
-      /* There should be a way, however, to let people look at a particular
-        function definition by saying `typeset -f foo'. */
-
-      if (flags_on & att_function)
-       {
-         if (offset)   /* declare -f [-rix] foo=bar */
-           {
-             builtin_error (_("cannot use `-f' to make functions"));
-             free (name);
-             return (EXECUTION_FAILURE);
-           }
-         else          /* declare -f [-rx] name [name...] */
-           {
-             var = find_function (name);
-
-             if (var)
-               {
-                 if (readonly_p (var) && (flags_off & att_readonly))
-                   {
-                     builtin_error (_("%s: readonly function"), name);
-                     any_failed++;
-                     NEXT_VARIABLE ();
-                   }
-
-                 /* declare -[Ff] name [name...] */
-                 if (flags_on == att_function && flags_off == 0)
-                   {
-#if defined (DEBUGGER)
-                     if (nodefs && debugging_mode)
-                       {
-                         shell_fn = find_function_def (var->name);
-                         if (shell_fn)
-                           printf ("%s %d %s\n", var->name, shell_fn->line, shell_fn->source_file);
-                         else
-                           printf ("%s\n", var->name);
-                       }
-                     else
-#endif /* DEBUGGER */
-                       {       
-                         t = nodefs ? var->name
-                                    : named_function_string (name, function_cell (var), FUNC_MULTILINE|FUNC_EXTERNAL);
-                         printf ("%s\n", t);
-                         any_failed = sh_chkwrite (any_failed);
-                       }
-                   }
-                 else          /* declare -[fF] -[rx] name [name...] */
-                   {
-                     VSETATTR (var, flags_on);
-                     VUNSETATTR (var, flags_off);
-                   }
-               }
-             else
-               any_failed++;
-             NEXT_VARIABLE ();
-           }
-       }
-      else             /* declare -[aAirx] name [name...] */
-       {
-         /* Non-null if we just created or fetched a local variable. */
-         if (var == 0)
-           var = find_variable (name);
-
-         if (var == 0)
-           {
-#if defined (ARRAY_VARS)
-             if (flags_on & att_assoc)
-               var = make_new_assoc_variable (name);
-             else if ((flags_on & att_array) || making_array_special)
-               var = make_new_array_variable (name);
-             else
-#endif
-
-             if (offset)
-               var = bind_variable (name, "", 0);
-             else
-               {
-                 var = bind_variable (name, (char *)NULL, 0);
-                 VSETATTR (var, att_invisible);
-               }
-           }
-
-         /* Cannot use declare +r to turn off readonly attribute. */ 
-         if (readonly_p (var) && (flags_off & att_readonly))
-           {
-             sh_readonly (name);
-             any_failed++;
-             NEXT_VARIABLE ();
-           }
-
-         /* Cannot use declare to assign value to readonly or noassign
-            variable. */
-         if ((readonly_p (var) || noassign_p (var)) && offset)
-           {
-             if (readonly_p (var))
-               sh_readonly (name);
-             assign_error++;
-             NEXT_VARIABLE ();
-           }
-
-#if defined (ARRAY_VARS)
-         if ((making_array_special || (flags_on & (att_array|att_assoc)) || array_p (var) || assoc_p (var)) && offset)
-           {
-             int vlen;
-             vlen = STRLEN (value);
-
-             if (value[0] == '(' && value[vlen-1] == ')')
-               compound_array_assign = 1;
-             else
-               simple_array_assign = 1;
-           }
-
-         /* Cannot use declare +a name or declare +A name to remove an
-            array variable. */
-         if (((flags_off & att_array) && array_p (var)) || ((flags_off & att_assoc) && assoc_p (var)))
-           {
-             builtin_error (_("%s: cannot destroy array variables in this way"), name);
-             any_failed++;
-             NEXT_VARIABLE ();
-           }
-
-         if ((flags_on & att_array) && assoc_p (var))
-           {
-             builtin_error (_("%s: cannot convert associative to indexed array"), name);
-             any_failed++;
-             NEXT_VARIABLE ();
-           }
-         if ((flags_on & att_assoc) && array_p (var))
-           {
-             builtin_error (_("%s: cannot convert indexed to associative array"), name);
-             any_failed++;
-             NEXT_VARIABLE ();
-           }
-
-         /* declare -A name[[n]] makes name an associative array variable. */
-         if (flags_on & att_assoc)
-           {
-             if (assoc_p (var) == 0)
-               var = convert_var_to_assoc (var);
-           }
-         /* declare -a name[[n]] or declare name[n] makes name an indexed
-            array variable. */
-         else if ((making_array_special || (flags_on & att_array)) && array_p (var) == 0 && assoc_p (var) == 0)
-           var = convert_var_to_array (var);
-#endif /* ARRAY_VARS */
-
-         VSETATTR (var, flags_on);
-         VUNSETATTR (var, flags_off);
-
-#if defined (ARRAY_VARS)
-         if (offset && compound_array_assign)
-           assign_array_var_from_string (var, value, aflags);
-         else if (simple_array_assign && subscript_start)
-           {
-             /* declare [-aA] name[N]=value */
-             *subscript_start = '[';   /* ] */
-             var = assign_array_element (name, value, 0);      /* XXX - not aflags */
-             *subscript_start = '\0';
-           }
-         else if (simple_array_assign)
-           /* let bind_array_variable take care of this. */
-           bind_array_variable (name, 0, value, aflags);
-         else
-#endif
-         /* bind_variable_value duplicates the essential internals of
-            bind_variable() */
-         if (offset)
-           bind_variable_value (var, value, aflags);
-
-         /* If we found this variable in the temporary environment, as with
-            `var=value declare -x var', make sure it is treated identically
-            to `var=value export var'.  Do the same for `declare -r' and
-            `readonly'.  Preserve the attributes, except for att_tempvar. */
-         /* XXX -- should this create a variable in the global scope, or
-            modify the local variable flags?  ksh93 has it modify the
-            global scope.
-            Need to handle case like in set_var_attribute where a temporary
-            variable is in the same table as the function local vars. */
-         if ((flags_on & (att_exported|att_readonly)) && tempvar_p (var))
-           {
-             SHELL_VAR *tv;
-             char *tvalue;
-
-             tv = find_tempenv_variable (var->name);
-             if (tv)
-               {
-                 tvalue = var_isset (var) ? savestring (value_cell (var)) : savestring ("");
-                 tv = bind_variable (var->name, tvalue, 0);
-                 tv->attributes |= var->attributes & ~att_tempvar;
-                 if (tv->context > 0)
-                   VSETATTR (tv, att_propagate);
-                 free (tvalue);
-               }
-             VSETATTR (var, att_propagate);
-           }
-       }
-
-      stupidly_hack_special_variables (name);
-
-      NEXT_VARIABLE ();
-    }
-
-  return (assign_error ? EX_BADASSIGN
-                      : ((any_failed == 0) ? EXECUTION_SUCCESS
-                                           : EXECUTION_FAILURE));
-}
diff --git a/builtins/evalfile.c~ b/builtins/evalfile.c~
deleted file mode 100644 (file)
index ee480b9..0000000
+++ /dev/null
@@ -1,343 +0,0 @@
-/* evalfile.c - read and evaluate commands from a file or file descriptor */
-
-/* Copyright (C) 1996-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/>.
-*/
-
-#include <config.h>
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include "../bashtypes.h"
-#include "posixstat.h"
-#include "filecntl.h"
-
-#include <stdio.h>
-#include <signal.h>
-#include <errno.h>
-
-#include "../bashansi.h"
-#include "../bashintl.h"
-
-#include "../shell.h"
-#include "../jobs.h"
-#include "../builtins.h"
-#include "../flags.h"
-#include "../input.h"
-#include "../execute_cmd.h"
-#include "../trap.h"
-
-#if defined (HISTORY)
-#  include "../bashhist.h"
-#endif
-
-#include <typemax.h>
-
-#include "common.h"
-
-#if !defined (errno)
-extern int errno;
-#endif
-
-/* Flags for _evalfile() */
-#define FEVAL_ENOENTOK         0x001
-#define FEVAL_BUILTIN          0x002
-#define FEVAL_UNWINDPROT       0x004
-#define FEVAL_NONINT           0x008
-#define FEVAL_LONGJMP          0x010
-#define FEVAL_HISTORY          0x020
-#define FEVAL_CHECKBINARY      0x040
-#define FEVAL_REGFILE          0x080
-#define FEVAL_NOPUSHARGS       0x100
-
-extern int posixly_correct;
-extern int indirection_level, subshell_environment;
-extern int return_catch_flag, return_catch_value;
-extern int last_command_exit_value;
-
-/* How many `levels' of sourced files we have. */
-int sourcelevel = 0;
-
-static int
-_evalfile (filename, flags)
-     const char *filename;
-     int flags;
-{
-  volatile int old_interactive;
-  procenv_t old_return_catch;
-  int return_val, fd, result, pflags, i;
-  ssize_t nr;                  /* return value from read(2) */
-  char *string;
-  struct stat finfo;
-  size_t file_size;
-  sh_vmsg_func_t *errfunc;
-#if defined (ARRAY_VARS)
-  SHELL_VAR *funcname_v, *nfv, *bash_source_v, *bash_lineno_v;
-  ARRAY *funcname_a, *bash_source_a, *bash_lineno_a;
-#  if defined (DEBUGGER)
-  SHELL_VAR *bash_argv_v, *bash_argc_v;
-  ARRAY *bash_argv_a, *bash_argc_a;
-#  endif
-  char *t, tt[2];
-#endif
-
-  USE_VAR(pflags);
-
-#if defined (ARRAY_VARS)
-  GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a);
-  GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
-  GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a);
-#  if defined (DEBUGGER)
-  GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
-  GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
-#  endif
-#endif
-  
-  fd = open (filename, O_RDONLY);
-
-  if (fd < 0 || (fstat (fd, &finfo) == -1))
-    {
-file_error_and_exit:
-      if (((flags & FEVAL_ENOENTOK) == 0) || errno != ENOENT)
-       file_error (filename);
-
-      if (flags & FEVAL_LONGJMP)
-       {
-         last_command_exit_value = 1;
-         jump_to_top_level (EXITPROG);
-       }
-
-      return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE
-                                     : ((errno == ENOENT) ? 0 : -1));
-    }
-
-  errfunc = ((flags & FEVAL_BUILTIN) ? builtin_error : internal_error);
-
-  if (S_ISDIR (finfo.st_mode))
-    {
-      (*errfunc) (_("%s: is a directory"), filename);
-      return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
-    }
-  else if ((flags & FEVAL_REGFILE) && S_ISREG (finfo.st_mode) == 0)
-    {
-      (*errfunc) (_("%s: not a regular file"), filename);
-      return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
-    }
-
-  file_size = (size_t)finfo.st_size;
-  /* Check for overflow with large files. */
-  if (file_size != finfo.st_size || file_size + 1 < file_size)
-    {
-      (*errfunc) (_("%s: file is too large"), filename);
-      return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
-    }      
-
-#if defined (__CYGWIN__) && defined (O_TEXT)
-  setmode (fd, O_TEXT);
-#endif
-
-  if (S_ISREG (finfo.st_mode) && file_size <= SSIZE_MAX)
-    {
-      string = (char *)xmalloc (1 + file_size);
-      nr = read (fd, string, file_size);
-      if (nr >= 0)
-       string[nr] = '\0';
-    }
-  else
-    nr = zmapfd (fd, &string, 0);
-
-  return_val = errno;
-  close (fd);
-  errno = return_val;
-
-  if (nr < 0)          /* XXX was != file_size, not < 0 */
-    {
-      free (string);
-      goto file_error_and_exit;
-    }
-
-  if (nr == 0)
-    {
-      free (string);
-      return ((flags & FEVAL_BUILTIN) ? EXECUTION_SUCCESS : 1);
-    }
-      
-  if ((flags & FEVAL_CHECKBINARY) && 
-      check_binary_file (string, (nr > 80) ? 80 : nr))
-    {
-      free (string);
-      (*errfunc) (_("%s: cannot execute binary file"), filename);
-      return ((flags & FEVAL_BUILTIN) ? EX_BINARY_FILE : -1);
-    }
-
-  i = strlen (string);
-itrace("_evalfile: nr = %d strlen(string) = %d", nr, i);
-  if (i < nr)
-    {
-      for (i = 0; i < nr; i++)
-       if (string[i] == '\0')
-          {
-           memmove (string+i, string+i+1, nr - i);
-           nr--;
-          }
-    }
-
-  if (flags & FEVAL_UNWINDPROT)
-    {
-      begin_unwind_frame ("_evalfile");
-
-      unwind_protect_int (return_catch_flag);
-      unwind_protect_jmp_buf (return_catch);
-      if (flags & FEVAL_NONINT)
-       unwind_protect_int (interactive);
-      unwind_protect_int (sourcelevel);
-    }
-  else
-    {
-      COPY_PROCENV (return_catch, old_return_catch);
-      if (flags & FEVAL_NONINT)
-       old_interactive = interactive;
-    }
-
-  if (flags & FEVAL_NONINT)
-    interactive = 0;
-
-  return_catch_flag++;
-  sourcelevel++;
-
-#if defined (ARRAY_VARS)
-  array_push (bash_source_a, (char *)filename);
-  t = itos (executing_line_number ());
-  array_push (bash_lineno_a, t);
-  free (t);
-  array_push (funcname_a, "source");   /* not exactly right */
-#  if defined (DEBUGGER)
-  /* Have to figure out a better way to do this when `source' is supplied
-     arguments */
-  if ((flags & FEVAL_NOPUSHARGS) == 0)
-    {
-      array_push (bash_argv_a, (char *)filename);
-      tt[0] = '1'; tt[1] = '\0';
-      array_push (bash_argc_a, tt);
-    }
-#  endif
-#endif
-
-  /* set the flags to be passed to parse_and_execute */
-  pflags = SEVAL_RESETLINE;
-  pflags |= (flags & FEVAL_HISTORY) ? 0 : SEVAL_NOHIST;
-
-  if (flags & FEVAL_BUILTIN)
-    result = EXECUTION_SUCCESS;
-
-  return_val = setjmp (return_catch);
-
-  /* If `return' was seen outside of a function, but in the script, then
-     force parse_and_execute () to clean up. */
-  if (return_val)
-    {
-      parse_and_execute_cleanup ();
-      result = return_catch_value;
-    }
-  else
-    result = parse_and_execute (string, filename, pflags);
-
-  if (flags & FEVAL_UNWINDPROT)
-    run_unwind_frame ("_evalfile");
-  else
-    {
-      if (flags & FEVAL_NONINT)
-       interactive = old_interactive;
-      return_catch_flag--;
-      sourcelevel--;
-      COPY_PROCENV (old_return_catch, return_catch);
-    }
-
-#if defined (ARRAY_VARS)
-  /* These two variables cannot be unset, and cannot be affected by the
-     sourced file. */
-  array_pop (bash_source_a);
-  array_pop (bash_lineno_a);
-
-  /* FUNCNAME can be unset, and so can potentially be changed by the
-     sourced file. */
-  GET_ARRAY_FROM_VAR ("FUNCNAME", nfv, funcname_a);
-  if (nfv == funcname_v)
-    array_pop (funcname_a);
-#  if defined (DEBUGGER)
-  if ((flags & FEVAL_NOPUSHARGS) == 0)
-    {
-      array_pop (bash_argc_a);
-      array_pop (bash_argv_a);
-    }
-#  endif
-#endif
-
-  return ((flags & FEVAL_BUILTIN) ? result : 1);
-}
-
-int
-maybe_execute_file (fname, force_noninteractive)
-     const char *fname;
-     int force_noninteractive;
-{
-  char *filename;
-  int result, flags;
-
-  filename = bash_tilde_expand (fname, 0);
-  flags = FEVAL_ENOENTOK;
-  if (force_noninteractive)
-    flags |= FEVAL_NONINT;
-  result = _evalfile (filename, flags);
-  free (filename);
-  return result;
-}
-
-#if defined (HISTORY)
-int
-fc_execute_file (filename)
-     const char *filename;
-{
-  int flags;
-
-  /* We want these commands to show up in the history list if
-     remember_on_history is set. */
-  flags = FEVAL_ENOENTOK|FEVAL_HISTORY|FEVAL_REGFILE;
-  return (_evalfile (filename, flags));
-}
-#endif /* HISTORY */
-
-int
-source_file (filename, sflags)
-     const char *filename;
-     int sflags;
-{
-  int flags, rval;
-
-  flags = FEVAL_BUILTIN|FEVAL_UNWINDPROT|FEVAL_NONINT;
-  if (sflags)
-    flags |= FEVAL_NOPUSHARGS;
-  /* POSIX shells exit if non-interactive and file error. */
-  if (posixly_correct && !interactive_shell)
-    flags |= FEVAL_LONGJMP;
-  rval = _evalfile (filename, flags);
-
-  run_return_trap ();
-  return rval;
-}
diff --git a/builtins/evalstring.c~ b/builtins/evalstring.c~
deleted file mode 100644 (file)
index c705ecc..0000000
+++ /dev/null
@@ -1,512 +0,0 @@
-/* evalstring.c - evaluate a string as one or more shell commands. 
-
-/* Copyright (C) 1996-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/>.
-*/
-
-#include <config.h>
-
-#if defined (HAVE_UNISTD_H)
-#  ifdef _MINIX
-#    include <sys/types.h>
-#  endif
-#  include <unistd.h>
-#endif
-
-#include <stdio.h>
-#include <signal.h>
-
-#include <errno.h>
-
-#include "filecntl.h"
-#include "../bashansi.h"
-
-#include "../shell.h"
-#include "../jobs.h"
-#include "../builtins.h"
-#include "../flags.h"
-#include "../input.h"
-#include "../execute_cmd.h"
-#include "../redir.h"
-#include "../trap.h"
-#include "../bashintl.h"
-
-#include <y.tab.h>
-
-#if defined (HISTORY)
-#  include "../bashhist.h"
-#endif
-
-#include "common.h"
-#include "builtext.h"
-
-#if !defined (errno)
-extern int errno;
-#endif
-
-#define IS_BUILTIN(s)  (builtin_address_internal(s, 0) != (struct builtin *)NULL)
-
-extern int indirection_level, subshell_environment;
-extern int line_number;
-extern int current_token, shell_eof_token;
-extern int last_command_exit_value;
-extern int running_trap;
-extern int loop_level;
-extern int executing_list;
-extern int comsub_ignore_return;
-extern int posixly_correct;
-extern sh_builtin_func_t *this_shell_builtin;
-
-int parse_and_execute_level = 0;
-
-static int cat_file __P((REDIRECT *));
-
-#define PE_TAG "parse_and_execute top"
-#define PS_TAG "parse_string top"
-
-#if defined (HISTORY)
-static void
-set_history_remembering ()
-{
-  remember_on_history = enable_history_list;
-}
-#endif
-
-/* How to force parse_and_execute () to clean up after itself. */
-void
-parse_and_execute_cleanup ()
-{
-  if (running_trap)
-    {
-      run_trap_cleanup (running_trap - 1);
-      unfreeze_jobs_list ();
-    }
-
-  if (have_unwind_protects ())
-     run_unwind_frame (PE_TAG);
-  else
-    parse_and_execute_level = 0;                       /* XXX */
-}
-
-static void
-parse_prologue (string, flags, tag)
-     char *string;
-     int flags;
-     char *tag;
-{
-  char *orig_string;
-  int x;
-
-  orig_string = string;
-  /* Unwind protect this invocation of parse_and_execute (). */
-  begin_unwind_frame (tag);
-  unwind_protect_int (parse_and_execute_level);
-  unwind_protect_jmp_buf (top_level);
-  unwind_protect_int (indirection_level);
-  unwind_protect_int (line_number);
-  unwind_protect_int (loop_level);
-  unwind_protect_int (executing_list);
-  unwind_protect_int (comsub_ignore_return);
-  if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
-    unwind_protect_int (interactive);
-
-#if defined (HISTORY)
-  if (parse_and_execute_level == 0)
-    add_unwind_protect (set_history_remembering, (char *)NULL);
-  else
-    unwind_protect_int (remember_on_history);  /* can be used in scripts */
-#  if defined (BANG_HISTORY)
-  if (interactive_shell)
-    unwind_protect_int (history_expansion_inhibited);
-#  endif /* BANG_HISTORY */
-#endif /* HISTORY */
-
-  if (interactive_shell)
-    {
-      x = get_current_prompt_level ();
-      add_unwind_protect (set_current_prompt_level, x);
-    }
-  
-  add_unwind_protect (pop_stream, (char *)NULL);
-  if (orig_string && ((flags & SEVAL_NOFREE) == 0))
-    add_unwind_protect (xfree, orig_string);
-  end_unwind_frame ();
-
-  if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
-    interactive = (flags & SEVAL_NONINT) ? 0 : 1;
-
-#if defined (HISTORY)
-  if (flags & SEVAL_NOHIST)
-    bash_history_disable ();
-#endif /* HISTORY */
-}
-
-/* Parse and execute the commands in STRING.  Returns whatever
-   execute_command () returns.  This frees STRING.  FLAGS is a
-   flags word; look in common.h for the possible values.  Actions
-   are:
-       (flags & SEVAL_NONINT) -> interactive = 0;
-       (flags & SEVAL_INTERACT) -> interactive = 1;
-       (flags & SEVAL_NOHIST) -> call bash_history_disable ()
-       (flags & SEVAL_NOFREE) -> don't free STRING when finished
-       (flags & SEVAL_RESETLINE) -> reset line_number to 1
-*/
-
-int
-parse_and_execute (string, from_file, flags)
-     char *string;
-     const char *from_file;
-     int flags;
-{
-  int code, lreset;
-  volatile int should_jump_to_top_level, last_result;
-  COMMAND *volatile command;
-
-  parse_prologue (string, flags, PE_TAG);
-
-  parse_and_execute_level++;
-
-  lreset = flags & SEVAL_RESETLINE;
-itrace("parse_and_execute: lreset = %d", lreset);
-  /* Reset the line number if the caller wants us to.  If we don't reset the
-     line number, we have to subtract one, because we will add one just
-     before executing the next command (resetting the line number sets it to
-     0; the first line number is 1). */
-  push_stream (lreset);
-  if (lreset == 0)
-    line_number--;
-    
-  indirection_level++;
-
-  code = should_jump_to_top_level = 0;
-  last_result = EXECUTION_SUCCESS;
-
-  with_input_from_string (string, from_file);
-  while (*(bash_input.location.string))
-    {
-      command = (COMMAND *)NULL;
-
-      if (interrupt_state)
-       {
-         last_result = EXECUTION_FAILURE;
-         break;
-       }
-
-      /* Provide a location for functions which `longjmp (top_level)' to
-        jump to.  This prevents errors in substitution from restarting
-        the reader loop directly, for example. */
-      code = setjmp (top_level);
-
-      if (code)
-       {
-         should_jump_to_top_level = 0;
-         switch (code)
-           {
-           case FORCE_EOF:
-           case ERREXIT:
-           case EXITPROG:
-             if (command)
-               run_unwind_frame ("pe_dispose");
-             /* Remember to call longjmp (top_level) after the old
-                value for it is restored. */
-             should_jump_to_top_level = 1;
-             goto out;
-
-           case DISCARD:
-             if (command)
-               run_unwind_frame ("pe_dispose");
-             last_result = last_command_exit_value = EXECUTION_FAILURE; /* XXX */
-             if (subshell_environment)
-               {
-                 should_jump_to_top_level = 1;
-                 goto out;
-               }
-             else
-               {
-#if 0
-                 dispose_command (command);    /* pe_dispose does this */
-#endif
-                 continue;
-               }
-
-           default:
-             command_error ("parse_and_execute", CMDERR_BADJUMP, code, 0);
-             break;
-           }
-       }
-         
-      if (parse_command () == 0)
-       {
-         if ((flags & SEVAL_PARSEONLY) || (interactive_shell == 0 && read_but_dont_execute))
-           {
-             last_result = EXECUTION_SUCCESS;
-             dispose_command (global_command);
-             global_command = (COMMAND *)NULL;
-           }
-         else if (command = global_command)
-           {
-             struct fd_bitmap *bitmap;
-
-             bitmap = new_fd_bitmap (FD_BITMAP_SIZE);
-             begin_unwind_frame ("pe_dispose");
-             add_unwind_protect (dispose_fd_bitmap, bitmap);
-             add_unwind_protect (dispose_command, command);    /* XXX */
-
-             global_command = (COMMAND *)NULL;
-
-             if ((subshell_environment & SUBSHELL_COMSUB) && comsub_ignore_return)
-               command->flags |= CMD_IGNORE_RETURN;
-
-#if defined (ONESHOT)
-             /*
-              * IF
-              *   we were invoked as `bash -c' (startup_state == 2) AND
-              *   parse_and_execute has not been called recursively AND
-              *   we're not running a trap AND
-              *   we have parsed the full command (string == '\0') AND
-              *   we're not going to run the exit trap AND
-              *   we have a simple command without redirections AND
-              *   the command is not being timed AND
-              *   the command's return status is not being inverted
-              * THEN
-              *   tell the execution code that we don't need to fork
-              */
-             if (startup_state == 2 && parse_and_execute_level == 1 &&
-                 running_trap == 0 &&
-                 *bash_input.location.string == '\0' &&
-                 command->type == cm_simple &&
-                 signal_is_trapped (EXIT_TRAP) == 0 &&
-                 command->redirects == 0 && command->value.Simple->redirects == 0 &&
-                 ((command->flags & CMD_TIME_PIPELINE) == 0) &&
-                 ((command->flags & CMD_INVERT_RETURN) == 0))
-               {
-                 command->flags |= CMD_NO_FORK;
-                 command->value.Simple->flags |= CMD_NO_FORK;
-               }
-#endif /* ONESHOT */
-
-             /* See if this is a candidate for $( <file ). */
-             if (startup_state == 2 &&
-                 (subshell_environment & SUBSHELL_COMSUB) &&
-                 *bash_input.location.string == '\0' &&
-                 command->type == cm_simple && !command->redirects &&
-                 (command->flags & CMD_TIME_PIPELINE) == 0 &&
-                 command->value.Simple->words == 0 &&
-                 command->value.Simple->redirects &&
-                 command->value.Simple->redirects->next == 0 &&
-                 command->value.Simple->redirects->instruction == r_input_direction)
-               {
-                 int r;
-                 r = cat_file (command->value.Simple->redirects);
-                 last_result = (r < 0) ? EXECUTION_FAILURE : EXECUTION_SUCCESS;
-               }
-             else
-               last_result = execute_command_internal
-                               (command, 0, NO_PIPE, NO_PIPE, bitmap);
-
-             dispose_command (command);
-             dispose_fd_bitmap (bitmap);
-             discard_unwind_frame ("pe_dispose");
-           }
-       }
-      else
-       {
-         last_result = EXECUTION_FAILURE;
-
-         if (interactive_shell == 0 && this_shell_builtin &&
-             (this_shell_builtin == source_builtin || this_shell_builtin == eval_builtin) &&
-             last_command_exit_value == EX_BADSYNTAX && posixly_correct)
-           {
-#if 0  /* XXX - for bash-4.2 */
-             should_jump_to_top_level = 1;
-             code = ERREXIT;
-             last_command_exit_value = EX_BADUSAGE;
-#else
-             internal_warning (_("syntax errors in . or eval will cause future versions of the shell to abort as Posix requires"));
-#endif
-           }
-
-         /* Since we are shell compatible, syntax errors in a script
-            abort the execution of the script.  Right? */
-         break;
-       }
-    }
-
- out:
-
-  run_unwind_frame (PE_TAG);
-
-  if (interrupt_state && parse_and_execute_level == 0)
-    {
-      /* An interrupt during non-interactive execution in an
-        interactive shell (e.g. via $PROMPT_COMMAND) should
-        not cause the shell to exit. */
-      interactive = interactive_shell;
-      throw_to_top_level ();
-    }
-
-  if (should_jump_to_top_level)
-    jump_to_top_level (code);
-
-  return (last_result);
-}
-
-/* Parse a command contained in STRING according to FLAGS and return the
-   number of characters consumed from the string.  If non-NULL, set *ENDP
-   to the position in the string where the parse ended.  Used to validate
-   command substitutions during parsing to obey Posix rules about finding
-   the end of the command and balancing parens. */
-int
-parse_string (string, from_file, flags, endp)
-     char *string;
-     const char *from_file;
-     int flags;
-     char **endp;
-{
-  int code, nc;
-  volatile int should_jump_to_top_level;
-  COMMAND *volatile command, *oglobal;
-  char *ostring;
-
-  parse_prologue (string, flags, PS_TAG);
-
-  /* Reset the line number if the caller wants us to.  If we don't reset the
-     line number, we have to subtract one, because we will add one just
-     before executing the next command (resetting the line number sets it to
-     0; the first line number is 1). */
-  push_stream (0);
-    
-  code = should_jump_to_top_level = 0;
-  oglobal = global_command;
-  ostring = string;
-
-  with_input_from_string (string, from_file);
-  while (*(bash_input.location.string))
-    {
-      command = (COMMAND *)NULL;
-
-#if 0
-      if (interrupt_state)
-       break;
-#endif
-
-      /* Provide a location for functions which `longjmp (top_level)' to
-        jump to. */
-      code = setjmp (top_level);
-
-      if (code)
-       {
-#if defined (DEBUG)
-itrace("parse_string: longjmp executed: code = %d", code);
-#endif
-         should_jump_to_top_level = 0;
-         switch (code)
-           {
-           case FORCE_EOF:
-           case ERREXIT:
-           case EXITPROG:
-           case DISCARD:               /* XXX */
-             if (command)
-               dispose_command (command);
-             /* Remember to call longjmp (top_level) after the old
-                value for it is restored. */
-             should_jump_to_top_level = 1;
-             goto out;
-
-           default:
-             command_error ("parse_string", CMDERR_BADJUMP, code, 0);
-             break;
-           }
-       }
-         
-      if (parse_command () == 0)
-       {
-         dispose_command (global_command);
-         global_command = (COMMAND *)NULL;
-       }
-      else
-       {
-         if ((flags & SEVAL_NOLONGJMP) == 0)
-           {
-             should_jump_to_top_level = 1;
-             code = DISCARD;
-           }
-         else
-           reset_parser ();    /* XXX - sets token_to_read */
-         break;
-       }
-
-      if (current_token == yacc_EOF || current_token == shell_eof_token)
-         break;
-    }
-
- out:
-
-  global_command = oglobal;
-  nc = bash_input.location.string - ostring;
-  if (endp)
-    *endp = bash_input.location.string;
-
-  run_unwind_frame (PS_TAG);
-
-  if (should_jump_to_top_level)
-    jump_to_top_level (code);
-
-  return (nc);
-}
-
-/* Handle a $( < file ) command substitution.  This expands the filename,
-   returning errors as appropriate, then just cats the file to the standard
-   output. */
-static int
-cat_file (r)
-     REDIRECT *r;
-{
-  char *fn;
-  int fd, rval;
-
-  if (r->instruction != r_input_direction)
-    return -1;
-
-  /* Get the filename. */
-  if (posixly_correct && !interactive_shell)
-    disallow_filename_globbing++;
-  fn = redirection_expand (r->redirectee.filename);
-  if (posixly_correct && !interactive_shell)
-    disallow_filename_globbing--;
-
-  if (fn == 0)
-    {
-      redirection_error (r, AMBIGUOUS_REDIRECT);
-      return -1;
-    }
-
-  fd = open(fn, O_RDONLY);
-  if (fd < 0)
-    {
-      file_error (fn);
-      free (fn);
-      return -1;
-    }
-
-  rval = zcatfd (fd, 1, fn);
-
-  free (fn);
-  close (fd);
-
-  return (rval);
-}
diff --git a/builtins/exit.def~ b/builtins/exit.def~
deleted file mode 100644 (file)
index edf8db0..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-This file is exit.def, from which is created exit.c.
-It implements the builtins "exit", and "logout" in Bash.
-
-Copyright (C) 1987-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/>.
-
-$PRODUCES exit.c
-
-$BUILTIN exit
-$FUNCTION exit_builtin
-$SHORT_DOC exit [n]
-Exit the shell.
-
-Exits the shell with a status of N.  If N is omitted, the exit status
-is that of the last command executed.
-$END
-
-#include <config.h>
-
-#include "../bashtypes.h"
-#include <stdio.h>
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include "../bashintl.h"
-
-#include "../shell.h"
-#include "../jobs.h"
-
-#include "common.h"
-#include "builtext.h"  /* for jobs_builtin */
-
-extern int check_jobs_at_exit;
-extern int last_command_exit_value;
-extern int running_trap, trap_saved_exit_value;
-extern int subshell_environment;
-extern sh_builtin_func_t *this_shell_builtin;
-extern sh_builtin_func_t *last_shell_builtin;
-
-static int exit_or_logout __P((WORD_LIST *));
-static int sourced_logout;
-
-int
-exit_builtin (list)
-     WORD_LIST *list;
-{
-  if (interactive)
-    {
-      fprintf (stderr, login_shell ? _("logout\n") : "exit\n");
-      fflush (stderr);
-    }
-
-  return (exit_or_logout (list));
-}
-
-$BUILTIN logout
-$FUNCTION logout_builtin
-$SHORT_DOC logout [n]
-Exit a login shell.
-
-Exits a login shell with exit status N.  Returns an error if not executed
-in a login shell.
-$END
-
-/* How to logout. */
-int
-logout_builtin (list)
-     WORD_LIST *list;
-{
-  if (login_shell == 0 /* && interactive */)
-    {
-      builtin_error (_("not login shell: use `exit'"));
-      return (EXECUTION_FAILURE);
-    }
-  else
-    return (exit_or_logout (list));
-}
-
-static int
-exit_or_logout (list)
-     WORD_LIST *list;
-{
-  int exit_value;
-
-#if defined (JOB_CONTROL)
-  int exit_immediate_okay, stopmsg;
-
-  exit_immediate_okay = (interactive  == 0 ||
-                        last_shell_builtin == exit_builtin ||
-                        last_shell_builtin == logout_builtin ||
-                        last_shell_builtin == jobs_builtin);
-
-  /* Check for stopped jobs if the user wants to. */
-  if (exit_immediate_okay == 0)
-    {
-      register int i;
-      for (i = stopmsg = 0; i < js.j_jobslots; i++)
-       if (jobs[i] && STOPPED (i))
-         stopmsg = JSTOPPED;
-       else if (check_jobs_at_exit && stopmsg == 0 && RUNNING (i))
-         stopmsg = JRUNNING;
-
-      if (stopmsg == JSTOPPED)
-       fprintf (stderr, _("There are stopped jobs.\n"));
-      else if (stopmsg == JRUNNING)
-       fprintf (stderr, _("There are running jobs.\n"));
-
-      if (stopmsg && check_jobs_at_exit)
-        list_all_jobs (JLIST_STANDARD);
-
-      if (stopmsg)
-       {
-         /* This is NOT superfluous because EOF can get here without
-            going through the command parser.  Set both last and this
-            so that either `exit', `logout', or ^D will work to exit
-            immediately if nothing intervenes. */
-         this_shell_builtin = last_shell_builtin = exit_builtin;
-         return (EXECUTION_FAILURE);
-       }
-    }
-#endif /* JOB_CONTROL */
-
-  /* Get return value if present.  This means that you can type
-     `logout 5' to a shell, and it returns 5. */
-
-  /* If we're running the exit trap (running_trap == 1, since running_trap
-     gets set to SIG+1), and we don't have a argument given to `exit'
-     (list == 0), use the exit status we saved before running the trap
-     commands (trap_saved_exit_value). */
-  exit_value = (running_trap == 1 && list == 0) ? trap_saved_exit_value : get_exitstat (list);
-
-  bash_logout ();
-
-  last_command_exit_value = exit_value;
-
-  /* Exit the program. */
-  jump_to_top_level (EXITPROG);
-  /*NOTREACHED*/
-}
-
-void
-bash_logout ()
-{
-  /* Run our `~/.bash_logout' file if it exists, and this is a login shell. */
-  if (login_shell && sourced_logout++ == 0 && subshell_environment == 0)
-    {
-      maybe_execute_file ("~/.bash_logout", 1);
-#ifdef SYS_BASH_LOGOUT
-      maybe_execute_file (SYS_BASH_LOGOUT, 1);
-#endif
-    }
-}
diff --git a/builtins/fc.def.save b/builtins/fc.def.save
deleted file mode 100644 (file)
index b00e2cc..0000000
+++ /dev/null
@@ -1,669 +0,0 @@
-This file is fc.def, from which is created fc.c.
-It implements the builtin "fc" in Bash.
-
-Copyright (C) 1987-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/>.
-
-$PRODUCES fc.c
-
-$BUILTIN fc
-$FUNCTION fc_builtin
-$DEPENDS_ON HISTORY
-$SHORT_DOC fc [-e ename] [-lnr] [first] [last] or fc -s [pat=rep] [command]
-Display or execute commands from the history list.
-
-fc is used to list or edit and re-execute commands from the history list.
-FIRST and LAST can be numbers specifying the range, or FIRST can be a
-string, which means the most recent command beginning with that
-string.
-
-Options:
-  -e ENAME     select which editor to use.  Default is FCEDIT, then EDITOR,
-               then vi
-  -l   list lines instead of editing
-  -n   omit line numbers when listing
-  -r   reverse the order of the lines (newest listed first)
-
-With the `fc -s [pat=rep ...] [command]' format, COMMAND is
-re-executed after the substitution OLD=NEW is performed.
-
-A useful alias to use with this is r='fc -s', so that typing `r cc'
-runs the last command beginning with `cc' and typing `r' re-executes
-the last command.
-
-Exit Status:
-Returns success or status of executed command; non-zero if an error occurs.
-$END
-
-#include <config.h>
-
-#if defined (HISTORY)
-#ifndef _MINIX
-#  include <sys/param.h>
-#endif
-#include "../bashtypes.h"
-#include "posixstat.h"
-#if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H)
-#  include <sys/file.h>
-#endif
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include <stdio.h>
-#include <chartypes.h>
-
-#include "../bashansi.h"
-#include "../bashintl.h"
-#include <errno.h>
-
-#include "../shell.h"
-#include "../builtins.h"
-#include "../flags.h"
-#include "../bashhist.h"
-#include "maxpath.h"
-#include <readline/history.h>
-#include "bashgetopt.h"
-#include "common.h"
-
-#if !defined (errno)
-extern int errno;
-#endif /* !errno */
-
-extern int current_command_line_count;
-extern int literal_history;
-extern int posixly_correct;
-extern int subshell_environment, interactive_shell;
-
-extern int unlink __P((const char *));
-
-extern FILE *sh_mktmpfp __P((char *, int, char **));
-
-/* **************************************************************** */
-/*                                                                 */
-/*     The K*rn shell style fc command (Fix Command)               */
-/*                                                                 */
-/* **************************************************************** */
-
-/* fc builtin command (fix command) for Bash for those who
-   like K*rn-style history better than csh-style.
-
-     fc [-e ename] [-nlr] [first] [last]
-
-   FIRST and LAST can be numbers specifying the range, or FIRST can be
-   a string, which means the most recent command beginning with that
-   string.
-
-   -e ENAME selects which editor to use.  Default is FCEDIT, then EDITOR,
-      then the editor which corresponds to the current readline editing
-      mode, then vi.
-
-   -l means list lines instead of editing.
-   -n means no line numbers listed.
-   -r means reverse the order of the lines (making it newest listed first).
-
-     fc -e - [pat=rep ...] [command]
-     fc -s [pat=rep ...] [command]
-
-   Equivalent to !command:sg/pat/rep execpt there can be multiple PAT=REP's.
-*/
-
-/* Data structure describing a list of global replacements to perform. */
-typedef struct repl {
-  struct repl *next;
-  char *pat;
-  char *rep;
-} REPL;
-
-/* Accessors for HIST_ENTRY lists that are called HLIST. */
-#define histline(i) (hlist[(i)]->line)
-#define histdata(i) (hlist[(i)]->data)
-
-#define FREE_RLIST() \
-       do { \
-               for (rl = rlist; rl; ) { \
-                       REPL *r;        \
-                       r = rl->next; \
-                       if (rl->pat) \
-                               free (rl->pat); \
-                       if (rl->rep) \
-                               free (rl->rep); \
-                       free (rl); \
-                       rl = r; \
-               } \
-       } while (0)
-
-static char *fc_dosubs __P((char *, REPL *));
-static char *fc_gethist __P((char *, HIST_ENTRY **));
-static int fc_gethnum __P((char *, HIST_ENTRY **));
-static int fc_number __P((WORD_LIST *));
-static void fc_replhist __P((char *));
-#ifdef INCLUDE_UNUSED
-static char *fc_readline __P((FILE *));
-static void fc_addhist __P((char *));
-#endif
-
-/* String to execute on a file that we want to edit. */
-#define FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-vi}}"
-#if defined (STRICT_POSIX)
-#  define POSIX_FC_EDIT_COMMAND "${FCEDIT:-ed}"
-#else
-#  define POSIX_FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-ed}}"
-#endif
-
-int
-fc_builtin (list)
-     WORD_LIST *list;
-{
-  register int i;
-  register char *sep;
-  int numbering, reverse, listing, execute;
-  int histbeg, histend, last_hist, retval, opt, rh;
-  FILE *stream;
-  REPL *rlist, *rl;
-  char *ename, *command, *newcom, *fcedit;
-  HIST_ENTRY **hlist;
-  char *fn;
-
-  numbering = 1;
-  reverse = listing = execute = 0;
-  ename = (char *)NULL;
-
-  /* Parse out the options and set which of the two forms we're in. */
-  reset_internal_getopt ();
-  lcurrent = list;             /* XXX */
-  while (fc_number (loptend = lcurrent) == 0 &&
-        (opt = internal_getopt (list, ":e:lnrs")) != -1)
-    {
-      switch (opt)
-       {
-       case 'n':
-         numbering = 0;
-         break;
-
-       case 'l':
-         listing = 1;
-         break;
-
-       case 'r':
-         reverse = 1;
-         break;
-
-       case 's':
-         execute = 1;
-         break;
-
-       case 'e':
-         ename = list_optarg;
-         break;
-
-       default:
-         builtin_usage ();
-         return (EX_USAGE);
-       }
-    }
-
-  list = loptend;
-
-  if (ename && (*ename == '-') && (ename[1] == '\0'))
-    execute = 1;
-
-  /* The "execute" form of the command (re-run, with possible string
-     substitutions). */
-  if (execute)
-    {
-      rlist = (REPL *)NULL;
-      while (list && ((sep = (char *)strchr (list->word->word, '=')) != NULL))
-       {
-         *sep++ = '\0';
-         rl = (REPL *)xmalloc (sizeof (REPL));
-         rl->next = (REPL *)NULL;
-         rl->pat = savestring (list->word->word);
-         rl->rep = savestring (sep);
-
-         if (rlist == NULL)
-           rlist = rl;
-         else
-           {
-             rl->next = rlist;
-             rlist = rl;
-           }
-         list = list->next;
-       }
-
-      /* If we have a list of substitutions to do, then reverse it
-        to get the replacements in the proper order. */
-
-      rlist = REVERSE_LIST (rlist, REPL *);
-
-      hlist = history_list ();
-
-      /* If we still have something in list, it is a command spec.
-        Otherwise, we use the most recent command in time. */
-      command = fc_gethist (list ? list->word->word : (char *)NULL, hlist);
-
-      if (command == NULL)
-       {
-         builtin_error (_("no command found"));
-         if (rlist)
-           FREE_RLIST ();
-
-         return (EXECUTION_FAILURE);
-       }
-
-      if (rlist)
-       {
-         newcom = fc_dosubs (command, rlist);
-         free (command);
-         FREE_RLIST ();
-         command = newcom;
-       }
-
-      fprintf (stderr, "%s\n", command);
-      fc_replhist (command);   /* replace `fc -s' with command */
-      /* Posix says that the re-executed commands should be entered into the
-        history. */
-      return (parse_and_execute (command, "fc", SEVAL_NOHIST));
-    }
-
-  /* This is the second form of the command (the list-or-edit-and-rerun
-     form). */
-  hlist = history_list ();
-  if (hlist == 0)
-    return (EXECUTION_SUCCESS);
-  for (i = 0; hlist[i]; i++);
-
-  /* With the Bash implementation of history, the current command line
-     ("fc blah..." and so on) is already part of the history list by
-     the time we get to this point.  This just skips over that command
-     and makes the last command that this deals with be the last command
-     the user entered before the fc.  We need to check whether the
-     line was actually added (HISTIGNORE may have caused it to not be),
-     so we check hist_last_line_added. */
-
-  /* Even though command substitution through parse_and_execute turns off
-     remember_on_history, command substitution in a shell when set -o history
-     has been enabled (interactive or not) should use it in the last_hist
-     calculation as if it were. */
-  rh = remember_on_history || ((subshell_environment & SUBSHELL_COMSUB) && enable_history_list);
-  last_hist = i - rh - hist_last_line_added;
-itrace("fc: last_hist = %d i = %d rh = %d hist_last_line_added = %d", last_hist, i, rh, hist_last_line_added);
-itrace("fc: enable_history_list = %d subshell_environment = %d interactive_shell = %d", enable_history_list, subshell_environment, interactive_shell);
-
-  if (list)
-    {
-      histbeg = fc_gethnum (list->word->word, hlist);
-      list = list->next;
-
-      if (list)
-       histend = fc_gethnum (list->word->word, hlist);
-      else
-       histend = listing ? last_hist : histbeg;
-    }
-  else
-    {
-      /* The default for listing is the last 16 history items. */
-      if (listing)
-       {
-         histend = last_hist;
-         histbeg = histend - 16 + 1;   /* +1 because loop below uses >= */
-         if (histbeg < 0)
-           histbeg = 0;
-       }
-      else
-       /* For editing, it is the last history command. */
-       histbeg = histend = last_hist;
-    }
-
-itrace("fc: histbeg = %d histend = %d", histbeg, histend);
-
-  /* "When not listing, the fc command that caused the editing shall not be
-     entered into the history list." */
-  if (listing == 0 && hist_last_line_added)
-    {
-      bash_delete_last_history ();
-      /* If we're editing a single command -- the last command in the
-        history -- and we just removed the dummy command added by
-        edit_and_execute_command (), we need to check whether or not we
-        just removed the last command in the history and need to back
-        the pointer up.  remember_on_history is off because we're running
-        in parse_and_execute(). */
-      if (histbeg == histend && histend == last_hist && hlist[last_hist] == 0)
-       last_hist = histbeg = --histend;
-    }
-
-  /* We print error messages for line specifications out of range. */
-  if ((histbeg < 0) || (histend < 0))
-    {
-      sh_erange ((char *)NULL, _("history specification"));
-      return (EXECUTION_FAILURE);
-    }
-
-  if (histend < histbeg)
-    {
-      i = histend;
-      histend = histbeg;
-      histbeg = i;
-
-      reverse = 1;
-    }
-
-  if (listing)
-    stream = stdout;
-  else
-    {
-      numbering = 0;
-      stream = sh_mktmpfp ("bash-fc", MT_USERANDOM|MT_USETMPDIR, &fn);
-      if (stream == 0)
-       {
-         builtin_error (_("%s: cannot open temp file: %s"), fn ? fn : "", strerror (errno));
-         FREE (fn);
-         return (EXECUTION_FAILURE);
-       }
-    }
-
-  for (i = reverse ? histend : histbeg; reverse ? i >= histbeg : i <= histend; reverse ? i-- : i++)
-    {
-      QUIT;
-      if (numbering)
-       fprintf (stream, "%d", i + history_base);
-      if (listing)
-       {
-         if (posixly_correct)
-           fputs ("\t", stream);
-         else
-           fprintf (stream, "\t%c", histdata (i) ? '*' : ' ');
-       }
-      fprintf (stream, "%s\n", histline (i));
-    }
-
-  if (listing)
-    return (sh_chkwrite (EXECUTION_SUCCESS));
-
-  fflush (stream);
-  if (ferror (stream))
-    {
-      sh_wrerror ();
-      fclose (stream);
-      return (EXECUTION_FAILURE);
-    }
-  fclose (stream);
-
-  /* Now edit the file of commands. */
-  if (ename)
-    {
-      command = (char *)xmalloc (strlen (ename) + strlen (fn) + 2);
-      sprintf (command, "%s %s", ename, fn);
-    }
-  else
-    {
-      fcedit = posixly_correct ? POSIX_FC_EDIT_COMMAND : FC_EDIT_COMMAND;
-      command = (char *)xmalloc (3 + strlen (fcedit) + strlen (fn));
-      sprintf (command, "%s %s", fcedit, fn);
-    }
-  retval = parse_and_execute (command, "fc", SEVAL_NOHIST);
-  if (retval != EXECUTION_SUCCESS)
-    {
-      unlink (fn);
-      free (fn);
-      return (EXECUTION_FAILURE);
-    }
-
-  /* Make sure parse_and_execute doesn't turn this off, even though a
-     call to parse_and_execute farther up the function call stack (e.g.,
-     if this is called by vi_edit_and_execute_command) may have already
-     called bash_history_disable. */
-  remember_on_history = 1;
-
-  /* Turn on the `v' flag while fc_execute_file runs so the commands
-     will be echoed as they are read by the parser. */
-  begin_unwind_frame ("fc builtin");
-  add_unwind_protect ((Function *)xfree, fn);
-  add_unwind_protect (unlink, fn);
-  unwind_protect_int (echo_input_at_read);
-  echo_input_at_read = 1;
-    
-  retval = fc_execute_file (fn);
-
-  run_unwind_frame ("fc builtin");
-
-  return (retval);
-}
-
-/* Return 1 if LIST->word->word is a legal number for fc's use. */
-static int
-fc_number (list)
-     WORD_LIST *list;
-{
-  char *s;
-
-  if (list == 0)
-    return 0;
-  s = list->word->word;
-  if (*s == '-')
-    s++;
-  return (legal_number (s, (intmax_t *)NULL));
-}
-
-/* Return an absolute index into HLIST which corresponds to COMMAND.  If
-   COMMAND is a number, then it was specified in relative terms.  If it
-   is a string, then it is the start of a command line present in HLIST. */
-static int
-fc_gethnum (command, hlist)
-     char *command;
-     HIST_ENTRY **hlist;
-{
-  int sign, n, clen, rh;
-  register int i, j;
-  register char *s;
-
-  sign = 1;
-  /* Count history elements. */
-  for (i = 0; hlist[i]; i++);
-
-  /* With the Bash implementation of history, the current command line
-     ("fc blah..." and so on) is already part of the history list by
-     the time we get to this point.  This just skips over that command
-     and makes the last command that this deals with be the last command
-     the user entered before the fc.  We need to check whether the
-     line was actually added (HISTIGNORE may have caused it to not be),
-     so we check hist_last_line_added.  This needs to agree with the
-     calculation of last_hist in fc_builtin above. */
-  /* Even though command substitution through parse_and_execute turns off
-     remember_on_history, command substitution in a shell when set -o history
-     has been enabled (interactive or not) should use it in the last_hist
-     calculation as if it were. */
-  rh = remember_on_history || ((subshell_environment & SUBSHELL_COMSUB) && enable_history_list);
-  i -= rh + hist_last_line_added;
-
-  /* No specification defaults to most recent command. */
-  if (command == NULL)
-    return (i);
-
-  /* Otherwise, there is a specification.  It can be a number relative to
-     the current position, or an absolute history number. */
-  s = command;
-
-  /* Handle possible leading minus sign. */
-  if (s && (*s == '-'))
-    {
-      sign = -1;
-      s++;
-    }
-
-  if (s && DIGIT(*s))
-    {
-      n = atoi (s);
-      n *= sign;
-
-      /* If the value is negative or zero, then it is an offset from
-        the current history item. */
-      if (n < 0)
-       {
-         n += i + 1;
-         return (n < 0 ? 0 : n);
-       }
-      else if (n == 0)
-       return (i);
-      else
-       {
-         n -= history_base;
-         return (i < n ? i : n);
-       }
-    }
-
-  clen = strlen (command);
-  for (j = i; j >= 0; j--)
-    {
-      if (STREQN (command, histline (j), clen))
-       return (j);
-    }
-  return (-1);
-}
-
-/* Locate the most recent history line which begins with
-   COMMAND in HLIST, and return a malloc()'ed copy of it. */
-static char *
-fc_gethist (command, hlist)
-     char *command;
-     HIST_ENTRY **hlist;
-{
-  int i;
-
-  if (hlist == 0)
-    return ((char *)NULL);
-
-  i = fc_gethnum (command, hlist);
-
-  if (i >= 0)
-    return (savestring (histline (i)));
-  else
-    return ((char *)NULL);
-}
-
-#ifdef INCLUDE_UNUSED
-/* Read the edited history lines from STREAM and return them
-   one at a time.  This can read unlimited length lines.  The
-   caller should free the storage. */
-static char *
-fc_readline (stream)
-     FILE *stream;
-{
-  register int c;
-  int line_len = 0, lindex = 0;
-  char *line = (char *)NULL;
-
-  while ((c = getc (stream)) != EOF)
-    {
-      if ((lindex + 2) >= line_len)
-       line = (char *)xrealloc (line, (line_len += 128));
-
-      if (c == '\n')
-       {
-         line[lindex++] = '\n';
-         line[lindex++] = '\0';
-         return (line);
-       }
-      else
-       line[lindex++] = c;
-    }
-
-  if (!lindex)
-    {
-      if (line)
-       free (line);
-
-      return ((char *)NULL);
-    }
-
-  if (lindex + 2 >= line_len)
-    line = (char *)xrealloc (line, lindex + 3);
-
-  line[lindex++] = '\n';           /* Finish with newline if none in file */
-  line[lindex++] = '\0';
-  return (line);
-}
-#endif
-
-/* Perform the SUBS on COMMAND.
-   SUBS is a list of substitutions, and COMMAND is a simple string.
-   Return a pointer to a malloc'ed string which contains the substituted
-   command. */
-static char *
-fc_dosubs (command, subs)
-     char *command;
-     REPL *subs;
-{
-  register char *new, *t;
-  register REPL *r;
-
-  for (new = savestring (command), r = subs; r; r = r->next)
-    {
-      t = strsub (new, r->pat, r->rep, 1);
-      free (new);
-      new = t;
-    }
-  return (new);
-}
-
-/* Use `command' to replace the last entry in the history list, which,
-   by this time, is `fc blah...'.  The intent is that the new command
-   become the history entry, and that `fc' should never appear in the
-   history list.  This way you can do `r' to your heart's content. */
-static void
-fc_replhist (command)
-     char *command;
-{
-  int n;
-
-  if (command == 0 || *command == '\0')
-    return;
-
-  n = strlen (command);
-  if (command[n - 1] == '\n')
-    command[n - 1] = '\0';
-
-  if (command && *command)
-    {
-      bash_delete_last_history ();
-      maybe_add_history (command);     /* Obeys HISTCONTROL setting. */
-    }
-}
-
-#ifdef INCLUDE_UNUSED
-/* Add LINE to the history, after removing a single trailing newline. */
-static void
-fc_addhist (line)
-     char *line;
-{
-  register int n;
-
-  if (line == 0 || *line == 0)
-    return;
-
-  n = strlen (line);
-
-  if (line[n - 1] == '\n')
-    line[n - 1] = '\0';
-
-  if (line && *line)
-    maybe_add_history (line);          /* Obeys HISTCONTROL setting. */
-}
-#endif
-
-#endif /* HISTORY */
diff --git a/builtins/fc.def~ b/builtins/fc.def~
deleted file mode 100644 (file)
index d8c8c23..0000000
+++ /dev/null
@@ -1,665 +0,0 @@
-This file is fc.def, from which is created fc.c.
-It implements the builtin "fc" in Bash.
-
-Copyright (C) 1987-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/>.
-
-$PRODUCES fc.c
-
-$BUILTIN fc
-$FUNCTION fc_builtin
-$DEPENDS_ON HISTORY
-$SHORT_DOC fc [-e ename] [-lnr] [first] [last] or fc -s [pat=rep] [command]
-Display or execute commands from the history list.
-
-fc is used to list or edit and re-execute commands from the history list.
-FIRST and LAST can be numbers specifying the range, or FIRST can be a
-string, which means the most recent command beginning with that
-string.
-
-Options:
-  -e ENAME     select which editor to use.  Default is FCEDIT, then EDITOR,
-               then vi
-  -l   list lines instead of editing
-  -n   omit line numbers when listing
-  -r   reverse the order of the lines (newest listed first)
-
-With the `fc -s [pat=rep ...] [command]' format, COMMAND is
-re-executed after the substitution OLD=NEW is performed.
-
-A useful alias to use with this is r='fc -s', so that typing `r cc'
-runs the last command beginning with `cc' and typing `r' re-executes
-the last command.
-
-Exit Status:
-Returns success or status of executed command; non-zero if an error occurs.
-$END
-
-#include <config.h>
-
-#if defined (HISTORY)
-#ifndef _MINIX
-#  include <sys/param.h>
-#endif
-#include "../bashtypes.h"
-#include "posixstat.h"
-#if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H)
-#  include <sys/file.h>
-#endif
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include <stdio.h>
-#include <chartypes.h>
-
-#include "../bashansi.h"
-#include "../bashintl.h"
-#include <errno.h>
-
-#include "../shell.h"
-#include "../builtins.h"
-#include "../flags.h"
-#include "../bashhist.h"
-#include "maxpath.h"
-#include <readline/history.h>
-#include "bashgetopt.h"
-#include "common.h"
-
-#if !defined (errno)
-extern int errno;
-#endif /* !errno */
-
-extern int current_command_line_count;
-extern int literal_history;
-extern int posixly_correct;
-extern int subshell_environment, interactive_shell;
-
-extern int unlink __P((const char *));
-
-extern FILE *sh_mktmpfp __P((char *, int, char **));
-
-/* **************************************************************** */
-/*                                                                 */
-/*     The K*rn shell style fc command (Fix Command)               */
-/*                                                                 */
-/* **************************************************************** */
-
-/* fc builtin command (fix command) for Bash for those who
-   like K*rn-style history better than csh-style.
-
-     fc [-e ename] [-nlr] [first] [last]
-
-   FIRST and LAST can be numbers specifying the range, or FIRST can be
-   a string, which means the most recent command beginning with that
-   string.
-
-   -e ENAME selects which editor to use.  Default is FCEDIT, then EDITOR,
-      then the editor which corresponds to the current readline editing
-      mode, then vi.
-
-   -l means list lines instead of editing.
-   -n means no line numbers listed.
-   -r means reverse the order of the lines (making it newest listed first).
-
-     fc -e - [pat=rep ...] [command]
-     fc -s [pat=rep ...] [command]
-
-   Equivalent to !command:sg/pat/rep execpt there can be multiple PAT=REP's.
-*/
-
-/* Data structure describing a list of global replacements to perform. */
-typedef struct repl {
-  struct repl *next;
-  char *pat;
-  char *rep;
-} REPL;
-
-/* Accessors for HIST_ENTRY lists that are called HLIST. */
-#define histline(i) (hlist[(i)]->line)
-#define histdata(i) (hlist[(i)]->data)
-
-#define FREE_RLIST() \
-       do { \
-               for (rl = rlist; rl; ) { \
-                       REPL *r;        \
-                       r = rl->next; \
-                       if (rl->pat) \
-                               free (rl->pat); \
-                       if (rl->rep) \
-                               free (rl->rep); \
-                       free (rl); \
-                       rl = r; \
-               } \
-       } while (0)
-
-static char *fc_dosubs __P((char *, REPL *));
-static char *fc_gethist __P((char *, HIST_ENTRY **));
-static int fc_gethnum __P((char *, HIST_ENTRY **));
-static int fc_number __P((WORD_LIST *));
-static void fc_replhist __P((char *));
-#ifdef INCLUDE_UNUSED
-static char *fc_readline __P((FILE *));
-static void fc_addhist __P((char *));
-#endif
-
-/* String to execute on a file that we want to edit. */
-#define FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-vi}}"
-#if defined (STRICT_POSIX)
-#  define POSIX_FC_EDIT_COMMAND "${FCEDIT:-ed}"
-#else
-#  define POSIX_FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-ed}}"
-#endif
-
-int
-fc_builtin (list)
-     WORD_LIST *list;
-{
-  register int i;
-  register char *sep;
-  int numbering, reverse, listing, execute;
-  int histbeg, histend, last_hist, retval, opt, rh;
-  FILE *stream;
-  REPL *rlist, *rl;
-  char *ename, *command, *newcom, *fcedit;
-  HIST_ENTRY **hlist;
-  char *fn;
-
-  numbering = 1;
-  reverse = listing = execute = 0;
-  ename = (char *)NULL;
-
-  /* Parse out the options and set which of the two forms we're in. */
-  reset_internal_getopt ();
-  lcurrent = list;             /* XXX */
-  while (fc_number (loptend = lcurrent) == 0 &&
-        (opt = internal_getopt (list, ":e:lnrs")) != -1)
-    {
-      switch (opt)
-       {
-       case 'n':
-         numbering = 0;
-         break;
-
-       case 'l':
-         listing = 1;
-         break;
-
-       case 'r':
-         reverse = 1;
-         break;
-
-       case 's':
-         execute = 1;
-         break;
-
-       case 'e':
-         ename = list_optarg;
-         break;
-
-       default:
-         builtin_usage ();
-         return (EX_USAGE);
-       }
-    }
-
-  list = loptend;
-
-  if (ename && (*ename == '-') && (ename[1] == '\0'))
-    execute = 1;
-
-  /* The "execute" form of the command (re-run, with possible string
-     substitutions). */
-  if (execute)
-    {
-      rlist = (REPL *)NULL;
-      while (list && ((sep = (char *)strchr (list->word->word, '=')) != NULL))
-       {
-         *sep++ = '\0';
-         rl = (REPL *)xmalloc (sizeof (REPL));
-         rl->next = (REPL *)NULL;
-         rl->pat = savestring (list->word->word);
-         rl->rep = savestring (sep);
-
-         if (rlist == NULL)
-           rlist = rl;
-         else
-           {
-             rl->next = rlist;
-             rlist = rl;
-           }
-         list = list->next;
-       }
-
-      /* If we have a list of substitutions to do, then reverse it
-        to get the replacements in the proper order. */
-
-      rlist = REVERSE_LIST (rlist, REPL *);
-
-      hlist = history_list ();
-
-      /* If we still have something in list, it is a command spec.
-        Otherwise, we use the most recent command in time. */
-      command = fc_gethist (list ? list->word->word : (char *)NULL, hlist);
-
-      if (command == NULL)
-       {
-         builtin_error (_("no command found"));
-         if (rlist)
-           FREE_RLIST ();
-
-         return (EXECUTION_FAILURE);
-       }
-
-      if (rlist)
-       {
-         newcom = fc_dosubs (command, rlist);
-         free (command);
-         FREE_RLIST ();
-         command = newcom;
-       }
-
-      fprintf (stderr, "%s\n", command);
-      fc_replhist (command);   /* replace `fc -s' with command */
-      /* Posix says that the re-executed commands should be entered into the
-        history. */
-      return (parse_and_execute (command, "fc", SEVAL_NOHIST));
-    }
-
-  /* This is the second form of the command (the list-or-edit-and-rerun
-     form). */
-  hlist = history_list ();
-  if (hlist == 0)
-    return (EXECUTION_SUCCESS);
-  for (i = 0; hlist[i]; i++);
-
-  /* With the Bash implementation of history, the current command line
-     ("fc blah..." and so on) is already part of the history list by
-     the time we get to this point.  This just skips over that command
-     and makes the last command that this deals with be the last command
-     the user entered before the fc.  We need to check whether the
-     line was actually added (HISTIGNORE may have caused it to not be),
-     so we check hist_last_line_added. */
-
-  /* Even though command substitution through parse_and_execute turns off
-     remember_on_history, command substitution in a shell when set -o history
-     has been enabled (interactive or not) should use it in the last_hist
-     calculation as if it were. */
-  rh = remember_on_history || ((subshell_environment & SUBSHELL_COMSUB) && enable_history_list);
-  last_hist = i - rh - hist_last_line_added;
-
-  if (list)
-    {
-      histbeg = fc_gethnum (list->word->word, hlist);
-      list = list->next;
-
-      if (list)
-       histend = fc_gethnum (list->word->word, hlist);
-      else
-       histend = listing ? last_hist : histbeg;
-    }
-  else
-    {
-      /* The default for listing is the last 16 history items. */
-      if (listing)
-       {
-         histend = last_hist;
-         histbeg = histend - 16 + 1;   /* +1 because loop below uses >= */
-         if (histbeg < 0)
-           histbeg = 0;
-       }
-      else
-       /* For editing, it is the last history command. */
-       histbeg = histend = last_hist;
-    }
-
-  /* "When not listing, the fc command that caused the editing shall not be
-     entered into the history list." */
-  if (listing == 0 && hist_last_line_added)
-    {
-      bash_delete_last_history ();
-      /* If we're editing a single command -- the last command in the
-        history -- and we just removed the dummy command added by
-        edit_and_execute_command (), we need to check whether or not we
-        just removed the last command in the history and need to back
-        the pointer up.  remember_on_history is off because we're running
-        in parse_and_execute(). */
-      if (histbeg == histend && histend == last_hist && hlist[last_hist] == 0)
-       last_hist = histbeg = --histend;
-    }
-
-  /* We print error messages for line specifications out of range. */
-  if ((histbeg < 0) || (histend < 0))
-    {
-      sh_erange ((char *)NULL, _("history specification"));
-      return (EXECUTION_FAILURE);
-    }
-
-  if (histend < histbeg)
-    {
-      i = histend;
-      histend = histbeg;
-      histbeg = i;
-
-      reverse = 1;
-    }
-
-  if (listing)
-    stream = stdout;
-  else
-    {
-      numbering = 0;
-      stream = sh_mktmpfp ("bash-fc", MT_USERANDOM|MT_USETMPDIR, &fn);
-      if (stream == 0)
-       {
-         builtin_error (_("%s: cannot open temp file: %s"), fn ? fn : "", strerror (errno));
-         FREE (fn);
-         return (EXECUTION_FAILURE);
-       }
-    }
-
-  for (i = reverse ? histend : histbeg; reverse ? i >= histbeg : i <= histend; reverse ? i-- : i++)
-    {
-      QUIT;
-      if (numbering)
-       fprintf (stream, "%d", i + history_base);
-      if (listing)
-       {
-         if (posixly_correct)
-           fputs ("\t", stream);
-         else
-           fprintf (stream, "\t%c", histdata (i) ? '*' : ' ');
-       }
-      fprintf (stream, "%s\n", histline (i));
-    }
-
-  if (listing)
-    return (sh_chkwrite (EXECUTION_SUCCESS));
-
-  fflush (stream);
-  if (ferror (stream))
-    {
-      sh_wrerror ();
-      fclose (stream);
-      return (EXECUTION_FAILURE);
-    }
-  fclose (stream);
-
-  /* Now edit the file of commands. */
-  if (ename)
-    {
-      command = (char *)xmalloc (strlen (ename) + strlen (fn) + 2);
-      sprintf (command, "%s %s", ename, fn);
-    }
-  else
-    {
-      fcedit = posixly_correct ? POSIX_FC_EDIT_COMMAND : FC_EDIT_COMMAND;
-      command = (char *)xmalloc (3 + strlen (fcedit) + strlen (fn));
-      sprintf (command, "%s %s", fcedit, fn);
-    }
-  retval = parse_and_execute (command, "fc", SEVAL_NOHIST);
-  if (retval != EXECUTION_SUCCESS)
-    {
-      unlink (fn);
-      free (fn);
-      return (EXECUTION_FAILURE);
-    }
-
-  /* Make sure parse_and_execute doesn't turn this off, even though a
-     call to parse_and_execute farther up the function call stack (e.g.,
-     if this is called by vi_edit_and_execute_command) may have already
-     called bash_history_disable. */
-  remember_on_history = 1;
-
-  /* Turn on the `v' flag while fc_execute_file runs so the commands
-     will be echoed as they are read by the parser. */
-  begin_unwind_frame ("fc builtin");
-  add_unwind_protect ((Function *)xfree, fn);
-  add_unwind_protect (unlink, fn);
-  unwind_protect_int (echo_input_at_read);
-  echo_input_at_read = 1;
-    
-  retval = fc_execute_file (fn);
-
-  run_unwind_frame ("fc builtin");
-
-  return (retval);
-}
-
-/* Return 1 if LIST->word->word is a legal number for fc's use. */
-static int
-fc_number (list)
-     WORD_LIST *list;
-{
-  char *s;
-
-  if (list == 0)
-    return 0;
-  s = list->word->word;
-  if (*s == '-')
-    s++;
-  return (legal_number (s, (intmax_t *)NULL));
-}
-
-/* Return an absolute index into HLIST which corresponds to COMMAND.  If
-   COMMAND is a number, then it was specified in relative terms.  If it
-   is a string, then it is the start of a command line present in HLIST. */
-static int
-fc_gethnum (command, hlist)
-     char *command;
-     HIST_ENTRY **hlist;
-{
-  int sign, n, clen, rh;
-  register int i, j;
-  register char *s;
-
-  sign = 1;
-  /* Count history elements. */
-  for (i = 0; hlist[i]; i++);
-
-  /* With the Bash implementation of history, the current command line
-     ("fc blah..." and so on) is already part of the history list by
-     the time we get to this point.  This just skips over that command
-     and makes the last command that this deals with be the last command
-     the user entered before the fc.  We need to check whether the
-     line was actually added (HISTIGNORE may have caused it to not be),
-     so we check hist_last_line_added.  This needs to agree with the
-     calculation of last_hist in fc_builtin above. */
-  /* Even though command substitution through parse_and_execute turns off
-     remember_on_history, command substitution in a shell when set -o history
-     has been enabled (interactive or not) should use it in the last_hist
-     calculation as if it were. */
-  rh = remember_on_history || ((subshell_environment & SUBSHELL_COMSUB) && enable_history_list);
-  i -= rh + hist_last_line_added;
-
-  /* No specification defaults to most recent command. */
-  if (command == NULL)
-    return (i);
-
-  /* Otherwise, there is a specification.  It can be a number relative to
-     the current position, or an absolute history number. */
-  s = command;
-
-  /* Handle possible leading minus sign. */
-  if (s && (*s == '-'))
-    {
-      sign = -1;
-      s++;
-    }
-
-  if (s && DIGIT(*s))
-    {
-      n = atoi (s);
-      n *= sign;
-
-      /* If the value is negative or zero, then it is an offset from
-        the current history item. */
-      if (n < 0)
-       {
-         n += i + 1;
-         return (n < 0 ? 0 : n);
-       }
-      else if (n == 0)
-       return (i);
-      else
-       {
-         n -= history_base;
-         return (i < n ? i : n);
-       }
-    }
-
-  clen = strlen (command);
-  for (j = i; j >= 0; j--)
-    {
-      if (STREQN (command, histline (j), clen))
-       return (j);
-    }
-  return (-1);
-}
-
-/* Locate the most recent history line which begins with
-   COMMAND in HLIST, and return a malloc()'ed copy of it. */
-static char *
-fc_gethist (command, hlist)
-     char *command;
-     HIST_ENTRY **hlist;
-{
-  int i;
-
-  if (hlist == 0)
-    return ((char *)NULL);
-
-  i = fc_gethnum (command, hlist);
-
-  if (i >= 0)
-    return (savestring (histline (i)));
-  else
-    return ((char *)NULL);
-}
-
-#ifdef INCLUDE_UNUSED
-/* Read the edited history lines from STREAM and return them
-   one at a time.  This can read unlimited length lines.  The
-   caller should free the storage. */
-static char *
-fc_readline (stream)
-     FILE *stream;
-{
-  register int c;
-  int line_len = 0, lindex = 0;
-  char *line = (char *)NULL;
-
-  while ((c = getc (stream)) != EOF)
-    {
-      if ((lindex + 2) >= line_len)
-       line = (char *)xrealloc (line, (line_len += 128));
-
-      if (c == '\n')
-       {
-         line[lindex++] = '\n';
-         line[lindex++] = '\0';
-         return (line);
-       }
-      else
-       line[lindex++] = c;
-    }
-
-  if (!lindex)
-    {
-      if (line)
-       free (line);
-
-      return ((char *)NULL);
-    }
-
-  if (lindex + 2 >= line_len)
-    line = (char *)xrealloc (line, lindex + 3);
-
-  line[lindex++] = '\n';           /* Finish with newline if none in file */
-  line[lindex++] = '\0';
-  return (line);
-}
-#endif
-
-/* Perform the SUBS on COMMAND.
-   SUBS is a list of substitutions, and COMMAND is a simple string.
-   Return a pointer to a malloc'ed string which contains the substituted
-   command. */
-static char *
-fc_dosubs (command, subs)
-     char *command;
-     REPL *subs;
-{
-  register char *new, *t;
-  register REPL *r;
-
-  for (new = savestring (command), r = subs; r; r = r->next)
-    {
-      t = strsub (new, r->pat, r->rep, 1);
-      free (new);
-      new = t;
-    }
-  return (new);
-}
-
-/* Use `command' to replace the last entry in the history list, which,
-   by this time, is `fc blah...'.  The intent is that the new command
-   become the history entry, and that `fc' should never appear in the
-   history list.  This way you can do `r' to your heart's content. */
-static void
-fc_replhist (command)
-     char *command;
-{
-  int n;
-
-  if (command == 0 || *command == '\0')
-    return;
-
-  n = strlen (command);
-  if (command[n - 1] == '\n')
-    command[n - 1] = '\0';
-
-  if (command && *command)
-    {
-      bash_delete_last_history ();
-      maybe_add_history (command);     /* Obeys HISTCONTROL setting. */
-    }
-}
-
-#ifdef INCLUDE_UNUSED
-/* Add LINE to the history, after removing a single trailing newline. */
-static void
-fc_addhist (line)
-     char *line;
-{
-  register int n;
-
-  if (line == 0 || *line == 0)
-    return;
-
-  n = strlen (line);
-
-  if (line[n - 1] == '\n')
-    line[n - 1] = '\0';
-
-  if (line && *line)
-    maybe_add_history (line);          /* Obeys HISTCONTROL setting. */
-}
-#endif
-
-#endif /* HISTORY */
diff --git a/builtins/help.def~ b/builtins/help.def~
deleted file mode 100644 (file)
index 2444e6d..0000000
+++ /dev/null
@@ -1,383 +0,0 @@
-This file is help.def, from which is created help.c.
-It implements the builtin "help" in Bash.
-
-Copyright (C) 1987-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/>.
-
-$PRODUCES help.c
-
-$BUILTIN help
-$FUNCTION help_builtin
-$DEPENDS_ON HELP_BUILTIN
-$SHORT_DOC help [-dms] [pattern ...]
-Display information about builtin commands.
-
-Displays brief summaries of builtin commands.  If PATTERN is
-specified, gives detailed help on all commands matching PATTERN,
-otherwise the list of help topics is printed.
-
-Options:
-  -d   output short description for each topic
-  -m   display usage in pseudo-manpage format
-  -s   output only a short usage synopsis for each topic matching
-       PATTERN
-
-Arguments:
-  PATTERN      Pattern specifiying a help topic
-
-Exit Status:
-Returns success unless PATTERN is not found or an invalid option is given.
-$END
-
-#include <config.h>
-
-#if defined (HELP_BUILTIN)
-#include <stdio.h>
-
-#if defined (HAVE_UNISTD_H)
-#  ifdef _MINIX
-#    include <sys/types.h>
-#  endif
-#  include <unistd.h>
-#endif
-
-#include <errno.h>
-
-#include <filecntl.h>
-
-#include "../bashintl.h"
-
-#include "../shell.h"
-#include "../builtins.h"
-#include "../pathexp.h"
-#include "common.h"
-#include "bashgetopt.h"
-
-#include <glob/strmatch.h>
-#include <glob/glob.h>
-
-#ifndef errno
-extern int errno;
-#endif
-
-extern const char * const bash_copyright;
-extern const char * const bash_license;
-
-static void show_builtin_command_help __P((void));
-static int open_helpfile __P((char *));
-static void show_desc __P((char *, int));
-static void show_manpage __P((char *, int));
-static void show_longdoc __P((int));
-
-/* Print out a list of the known functions in the shell, and what they do.
-   If LIST is supplied, print out the list which matches for each pattern
-   specified. */
-int
-help_builtin (list)
-     WORD_LIST *list;
-{
-  register int i;
-  char *pattern, *name;
-  int plen, match_found, sflag, dflag, mflag;
-
-  dflag = sflag = mflag = 0;
-  reset_internal_getopt ();
-  while ((i = internal_getopt (list, "dms")) != -1)
-    {
-      switch (i)
-       {
-       case 'd':
-         dflag = 1;
-         break;
-       case 'm':
-         mflag = 1;
-         break;
-       case 's':
-         sflag = 1;
-         break;
-       default:
-         builtin_usage ();
-         return (EX_USAGE);
-       }
-    }
-  list = loptend;
-
-  if (list == 0)
-    {
-      show_shell_version (0);
-      show_builtin_command_help ();
-      return (EXECUTION_SUCCESS);
-    }
-
-  /* We should consider making `help bash' do something. */
-
-  if (glob_pattern_p (list->word->word))
-    {
-      printf (ngettext ("Shell commands matching keyword `", "Shell commands matching keywords `", (list->next ? 2 : 1)));
-      print_word_list (list, ", ");
-      printf ("'\n\n");
-    }
-
-  for (match_found = 0, pattern = ""; list; list = list->next)
-    {
-      pattern = list->word->word;
-      plen = strlen (pattern);
-
-      for (i = 0; name = shell_builtins[i].name; i++)
-       {
-         QUIT;
-         if ((strncmp (pattern, name, plen) == 0) ||
-             (strmatch (pattern, name, FNMATCH_EXTFLAG) != FNM_NOMATCH))
-           {
-             match_found++;
-             if (dflag)
-               {
-                 show_desc (name, i);
-                 continue;
-               }
-             else if (mflag)
-               {
-                 show_manpage (name, i);
-                 continue;
-               }
-
-             printf ("%s: %s\n", name, shell_builtins[i].short_doc);
-
-             if (sflag == 0)
-               show_longdoc (i);
-           }
-       }
-    }
-
-  if (match_found == 0)
-    {
-      builtin_error (_("no help topics match `%s'.  Try `help help' or `man -k %s' or `info %s'."), pattern, pattern, pattern);
-      return (EXECUTION_FAILURE);
-    }
-
-  fflush (stdout);
-  return (EXECUTION_SUCCESS);
-}
-
-static int
-open_helpfile (name)
-     char *name;
-{
-  int fd;
-
-  fd = open (name, O_RDONLY);
-  if (fd == -1)
-    {
-      builtin_error (_("%s: cannot open: %s"), name, strerror (errno));
-      return -1;
-    }
-  return fd;
-}
-
-/* By convention, enforced by mkbuiltins.c, if separate help files are being
-   used, the long_doc array contains one string -- the full pathname of the
-   help file for this builtin.  */
-static void
-show_longdoc (i)
-     int i;
-{
-  register int j;
-  char * const *doc;
-  int fd;
-
-  doc = shell_builtins[i].long_doc;
-
-  if (doc && doc[0] && *doc[0] == '/' && doc[1] == (char *)NULL)
-    {
-      fd = open_helpfile (doc[0]);
-      if (fd < 0)
-       return;
-      zcatfd (fd, 1, doc[0]);
-      close (fd);
-    }
-  else
-    for (j = 0; doc[j]; j++)
-      printf ("%*s%s\n", BASE_INDENT, " ", _(doc[j]));
-}
-
-static void
-show_desc (name, i)
-     char *name;
-     int i;
-{
-  register int j;
-  char **doc, *line;
-  int fd, usefile;
-
-  doc = (char **)shell_builtins[i].long_doc;
-
-  usefile = (doc && doc[0] && *doc[0] == '/' && doc[1] == (char *)NULL);
-  if (usefile)
-    {
-      fd = open_helpfile (doc[0]);
-      if (fd < 0)
-       return;
-      zmapfd (fd, &line, doc[0]);
-      close (fd);
-    }
-  else
-    line = doc ? doc[0] : (char *)NULL;
-
-  printf ("%s - ", name);
-  for (j = 0; line && line[j]; j++)
-    {
-      putchar (line[j]);
-      if (line[j] == '\n')
-       break;
-    }
-  
-  fflush (stdout);
-
-  if (usefile)
-    free (line);
-}
-
-/* Print builtin help in pseudo-manpage format. */
-static void
-show_manpage (name, i)
-     char *name;
-     int i;
-{
-  register int j;
-  char **doc, *line;
-  int fd, usefile;
-
-  doc = (char **)shell_builtins[i].long_doc;
-
-  usefile = (doc && doc[0] && *doc[0] == '/' && doc[1] == (char *)NULL);
-  if (usefile)
-    {
-      fd = open_helpfile (doc[0]);
-      if (fd < 0)
-       return;
-      zmapfd (fd, &line, doc[0]);
-      close (fd);
-    }
-  else
-    line = doc ? _(doc[0]) : (char *)NULL;
-
-  /* NAME */
-  printf ("NAME\n");
-  printf ("%*s%s - ", BASE_INDENT, " ", name);
-  for (j = 0; line && line[j]; j++)
-    {
-      putchar (line[j]);
-      if (line[j] == '\n')
-       break;
-    }
-  printf ("\n");
-
-  /* SYNOPSIS */
-  printf ("SYNOPSIS\n");
-  printf ("%*s%s\n\n", BASE_INDENT, " ", shell_builtins[i].short_doc);
-
-  /* DESCRIPTION */
-  printf ("DESCRIPTION\n");
-  if (usefile == 0)
-    {
-      for (j = 0; doc[j]; j++)
-        printf ("%*s%s\n", BASE_INDENT, " ", _(doc[j]));
-    }
-  else
-    {
-      for (j = 0; line && line[j]; j++)
-       {
-         putchar (line[j]);
-         if (line[j] == '\n')
-           printf ("%*s", BASE_INDENT, " ");
-       }
-    }
-  putchar ('\n');
-
-  /* SEE ALSO */
-  printf ("SEE ALSO\n");
-  printf ("%*sbash(1)\n\n", BASE_INDENT, " ");
-
-  /* IMPLEMENTATION */
-  printf ("IMPLEMENTATION\n");
-  printf ("%*s", BASE_INDENT, " ");
-  show_shell_version (0);
-  printf ("%*s", BASE_INDENT, " ");
-  printf ("%s\n", _(bash_copyright));
-  printf ("%*s", BASE_INDENT, " ");
-  printf ("%s\n", _(bash_license));
-
-  fflush (stdout);
-  if (usefile)
-    free (line);
-}
-
-static void
-show_builtin_command_help ()
-{
-  int i, j;
-  int height, width;
-  char *t, blurb[128];
-
-  printf (
-_("These shell commands are defined internally.  Type `help' to see this list.\n\
-Type `help name' to find out more about the function `name'.\n\
-Use `info bash' to find out more about the shell in general.\n\
-Use `man -k' or `info' to find out more about commands not in this list.\n\
-\n\
-A star (*) next to a name means that the command is disabled.\n\
-\n"));
-
-  t = get_string_value ("COLUMNS");
-  width = (t && *t) ? atoi (t) : 80;
-  if (width <= 0)
-    width = 80;
-
-  width /= 2;
-  if (width > sizeof (blurb))
-    width = sizeof (blurb);
-  height = (num_shell_builtins + 1) / 2;       /* number of rows */
-
-  for (i = 0; i < height; i++)
-    {
-      QUIT;
-
-      /* first column */
-      blurb[0] = (shell_builtins[i].flags & BUILTIN_ENABLED) ? ' ' : '*';
-      strncpy (blurb + 1, shell_builtins[i].short_doc, width - 2);
-      blurb[width - 2] = '>';          /* indicate truncation */
-      blurb[width - 1] = '\0';
-      printf ("%s", blurb);
-      if (((i << 1) >= num_shell_builtins) || (i+height >= num_shell_builtins))
-       {
-         printf ("\n");
-         break;
-       }
-
-      /* two spaces */
-      for (j = strlen (blurb); j < width; j++)
-        putc (' ', stdout);
-
-      /* second column */
-      blurb[0] = (shell_builtins[i+height].flags & BUILTIN_ENABLED) ? ' ' : '*';
-      strncpy (blurb + 1, shell_builtins[i+height].short_doc, width - 3);
-      blurb[width - 3] = '>';          /* indicate truncation */
-      blurb[width - 2] = '\0';
-      printf ("%s\n", blurb);
-    }
-}
-#endif /* HELP_BUILTIN */
diff --git a/builtins/kill.def~ b/builtins/kill.def~
deleted file mode 100644 (file)
index cfb0673..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-This file is kill.def, from which is created kill.c.
-It implements the builtin "kill" in Bash.
-
-Copyright (C) 1987-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/>.
-
-$PRODUCES kill.c
-
-$BUILTIN kill
-$FUNCTION kill_builtin
-$SHORT_DOC kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
-Send a signal to a job.
-
-Send the processes identified by PID or JOBSPEC the signal named by
-SIGSPEC or SIGNUM.  If neither SIGSPEC nor SIGNUM is present, then
-SIGTERM is assumed.
-
-Options:
-  -s sig       SIG is a signal name
-  -n sig       SIG is a signal number
-  -l   list the signal names; if arguments follow `-l' they are
-       assumed to be signal numbers for which names should be listed
-
-Kill is a shell builtin for two reasons: it allows job IDs to be used
-instead of process IDs, and allows processes to be killed if the limit
-on processes that you can create is reached.
-
-Exit Status:
-Returns success unless an invalid option is given or an error occurs.
-$END
-
-#include <config.h>
-
-#include <stdio.h>
-#include <errno.h>
-#if defined (HAVE_UNISTD_H)
-#  ifdef _MINIX
-#    include <sys/types.h>
-#  endif
-#  include <unistd.h>
-#endif
-
-#include "../bashansi.h"
-#include "../bashintl.h"
-
-#include "../shell.h"
-#include "../trap.h"
-#include "../jobs.h"
-#include "common.h"
-
-/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
-#if !defined (errno)
-extern int errno;
-#endif /* !errno */
-
-extern int posixly_correct;
-
-static void kill_error __P((pid_t, int));
-
-#if !defined (CONTINUE_AFTER_KILL_ERROR)
-#  define CONTINUE_OR_FAIL return (EXECUTION_FAILURE)
-#else
-#  define CONTINUE_OR_FAIL goto continue_killing
-#endif /* CONTINUE_AFTER_KILL_ERROR */
-
-/* Here is the kill builtin.  We only have it so that people can type
-   kill -KILL %1?  No, if you fill up the process table this way you
-   can still kill some. */
-int
-kill_builtin (list)
-     WORD_LIST *list;
-{
-  int sig, any_succeeded, listing, saw_signal, dflags;
-  char *sigspec, *word;
-  pid_t pid;
-  intmax_t pid_value;
-
-  if (list == 0)
-    {
-      builtin_usage ();
-      return (EXECUTION_FAILURE);
-    }
-
-  any_succeeded = listing = saw_signal = 0;
-  sig = SIGTERM;
-  sigspec = "TERM";
-
-  dflags = DSIG_NOCASE | ((posixly_correct == 0) ? DSIG_SIGPREFIX : 0);
-  /* Process options. */
-  while (list)
-    {
-      word = list->word->word;
-
-      if (ISOPTION (word, 'l'))
-       {
-         listing++;
-         list = list->next;
-       }
-      else if (ISOPTION (word, 's') || ISOPTION (word, 'n'))
-       {
-         list = list->next;
-         if (list)
-           {
-             sigspec = list->word->word;
-             if (sigspec[0] == '0' && sigspec[1] == '\0')
-               sig = 0;
-             else
-               sig = decode_signal (sigspec, dflags);
-             list = list->next;
-             saw_signal++;
-           }
-         else
-           {
-             sh_needarg (word);
-             return (EXECUTION_FAILURE);
-           }
-       }
-      else if (ISOPTION (word, '-'))
-       {
-         list = list->next;
-         break;
-       }
-      else if (ISOPTION (word, '?'))
-       {
-         builtin_usage ();
-         return (EXECUTION_SUCCESS);
-       }
-      /* If this is a signal specification then process it.  We only process
-        the first one seen; other arguments may signify process groups (e.g,
-        -num == process group num). */
-      else if (*word == '-' && saw_signal == 0)
-       {
-         sigspec = word + 1;
-         sig = decode_signal (sigspec, dflags);
-         saw_signal++;
-         list = list->next;
-       }
-      else
-       break;
-    }
-
-  if (listing)
-    return (display_signal_list (list, 0));
-
-  /* OK, we are killing processes. */
-  if (sig == NO_SIG)
-    {
-      sh_invalidsig (sigspec);
-      return (EXECUTION_FAILURE);
-    }
-
-  if (list == 0)
-    {
-      builtin_usage ();
-      return (EXECUTION_FAILURE);
-    }
-
-  while (list)
-    {
-      word = list->word->word;
-
-      if (*word == '-')
-       word++;
-
-      /* Use the entire argument in case of minus sign presence. */
-      if (*word && legal_number (list->word->word, &pid_value) && (pid_value == (pid_t)pid_value))
-       {
-         pid = (pid_t) pid_value;
-
-         if (kill_pid (pid, sig, pid < -1) < 0)
-           {
-             if (errno == EINVAL)
-               sh_invalidsig (sigspec);
-             else
-               kill_error (pid, errno);
-             CONTINUE_OR_FAIL;
-           }
-         else
-           any_succeeded++;
-       }
-#if defined (JOB_CONTROL)
-      else if (*list->word->word && *list->word->word != '%')
-       {
-         builtin_error (_("%s: arguments must be process or job IDs"), list->word->word);
-         CONTINUE_OR_FAIL;
-       }
-      else if (*word)
-       /* Posix.2 says you can kill without job control active (4.32.4) */
-       {                       /* Must be a job spec.  Check it out. */
-         int job;
-         sigset_t set, oset;
-         JOB *j;
-
-         BLOCK_CHILD (set, oset);
-         job = get_job_spec (list);
-
-         if (INVALID_JOB (job))
-           {
-             if (job != DUP_JOB)
-               sh_badjob (list->word->word);
-             UNBLOCK_CHILD (oset);
-             CONTINUE_OR_FAIL;
-           }
-
-         j = get_job_by_jid (job);
-         /* Job spec used.  Kill the process group. If the job was started
-            without job control, then its pgrp == shell_pgrp, so we have
-            to be careful.  We take the pid of the first job in the pipeline
-            in that case. */
-         pid = IS_JOBCONTROL (job) ? j->pgrp : j->pipe->pid;
-
-         UNBLOCK_CHILD (oset);
-
-         if (kill_pid (pid, sig, 1) < 0)
-           {
-             if (errno == EINVAL)
-               sh_invalidsig (sigspec);
-             else
-               kill_error (pid, errno);
-             CONTINUE_OR_FAIL;
-           }
-         else
-           any_succeeded++;
-       }
-#endif /* !JOB_CONTROL */
-      else
-       {
-         sh_badpid (list->word->word);
-         CONTINUE_OR_FAIL;
-       }
-    continue_killing:
-      list = list->next;
-    }
-
-  return (any_succeeded ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
-}
-
-static void
-kill_error (pid, e)
-     pid_t pid;
-     int e;
-{
-  char *x;
-
-  x = strerror (e);
-  if (x == 0)
-    x = _("Unknown error");
-  builtin_error ("(%ld) - %s", (long)pid, x);
-}
diff --git a/builtins/mapfile.def~ b/builtins/mapfile.def~
deleted file mode 100644 (file)
index 4843751..0000000
+++ /dev/null
@@ -1,351 +0,0 @@
-This file is mapfile.def, from which is created mapfile.c.
-It implements the builtin "mapfile" in Bash.
-
-Copyright (C) 2005-2006 Rocky Bernstein for Free Software Foundation, Inc.
-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/>.
-
-$PRODUCES mapfile.c
-
-$BUILTIN mapfile
-$FUNCTION mapfile_builtin
-$SHORT_DOC mapfile [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]
-Read lines from the standard input into an indexed array variable.
-
-Read lines from the standard input into the indexed array variable ARRAY, or
-from file descriptor FD if the -u option is supplied.  The variable MAPFILE
-is the default ARRAY.
-
-Options:
-  -n count     Copy at most COUNT lines.  If COUNT is 0, all lines are copied.
-  -O origin    Begin assigning to ARRAY at index ORIGIN.  The default index is 0.
-  -s count     Discard the first COUNT lines read.
-  -t           Remove a trailing newline from each line read.
-  -u fd                Read lines from file descriptor FD instead of the standard input.
-  -C callback  Evaluate CALLBACK each time QUANTUM lines are read.
-  -c quantum   Specify the number of lines read between each call to CALLBACK.
-
-Arguments:
-  ARRAY                Array variable name to use for file data.
-
-If -C is supplied without -c, the default quantum is 5000.  When
-CALLBACK is evaluated, it is supplied the index of the next array
-element to be assigned as an additional argument.
-
-If not supplied with an explicit origin, mapfile will clear ARRAY before
-assigning to it.
-
-Exit Status:
-Returns success unless an invalid option is given or ARRAY is readonly or
-not an indexed array.
-$END
-
-$BUILTIN readarray
-$FUNCTION mapfile_builtin
-$SHORT_DOC readarray [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]
-Read lines from a file into an array variable.
-
-A synonym for `mapfile'.
-$END
-
-#include <config.h>
-
-#include "builtins.h"
-#include "posixstat.h"
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include "bashansi.h"
-#include "bashintl.h"
-
-#include <stdio.h>
-#include <errno.h>
-
-#include "../bashintl.h"
-#include "../shell.h"
-#include "common.h"
-#include "bashgetopt.h"
-
-#if !defined (errno)
-extern int errno;
-#endif
-
-#if defined (ARRAY_VARS)
-
-#define DEFAULT_ARRAY_NAME     "MAPFILE"
-
-/* The value specifying how frequently `mapfile'  calls the callback. */
-#define DEFAULT_QUANTUM 5000
-
-/* Values for FLAGS */
-#define MAPF_CLEARARRAY        0x01
-#define MAPF_CHOP      0x02
-
-static int
-run_callback(callback, current_index)
-     const char *callback;
-     unsigned int current_index;
-{
-  unsigned int execlen;
-  char  *execstr;
-  int flags;
-
-  execlen = strlen (callback) + 10;
-  /* 1 for space between %s and %d,
-     another 1 for the last nul char for C string. */
-  execlen += 2;
-  execstr = xmalloc (execlen);
-
-  flags = 0;
-#if 0
-  if (interactive)
-    flags |= SEVAL_NOHIST|SEVAL_INTERACT;
-#endif
-  snprintf (execstr, execlen, "%s %d", callback, current_index);
-  return parse_and_execute(execstr, NULL, flags);
-}
-
-static void
-do_chop(line)
-     char * line;
-{
-  int length;
-
-  length = strlen (line);
-  if (length && line[length-1] == '\n') 
-    line[length-1] = '\0';
-}
-
-static int
-mapfile (fd, line_count_goal, origin, nskip, callback_quantum, callback, array_name, flags)
-     int fd;
-     long line_count_goal, origin, nskip, callback_quantum;
-     char *callback, *array_name;
-     int flags;
-{
-  char *line;
-  size_t line_length;
-  unsigned int array_index, line_count;
-  SHELL_VAR *entry;
-  int unbuffered_read;
-  
-  line = NULL;
-  line_length = 0;
-  unbuffered_read = 0;
-
-  /* The following check should be done before reading any lines.  Doing it
-     here allows us to call bind_array_element instead of bind_array_variable
-     and skip the variable lookup on every call. */
-  entry = find_or_make_array_variable (array_name, 1);
-  if (entry == 0 || readonly_p (entry) || noassign_p (entry))
-    {
-      if (entry && readonly_p (entry))
-       err_readonly (array_name);
-       
-      return (EXECUTION_FAILURE);
-    }
-  else if (array_p (entry) == 0)
-    {
-      builtin_error (_("%s: not an indexed array", array_name));
-      return (EXECUTION_FAILURE);
-    }
-      
-  if (flags & MAPF_CLEARARRAY)
-    array_flush (array_cell (entry));
-
-#ifndef __CYGWIN__
-  unbuffered_read = (lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE);
-#else
-  unbuffered_read = 1;
-#endif
-
-  zreset ();
-
-  /* Skip any lines at beginning of file? */
-  for (line_count = 0; line_count < nskip; line_count++)
-    if (zgetline (fd, &line, &line_length, unbuffered_read) < 0)
-      break;
-
-  line = 0;
-  line_length = 0;    
-
-  /* Reset the buffer for bash own stream */
-  interrupt_immediately++;
-  for (array_index = origin, line_count = 1; 
-       zgetline (fd, &line, &line_length, unbuffered_read) != -1;
-       array_index++, line_count++) 
-    {
-      /* Have we exceeded # of lines to store? */
-      if (line_count_goal != 0 && line_count > line_count_goal) 
-       break;
-
-      /* Remove trailing newlines? */
-      if (flags & MAPF_CHOP)
-       do_chop (line);
-         
-      /* Has a callback been registered and if so is it time to call it? */
-      if (callback && line_count && (line_count % callback_quantum) == 0) 
-       {
-         run_callback (callback, array_index);
-
-         /* Reset the buffer for bash own stream. */
-         if (unbuffered_read == 0)
-           zsyncfd (fd);
-       }
-
-      bind_array_element (entry, array_index, line, 0);
-    }
-
-  xfree (line);
-
-  if (unbuffered_read == 0)
-    zsyncfd (fd);
-
-  interrupt_immediately--;
-  return EXECUTION_SUCCESS;
-}
-
-int
-mapfile_builtin (list)
-     WORD_LIST *list;
-{
-  int opt, code, fd, clear_array, flags;
-  intmax_t intval;
-  long lines, origin, nskip, callback_quantum;
-  char *array_name, *callback;
-
-  clear_array = 1;
-  fd = 0;
-  lines = origin = nskip = 0;
-  flags = MAPF_CLEARARRAY;
-  callback_quantum = DEFAULT_QUANTUM;
-  callback = 0;
-
-  reset_internal_getopt ();
-  while ((opt = internal_getopt (list, "u:n:O:tC:c:s:")) != -1)
-    {
-      switch (opt)
-       {
-       case 'u':
-         code = legal_number (list_optarg, &intval);
-         if (code == 0 || intval < 0 || intval != (int)intval)
-           {
-             builtin_error (_("%s: invalid file descriptor specification"), list_optarg);
-             return (EXECUTION_FAILURE);
-           }
-         else
-           fd = intval;
-
-         if (sh_validfd (fd) == 0)
-           {
-             builtin_error (_("%d: invalid file descriptor: %s"), fd, strerror (errno));
-             return (EXECUTION_FAILURE);
-           }
-         break;          
-
-       case 'n':
-         code = legal_number (list_optarg, &intval);
-         if (code == 0 || intval < 0 || intval != (unsigned)intval)
-           {
-             builtin_error (_("%s: invalid line count"), list_optarg);
-             return (EXECUTION_FAILURE);
-           }
-         else
-           lines = intval;
-         break;
-
-       case 'O':
-         code = legal_number (list_optarg, &intval);
-         if (code == 0 || intval < 0 || intval != (unsigned)intval)
-           {
-             builtin_error (_("%s: invalid array origin"), list_optarg);
-             return (EXECUTION_FAILURE);
-           }
-         else
-           origin = intval;
-         flags &= ~MAPF_CLEARARRAY;
-         break;
-       case 't':
-         flags |= MAPF_CHOP;
-         break;
-       case 'C':
-         callback = list_optarg;
-         break;
-       case 'c':
-         code = legal_number (list_optarg, &intval);
-         if (code == 0 || intval <= 0 || intval != (unsigned)intval)
-           {
-             builtin_error (_("%s: invalid callback quantum"), list_optarg);
-             return (EXECUTION_FAILURE);
-           }
-         else
-           callback_quantum = intval;
-         break;
-       case 's':
-         code = legal_number (list_optarg, &intval);
-         if (code == 0 || intval < 0 || intval != (unsigned)intval)
-           {
-             builtin_error (_("%s: invalid line count"), list_optarg);
-             return (EXECUTION_FAILURE);
-           }
-         else
-           nskip = intval;
-         break;
-       default:
-         builtin_usage ();
-         return (EX_USAGE);
-       }
-    }
-  list = loptend;
-
-  if (list == 0) 
-    array_name = DEFAULT_ARRAY_NAME;
-  else if (list->word == 0 || list->word->word == 0)
-    {
-      builtin_error ("internal error: getting variable name");
-      return (EXECUTION_FAILURE);
-    }
-  else if (list->word->word[0] == '\0')
-    {
-      builtin_error (_("empty array variable name"));
-      return (EX_USAGE);
-    } 
-  else
-    array_name = list->word->word;
-  
-  if (legal_identifier (array_name) == 0 && valid_array_reference (array_name) == 0)
-    {
-      sh_invalidid (array_name);
-      return (EXECUTION_FAILURE);
-    }
-
-  return mapfile (fd, lines, origin, nskip, callback_quantum, callback, array_name, flags);
-}
-
-#else
-
-int
-mapfile_builtin (list)
-     WORD_LIST *list;
-{
-  builtin_error (_("array variable support required"));
-  return (EXECUTION_FAILURE);
-}
-
-#endif  /* ARRAY_VARS */
diff --git a/builtins/printf.def~ b/builtins/printf.def~
deleted file mode 100644 (file)
index 4a9f68a..0000000
+++ /dev/null
@@ -1,1118 +0,0 @@
-This file is printf.def, from which is created printf.c.
-It implements the builtin "printf" in Bash.
-
-Copyright (C) 1997-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/>.
-
-$PRODUCES printf.c
-
-$BUILTIN printf
-$FUNCTION printf_builtin
-$SHORT_DOC printf [-v var] format [arguments]
-Formats and prints ARGUMENTS under control of the FORMAT.
-
-Options:
-  -v var       assign the output to shell variable VAR rather than
-               display it on the standard output
-
-FORMAT 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
-argument.
-
-In addition to the standard format specifications described in printf(1)
-and printf(3), printf interprets:
-
-  %b   expand backslash escape sequences in the corresponding argument
-  %q   quote the argument in a way that can be reused as shell input
-
-Exit Status:
-Returns success unless an invalid option is given or a write or assignment
-error occurs.
-$END
-
-#include <config.h>
-
-#include "../bashtypes.h"
-
-#include <errno.h>
-#if defined (HAVE_LIMITS_H)
-#  include <limits.h>
-#else
-   /* Assume 32-bit ints. */
-#  define INT_MAX              2147483647
-#  define INT_MIN              (-2147483647-1)
-#endif
-
-#if defined (PREFER_STDARG)
-#  include <stdarg.h>
-#else
-#  include <varargs.h>
-#endif
-
-#include <stdio.h>
-#include <chartypes.h>
-
-#ifdef HAVE_INTTYPES_H
-#  include <inttypes.h>
-#endif
-
-#include "../bashansi.h"
-#include "../bashintl.h"
-
-#include "../shell.h"
-#include "shmbutil.h"
-#include "stdc.h"
-#include "bashgetopt.h"
-#include "common.h"
-
-#if defined (PRI_MACROS_BROKEN)
-#  undef PRIdMAX
-#endif
-
-#if !defined (PRIdMAX)
-#  if HAVE_LONG_LONG
-#    define PRIdMAX    "lld"
-#  else
-#    define PRIdMAX    "ld"
-#  endif
-#endif
-
-#if !defined (errno)
-extern int errno;
-#endif
-
-#define PC(c) \
-  do { \
-    char b[2]; \
-    tw++; \
-    b[0] = c; b[1] = '\0'; \
-    if (vflag) \
-      vbadd (b, 1); \
-    else \
-      putchar (c); \
-  } while (0)
-
-#define PF(f, func) \
-  do { \
-    int nw; \
-    clearerr (stdout); \
-    if (have_fieldwidth && have_precision) \
-      nw = vflag ? vbprintf (f, fieldwidth, precision, func) : printf (f, fieldwidth, precision, func); \
-    else if (have_fieldwidth) \
-      nw = vflag ? vbprintf (f, fieldwidth, func) : printf (f, fieldwidth, func); \
-    else if (have_precision) \
-      nw = vflag ? vbprintf (f, precision, func) : printf (f, fieldwidth, func); \
-    else \
-      nw = vflag ? vbprintf (f, func) : printf (f, func); \
-    tw += nw; \
-    if (ferror (stdout)) \
-      { \
-       sh_wrerror (); \
-       clearerr (stdout); \
-       return (EXECUTION_FAILURE); \
-      } \
-  } while (0)
-
-/* We free the buffer used by mklong() if it's `too big'. */
-#define PRETURN(value) \
-  do \
-    { \
-      if (vflag) \
-       { \
-         bind_printf_variable  (vname, vbuf, 0); \
-         stupidly_hack_special_variables (vname); \
-       } \
-      if (conv_bufsize > 4096 ) \
-       { \
-         free (conv_buf); \
-         conv_bufsize = 0; \
-         conv_buf = 0; \
-       } \
-      if (vbsize > 4096) \
-       { \
-         free (vbuf); \
-         vbsize = 0; \
-         vbuf = 0; \
-       } \
-      else if (vbuf) \
-       vbuf[0] = 0; \
-      terminate_immediately--; \
-      fflush (stdout); \
-      if (ferror (stdout)) \
-       { \
-         sh_wrerror (); \
-         clearerr (stdout); \
-         return (EXECUTION_FAILURE); \
-       } \
-      return (value); \
-    } \
-  while (0)
-
-#define SKIP1 "#'-+ 0"
-#define LENMODS "hjlLtz"
-
-#ifndef HAVE_ASPRINTF
-extern int asprintf __P((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3)));
-#endif
-
-#ifndef HAVE_VSNPRINTF
-extern int vsnprintf __P((char *, size_t, const char *, ...)) __attribute__((__format__ (printf, 3, 4)));
-#endif
-
-static void printf_erange __P((char *));
-static int printstr __P((char *, char *, int, int, int));
-static int tescape __P((char *, char *, int *));
-static char *bexpand __P((char *, int, int *, int *));
-static char *vbadd __P((char *, int));
-static int vbprintf __P((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
-static char *mklong __P((char *, char *, size_t));
-static int getchr __P((void));
-static char *getstr __P((void));
-static int  getint __P((void));
-static intmax_t getintmax __P((void));
-static uintmax_t getuintmax __P((void));
-static SHELL_VAR *bind_printf_variable __P((char *, char *, int));
-
-#if defined (HAVE_LONG_DOUBLE) && HAVE_DECL_STRTOLD && !defined(STRTOLD_BROKEN)
-typedef long double floatmax_t;
-#  define FLOATMAX_CONV        "L"
-#  define strtofltmax  strtold
-#else
-typedef double floatmax_t;
-#  define FLOATMAX_CONV        ""
-#  define strtofltmax  strtod
-#endif
-static floatmax_t getfloatmax __P((void));
-
-static intmax_t asciicode __P((void));
-
-static WORD_LIST *garglist;
-static int retval;
-static int conversion_error;
-
-/* printf -v var support */
-static int vflag = 0;
-static char *vbuf, *vname;
-static size_t vbsize;
-static int vblen;
-
-static intmax_t tw;
-
-static char *conv_buf;
-static size_t conv_bufsize;
-
-int
-printf_builtin (list)
-     WORD_LIST *list;
-{
-  int ch, fieldwidth, precision;
-  int have_fieldwidth, have_precision;
-  char convch, thisch, nextch, *format, *modstart, *fmt, *start;
-
-  conversion_error = 0;
-  retval = EXECUTION_SUCCESS;
-
-  vflag = 0;
-
-  reset_internal_getopt ();
-  while ((ch = internal_getopt (list, "v:")) != -1)
-    {
-      switch (ch)
-       {
-       case 'v':
-         vname = list_optarg;
-#if defined (ARRAY_VARS)
-         if (legal_identifier (vname) || valid_array_reference (vname))
-#else
-         if (legal_identifier (vname))
-#endif
-           {
-             vflag = 1;
-             vblen = 0;
-             if (vbuf)
-               vbuf[0] = 0;
-           }
-         else
-           {
-             sh_invalidid (vname);
-             return (EX_USAGE);
-           }
-         break;
-       default:
-         builtin_usage ();
-         return (EX_USAGE);
-       }
-    }
-  list = loptend;      /* skip over possible `--' */
-
-  if (list == 0)
-    {
-      builtin_usage ();
-      return (EX_USAGE);
-    }
-
-  if (list->word->word == 0 || list->word->word[0] == '\0')
-    return (EXECUTION_SUCCESS);
-
-  format = list->word->word;
-  tw = 0;
-
-  garglist = list->next;
-
-  /* If the format string is empty after preprocessing, return immediately. */
-  if (format == 0 || *format == 0)
-    return (EXECUTION_SUCCESS);
-
-  terminate_immediately++;
-         
-  /* Basic algorithm is to scan the format string for conversion
-     specifications -- once one is found, find out if the field
-     width or precision is a '*'; if it is, gather up value.  Note,
-     format strings are reused as necessary to use up the provided
-     arguments, arguments of zero/null string are provided to use
-     up the format string. */
-  do
-    {
-      tw = 0;
-      /* find next format specification */
-      for (fmt = format; *fmt; fmt++)
-       {
-         precision = fieldwidth = 0;
-         have_fieldwidth = have_precision = 0;
-
-         if (*fmt == '\\')
-           {
-             fmt++;
-             /* A NULL third argument to tescape means to bypass the
-                special processing for arguments to %b. */
-             fmt += tescape (fmt, &nextch, (int *)NULL);
-             PC (nextch);
-             fmt--;    /* for loop will increment it for us again */
-             continue;
-           }
-
-         if (*fmt != '%')
-           {
-             PC (*fmt);
-             continue;
-           }
-
-         /* ASSERT(*fmt == '%') */
-         start = fmt++;
-
-         if (*fmt == '%')              /* %% prints a % */
-           {
-             PC ('%');
-             continue;
-           }
-
-         /* found format specification, skip to field width */
-         for (; *fmt && strchr(SKIP1, *fmt); ++fmt)
-           ;
-
-         /* Skip optional field width. */
-         if (*fmt == '*')
-           {
-             fmt++;
-             have_fieldwidth = 1;
-             fieldwidth = getint ();
-           }
-         else
-           while (DIGIT (*fmt))
-             fmt++;
-
-         /* Skip optional '.' and precision */
-         if (*fmt == '.')
-           {
-             ++fmt;
-             if (*fmt == '*')
-               {
-                 fmt++;
-                 have_precision = 1;
-                 precision = getint ();
-               }
-             else
-               {
-                 /* Negative precisions are allowed but treated as if the
-                    precision were missing; I would like to allow a leading
-                    `+' in the precision number as an extension, but lots
-                    of asprintf/fprintf implementations get this wrong. */
-#if 0
-                 if (*fmt == '-' || *fmt == '+')
-#else
-                 if (*fmt == '-')
-#endif
-                   fmt++;
-                 while (DIGIT (*fmt))
-                   fmt++;
-               }
-           }
-
-         /* skip possible format modifiers */
-         modstart = fmt;
-         while (*fmt && strchr (LENMODS, *fmt))
-           fmt++;
-           
-         if (*fmt == 0)
-           {
-             builtin_error (_("`%s': missing format character"), start);
-             PRETURN (EXECUTION_FAILURE);
-           }
-
-         convch = *fmt;
-         thisch = modstart[0];
-         nextch = modstart[1];
-         modstart[0] = convch;
-         modstart[1] = '\0';
-
-         switch(convch)
-           {
-           case 'c':
-             {
-               char p;
-
-               p = getchr ();
-               PF(start, p);
-               break;
-             }
-
-           case 's':
-             {
-               char *p;
-
-               p = getstr ();
-               PF(start, p);
-               break;
-             }
-
-           case 'n':
-             {
-               char *var;
-
-               var = getstr ();
-               if (var && *var)
-                 {
-                   if (legal_identifier (var))
-                     bind_var_to_int (var, tw);
-                   else
-                     {
-                       sh_invalidid (var);
-                       PRETURN (EXECUTION_FAILURE);
-                     }
-                 }
-               break;
-             }
-
-           case 'b':           /* expand escapes in argument */
-             {
-               char *p, *xp;
-               int rlen, r;
-
-               p = getstr ();
-               ch = rlen = r = 0;
-               xp = bexpand (p, strlen (p), &ch, &rlen);
-
-               if (xp)
-                 {
-                   /* Have to use printstr because of possible NUL bytes
-                      in XP -- printf does not handle that well. */
-                   r = printstr (start, xp, rlen, fieldwidth, precision);
-                   if (r < 0)
-                     {
-                       sh_wrerror ();
-                       clearerr (stdout);
-                       retval = EXECUTION_FAILURE;
-                     }
-                   free (xp);
-                 }
-
-               if (ch || r < 0)
-                 PRETURN (retval);
-               break;
-             }
-
-           case 'q':           /* print with shell quoting */
-             {
-               char *p, *xp;
-               int r;
-
-               r = 0;
-               p = getstr ();
-               if (p && *p == 0)       /* XXX - getstr never returns null */
-                 xp = savestring ("''");
-               else if (ansic_shouldquote (p))
-                 xp = ansic_quote (p, 0, (int *)0);
-               else
-                 xp = sh_backslash_quote (p);
-               if (xp)
-                 {
-                   /* Use printstr to get fieldwidth and precision right. */
-                   r = printstr (start, xp, strlen (xp), fieldwidth, precision);
-                   if (r < 0)
-                     {
-                       sh_wrerror ();
-                       clearerr (stdout);
-                     }
-                   free (xp);
-                 }
-
-               if (r < 0)
-                 PRETURN (EXECUTION_FAILURE);
-               break;
-             }
-
-           case 'd':
-           case 'i':
-             {
-               char *f;
-               long p;
-               intmax_t pp;
-
-               p = pp = getintmax ();
-               if (p != pp)
-                 {
-                   f = mklong (start, PRIdMAX, sizeof (PRIdMAX) - 2);
-                   PF (f, pp);
-                 }
-               else
-                 {
-                   /* Optimize the common case where the integer fits
-                      in "long".  This also works around some long
-                      long and/or intmax_t library bugs in the common
-                      case, e.g. glibc 2.2 x86.  */
-                   f = mklong (start, "l", 1);
-                   PF (f, p);
-                 }
-               break;
-             }
-
-           case 'o':
-           case 'u':
-           case 'x':
-           case 'X':
-             {
-               char *f;
-               unsigned long p;
-               uintmax_t pp;
-
-               p = pp = getuintmax ();
-               if (p != pp)
-                 {
-                   f = mklong (start, PRIdMAX, sizeof (PRIdMAX) - 2);
-                   PF (f, pp);
-                 }
-               else
-                 {
-                   f = mklong (start, "l", 1);
-                   PF (f, p);
-                 }
-               break;
-             }
-
-           case 'e':
-           case 'E':
-           case 'f':
-           case 'F':
-           case 'g':
-           case 'G':
-#if defined (HAVE_PRINTF_A_FORMAT)
-           case 'a':
-           case 'A':
-#endif
-             {
-               char *f;
-               floatmax_t p;
-
-               p = getfloatmax ();
-               f = mklong (start, FLOATMAX_CONV, sizeof(FLOATMAX_CONV) - 1);
-               PF (f, p);
-               break;
-             }
-
-           /* We don't output unrecognized format characters; we print an
-              error message and return a failure exit status. */
-           default:
-             builtin_error (_("`%c': invalid format character"), convch);
-             PRETURN (EXECUTION_FAILURE);
-           }
-
-         modstart[0] = thisch;
-         modstart[1] = nextch;
-       }
-
-      if (ferror (stdout))
-       {
-         sh_wrerror ();
-         clearerr (stdout);
-         PRETURN (EXECUTION_FAILURE);
-       }
-    }
-  while (garglist && garglist != list->next);
-
-  if (conversion_error)
-    retval = EXECUTION_FAILURE;
-
-  PRETURN (retval);
-}
-
-static void
-printf_erange (s)
-     char *s;
-{
-  builtin_error (_("warning: %s: %s"), s, strerror(ERANGE));
-}
-
-/* We duplicate a lot of what printf(3) does here. */
-static int
-printstr (fmt, string, len, fieldwidth, precision)
-     char *fmt;                        /* format */
-     char *string;             /* expanded string argument */
-     int len;                  /* length of expanded string */
-     int fieldwidth;           /* argument for width of `*' */
-     int precision;            /* argument for precision of `*' */
-{
-#if 0
-  char *s;
-#endif
-  int padlen, nc, ljust, i;
-  int fw, pr;                  /* fieldwidth and precision */
-
-#if 0
-  if (string == 0 || *string == '\0')
-#else
-  if (string == 0 || len == 0)
-#endif
-    return 0;
-
-#if 0
-  s = fmt;
-#endif
-  if (*fmt == '%')
-    fmt++;
-
-  ljust = fw = 0;
-  pr = -1;
-
-  /* skip flags */
-  while (strchr (SKIP1, *fmt))
-    {
-      if (*fmt == '-')
-       ljust = 1;
-      fmt++;
-    }
-
-  /* get fieldwidth, if present */
-  if (*fmt == '*')
-    {
-      fmt++;
-      fw = fieldwidth;
-      if (fw < 0)
-       {
-         fw = -fw;
-         ljust = 1;
-       }
-    }
-  else if (DIGIT (*fmt))
-    {
-      fw = *fmt++ - '0';
-      while (DIGIT (*fmt))
-       fw = (fw * 10) + (*fmt++ - '0');
-    }
-
-  /* get precision, if present */
-  if (*fmt == '.')
-    {
-      fmt++;
-      if (*fmt == '*')
-       {
-         fmt++;
-         pr = precision;
-       }
-      else if (DIGIT (*fmt))
-       {
-         pr = *fmt++ - '0';
-         while (DIGIT (*fmt))
-           pr = (pr * 10) + (*fmt++ - '0');
-       }
-    }
-
-#if 0
-  /* If we remove this, get rid of `s'. */
-  if (*fmt != 'b' && *fmt != 'q')
-    {
-      internal_error ("format parsing problem: %s", s);
-      fw = pr = 0;
-    }
-#endif
-
-  /* chars from string to print */
-  nc = (pr >= 0 && pr <= len) ? pr : len;
-
-  padlen = fw - nc;
-  if (padlen < 0)
-    padlen = 0;
-  if (ljust)
-    padlen = -padlen;
-
-  /* leading pad characters */
-  for (; padlen > 0; padlen--)
-    PC (' ');
-
-  /* output NC characters from STRING */
-  for (i = 0; i < nc; i++)
-    PC (string[i]);
-
-  /* output any necessary trailing padding */
-  for (; padlen < 0; padlen++)
-    PC (' ');
-
-  return (ferror (stdout) ? -1 : 0);
-}
-  
-/* Convert STRING by expanding the escape sequences specified by the
-   POSIX standard for printf's `%b' format string.  If SAWC is non-null,
-   perform the processing appropriate for %b arguments.  In particular,
-   recognize `\c' and use that as a string terminator.  If we see \c, set
-   *SAWC to 1 before returning.  LEN is the length of STRING. */
-
-/* Translate a single backslash-escape sequence starting at ESTART (the
-   character after the backslash) and return the number of characters
-   consumed by the sequence.  CP is the place to return the translated
-   value.  *SAWC is set to 1 if the escape sequence was \c, since that means
-   to short-circuit the rest of the processing.  If SAWC is null, we don't
-   do the \c short-circuiting, and \c is treated as an unrecognized escape
-   sequence; we also bypass the other processing specific to %b arguments.  */
-static int
-tescape (estart, cp, sawc)
-     char *estart;
-     char *cp;
-     int *sawc;
-{
-  register char *p;
-  int temp, c, evalue;
-
-  p = estart;
-
-  switch (c = *p++)
-    {
-#if defined (__STDC__)
-      case 'a': *cp = '\a'; break;
-#else
-      case 'a': *cp = '\007'; break;
-#endif
-
-      case 'b': *cp = '\b'; break;
-
-      case 'e':
-      case 'E': *cp = '\033'; break;   /* ESC -- non-ANSI */
-
-      case 'f': *cp = '\f'; break;
-
-      case 'n': *cp = '\n'; break;
-
-      case 'r': *cp = '\r'; break;
-
-      case 't': *cp = '\t'; break;
-
-      case 'v': *cp = '\v'; break;
-
-      /* The octal escape sequences are `\0' followed by up to three octal
-        digits (if SAWC), or `\' followed by up to three octal digits (if
-        !SAWC).  As an extension, we allow the latter form even if SAWC. */
-      case '0': case '1': case '2': case '3':
-      case '4': case '5': case '6': case '7':
-       evalue = OCTVALUE (c);
-       for (temp = 2 + (!evalue && !!sawc); ISOCTAL (*p) && temp--; p++)
-         evalue = (evalue * 8) + OCTVALUE (*p);
-       *cp = evalue & 0xFF;
-       break;
-
-      /* And, as another extension, we allow \xNNN, where each N is a
-        hex digit. */
-      case 'x':
-#if 0
-       for (evalue = 0; ISXDIGIT ((unsigned char)*p); p++)
-#else
-       for (temp = 2, evalue = 0; ISXDIGIT ((unsigned char)*p) && temp--; p++)
-#endif
-         evalue = (evalue * 16) + HEXVALUE (*p);
-       if (p == estart + 1)
-         {
-           builtin_error (_("missing hex digit for \\x"));
-           *cp = '\\';
-           return 0;
-         }
-       *cp = evalue & 0xFF;
-       break;
-
-      case '\\':       /* \\ -> \ */
-       *cp = c;
-       break;
-
-      /* SAWC == 0 means that \', \", and \? are recognized as escape
-        sequences, though the only processing performed is backslash
-        removal. */
-      case '\'': case '"': case '?':
-       if (!sawc)
-         *cp = c;
-       else
-         {
-           *cp = '\\';
-           return 0;
-         }
-       break;
-
-      case 'c':
-       if (sawc)
-         {
-           *sawc = 1;
-           break;
-         }
-      /* other backslash escapes are passed through unaltered */
-      default:
-       *cp = '\\';
-       return 0;
-      }
-  return (p - estart);
-}
-
-static char *
-bexpand (string, len, sawc, lenp)
-     char *string;
-     int len, *sawc, *lenp;
-{
-  int temp;
-  char *ret, *r, *s, c;
-
-#if 0
-  if (string == 0 || *string == '\0')
-#else
-  if (string == 0 || len == 0)
-#endif
-    {
-      if (sawc)
-       *sawc = 0;
-      if (lenp)
-       *lenp = 0;
-      return ((char *)NULL);
-    }
-
-  ret = (char *)xmalloc (len + 1);
-  for (r = ret, s = string; s && *s; )
-    {
-      c = *s++;
-      if (c != '\\' || *s == '\0')
-       {
-         *r++ = c;
-         continue;
-       }
-      temp = 0;
-      s += tescape (s, &c, &temp);
-      if (temp)
-       {
-         if (sawc)
-           *sawc = 1;
-         break;
-       }
-
-      *r++ = c;
-    }
-
-  *r = '\0';
-  if (lenp)
-    *lenp = r - ret;
-  return ret;
-}
-
-static char *
-vbadd (buf, blen)
-     char *buf;
-     int blen;
-{
-  size_t nlen;
-
-  nlen = vblen + blen + 1;
-  if (nlen >= vbsize)
-    {
-      vbsize = ((nlen + 63) >> 6) << 6;
-      vbuf = (char *)xrealloc (vbuf, vbsize);
-    }
-
-  if (blen == 1)
-    vbuf[vblen++] = buf[0];
-  else if (blen > 1)
-    {
-      FASTCOPY (buf, vbuf  + vblen, blen);
-      vblen += blen;
-    }
-  vbuf[vblen] = '\0';
-
-#ifdef DEBUG
-  if  (strlen (vbuf) != vblen)
-    internal_error  ("printf:vbadd: vblen (%d) != strlen (vbuf) (%d)", vblen, (int)strlen (vbuf));
-#endif
-
-  return vbuf;
-}
-
-static int
-#if defined (PREFER_STDARG)
-vbprintf (const char *format, ...)
-#else
-vbprintf (format, va_alist)
-  const char *format;
-  va_dcl
-#endif
-{
-  va_list args;
-  size_t nlen;
-  int blen;
-
-  SH_VA_START (args, format);
-  blen = vsnprintf (vbuf + vblen, vbsize - vblen, format, args);
-  va_end (args);
-
-  nlen = vblen + blen + 1;
-  if (nlen >= vbsize)
-    {
-      vbsize = ((nlen + 63) >> 6) << 6;
-      vbuf = (char *)xrealloc (vbuf, vbsize);
-      SH_VA_START (args, format);
-      blen = vsnprintf (vbuf + vblen, vbsize - vblen, format, args);
-      va_end (args);
-    }
-
-  vblen += blen;
-  vbuf[vblen] = '\0';
-
-#ifdef DEBUG
-  if  (strlen (vbuf) != vblen)
-    internal_error  ("printf:vbadd: vblen (%d) != strlen (vbuf) (%d)", vblen, (int)strlen (vbuf));
-#endif
-  
-  return (blen);
-}
-
-static char *
-mklong (str, modifiers, mlen)
-     char *str;
-     char *modifiers;
-     size_t mlen;
-{
-  size_t len, slen;
-
-  slen = strlen (str);
-  len = slen + mlen + 1;
-
-  if (len > conv_bufsize)
-    {
-      conv_bufsize = (((len + 1023) >> 10) << 10);
-      conv_buf = (char *)xrealloc (conv_buf, conv_bufsize);
-    }
-
-  FASTCOPY (str, conv_buf, slen - 1);
-  FASTCOPY (modifiers, conv_buf + slen - 1, mlen);
-
-  conv_buf[len - 2] = str[slen - 1];
-  conv_buf[len - 1] = '\0';
-  return (conv_buf);
-}
-
-static int
-getchr ()
-{
-  int ret;
-
-  if (garglist == 0)
-    return ('\0');
-
-  ret = (int)garglist->word->word[0];
-  garglist = garglist->next;
-  return ret;
-}
-
-static char *
-getstr ()
-{
-  char *ret;
-
-  if (garglist == 0)
-    return ("");
-
-  ret = garglist->word->word;
-  garglist = garglist->next;
-  return ret;
-}
-
-static int
-getint ()
-{
-  intmax_t ret;
-
-  ret = getintmax ();
-
-  if (ret > INT_MAX)
-    {
-      printf_erange (garglist->word->word);
-      ret = INT_MAX;
-    }
-  else if (ret < INT_MIN)
-    {
-      printf_erange (garglist->word->word);
-      ret = INT_MIN;
-    }
-
-  return ((int)ret);
-}
-
-static intmax_t
-getintmax ()
-{
-  intmax_t ret;
-  char *ep;
-
-  if (garglist == 0)
-    return (0);
-
-  if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"')
-    return asciicode ();
-
-  errno = 0;
-  ret = strtoimax (garglist->word->word, &ep, 0);
-
-  if (*ep)
-    {
-      sh_invalidnum (garglist->word->word);
-      /* POSIX.2 says ``...a diagnostic message shall be written to standard
-        error, and the utility shall not exit with a zero exit status, but
-        shall continue processing any remaining operands and shall write the
-         value accumulated at the time the error was detected to standard
-        output.''  Yecch. */
-#if 0
-      ret = 0;         /* return partially-converted value from strtoimax */
-#endif
-      conversion_error = 1;
-    }
-  else if (errno == ERANGE)
-    printf_erange (garglist->word->word);
-
-  garglist = garglist->next;
-  return (ret);
-}
-
-static uintmax_t
-getuintmax ()
-{
-  uintmax_t ret;
-  char *ep;
-
-  if (garglist == 0)
-    return (0);
-
-  if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"')
-    return asciicode ();
-
-  errno = 0;
-  ret = strtoumax (garglist->word->word, &ep, 0);
-  
-  if (*ep)
-    {
-      sh_invalidnum (garglist->word->word);
-      /* Same POSIX.2 conversion error requirements as getintmax(). */
-      ret = 0;
-      conversion_error = 1;
-    }
-  else if (errno == ERANGE)
-    printf_erange (garglist->word->word);
-
-  garglist = garglist->next;
-  return (ret);
-}
-
-static floatmax_t
-getfloatmax ()
-{
-  floatmax_t ret;
-  char *ep;
-
-  if (garglist == 0)
-    return (0);
-
-  if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"')
-    return asciicode ();
-
-  errno = 0;
-  ret = strtofltmax (garglist->word->word, &ep);
-
-  if (*ep)
-    {
-      sh_invalidnum (garglist->word->word);
-      /* Same thing about POSIX.2 conversion error requirements. */
-      ret = 0;
-      conversion_error = 1;
-    }
-  else if (errno == ERANGE)
-    printf_erange (garglist->word->word);
-
-  garglist = garglist->next;
-  return (ret);
-}
-
-/* NO check is needed for garglist here. */
-static intmax_t
-asciicode ()
-{
-  register intmax_t ch;
-#if defined (HANDLE_MULTIBYTE)
-  wchar_t wc;
-  size_t mblength, slen;
-#endif
-  DECLARE_MBSTATE;
-
-#if defined (HANDLE_MULTIBYTE)
-  slen = strlen (garglist->word->word+1);
-  mblength = MBLEN (garglist->word->word+1, slen);
-  if (mblength > 1)
-    {
-      mblength = mbtowc (&wc, garglist->word->word+1, slen);
-      ch = wc;         /* XXX */
-    }
-  else
-#endif
-    ch = (unsigned char)garglist->word->word[1];
-
-  garglist = garglist->next;
-  return (ch);
-}
-
-static SHELL_VAR *
-bind_printf_variable (name, value, flags)
-     char *name;
-     char *value;
-     int flags;
-{
-#if defined (ARRAY_VARS)
-  if (valid_array_reference (name) == 0)
-    return (bind_variable (name, value, flags));
-  else
-    return (assign_array_element (name, value, flags));
-#else /* !ARRAY_VARS */
-  return bind_variable (name, value, flags);
-#endif /* !ARRAY_VARS */
-}
diff --git a/builtins/shopt.def~ b/builtins/shopt.def~
deleted file mode 100644 (file)
index 0bdb889..0000000
+++ /dev/null
@@ -1,687 +0,0 @@
-This file is shopt.def, from which is created shopt.c.
-It implements the Bash `shopt' builtin.
-
-Copyright (C) 1994-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/>.
-
-$PRODUCES shopt.c
-
-$BUILTIN shopt
-$FUNCTION shopt_builtin
-$SHORT_DOC shopt [-pqsu] [-o] [optname ...]
-Set and unset shell options.
-
-Change the setting of each shell option OPTNAME.  Without any option
-arguments, list all shell options with an indication of whether or not each
-is set. 
-
-Options:
-  -o   restrict OPTNAMEs to those defined for use with `set -o'
-  -p   print each shell option with an indication of its status
-  -q   suppress output
-  -s   enable (set) each OPTNAME
-  -u   disable (unset) each OPTNAME
-
-Exit Status:
-Returns success if OPTNAME is enabled; fails if an invalid option is
-given or OPTNAME is disabled.
-$END
-
-#include <config.h>
-
-#if defined (HAVE_UNISTD_H)
-#  ifdef _MINIX
-#    include <sys/types.h>
-#  endif
-#  include <unistd.h>
-#endif
-
-#include <stdio.h>
-
-#include "version.h"
-
-#include "../bashintl.h"
-
-#include "../shell.h"
-#include "../flags.h"
-#include "common.h"
-#include "bashgetopt.h"
-
-#if defined (HISTORY)
-#  include "../bashhist.h"
-#endif
-
-#define UNSETOPT       0
-#define SETOPT         1
-
-#define OPTFMT         "%-15s\t%s\n"
-
-extern int allow_null_glob_expansion, fail_glob_expansion, glob_dot_filenames;
-extern int cdable_vars, mail_warning, source_uses_path;
-extern int no_exit_on_failed_exec, print_shift_error;
-extern int check_hashed_filenames, promptvars;
-extern int cdspelling, expand_aliases;
-extern int extended_quote;
-extern int check_window_size;
-extern int glob_ignore_case, match_ignore_case;
-extern int hup_on_exit;
-extern int xpg_echo;
-extern int gnu_error_format;
-extern int check_jobs_at_exit;
-extern int autocd;
-extern int glob_star;
-
-#if defined (EXTENDED_GLOB)
-extern int extended_glob;
-#endif
-
-#if defined (READLINE)
-extern int hist_verify, history_reediting, perform_hostname_completion;
-extern int no_empty_command_completion;
-extern int force_fignore;
-extern int dircomplete_spelling;
-
-extern int enable_hostname_completion __P((int));
-#endif
-
-#if defined (PROGRAMMABLE_COMPLETION)
-extern int prog_completion_enabled;
-#endif
-
-#if defined (RESTRICTED_SHELL)
-extern char *shell_name;
-#endif
-
-#if defined (DEBUGGER)
-extern int debugging_mode;
-#endif
-
-static void shopt_error __P((char *));
-
-static int set_shellopts_after_change __P((int));
-
-static int set_compatibility_level __P((int));
-
-#if defined (RESTRICTED_SHELL)
-static int set_restricted_shell __P((int));
-#endif
-
-static int shopt_login_shell;
-static int shopt_compat31;
-static int shopt_compat32;
-static int shopt_compat40;
-
-typedef int shopt_set_func_t __P((int));
-
-static struct {
-  char *name;
-  int  *value;
-  shopt_set_func_t *set_func;
-} shopt_vars[] = {
-  { "autocd", &autocd, (shopt_set_func_t *)NULL },
-  { "cdable_vars", &cdable_vars, (shopt_set_func_t *)NULL },
-  { "cdspell", &cdspelling, (shopt_set_func_t *)NULL },
-  { "checkhash", &check_hashed_filenames, (shopt_set_func_t *)NULL },
-#if defined (JOB_CONTROL)
-  { "checkjobs", &check_jobs_at_exit, (shopt_set_func_t *)NULL },
-#endif
-  { "checkwinsize", &check_window_size, (shopt_set_func_t *)NULL },
-#if defined (HISTORY)
-  { "cmdhist", &command_oriented_history, (shopt_set_func_t *)NULL },
-#endif
-  { "compat31", &shopt_compat31, set_compatibility_level },
-  { "compat32", &shopt_compat32, set_compatibility_level },
-#if defined (READLINE)
-  { "dirspell", &dircomplete_spelling, (shopt_set_func_t *)NULL },
-#endif
-  { "dotglob", &glob_dot_filenames, (shopt_set_func_t *)NULL },
-  { "execfail", &no_exit_on_failed_exec, (shopt_set_func_t *)NULL },
-  { "expand_aliases", &expand_aliases, (shopt_set_func_t *)NULL },
-#if defined (DEBUGGER)
-  { "extdebug", &debugging_mode, (shopt_set_func_t *)NULL },
-#endif
-#if defined (EXTENDED_GLOB)
-  { "extglob", &extended_glob, (shopt_set_func_t *)NULL },
-#endif
-  { "extquote", &extended_quote, (shopt_set_func_t *)NULL },
-  { "failglob", &fail_glob_expansion, (shopt_set_func_t *)NULL },
-#if defined (READLINE)
-  { "force_fignore", &force_fignore, (shopt_set_func_t *)NULL },
-#endif
-  { "globstar", &glob_star, (shopt_set_func_t *)NULL },
-  { "gnu_errfmt", &gnu_error_format, (shopt_set_func_t *)NULL },
-#if defined (HISTORY)
-  { "histappend", &force_append_history, (shopt_set_func_t *)NULL },
-#endif
-#if defined (READLINE)
-  { "histreedit", &history_reediting, (shopt_set_func_t *)NULL },
-  { "histverify", &hist_verify, (shopt_set_func_t *)NULL },
-  { "hostcomplete", &perform_hostname_completion, enable_hostname_completion },
-#endif
-  { "huponexit", &hup_on_exit, (shopt_set_func_t *)NULL },
-  { "interactive_comments", &interactive_comments, set_shellopts_after_change },
-#if defined (HISTORY)
-  { "lithist", &literal_history, (shopt_set_func_t *)NULL },
-#endif
-  { "login_shell", &shopt_login_shell, set_login_shell },
-  { "mailwarn", &mail_warning, (shopt_set_func_t *)NULL },
-#if defined (READLINE)
-  { "no_empty_cmd_completion", &no_empty_command_completion, (shopt_set_func_t *)NULL },
-#endif
-  { "nocaseglob", &glob_ignore_case, (shopt_set_func_t *)NULL },
-  { "nocasematch", &match_ignore_case, (shopt_set_func_t *)NULL },
-  { "nullglob",        &allow_null_glob_expansion, (shopt_set_func_t *)NULL },
-#if defined (PROGRAMMABLE_COMPLETION)
-  { "progcomp", &prog_completion_enabled, (shopt_set_func_t *)NULL },
-#endif
-  { "promptvars", &promptvars, (shopt_set_func_t *)NULL },
-#if defined (RESTRICTED_SHELL)
-  { "restricted_shell", &restricted_shell, set_restricted_shell },
-#endif
-  { "shift_verbose", &print_shift_error, (shopt_set_func_t *)NULL },
-  { "sourcepath", &source_uses_path, (shopt_set_func_t *)NULL },
-  { "xpg_echo", &xpg_echo, (shopt_set_func_t *)NULL },
-  { (char *)0, (int *)0, (shopt_set_func_t *)NULL }
-};
-
-#define N_SHOPT_OPTIONS                (sizeof (shopt_vars) / sizeof (shopt_vars[0]))
-
-#define GET_SHOPT_OPTION_VALUE(i)      (*shopt_vars[i].value)
-
-static const char * const on = "on";
-static const char * const off = "off";
-
-static int find_shopt __P((char *));
-static int toggle_shopts __P((int, WORD_LIST *, int));
-static void print_shopt __P((char *, int, int));
-static int list_shopts __P((WORD_LIST *, int));
-static int list_some_shopts __P((int, int));
-static int list_shopt_o_options __P((WORD_LIST *, int));
-static int list_some_o_options __P((int, int));
-static int set_shopt_o_options __P((int, WORD_LIST *, int));
-
-#define SFLAG  0x01
-#define UFLAG  0x02
-#define QFLAG  0x04
-#define OFLAG  0x08
-#define PFLAG  0x10
-
-int
-shopt_builtin (list)
-     WORD_LIST *list;
-{
-  int opt, flags, rval;
-
-  flags = 0;
-  reset_internal_getopt ();
-  while ((opt = internal_getopt (list, "psuoq")) != -1)
-    {
-      switch (opt)
-       {
-       case 's':
-         flags |= SFLAG;
-         break;
-       case 'u':
-         flags |= UFLAG;
-         break;
-       case 'q':
-         flags |= QFLAG;
-         break;
-       case 'o':
-         flags |= OFLAG;
-         break;
-       case 'p':
-         flags |= PFLAG;
-         break;
-       default:
-         builtin_usage ();
-         return (EX_USAGE);
-       }
-    }
-  list = loptend;
-
-  if ((flags & (SFLAG|UFLAG)) == (SFLAG|UFLAG))
-    {
-      builtin_error (_("cannot set and unset shell options simultaneously"));
-      return (EXECUTION_FAILURE);
-    }
-
-  rval = EXECUTION_SUCCESS;
-  if ((flags & OFLAG) && ((flags & (SFLAG|UFLAG)) == 0))       /* shopt -o */
-    rval = list_shopt_o_options (list, flags);
-  else if (list && (flags & OFLAG))            /* shopt -so args */
-    rval = set_shopt_o_options ((flags & SFLAG) ? FLAG_ON : FLAG_OFF, list, flags & QFLAG);
-  else if (flags & OFLAG)      /* shopt -so */
-    rval = list_some_o_options ((flags & SFLAG) ? 1 : 0, flags);
-  else if (list && (flags & (SFLAG|UFLAG)))    /* shopt -su args */
-    rval = toggle_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, list, flags & QFLAG);
-  else if ((flags & (SFLAG|UFLAG)) == 0)       /* shopt [args] */
-    rval = list_shopts (list, flags);
-  else                                         /* shopt -su */
-    rval = list_some_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, flags);
-  return (rval);
-}
-
-/* Reset the options managed by `shopt' to the values they would have at
-   shell startup. */
-void
-reset_shopt_options ()
-{
-  allow_null_glob_expansion = glob_dot_filenames = 0;
-  cdable_vars = mail_warning = 0;
-  no_exit_on_failed_exec = print_shift_error = 0;
-  check_hashed_filenames = cdspelling = expand_aliases = check_window_size = 0;
-
-  source_uses_path = promptvars = 1;
-
-#if defined (EXTENDED_GLOB)
-  extended_glob = 0;
-#endif
-
-#if defined (HISTORY)
-  literal_history = force_append_history = 0;
-  command_oriented_history = 1;
-#endif
-
-#if defined (READLINE)
-  hist_verify = history_reediting = 0;
-  perform_hostname_completion = 1;
-#endif
-
-  shopt_login_shell = login_shell;
-}
-
-static int
-find_shopt (name)
-     char *name;
-{
-  int i;
-
-  for (i = 0; shopt_vars[i].name; i++)
-    if (STREQ (name, shopt_vars[i].name))
-      return i;
-  return -1;
-}
-
-static void
-shopt_error (s)
-     char *s;
-{
-  builtin_error (_("%s: invalid shell option name"), s);
-}
-
-static int
-toggle_shopts (mode, list, quiet)
-     int mode;
-     WORD_LIST *list;
-     int quiet;
-{
-  WORD_LIST *l;
-  int ind, rval;
-
-  for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
-    {
-      ind = find_shopt (l->word->word);
-      if (ind < 0)
-       {
-         shopt_error (l->word->word);
-         rval = EXECUTION_FAILURE;
-       }
-      else
-       {
-         *shopt_vars[ind].value = mode;        /* 1 for set, 0 for unset */
-         if (shopt_vars[ind].set_func)
-           (*shopt_vars[ind].set_func) (mode);
-       }
-    }
-  return (rval);
-}
-
-static void
-print_shopt (name, val, flags)
-     char *name;
-     int val, flags;
-{
-  if (flags & PFLAG)
-    printf ("shopt %s %s\n", val ? "-s" : "-u", name);
-  else
-    printf (OPTFMT, name, val ? on : off);
-}
-
-/* List the values of all or any of the `shopt' options.  Returns 0 if
-   all were listed or all variables queried were on; 1 otherwise. */
-static int
-list_shopts (list, flags)
-     WORD_LIST *list;
-     int flags;
-{
-  WORD_LIST *l;
-  int i, val, rval;
-
-  if (list == 0)
-    {
-      for (i = 0; shopt_vars[i].name; i++)
-       {
-         val = *shopt_vars[i].value;
-         if ((flags & QFLAG) == 0)
-           print_shopt (shopt_vars[i].name, val, flags);
-       }
-      return (sh_chkwrite (EXECUTION_SUCCESS));
-    }
-
-  for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
-    {
-      i = find_shopt (l->word->word);
-      if (i < 0)
-       {
-         shopt_error (l->word->word);
-         rval = EXECUTION_FAILURE;
-         continue;
-       }
-      val = *shopt_vars[i].value;
-      if (val == 0)
-       rval = EXECUTION_FAILURE;
-      if ((flags & QFLAG) == 0)
-       print_shopt (l->word->word, val, flags);
-    }
-
-  return (sh_chkwrite (rval));
-}
-
-static int
-list_some_shopts (mode, flags)
-     int mode, flags;
-{
-  int val, i;
-
-  for (i = 0; shopt_vars[i].name; i++)
-    {
-      val = *shopt_vars[i].value;
-      if (((flags & QFLAG) == 0) && mode == val)
-       print_shopt (shopt_vars[i].name, val, flags);
-    }
-  return (sh_chkwrite (EXECUTION_SUCCESS));
-}
-
-static int
-list_shopt_o_options (list, flags)
-     WORD_LIST *list;
-     int flags;
-{
-  WORD_LIST *l;
-  int val, rval;
-
-  if (list == 0)
-    {
-      if ((flags & QFLAG) == 0)
-       list_minus_o_opts (-1, (flags & PFLAG));
-      return (sh_chkwrite (EXECUTION_SUCCESS));
-    }
-
-  for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
-    {
-      val = minus_o_option_value (l->word->word);
-      if (val == -1)
-       {
-         sh_invalidoptname (l->word->word);
-         rval = EXECUTION_FAILURE;
-         continue;
-       }
-      if (val == 0)
-       rval = EXECUTION_FAILURE;
-      if ((flags & QFLAG) == 0)
-       {
-         if (flags & PFLAG)
-           printf ("set %co %s\n", val ? '-' : '+', l->word->word);
-         else
-           printf (OPTFMT, l->word->word, val ? on : off);
-       }
-    }
-  return (sh_chkwrite (rval));
-}
-
-static int
-list_some_o_options (mode, flags)
-     int mode, flags;
-{
-  if ((flags & QFLAG) == 0)
-    list_minus_o_opts (mode, (flags & PFLAG));
-  return (sh_chkwrite (EXECUTION_SUCCESS));
-}
-
-static int
-set_shopt_o_options (mode, list, quiet)
-     int mode;
-     WORD_LIST *list;
-     int quiet;
-{
-  WORD_LIST *l;
-  int rval;
-
-  for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
-    {
-      if (set_minus_o_option (mode, l->word->word) == EXECUTION_FAILURE)
-       rval = EXECUTION_FAILURE;
-    }
-  set_shellopts ();
-  return rval;
-}
-
-/* If we set or unset interactive_comments with shopt, make sure the
-   change is reflected in $SHELLOPTS. */
-static int
-set_shellopts_after_change (mode)
-     int mode;
-{
-  set_shellopts ();
-  return (0);
-}
-
-static int
-set_compatibility_level (mode)
-     int mode;
-{
-  /* Need to change logic here as we add more compatibility levels */
-  if (shopt_compat31)
-    shell_compatibility_level = 31;
-  else if (shopt_compat32)
-    shell_compatibility_level = 32;
-  else
-    shell_compatibility_level = DEFAULT_COMPAT_LEVEL;
-  return 0;
-}
-
-#if defined (RESTRICTED_SHELL)
-/* Don't allow the value of restricted_shell to be modified. */
-
-static int
-set_restricted_shell (mode)
-     int mode;
-{
-  static int save_restricted = -1;
-
-  if (save_restricted == -1)
-    save_restricted = shell_is_restricted (shell_name);
-
-  restricted_shell = save_restricted;
-  return (0);
-}
-#endif /* RESTRICTED_SHELL */
-
-/* Not static so shell.c can call it to initialize shopt_login_shell */
-int
-set_login_shell (mode)
-     int mode;
-{
-  shopt_login_shell = login_shell != 0;
-  return (0);
-}
-
-char **
-get_shopt_options ()
-{
-  char **ret;
-  int n, i;
-
-  n = sizeof (shopt_vars) / sizeof (shopt_vars[0]);
-  ret = strvec_create (n + 1);
-  for (i = 0; shopt_vars[i].name; i++)
-    ret[i] = savestring (shopt_vars[i].name);
-  ret[i] = (char *)NULL;
-  return ret;
-}
-
-/*
- * External interface for other parts of the shell.  NAME is a string option;
- * MODE is 0 if we want to unset an option; 1 if we want to set an option.
- * REUSABLE is 1 if we want to print output in a form that may be reused.
- */
-int
-shopt_setopt (name, mode)
-     char *name;
-     int mode;
-{
-  WORD_LIST *wl;
-  int r;
-
-  wl = add_string_to_list (name, (WORD_LIST *)NULL);
-  r = toggle_shopts (mode, wl, 0);
-  dispose_words (wl);
-  return r;
-}
-
-int
-shopt_listopt (name, reusable)
-     char *name;
-     int reusable;
-{
-  int i;
-
-  if (name == 0)
-    return (list_shopts ((WORD_LIST *)NULL, reusable ? PFLAG : 0));
-
-  i = find_shopt (name);
-  if (i < 0)
-    {
-      shopt_error (name);
-      return (EXECUTION_FAILURE);
-    }
-
-  print_shopt (name, *shopt_vars[i].value, reusable ? PFLAG : 0);
-  return (sh_chkwrite (EXECUTION_SUCCESS));
-}
-
-void
-set_bashopts ()
-{
-  char *value;
-  char tflag[N_SHOPT_OPTIONS];
-  int vsize, i, vptr, *ip, exported;
-  SHELL_VAR *v;
-
-  for (vsize = i = 0; shopt_vars[i].name; i++)
-    {
-      tflag[i] = 0;
-      if (GET_SHOPT_OPTION_VALUE (i))
-       {
-         vsize += strlen (shopt_vars[i].name) + 1;
-         tflag[i] = 1;
-       }
-    }
-
-  value = (char *)xmalloc (vsize + 1);
-
-  for (i = vptr = 0; shopt_vars[i].name; i++)
-    {
-      if (tflag[i])
-       {
-         strcpy (value + vptr, shopt_vars[i].name);
-         vptr += strlen (shopt_vars[i].name);
-         value[vptr++] = ':';
-       }
-    }
-
-  if (vptr)
-    vptr--;                    /* cut off trailing colon */
-  value[vptr] = '\0';
-
-  v = find_variable ("BASHOPTS");
-
-  /* Turn off the read-only attribute so we can bind the new value, and
-     note whether or not the variable was exported. */
-  if (v)
-    {
-      VUNSETATTR (v, att_readonly);
-      exported = exported_p (v);
-    }
-  else
-    exported = 0;
-
-  v = bind_variable ("BASHOPTS", value, 0);
-
-  /* Turn the read-only attribute back on, and turn off the export attribute
-     if it was set implicitly by mark_modified_vars and SHELLOPTS was not
-     exported before we bound the new value. */
-  VSETATTR (v, att_readonly);
-  if (mark_modified_vars && exported == 0 && exported_p (v))
-    VUNSETATTR (v, att_exported);
-
-  free (value);
-}
-
-void
-parse_bashopts (value)
-     char *value;
-{
-  char *vname;
-  int vptr, ind;
-
-  vptr = 0;
-  while (vname = extract_colon_unit (value, &vptr))
-    {
-      ind = find_shopt (vname);
-      if (ind >= 0)
-        *shopt_vars[ind].value = 1;
-      free (vname);
-    }
-}
-
-void
-initialize_bashopts (no_bashopts)
-     int no_bashopts;
-{
-  char *temp;
-  SHELL_VAR *var;
-
-  if (no_bashopts == 0)
-    {
-      var = find_variable ("BASHOPTS");
-      /* set up any shell options we may have inherited. */
-      if (var && imported_p (var))
-       {
-         temp = (array_p (var) || assoc_p (var)) ? (char *)NULL : savestring (value_cell (var));
-         if (temp)
-           {
-             parse_bashopts (temp);
-             free (temp);
-           }
-       }
-    }
-
-  /* Set up the $BASHOPTS variable. */
-  set_bashopts ();
-}
diff --git a/command.h~ b/command.h~
deleted file mode 100644 (file)
index 3ee8e7f..0000000
+++ /dev/null
@@ -1,384 +0,0 @@
-/* command.h -- The structures used internally to represent commands, and
-   the extern declarations of the functions used to create them. */
-
-/* Copyright (C) 1993-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 (_COMMAND_H_)
-#define _COMMAND_H_
-
-#include "stdc.h"
-
-/* Instructions describing what kind of thing to do for a redirection. */
-enum r_instruction {
-  r_output_direction, r_input_direction, r_inputa_direction,
-  r_appending_to, r_reading_until, r_reading_string,
-  r_duplicating_input, r_duplicating_output, r_deblank_reading_until,
-  r_close_this, r_err_and_out, r_input_output, r_output_force,
-  r_duplicating_input_word, r_duplicating_output_word,
-  r_move_input, r_move_output, r_move_input_word, r_move_output_word,
-  r_append_err_and_out
-};
-
-/* Redirection flags; values for rflags */
-#define REDIR_VARASSIGN                0x01
-
-/* Redirection errors. */
-#define AMBIGUOUS_REDIRECT  -1
-#define NOCLOBBER_REDIRECT  -2
-#define RESTRICTED_REDIRECT -3 /* can only happen in restricted shells. */
-#define HEREDOC_REDIRECT    -4  /* here-doc temp file can't be created */
-#define BADVAR_REDIRECT            -5  /* something wrong with {varname}redir */
-
-#define CLOBBERING_REDIRECT(ri) \
-  (ri == r_output_direction || ri == r_err_and_out)
-
-#define OUTPUT_REDIRECT(ri) \
-  (ri == r_output_direction || ri == r_input_output || ri == r_err_and_out || ri == r_append_err_and_out)
-
-#define INPUT_REDIRECT(ri) \
-  (ri == r_input_direction || ri == r_inputa_direction || ri == r_input_output)
-
-#define WRITE_REDIRECT(ri) \
-  (ri == r_output_direction || \
-       ri == r_input_output || \
-       ri == r_err_and_out || \
-       ri == r_appending_to || \
-       ri == r_append_err_and_out || \
-       ri == r_output_force)
-
-/* redirection needs translation */
-#define TRANSLATE_REDIRECT(ri) \
-  (ri == r_duplicating_input_word || ri == r_duplicating_output_word || \
-   ri == r_move_input_word || ri == r_move_output_word)
-
-/* Command Types: */
-enum command_type { cm_for, cm_case, cm_while, cm_if, cm_simple, cm_select,
-                   cm_connection, cm_function_def, cm_until, cm_group,
-                   cm_arith, cm_cond, cm_arith_for, cm_subshell, cm_coproc };
-
-/* Possible values for the `flags' field of a WORD_DESC. */
-#define W_HASDOLLAR    0x000001        /* Dollar sign present. */
-#define W_QUOTED       0x000002        /* Some form of quote character is present. */
-#define W_ASSIGNMENT   0x000004        /* This word is a variable assignment. */
-#define W_GLOBEXP      0x000008        /* This word is the result of a glob expansion. */
-#define W_NOSPLIT      0x000010        /* Do not perform word splitting on this word. */
-#define W_NOGLOB       0x000020        /* Do not perform globbing on this word. */
-#define W_NOSPLIT2     0x000040        /* Don't split word except for $@ expansion. */
-#define W_TILDEEXP     0x000080        /* Tilde expand this assignment word */
-#define W_DOLLARAT     0x000100        /* $@ and its special handling */
-#define W_DOLLARSTAR   0x000200        /* $* and its special handling */
-#define W_NOCOMSUB     0x000400        /* Don't perform command substitution on this word */
-#define W_ASSIGNRHS    0x000800        /* Word is rhs of an assignment statement */
-#define W_NOTILDE      0x001000        /* Don't perform tilde expansion on this word */
-#define W_ITILDE       0x002000        /* Internal flag for word expansion */
-#define W_NOEXPAND     0x004000        /* Don't expand at all -- do quote removal */
-#define W_COMPASSIGN   0x008000        /* Compound assignment */
-#define W_ASSNBLTIN    0x010000        /* word is a builtin command that takes assignments */
-#define W_ASSIGNARG    0x020000        /* word is assignment argument to command */
-#define W_HASQUOTEDNULL        0x040000        /* word contains a quoted null character */
-#define W_DQUOTE       0x080000        /* word should be treated as if double-quoted */
-#define W_NOPROCSUB    0x100000        /* don't perform process substitution */
-#define W_HASCTLESC    0x200000        /* word contains literal CTLESC characters */
-#define W_ASSIGNASSOC  0x400000        /* word looks like associative array assignment */
-
-/* Possible values for subshell_environment */
-#define SUBSHELL_ASYNC 0x01    /* subshell caused by `command &' */
-#define SUBSHELL_PAREN 0x02    /* subshell caused by ( ... ) */
-#define SUBSHELL_COMSUB        0x04    /* subshell caused by `command` or $(command) */
-#define SUBSHELL_FORK  0x08    /* subshell caused by executing a disk command */
-#define SUBSHELL_PIPE  0x10    /* subshell from a pipeline element */
-#define SUBSHELL_PROCSUB 0x20  /* subshell caused by <(command) or >(command) */
-#define SUBSHELL_COPROC        0x40    /* subshell from a coproc pipeline */
-
-/* A structure which represents a word. */
-typedef struct word_desc {
-  char *word;          /* Zero terminated string. */
-  int flags;           /* Flags associated with this word. */
-} WORD_DESC;
-
-/* A linked list of words. */
-typedef struct word_list {
-  struct word_list *next;
-  WORD_DESC *word;
-} WORD_LIST;
-
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Shell Command Structs                       */
-/*                                                                 */
-/* **************************************************************** */
-
-/* What a redirection descriptor looks like.  If the redirection instruction
-   is ri_duplicating_input or ri_duplicating_output, use DEST, otherwise
-   use the file in FILENAME.  Out-of-range descriptors are identified by a
-   negative DEST. */
-
-typedef union {
-  int dest;                    /* Place to redirect REDIRECTOR to, or ... */
-  WORD_DESC *filename;         /* filename to redirect to. */
-} REDIRECTEE;
-
-/* Structure describing a redirection.  If REDIRECTOR is negative, the parser
-   (or translator in redir.c) encountered an out-of-range file descriptor. */
-typedef struct redirect {
-  struct redirect *next;       /* Next element, or NULL. */
-  REDIRECTEE redirector;       /* Descriptor or varname to be redirected. */
-  int rflags;                  /* Private flags for this redirection */
-  int flags;                   /* Flag value for `open'. */
-  enum r_instruction  instruction; /* What to do with the information. */
-  REDIRECTEE redirectee;       /* File descriptor or filename */
-  char *here_doc_eof;          /* The word that appeared in <<foo. */
-} REDIRECT;
-
-/* An element used in parsing.  A single word or a single redirection.
-   This is an ephemeral construct. */
-typedef struct element {
-  WORD_DESC *word;
-  REDIRECT *redirect;
-} ELEMENT;
-
-/* Possible values for command->flags. */
-#define CMD_WANT_SUBSHELL  0x01        /* User wants a subshell: ( command ) */
-#define CMD_FORCE_SUBSHELL 0x02        /* Shell needs to force a subshell. */
-#define CMD_INVERT_RETURN  0x04        /* Invert the exit value. */
-#define CMD_IGNORE_RETURN  0x08        /* Ignore the exit value.  For set -e. */
-#define CMD_NO_FUNCTIONS   0x10 /* Ignore functions during command lookup. */
-#define CMD_INHIBIT_EXPANSION 0x20 /* Do not expand the command words. */
-#define CMD_NO_FORK       0x40 /* Don't fork; just call execve */
-#define CMD_TIME_PIPELINE  0x80 /* Time a pipeline */
-#define CMD_TIME_POSIX    0x100 /* time -p; use POSIX.2 time output spec. */
-#define CMD_AMPERSAND     0x200 /* command & */
-#define CMD_STDIN_REDIR           0x400 /* async command needs implicit </dev/null */
-#define CMD_COMMAND_BUILTIN 0x0800 /* command executed by `command' builtin */
-#define CMD_COPROC_SUBSHELL 0x1000
-
-/* What a command looks like. */
-typedef struct command {
-  enum command_type type;      /* FOR CASE WHILE IF CONNECTION or SIMPLE. */
-  int flags;                   /* Flags controlling execution environment. */
-  int line;                    /* line number the command starts on */
-  REDIRECT *redirects;         /* Special redirects for FOR CASE, etc. */
-  union {
-    struct for_com *For;
-    struct case_com *Case;
-    struct while_com *While;
-    struct if_com *If;
-    struct connection *Connection;
-    struct simple_com *Simple;
-    struct function_def *Function_def;
-    struct group_com *Group;
-#if defined (SELECT_COMMAND)
-    struct select_com *Select;
-#endif
-#if defined (DPAREN_ARITHMETIC)
-    struct arith_com *Arith;
-#endif
-#if defined (COND_COMMAND)
-    struct cond_com *Cond;
-#endif
-#if defined (ARITH_FOR_COMMAND)
-    struct arith_for_com *ArithFor;
-#endif
-    struct subshell_com *Subshell;
-    struct coproc_com *Coproc;
-  } value;
-} COMMAND;
-
-/* Structure used to represent the CONNECTION type. */
-typedef struct connection {
-  int ignore;                  /* Unused; simplifies make_command (). */
-  COMMAND *first;              /* Pointer to the first command. */
-  COMMAND *second;             /* Pointer to the second command. */
-  int connector;               /* What separates this command from others. */
-} CONNECTION;
-
-/* Structures used to represent the CASE command. */
-
-/* Values for FLAGS word in a PATTERN_LIST */
-#define CASEPAT_FALLTHROUGH    0x01
-#define CASEPAT_TESTNEXT       0x02
-
-/* Pattern/action structure for CASE_COM. */
-typedef struct pattern_list {
-  struct pattern_list *next;   /* Clause to try in case this one failed. */
-  WORD_LIST *patterns;         /* Linked list of patterns to test. */
-  COMMAND *action;             /* Thing to execute if a pattern matches. */
-  int flags;
-} PATTERN_LIST;
-
-/* The CASE command. */
-typedef struct case_com {
-  int flags;                   /* See description of CMD flags. */
-  int line;                    /* line number the `case' keyword appears on */
-  WORD_DESC *word;             /* The thing to test. */
-  PATTERN_LIST *clauses;       /* The clauses to test against, or NULL. */
-} CASE_COM;
-
-/* FOR command. */
-typedef struct for_com {
-  int flags;           /* See description of CMD flags. */
-  int line;            /* line number the `for' keyword appears on */
-  WORD_DESC *name;     /* The variable name to get mapped over. */
-  WORD_LIST *map_list; /* The things to map over.  This is never NULL. */
-  COMMAND *action;     /* The action to execute.
-                          During execution, NAME is bound to successive
-                          members of MAP_LIST. */
-} FOR_COM;
-
-#if defined (ARITH_FOR_COMMAND)
-typedef struct arith_for_com {
-  int flags;
-  int line;    /* generally used for error messages */
-  WORD_LIST *init;
-  WORD_LIST *test;
-  WORD_LIST *step;
-  COMMAND *action;
-} ARITH_FOR_COM;
-#endif
-
-#if defined (SELECT_COMMAND)
-/* KSH SELECT command. */
-typedef struct select_com {
-  int flags;           /* See description of CMD flags. */
-  int line;            /* line number the `select' keyword appears on */
-  WORD_DESC *name;     /* The variable name to get mapped over. */
-  WORD_LIST *map_list; /* The things to map over.  This is never NULL. */
-  COMMAND *action;     /* The action to execute.
-                          During execution, NAME is bound to the member of
-                          MAP_LIST chosen by the user. */
-} SELECT_COM;
-#endif /* SELECT_COMMAND */
-
-/* IF command. */
-typedef struct if_com {
-  int flags;                   /* See description of CMD flags. */
-  COMMAND *test;               /* Thing to test. */
-  COMMAND *true_case;          /* What to do if the test returned non-zero. */
-  COMMAND *false_case;         /* What to do if the test returned zero. */
-} IF_COM;
-
-/* WHILE command. */
-typedef struct while_com {
-  int flags;                   /* See description of CMD flags. */
-  COMMAND *test;               /* Thing to test. */
-  COMMAND *action;             /* Thing to do while test is non-zero. */
-} WHILE_COM;
-
-#if defined (DPAREN_ARITHMETIC)
-/* The arithmetic evaluation command, ((...)).  Just a set of flags and
-   a WORD_LIST, of which the first element is the only one used, for the
-   time being. */
-typedef struct arith_com {
-  int flags;
-  int line;
-  WORD_LIST *exp;
-} ARITH_COM;
-#endif /* DPAREN_ARITHMETIC */
-
-/* The conditional command, [[...]].  This is a binary tree -- we slippped
-   a recursive-descent parser into the YACC grammar to parse it. */
-#define COND_AND       1
-#define COND_OR                2
-#define COND_UNARY     3
-#define COND_BINARY    4
-#define COND_TERM      5
-#define COND_EXPR      6
-
-typedef struct cond_com {
-  int flags;
-  int line;
-  int type;
-  WORD_DESC *op;
-  struct cond_com *left, *right;
-} COND_COM;
-
-/* The "simple" command.  Just a collection of words and redirects. */
-typedef struct simple_com {
-  int flags;                   /* See description of CMD flags. */
-  int line;                    /* line number the command starts on */
-  WORD_LIST *words;            /* The program name, the arguments,
-                                  variable assignments, etc. */
-  REDIRECT *redirects;         /* Redirections to perform. */
-} SIMPLE_COM;
-
-/* The "function definition" command. */
-typedef struct function_def {
-  int flags;                   /* See description of CMD flags. */
-  int line;                    /* Line number the function def starts on. */
-  WORD_DESC *name;             /* The name of the function. */
-  COMMAND *command;            /* The parsed execution tree. */
-  char *source_file;           /* file in which function was defined, if any */
-} FUNCTION_DEF;
-
-/* A command that is `grouped' allows pipes and redirections to affect all
-   commands in the group. */
-typedef struct group_com {
-  int ignore;                  /* See description of CMD flags. */
-  COMMAND *command;
-} GROUP_COM;
-
-typedef struct subshell_com {
-  int flags;
-  COMMAND *command;
-} SUBSHELL_COM;
-
-#define COPROC_RUNNING 0x01
-#define COPROC_DEAD    0x02
-
-typedef struct coproc {
-  char *c_name;
-  pid_t c_pid;
-  int c_rfd;
-  int c_wfd;
-  int c_rsave;
-  int c_wsave;
-  int c_flags;
-  int c_status;
-} Coproc;
-
-typedef struct coproc_com {
-  int flags;
-  char *name;
-  COMMAND *command;
-} COPROC_COM;
-
-extern COMMAND *global_command;
-extern Coproc sh_coproc;
-
-/* Possible command errors */
-#define CMDERR_DEFAULT 0
-#define CMDERR_BADTYPE 1
-#define CMDERR_BADCONN 2
-#define CMDERR_BADJUMP 3
-
-#define CMDERR_LAST    3
-
-/* Forward declarations of functions declared in copy_cmd.c. */
-
-extern FUNCTION_DEF *copy_function_def_contents __P((FUNCTION_DEF *, FUNCTION_DEF *));
-extern FUNCTION_DEF *copy_function_def __P((FUNCTION_DEF *));
-
-extern WORD_DESC *copy_word __P((WORD_DESC *));
-extern WORD_LIST *copy_word_list __P((WORD_LIST *));
-extern REDIRECT *copy_redirect __P((REDIRECT *));
-extern REDIRECT *copy_redirects __P((REDIRECT *));
-extern COMMAND *copy_command __P((COMMAND *));
-
-#endif /* _COMMAND_H_ */
diff --git a/config-bot.h~ b/config-bot.h~
deleted file mode 100644 (file)
index 6363a4f..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-/* config-bot.h */
-/* modify settings or make new ones based on what autoconf tells us. */
-
-/* Copyright (C) 1989-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/>.
-*/
-
-/*********************************************************/
-/* Modify or set defines based on the configure results. */
-/*********************************************************/
-
-#if !defined (HAVE_VPRINTF) && defined (HAVE_DOPRNT)
-#  define USE_VFPRINTF_EMULATION
-#  define HAVE_VPRINTF
-#endif
-
-#if defined (HAVE_SYS_RESOURCE_H) && defined (HAVE_GETRLIMIT)
-#  define HAVE_RESOURCE
-#endif
-
-#if !defined (GETPGRP_VOID)
-#  define HAVE_BSD_PGRP
-#endif
-
-/* Try this without testing __STDC__ for the time being. */
-#if defined (HAVE_STDARG_H)
-#  define PREFER_STDARG
-#  define USE_VARARGS
-#else
-#  if defined (HAVE_VARARGS_H)
-#    define PREFER_VARARGS
-#    define USE_VARARGS
-#  endif
-#endif
-
-#if defined (HAVE_SYS_SOCKET_H) && defined (HAVE_GETPEERNAME) && defined (HAVE_NETINET_IN_H)
-#  define HAVE_NETWORK
-#endif
-
-#if defined (HAVE_REGEX_H) && defined (HAVE_REGCOMP) && defined (HAVE_REGEXEC)
-#  define HAVE_POSIX_REGEXP
-#endif
-
-/* backwards compatibility between different autoconf versions */
-#if HAVE_DECL_SYS_SIGLIST && !defined (SYS_SIGLIST_DECLARED)
-#  define SYS_SIGLIST_DECLARED
-#endif
-
-/***********************************************************************/
-/* Unset defines based on what configure reports as missing or broken. */
-/***********************************************************************/
-
-/* Ultrix botches type-ahead when switching from canonical to
-   non-canonical mode, at least through version 4.3 */
-#if !defined (HAVE_TERMIOS_H) || !defined (HAVE_TCGETATTR) || defined (ultrix)
-#  define TERMIOS_MISSING
-#endif
-
-/* If we have a getcwd(3), but one that does not dynamically allocate memory,
-   #undef HAVE_GETCWD so the replacement in getcwd.c will be built.  We do
-   not do this on Solaris, because their implementation of loopback mounts
-   breaks the traditional file system assumptions that getcwd uses. */
-#if defined (HAVE_GETCWD) && defined (GETCWD_BROKEN) && !defined (SOLARIS)
-#  undef HAVE_GETCWD
-#endif
-
-#if !defined (HAVE_DEV_FD) && defined (NAMED_PIPES_MISSING)
-#  undef PROCESS_SUBSTITUTION
-#endif
-
-#if defined (JOB_CONTROL_MISSING)
-#  undef JOB_CONTROL
-#endif
-
-#if defined (STRCOLL_BROKEN)
-#  undef HAVE_STRCOLL
-#endif
-
-#if !defined (HAVE_POSIX_REGEXP)
-#  undef COND_REGEXP
-#endif
-
-/* If the shell is called by this name, it will become restricted. */
-#if defined (RESTRICTED_SHELL)
-#  define RESTRICTED_SHELL_NAME "rbash"
-#endif
-
-/***********************************************************/
-/* Make sure feature defines have necessary prerequisites. */
-/***********************************************************/
-
-/* BANG_HISTORY requires HISTORY. */
-#if defined (BANG_HISTORY) && !defined (HISTORY)
-#  define HISTORY
-#endif /* BANG_HISTORY && !HISTORY */
-
-#if defined (READLINE) && !defined (HISTORY)
-#  define HISTORY
-#endif
-
-#if defined (PROGRAMMABLE_COMPLETION) && !defined (READLINE)
-#  undef PROGRAMMABLE_COMPLETION
-#endif
-
-#if !defined (V9_ECHO)
-#  undef DEFAULT_ECHO_TO_XPG
-#endif
-
-#if !defined (PROMPT_STRING_DECODE)
-#  undef PPROMPT
-#  define PPROMPT "$ "
-#endif
-
-/************************************************/
-/* check multibyte capability for I18N code    */
-/************************************************/
-
-/* For platforms which support the ISO C amendement 1 functionality we
-   support user defined character classes.  */
-/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>.  */
-#if defined (HAVE_WCTYPE_H) && defined (HAVE_WCHAR_H) && defined (HAVE_LOCALE_H)
-#  include <wchar.h>
-#  include <wctype.h>
-#  if defined (HAVE_ISWCTYPE) && \
-      defined (HAVE_ISWLOWER) && \
-      defined (HAVE_ISWUPPER) && \
-      defined (HAVE_MBSRTOWCS) && \
-      defined (HAVE_MBRTOWC) && \
-      defined (HAVE_MBRLEN) && \
-      defined (HAVE_TOWLOWER) && \
-      defined (HAVE_TOWUPPER) && \
-      defined (HAVE_WCHAR_T) && \
-      defined (HAVE_WCTYPE_T) && \
-      defined (HAVE_WINT_T) && \
-      defined (HAVE_WCWIDTH) && \
-      defined (HAVE_WCTYPE)
-     /* system is supposed to support XPG5 */
-#    define HANDLE_MULTIBYTE      1
-#  endif
-#endif
-
-/* If we don't want multibyte chars even on a system that supports them, let
-   the configuring user turn multibyte support off. */
-#if defined (NO_MULTIBYTE_SUPPORT)
-#  undef HANDLE_MULTIBYTE
-#endif
-
-/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t.  */
-#if HANDLE_MULTIBYTE && !defined (HAVE_MBSTATE_T)
-#  define wcsrtombs(dest, src, len, ps) (wcsrtombs) (dest, src, len, 0)
-#  define mbsrtowcs(dest, src, len, ps) (mbsrtowcs) (dest, src, len, 0)
-#  define wcrtomb(s, wc, ps) (wcrtomb) (s, wc, 0)
-#  define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
-#  define mbrlen(s, n, ps) (mbrlen) (s, n, 0)
-#  define mbstate_t int
-#endif
-
-/* Make sure MB_LEN_MAX is at least 16 (some systems define
-   MB_LEN_MAX as 1) */
-#ifdef HANDLE_MULTIBYTE
-#  include <limits.h>
-#  if defined(MB_LEN_MAX) && (MB_LEN_MAX < 16)
-#    undef MB_LEN_MAX
-#  endif
-#  if !defined (MB_LEN_MAX)
-#    define MB_LEN_MAX 16
-#  endif
-#endif
-
-/************************************************/
-/* end of multibyte capability checks for I18N */
-/************************************************/
-
-/******************************************************************/
-/* Placeholder for builders to #undef any unwanted features from  */
-/* config-top.h or created by configure (such as the default mail */
-/* file for mail checking).                                      */
-/******************************************************************/
-
-/* If you don't want bash to provide a default mail file to check. */
-/* #undef DEFAULT_MAIL_DIRECTORY */
diff --git a/config-top.h~ b/config-top.h~
deleted file mode 100644 (file)
index 406bffb..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/* config-top.h - various user-settable options not under the control of autoconf. */
-
-/* Copyright (C) 2002-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/>.
-*/
-
-/* Define CONTINUE_AFTER_KILL_ERROR if you want the kill command to
-   continue processing arguments after one of them fails.  This is
-   what POSIX.2 specifies. */
-#define CONTINUE_AFTER_KILL_ERROR
-
-/* Define BREAK_COMPLAINS if you want the non-standard, but useful
-   error messages about `break' and `continue' out of context. */
-#define BREAK_COMPLAINS
-
-/* Define BUFFERED_INPUT if you want the shell to do its own input
-   buffering, rather than using stdio.  Do not undefine this; it's
-   required to preserve semantics required by POSIX. */
-#define BUFFERED_INPUT
-
-/* Define ONESHOT if you want sh -c 'command' to avoid forking to execute
-   `command' whenever possible.  This is a big efficiency improvement. */
-#define ONESHOT
-
-/* Define V9_ECHO if you want to give the echo builtin backslash-escape
-   interpretation using the -e option, in the style of the Bell Labs 9th
-   Edition version of echo.  You cannot emulate the System V echo behavior
-   without this option. */
-#define V9_ECHO
-
-/* Define DONT_REPORT_SIGPIPE if you don't want to see `Broken pipe' messages
-   when a job like `cat jobs.c | exit 1' terminates due to a SIGPIPE. */
-#define DONT_REPORT_SIGPIPE
-
-/* Define DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS if you don't want builtins
-   like `echo' and `printf' to report errors when output does not succeed
-   due to EPIPE. */
-/* #define DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS */
-
-/* The default value of the PATH variable. */
-#ifndef DEFAULT_PATH_VALUE
-#define DEFAULT_PATH_VALUE \
-  "/usr/gnu/bin:/usr/local/bin:/bin:/usr/bin:."
-#endif
-
-/* The value for PATH when invoking `command -p'.  This is only used when
-   the Posix.2 confstr () function, or CS_PATH define are not present. */
-#ifndef STANDARD_UTILS_PATH
-#define STANDARD_UTILS_PATH \
-  "/bin:/usr/bin:/sbin:/usr/sbin:/etc:/usr/etc"
-#endif
-
-/* Default primary and secondary prompt strings. */
-#define PPROMPT "\\s-\\v\\$ "
-#define SPROMPT "> "
-
-/* Undefine this if you don't want the ksh-compatible behavior of reprinting
-   the select menu after a valid choice is made only if REPLY is set to NULL
-   in the body of the select command.  The menu is always reprinted if the
-   reply to the select query is an empty line. */
-#define KSH_COMPATIBLE_SELECT
-
-/* System-wide .bashrc file for interactive shells. */
-/* #define SYS_BASHRC "/etc/bash.bashrc" */
-
-/* System-wide .bash_logout for login shells. */
-/* #define SYS_BASH_LOGOUT "/etc/bash.bash_logout" */
-
-/* Define this to make non-interactive shells begun with argv[0][0] == '-'
-   run the startup files when not in posix mode. */
-/* #define NON_INTERACTIVE_LOGIN_SHELLS */
-
-/* Define this if you want bash to try to check whether it's being run by
-   sshd and source the .bashrc if so (like the rshd behavior).  This checks
-   for the presence of SSH_CLIENT or SSH2_CLIENT in the initial environment,
-   which can be fooled under certain not-uncommon circumstances. */
-/* #define SSH_SOURCE_BASHRC */
-
-/* Define if you want the case-capitalizing operators (~[~]) and the
-   `capcase' variable attribute (declare -c). */
-#define  CASEMOD_CAPCASE
-
-/* This is used as the name of a shell function to call when a command
-   name is not found.  If you want to name it something other than the
-   default ("command_not_found_handle"), change it here. */
-/* #define NOTFOUND_HOOK "command_not_found_handle" */
-
-/* Define if you want each line saved to the history list in bashhist.c:
-   bash_add_history() to be sent to syslog(). */
-/* #define SYSLOG_HISTORY */
-/* #define SYSLOG_FACILITY LOG_USER */
-/* #define SYSLOG_LEVEL LOG_INFO */
diff --git a/config.h.in~ b/config.h.in~
deleted file mode 100644 (file)
index 5f28b50..0000000
+++ /dev/null
@@ -1,1107 +0,0 @@
-/* config.h -- Configuration file for bash. */
-
-/* Copyright (C) 1987-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/>.
-*/
-
-#ifndef _CONFIG_H_
-#define _CONFIG_H_
-
-/* Configuration feature settings controllable by autoconf. */
-
-/* Define JOB_CONTROL if your operating system supports
-   BSD-like job control. */
-#undef JOB_CONTROL
-
-/* Define ALIAS if you want the alias features. */
-#undef ALIAS
-
-/* Define PUSHD_AND_POPD if you want those commands to be compiled in.
-   (Also the `dirs' commands.) */
-#undef PUSHD_AND_POPD
-
-/* Define BRACE_EXPANSION if you want curly brace expansion a la Csh:
-   foo{a,b} -> fooa foob.  Even if this is compiled in (the default) you
-   can turn it off at shell startup with `-nobraceexpansion', or during
-   shell execution with `set +o braceexpand'. */
-#undef BRACE_EXPANSION
-
-/* Define READLINE to get the nifty/glitzy editing features.
-   This is on by default.  You can turn it off interactively
-   with the -nolineediting flag. */
-#undef READLINE
-
-/* Define BANG_HISTORY if you want to have Csh style "!" history expansion.
-   This is unrelated to READLINE. */
-#undef BANG_HISTORY
-
-/* Define HISTORY if you want to have access to previously typed commands.
-
-   If both HISTORY and READLINE are defined, you can get at the commands
-   with line editing commands, and you can directly manipulate the history
-   from the command line.
-
-   If only HISTORY is defined, the `fc' and `history' builtins are
-   available. */
-#undef HISTORY
-
-/* Define this if you want completion that puts all alternatives into
-   a brace expansion shell expression. */
-#if defined (BRACE_EXPANSION) && defined (READLINE)
-#  define BRACE_COMPLETION
-#endif /* BRACE_EXPANSION */
-
-/* Define DEFAULT_ECHO_TO_XPG if you want the echo builtin to interpret
-   the backslash-escape characters by default, like the XPG Single Unix
-   Specification V2 for echo.
-   This requires that V9_ECHO be defined. */
-#undef DEFAULT_ECHO_TO_XPG
-
-/* Define HELP_BUILTIN if you want the `help' shell builtin and the long
-   documentation strings compiled into the shell. */
-#undef HELP_BUILTIN
-
-/* Define RESTRICTED_SHELL if you want the generated shell to have the
-   ability to be a restricted one.  The shell thus generated can become
-   restricted by being run with the name "rbash", or by setting the -r
-   flag. */
-#undef RESTRICTED_SHELL
-
-/* Define DISABLED_BUILTINS if you want "builtin foo" to always run the
-   shell builtin "foo", even if it has been disabled with "enable -n foo". */
-#undef DISABLED_BUILTINS
-
-/* Define PROCESS_SUBSTITUTION if you want the K*rn shell-like process
-   substitution features "<(file)". */
-/* Right now, you cannot do this on machines without fully operational
-   FIFO support.  This currently include NeXT and Alliant. */
-#undef PROCESS_SUBSTITUTION
-
-/* Define PROMPT_STRING_DECODE if you want the backslash-escaped special
-   characters in PS1 and PS2 expanded.  Variable expansion will still be
-   performed. */
-#undef PROMPT_STRING_DECODE
-
-/* Define SELECT_COMMAND if you want the Korn-shell style `select' command:
-       select word in word_list; do command_list; done */
-#undef SELECT_COMMAND
-
-/* Define COMMAND_TIMING of you want the ksh-style `time' reserved word and
-   the ability to time pipelines, functions, and builtins. */
-#undef COMMAND_TIMING
-
-/* Define ARRAY_VARS if you want ksh-style one-dimensional array variables. */
-#undef ARRAY_VARS
-
-/* Define DPAREN_ARITHMETIC if you want the ksh-style ((...)) arithmetic
-   evaluation command. */
-#undef DPAREN_ARITHMETIC
-
-/* Define EXTENDED_GLOB if you want the ksh-style [*+@?!](patlist) extended
-   pattern matching. */
-#undef EXTENDED_GLOB
-
-/* Define EXTGLOB_DEFAULT to the value you'd like the extglob shell option
-   to have by default */
-#undef EXTGLOB_DEFAULT
-
-/* Define COND_COMMAND if you want the ksh-style [[...]] conditional
-   command. */
-#undef COND_COMMAND
-
-/* Define COND_REGEXP if you want extended regular expression matching and the
-   =~ binary operator in the [[...]] conditional command. */
-#define COND_REGEXP
-
-/* Define COPROCESS_SUPPORT if you want support for ksh-like coprocesses and
-   the `coproc' reserved word */
-#define COPROCESS_SUPPORT
-
-/* Define ARITH_FOR_COMMAND if you want the ksh93-style
-       for (( init; test; step )) do list; done
-   arithmetic for command. */
-#undef ARITH_FOR_COMMAND
-
-/* Define NETWORK_REDIRECTIONS if you want /dev/(tcp|udp)/host/port to open
-   socket connections when used in redirections */
-#undef NETWORK_REDIRECTIONS
-
-/* Define PROGRAMMABLE_COMPLETION for the programmable completion features
-   and the complete builtin. */
-#undef PROGRAMMABLE_COMPLETION
-
-/* Define NO_MULTIBYTE_SUPPORT to not compile in support for multibyte
-   characters, even if the OS supports them. */
-#undef NO_MULTIBYTE_SUPPORT
-
-/* Define DEBUGGER if you want to compile in some features used only by the 
-   bash debugger. */
-#undef DEBUGGER
-
-/* Define STRICT_POSIX if you want bash to be strictly posix.2 conformant by
-   default (except for echo; that is controlled separately). */
-#undef STRICT_POSIX
-
-/* Define MEMSCRAMBLE if you want the bash malloc and free to scramble
-   memory contents on malloc() and free(). */
-#undef MEMSCRAMBLE
-
-/* Define AFS if you are using Transarc's AFS. */
-#undef AFS
-
-/* Define for case-modifying variable attributes; variables modified on
-   assignment */
-#undef CASEMOD_ATTRS
-
-/* Define for case-modifying word expansions */
-#undef CASEMOD_EXPANSIONS
-
-#undef ENABLE_NLS
-
-/* End of configuration settings controllable by autoconf. */
-/* Other settable options appear in config-top.h. */
-
-#include "config-top.h"
-
-/* Beginning of autoconf additions. */
-
-/* Characteristics of the C compiler */
-#undef const
-
-#undef inline
-
-#undef restrict
-
-#undef volatile
-
-/* Define if cpp supports the ANSI-C stringizing `#' operator */
-#undef HAVE_STRINGIZE
-
-/* Define if the compiler supports `long double' variables. */
-#undef HAVE_LONG_DOUBLE
-
-#undef PROTOTYPES
-
-#undef __CHAR_UNSIGNED__
-
-/* Define if the compiler supports `long long' variables. */
-#undef HAVE_LONG_LONG
-
-#undef HAVE_UNSIGNED_LONG_LONG
-
-/* The number of bytes in a int.  */
-#undef SIZEOF_INT
-
-/* The number of bytes in a long.  */
-#undef SIZEOF_LONG
-
-/* The number of bytes in a pointer to char.  */
-#undef SIZEOF_CHAR_P
-
-/* The number of bytes in a double (hopefully 8). */
-#undef SIZEOF_DOUBLE
-
-/* The number of bytes in a `long long', if we have one. */
-#undef SIZEOF_LONG_LONG
-
-/* System paths */
-
-#define DEFAULT_MAIL_DIRECTORY "/usr/spool/mail"
-
-/* Characteristics of the system's header files and libraries that affect
-   the compilation environment. */
-
-/* Define if the system does not provide POSIX.1 features except
-   with this defined.  */
-#undef _POSIX_1_SOURCE
-
-/* Define if you need to in order for stat and other things to work.  */
-#undef _POSIX_SOURCE
-
-/* Define to use GNU libc extensions */
-#undef _GNU_SOURCE
-
-/* Define if you have the ANSI C header files.  */
-#undef STDC_HEADERS
-
-/* Memory management functions. */
-
-/* Define if using the bash version of malloc in lib/malloc/malloc.c */
-#undef USING_BASH_MALLOC
-
-#undef DISABLE_MALLOC_WRAPPERS
-
-/* Define if using alloca.c.  */
-#undef C_ALLOCA
-
-/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
-   This function is required for alloca.c support on those systems.  */
-#undef CRAY_STACKSEG_END
-
-/* Define if you have alloca, as a function or macro.  */
-#undef HAVE_ALLOCA
-
-/* Define if you have <alloca.h> and it should be used (not on Ultrix).  */
-#undef HAVE_ALLOCA_H
-
-
-/* SYSTEM TYPES */
-
-/* Define to `long' if <sys/types.h> doesn't define.  */
-#undef off_t
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-#undef mode_t
-
-/* Define to `int' if <signal.h> doesn't define. */
-#undef sigset_t
-
-/* Define to `int' if <sys/types.h> doesn't define.  */
-#undef pid_t
-
-/* Define to `short' if <sys/types.h> doesn't define.  */
-#undef bits16_t
-
-/* Define to `unsigned short' if <sys/types.h> doesn't define.  */
-#undef u_bits16_t
-
-/* Define to `int' if <sys/types.h> doesn't define.  */
-#undef bits32_t
-
-/* Define to `unsigned int' if <sys/types.h> doesn't define.  */
-#undef u_bits32_t
-
-/* Define to `double' if <sys/types.h> doesn't define. */
-#undef bits64_t
-
-/* Define to `unsigned int' if <sys/types.h> doesn't define. */
-#undef u_int
-
-/* Define to `unsigned long' if <sys/types.h> doesn't define.  */
-#undef u_long
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-#undef ptrdiff_t
-
-/* Define to `unsigned' if <sys/types.h> doesn't define.  */
-#undef size_t
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-#undef ssize_t
-
-/* Define to `long' if <stdint.h> doesn't define. */
-#undef intmax_t
-
-/* Define to `unsigned long' if <stdint.h> doesn't define. */
-#undef uintmax_t
-/* Define to `int' if <sys/types.h> doesn't define.  */
-#undef uid_t
-
-/* Define to `long' if <sys/types.h> doesn't define.  */
-#undef clock_t
-
-/* Define to `long' if <sys/types.h> doesn't define.  */
-#undef time_t
-
-/* Define to `int' if <sys/types.h> doesn't define.  */
-#undef gid_t
-
-/* Define to `unsigned int' if <sys/socket.h> doesn't define. */
-#undef socklen_t
-
-/* Define to `int' if <signal.h> doesn't define. */
-#undef sig_atomic_t
-
-#undef HAVE_MBSTATE_T
-
-/* Define if you have quad_t in <sys/types.h>. */
-#undef HAVE_QUAD_T
-
-/* Define if you have wchar_t in <wctype.h>. */
-#undef HAVE_WCHAR_T
-
-/* Define if you have wctype_t in <wctype.h>. */
-#undef HAVE_WCTYPE_T
-
-/* Define if you have wint_t in <wctype.h>. */
-#undef HAVE_WINT_T
-
-#undef RLIMTYPE
-
-/* Define to the type of elements in the array set by `getgroups'.
-   Usually this is either `int' or `gid_t'.  */
-#undef GETGROUPS_T
-
-/* Characteristics of the machine archictecture. */
-
-/* If using the C implementation of alloca, define if you know the
-   direction of stack growth for your system; otherwise it will be
-   automatically deduced at run-time.
-       STACK_DIRECTION > 0 => grows toward higher addresses
-       STACK_DIRECTION < 0 => grows toward lower addresses
-       STACK_DIRECTION = 0 => direction of growth unknown
- */
-#undef STACK_DIRECTION
-
-/* Define if the machine architecture is big-endian. */
-#undef WORDS_BIGENDIAN
-
-/* Check for the presence of certain non-function symbols in the system
-   libraries. */
-
-/* Define if `sys_siglist' is declared by <signal.h> or <unistd.h>.  */
-#undef HAVE_DECL_SYS_SIGLIST
-#undef SYS_SIGLIST_DECLARED
-
-/* Define if `_sys_siglist' is declared by <signal.h> or <unistd.h>.  */
-#undef UNDER_SYS_SIGLIST_DECLARED
-
-#undef HAVE_SYS_SIGLIST
-
-#undef HAVE_UNDER_SYS_SIGLIST
-
-#undef HAVE_SYS_ERRLIST
-
-#undef HAVE_TZNAME
-#undef HAVE_DECL_TZNAME
-
-/* Characteristics of some of the system structures. */
-
-#undef HAVE_STRUCT_DIRENT_D_INO
-
-#undef HAVE_STRUCT_DIRENT_D_FILENO
-
-#undef HAVE_STRUCT_DIRENT_D_NAMLEN
-
-#undef TIOCSTAT_IN_SYS_IOCTL
-
-#undef FIONREAD_IN_SYS_IOCTL
-
-#undef GWINSZ_IN_SYS_IOCTL
-
-#undef STRUCT_WINSIZE_IN_SYS_IOCTL
-
-#undef TM_IN_SYS_TIME
-
-#undef STRUCT_WINSIZE_IN_TERMIOS
-
-#undef SPEED_T_IN_SYS_TYPES
-
-#undef TERMIOS_LDISC
-
-#undef TERMIO_LDISC
-
-#undef HAVE_STRUCT_STAT_ST_BLOCKS
-
-#undef HAVE_STRUCT_TM_TM_ZONE
-#undef HAVE_TM_ZONE
-
-#undef HAVE_TIMEVAL
-
-#undef HAVE_STRUCT_TIMEZONE
-
-/* Characteristics of definitions in the system header files. */
-
-#undef HAVE_GETPW_DECLS
-
-#undef HAVE_RESOURCE
-
-#undef HAVE_LIBC_FNM_EXTMATCH
-
-#undef HAVE_DECL_CONFSTR
-
-#undef HAVE_DECL_PRINTF
-
-#undef HAVE_DECL_SBRK
-
-#undef HAVE_DECL_STRCPY
-
-#undef HAVE_DECL_STRSIGNAL
-
-#undef HAVE_DECL_STRTOLD
-
-#undef PRI_MACROS_BROKEN
-
-#undef STRTOLD_BROKEN
-
-/* Define if WCONTINUED is defined in system headers, but rejected by waitpid */
-#undef WCONTINUED_BROKEN
-
-/* These are checked with BASH_CHECK_DECL */
-
-#undef HAVE_DECL_STRTOIMAX
-#undef HAVE_DECL_STRTOL
-#undef HAVE_DECL_STRTOLL
-#undef HAVE_DECL_STRTOUL
-#undef HAVE_DECL_STRTOULL
-#undef HAVE_DECL_STRTOUMAX
-
-/* Characteristics of system calls and C library functions. */
-
-/* Define if the `getpgrp' function takes no argument.  */
-#undef GETPGRP_VOID
-
-#undef NAMED_PIPES_MISSING
-
-#undef OPENDIR_NOT_ROBUST
-
-#undef PGRP_PIPE
-
-/* Define if the setvbuf function takes the buffering type as its second
-   argument and the buffer pointer as the third, as on System V
-   before release 3.  */
-#undef SETVBUF_REVERSED
-
-#undef STAT_MACROS_BROKEN
-
-#undef ULIMIT_MAXFDS
-
-#undef CAN_REDEFINE_GETENV
-
-#undef HAVE_STD_PUTENV
-
-#undef HAVE_STD_UNSETENV
-
-#undef HAVE_PRINTF_A_FORMAT
-
-#undef CTYPE_NON_ASCII
-
-/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
-#undef HAVE_LANGINFO_CODESET
-
-/* Characteristics of properties exported by the kernel. */
-
-/* Define if the kernel can exec files beginning with #! */
-#undef HAVE_HASH_BANG_EXEC
-
-/* Define if you have the /dev/fd devices to map open files into the file system. */
-#undef HAVE_DEV_FD
-
-/* Defined to /dev/fd or /proc/self/fd (linux). */
-#undef DEV_FD_PREFIX
-
-/* Define if you have the /dev/stdin device. */
-#undef HAVE_DEV_STDIN
-
-/* The type of iconv's `inbuf' argument */
-#undef ICONV_CONST
-
-/* Type and behavior of signal handling functions. */
-
-/* Define as the return type of signal handlers (int or void).  */
-#undef RETSIGTYPE
-
-/* Define if return type of signal handlers is void */
-#undef VOID_SIGHANDLER
-
-#undef MUST_REINSTALL_SIGHANDLERS
-
-#undef HAVE_BSD_SIGNALS
-
-#undef HAVE_POSIX_SIGNALS
-
-#undef HAVE_USG_SIGHOLD
-
-#undef UNUSABLE_RT_SIGNALS
-
-
-/* Presence of system and C library functions. */
-
-/* Define if you have the asprintf function.  */
-#undef HAVE_ASPRINTF
-
-/* Define if you have the bcopy function.  */
-#undef HAVE_BCOPY
-
-/* Define if you have the bzero function.  */
-#undef HAVE_BZERO
-
-/* Define if you have the confstr function.  */
-#undef HAVE_CONFSTR
-
-/* Define if you have the dlclose function.  */
-#undef HAVE_DLCLOSE
-
-/* Define if you have the dlopen function.  */
-#undef HAVE_DLOPEN
-
-/* Define if you have the dlsym function.  */
-#undef HAVE_DLSYM
-
-/* Define if you don't have vprintf but do have _doprnt.  */
-#undef HAVE_DOPRNT
-
-/* Define if you have the dup2 function.  */
-#undef HAVE_DUP2
-
-/* Define if you have the eaccess function.  */
-#undef HAVE_EACCESS
-
-/* Define if you have the fcntl function.  */
-#undef HAVE_FCNTL
-
-/* Define if you have the fdprintf function. */
-#undef HAVE_FDPRINTF
-
-/* Define if you have the fpurge/__fpurge function.  */
-#undef HAVE_FPURGE
-#undef HAVE___FPURGE
-#undef HAVE_DECL_FPURGE
-
-/* Define if you have the getaddrinfo function. */
-#undef HAVE_GETADDRINFO
-
-/* Define if you have the getcwd function.  */
-#undef HAVE_GETCWD
-
-/* Define if you have the getdtablesize function.  */
-#undef HAVE_GETDTABLESIZE
-
-/* Define if you have the getgroups function.  */
-#undef HAVE_GETGROUPS
-
-/* Define if you have the gethostbyname function.  */
-#undef HAVE_GETHOSTBYNAME
-
-/* Define if you have the gethostname function.  */
-#undef HAVE_GETHOSTNAME
-
-/* Define if you have the getpagesize function.  */
-#undef HAVE_GETPAGESIZE
-
-/* Define if you have the getpeername function.  */
-#undef HAVE_GETPEERNAME
-
-/* Define if you have the getpwent function. */
-#undef HAVE_GETPWENT
-
-/* Define if you have the getpwnam function. */
-#undef HAVE_GETPWNAM
-
-/* Define if you have the getpwuid function. */
-#undef HAVE_GETPWUID
-
-/* Define if you have the getrlimit function.  */
-#undef HAVE_GETRLIMIT
-
-/* Define if you have the getrusage function.  */
-#undef HAVE_GETRUSAGE
-
-/* Define if you have the getservbyname function.  */
-#undef HAVE_GETSERVBYNAME
-
-/* Define if you have the getservent function.  */
-#undef HAVE_GETSERVENT
-
-/* Define if you have the gettimeofday function.  */
-#undef HAVE_GETTIMEOFDAY
-
-/* Define if you have the getwd function.  */
-#undef HAVE_GETWD
-
-/* Define if you have the iconv function.  */
-#undef HAVE_ICONV
-
-/* Define if you have the inet_aton function.  */
-#undef HAVE_INET_ATON
-
-/* Define if you have the isascii function. */
-#undef HAVE_ISASCII
-
-/* Define if you have the isblank function.  */
-#undef HAVE_ISBLANK
-
-/* Define if you have the isgraph function.  */
-#undef HAVE_ISGRAPH
-
-/* Define if you have the isinf function in libc */
-#undef HAVE_ISINF_IN_LIBC
-
-/* Define if you have the isnan function in libc */
-#undef HAVE_ISNAN_IN_LIBC
-
-/* Define if you have the isprint function.  */
-#undef HAVE_ISPRINT
-
-/* Define if you have the isspace function.  */
-#undef HAVE_ISSPACE
-
-/* Define if you have the iswctype function.  */
-#undef HAVE_ISWCTYPE
-
-/* Define if you have the iswlower function.  */
-#undef HAVE_ISWLOWER
-
-/* Define if you have the iswupper function.  */
-#undef HAVE_ISWUPPER
-
-/* Define if you have the isxdigit function.  */
-#undef HAVE_ISXDIGIT
-
-/* Define if you have the kill function.  */
-#undef HAVE_KILL
-
-/* Define if you have the killpg function.  */
-#undef HAVE_KILLPG
-
-/* Define if you have the lstat function. */
-#undef HAVE_LSTAT
-
-/* Define if you have the mbrlen function. */
-#undef HAVE_MBRLEN
-
-/* Define if you have the mbrtowc function. */
-#undef HAVE_MBRTOWC
-
-/* Define if you have the mbscasecmp function. */
-#undef HAVE_MBSCASECMP
-
-/* Define if you have the mbschr function. */
-#undef HAVE_MBSCHR
-
-/* Define if you have the mbscmp function. */
-#undef HAVE_MBSCMP
-
-/* Define if you have the mbsrtowcs function. */
-#undef HAVE_MBSRTOWCS
-
-/* Define if you have the memmove function.  */
-#undef HAVE_MEMMOVE
-
-/* Define if you have the memset function.  */
-#undef HAVE_MEMSET
-
-/* Define if you have the mkfifo function.  */
-#undef HAVE_MKFIFO
-
-/* Define if you have the pathconf function. */
-#undef HAVE_PATHCONF
-
-/* Define if you have the putenv function.  */
-#undef HAVE_PUTENV
-
-/* Define if you have the raise function. */
-#undef HAVE_RAISE
-
-/* Define if you have the readlink function. */
-#undef HAVE_READLINK
-
-/* Define if you have the regcomp function. */
-#undef HAVE_REGCOMP
-
-/* Define if you have the regexec function. */
-#undef HAVE_REGEXEC
-
-/* Define if you have the rename function. */
-#undef HAVE_RENAME
-
-/* Define if you have the sbrk function. */
-#undef HAVE_SBRK
-
-/* Define if you have the select function.  */
-#undef HAVE_SELECT
-
-/* Define if you have the setdtablesize function.  */
-#undef HAVE_SETDTABLESIZE
-
-/* Define if you have the setenv function.  */
-#undef HAVE_SETENV
-
-/* Define if you have the setitimer function.  */
-#undef HAVE_SETITIMER
-
-/* Define if you have the setlinebuf function.  */
-#undef HAVE_SETLINEBUF
-
-/* Define if you have the setlocale function.  */
-#undef HAVE_SETLOCALE
-
-/* Define if you have the setostype function.  */
-#undef HAVE_SETOSTYPE
-
-/* Define if you have the setregid function.  */
-#undef HAVE_SETREGID
-#undef HAVE_DECL_SETREGID
-
-/* Define if you have the setvbuf function.  */
-#undef HAVE_SETVBUF
-
-/* Define if you have the siginterrupt function.  */
-#undef HAVE_SIGINTERRUPT
-
-/* Define if you have the POSIX.1-style sigsetjmp function.  */
-#undef HAVE_POSIX_SIGSETJMP
-
-/* Define if you have the snprintf function.  */
-#undef HAVE_SNPRINTF
-
-/* Define if you have the strcasecmp function.  */
-#undef HAVE_STRCASECMP
-
-/* Define if you have the strcasestr function.  */
-#undef HAVE_STRCASESTR
-
-/* Define if you have the strchr function.  */
-#undef HAVE_STRCHR
-
-/* Define if you have the strcoll function.  */
-#undef HAVE_STRCOLL
-
-/* Define if you have the strerror function.  */
-#undef HAVE_STRERROR
-
-/* Define if you have the strftime function. */
-#undef HAVE_STRFTIME
-
-/* Define if you have the strnlen function. */
-#undef HAVE_STRNLEN
-
-/* Define if you have the strpbrk function. */
-#undef HAVE_STRPBRK
-
-/* Define if you have the strstr function. */
-#undef HAVE_STRSTR
-
-/* Define if you have the strtod function. */
-#undef HAVE_STRTOD
-
-/* Define if you have the strtoimax function. */
-#undef HAVE_STRTOIMAX
-
-/* Define if you have the strtol function. */
-#undef HAVE_STRTOL
-
-/* Define if you have the strtoll function. */
-#undef HAVE_STRTOLL
-
-/* Define if you have the strtoul function. */
-#undef HAVE_STRTOUL
-
-/* Define if you have the strtoull function. */
-#undef HAVE_STRTOULL
-
-/* Define if you have the strtoumax function. */
-#undef HAVE_STRTOUMAX
-
-/* Define if you have the strsignal function or macro. */
-#undef HAVE_STRSIGNAL
-
-/* Define if you have the sysconf function. */
-#undef HAVE_SYSCONF
-
-/* Define if you have the syslog function. */
-#undef HAVE_SYSLOG
-
-/* Define if you have the tcgetattr function.  */
-#undef HAVE_TCGETATTR
-
-/* Define if you have the tcgetpgrp function.  */
-#undef HAVE_TCGETPGRP
-
-/* Define if you have the times function.  */
-#undef HAVE_TIMES
-
-/* Define if you have the towlower function.  */
-#undef HAVE_TOWLOWER
-
-/* Define if you have the towupper function.  */
-#undef HAVE_TOWUPPER
-
-/* Define if you have the ttyname function.  */
-#undef HAVE_TTYNAME
-
-/* Define if you have the tzset function. */
-#undef HAVE_TZSET
-
-/* Define if you have the ulimit function. */
-#undef HAVE_ULIMIT
-
-/* Define if you have the uname function. */
-#undef HAVE_UNAME
-
-/* Define if you have the unsetenv function.  */
-#undef HAVE_UNSETENV
-
-/* Define if you have the vasprintf function.  */
-#undef HAVE_VASPRINTF
-
-/* Define if you have the vprintf function.  */
-#undef HAVE_VPRINTF
-
-/* Define if you have the vsnprintf function.  */
-#undef HAVE_VSNPRINTF
-
-/* Define if you have the waitpid function. */
-#undef HAVE_WAITPID
-
-/* Define if you have the wait3 function.  */
-#undef HAVE_WAIT3
-
-/* Define if you have the wcrtomb function.  */
-#undef HAVE_WCRTOMB
-
-/* Define if you have the wcscoll function.  */
-#undef HAVE_WCSCOLL
-
-/* Define if you have the wcsdup function.  */
-#undef HAVE_WCSDUP
-
-/* Define if you have the wctype function.  */
-#undef HAVE_WCTYPE
-
-/* Define if you have the wcwidth function.  */
-#undef HAVE_WCWIDTH
-
-/* Presence of certain system include files. */
-
-/* Define if you have the <arpa/inet.h> header file. */
-#undef HAVE_ARPA_INET_H
-
-/* Define if you have the <dirent.h> header file.  */
-#undef HAVE_DIRENT_H
-
-/* Define if you have the <dlfcn.h> header file.  */
-#undef HAVE_DLFCN_H
-
-/* Define if you have the <grp.h> header file.  */
-#undef HAVE_GRP_H
-
-/* Define if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
-
-/* Define if you have the <langinfo.h> header file.  */
-#undef HAVE_LANGINFO_H
-
-/* Define if you have the <libintl.h> header file. */
-#undef HAVE_LIBINTL_H
-
-/* Define if you have the <limits.h> header file.  */
-#undef HAVE_LIMITS_H
-
-/* Define if you have the <locale.h> header file.  */
-#undef HAVE_LOCALE_H
-
-/* Define if you have the <ndir.h> header file.  */
-#undef HAVE_NDIR_H
-
-/* Define if you have the <netdh.h> header file. */
-#undef HAVE_NETDB_H
-
-/* Define if you have the <netinet/in.h> header file. */
-#undef HAVE_NETINET_IN_H
-
-/* Define if you have the <pwd.h> header file. */
-#undef HAVE_PWD_H
-
-/* Define if you have the <regex.h> header file. */
-#undef HAVE_REGEX_H
-
-/* Define if you have the <stdlib.h> header file.  */
-#undef HAVE_STDLIB_H
-
-/* Define if you have the <stdarg.h> header file.  */
-#undef HAVE_STDARG_H
-
-/* Define if you have the <string.h> header file.  */
-#undef HAVE_STRING_H
-
-/* Define if you have the <strings.h> header file.  */
-#undef HAVE_STRINGS_H
-
-/* Define if you have the <memory.h> header file.  */
-#undef HAVE_MEMORY_H
-
-/* Define if you have the <stddef.h> header file. */
-#undef HAVE_STDDEF_H
-
-/* Define if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
-
-/* Define if you have the <syslog.h> header file. */
-#undef HAVE_SYSLOG_H
-
-/* Define if you have the <sys/dir.h> header file.  */
-#undef HAVE_SYS_DIR_H
-
-/* Define if you have the <sys/file.h> header file.  */
-#undef HAVE_SYS_FILE_H
-
-/* Define if you have the <sys/ndir.h> header file.  */
-#undef HAVE_SYS_NDIR_H
-
-/* Define if you have the <sys/param.h> header file.  */
-#undef HAVE_SYS_PARAM_H
-
-/* Define if you have the <sys/pte.h> header file.  */
-#undef HAVE_SYS_PTE_H
-
-/* Define if you have the <sys/ptem.h> header file.  */
-#undef HAVE_SYS_PTEM_H
-
-/* Define if you have the <sys/resource.h> header file.  */
-#undef HAVE_SYS_RESOURCE_H
-
-/* Define if you have the <sys/select.h> header file.  */
-#undef HAVE_SYS_SELECT_H
-
-/* Define if you have the <sys/socket.h> header file.  */
-#undef HAVE_SYS_SOCKET_H
-
-/* Define if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
-
-/* Define if you have the <sys/stream.h> header file.  */
-#undef HAVE_SYS_STREAM_H
-
-/* Define if you have <sys/time.h> */
-#undef HAVE_SYS_TIME_H
-
-#undef TIME_WITH_SYS_TIME
-
-/* Define if you have <sys/times.h> */
-#undef HAVE_SYS_TIMES_H
-
-/* Define if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
-
-/* Define if you have <sys/wait.h> that is POSIX.1 compatible.  */
-#undef HAVE_SYS_WAIT_H
-
-/* Define if you have the <termcap.h> header file.  */
-#undef HAVE_TERMCAP_H
-
-/* Define if you have the <termio.h> header file.  */
-#undef HAVE_TERMIO_H
-
-/* Define if you have the <termios.h> header file.  */
-#undef HAVE_TERMIOS_H
-
-/* Define if you have the <unistd.h> header file.  */
-#undef HAVE_UNISTD_H
-
-/* Define if you have the <varargs.h> header file.  */
-#undef HAVE_VARARGS_H
-
-/* Define if you have the <wchar.h> header file.  */
-#undef HAVE_WCHAR_H
-
-/* Define if you have the <varargs.h> header file.  */
-#undef HAVE_WCTYPE_H
-
-/* Presence of certain system libraries. */
-
-#undef HAVE_LIBDL
-
-#undef HAVE_LIBSUN
-
-#undef HAVE_LIBSOCKET
-
-
-/* Define if on MINIX.  */
-#undef _MINIX
-
-/* Are we running SVR5 (UnixWare 7)? */
-#undef SVR5
-
-/* Are we running SVR4.2? */
-#undef SVR4_2
-
-/* Are we running some version of SVR4? */
-#undef SVR4
-
-/* Define if job control is unusable or unsupported. */
-#undef JOB_CONTROL_MISSING
-
-/* Do we need to define _KERNEL to get the RLIMIT_* defines from
-   <sys/resource.h>? */
-#undef RLIMIT_NEEDS_KERNEL
-
-/* Number of bits in a file offset, on hosts where this is settable. */
-#undef _FILE_OFFSET_BITS
-
-/* Define for large files on AIX-style hosts. */
-#undef _LARGE_FILES
-
-/* Do strcoll(3) and strcmp(3) give different results in the default locale? */
-#undef STRCOLL_BROKEN
-
-#undef DUP2_BROKEN
-
-#undef GETCWD_BROKEN
-
-/* Additional defines for configuring lib/intl, maintained by autoscan/autoheader */
-
-/* Define if you have the <argz.h> header file. */
-#undef HAVE_ARGZ_H
-
-/* Define if you have the <errno.h> header file. */
-#undef HAVE_ERRNO_H
-
-/* Define if you have the <fcntl.h> header file. */
-#undef HAVE_FCNTL_H
-
-/* Define if you have the <malloc.h> header file. */
-#undef HAVE_MALLOC_H
-
-/* Define if you have the <stdio_ext.h> header file. */
-#undef HAVE_STDIO_EXT_H
-
-/* Define if you have the `dcgettext' function. */
-#undef HAVE_DCGETTEXT
-
-/* Define if you have the `localeconv' function. */
-#undef HAVE_LOCALECONV
-
-/* Define if your system has a working `malloc' function. */
-/* #undef HAVE_MALLOC */
-
-/* Define if you have the `mempcpy' function. */
-#undef HAVE_MEMPCPY
-
-/* Define if you have a working `mmap' system call. */
-#undef HAVE_MMAP
-
-/* Define if you have the `munmap' function. */
-#undef HAVE_MUNMAP
-
-/* Define if you have the `nl_langinfo' function. */
-#undef HAVE_NL_LANGINFO
-
-/* Define if you have the `stpcpy' function. */
-#undef HAVE_STPCPY
-
-/* Define if you have the `strcspn' function. */
-#undef HAVE_STRCSPN
-
-/* Define if you have the `strdup' function. */
-#undef HAVE_STRDUP
-
-/* Define if you have the `__argz_count' function. */
-#undef HAVE___ARGZ_COUNT
-
-/* Define if you have the `__argz_next' function. */
-#undef HAVE___ARGZ_NEXT
-
-/* Define if you have the `__argz_stringify' function. */
-#undef HAVE___ARGZ_STRINGIFY
-
-/* End additions for lib/intl */
-
-#include "config-bot.h"
-
-#endif /* _CONFIG_H_ */
diff --git a/configure.in~ b/configure.in~
deleted file mode 100644 (file)
index 598544e..0000000
+++ /dev/null
@@ -1,1156 +0,0 @@
-dnl
-dnl Configure script for bash-4.1
-dnl
-dnl report bugs to chet@po.cwru.edu
-dnl
-dnl Process this file with autoconf to produce a configure script.
-
-# Copyright (C) 1987-2009 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
-
-AC_REVISION([for Bash 4.1, version 4.018])dnl
-
-define(bashvers, 4.1)
-define(relstatus, rc)
-
-AC_INIT([bash], bashvers-relstatus, [bug-bash@gnu.org])
-
-dnl make sure we are using a recent autoconf version
-AC_PREREQ(2.50)
-
-AC_CONFIG_SRCDIR(shell.h)
-dnl where to find install.sh, config.sub, and config.guess
-AC_CONFIG_AUX_DIR(./support)
-AC_CONFIG_HEADERS(config.h)
-
-dnl checks for version info
-BASHVERS=bashvers
-RELSTATUS=relstatus
-
-dnl defaults for debug settings
-case "$RELSTATUS" in
-alp*|bet*|dev*|rc*|maint*)     DEBUG='-DDEBUG' MALLOC_DEBUG='-DMALLOC_DEBUG' ;;
-*)     DEBUG= MALLOC_DEBUG= ;;
-esac
-
-dnl canonicalize the host and os so we can do some tricky things before
-dnl parsing options
-AC_CANONICAL_HOST
-
-dnl configure defaults
-opt_bash_malloc=yes
-opt_purify=no
-opt_purecov=no
-opt_afs=no
-opt_curses=no
-opt_with_installed_readline=no
-
-#htmldir=
-
-dnl some systems should be configured without the bash malloc by default
-dnl and some need a special compiler or loader
-dnl look in the NOTES file for more
-case "${host_cpu}-${host_os}" in
-alpha*-*)      opt_bash_malloc=no ;;   # alpha running osf/1 or linux
-*[[Cc]]ray*-*) opt_bash_malloc=no ;;   # Crays
-*-osf1*)       opt_bash_malloc=no ;;   # other osf/1 machines
-sparc-svr4*)   opt_bash_malloc=no ;;   # sparc SVR4, SVR4.2
-sparc-netbsd*) opt_bash_malloc=no ;;   # needs 8-byte alignment
-mips-irix6*)   opt_bash_malloc=no ;;   # needs 8-byte alignment
-m68k-sysv)     opt_bash_malloc=no ;;   # fixes file descriptor leak in closedir
-sparc-linux*)  opt_bash_malloc=no ;;   # sparc running linux; requires ELF
-#*-freebsd*-gnu)       opt_bash_malloc=no ;;   # there's some undetermined problem here
-#*-freebsd*)   opt_bash_malloc=no ;;   # they claim it's better; I disagree
-*-openbsd*)    opt_bash_malloc=no ;;   # they claim it needs eight-bit alignment
-*-aix*)                opt_bash_malloc=no ;;   # AIX machines
-*-nextstep*)   opt_bash_malloc=no ;;   # NeXT machines running NeXTstep
-*-macos*)      opt_bash_malloc=no ;;   # Apple MacOS X
-*-rhapsody*)   opt_bash_malloc=no ;;   # Apple Rhapsody (MacOS X)
-*-darwin*)     opt_bash_malloc=no ;;   # Apple Darwin (MacOS X)
-*-dgux*)       opt_bash_malloc=no ;;   # DG/UX machines
-*-qnx*)                opt_bash_malloc=no ;;   # QNX 4.2, QNX 6.x
-*-machten4)    opt_bash_malloc=no ;;   # MachTen 4.x
-*-bsdi2.1|*-bsdi3.?)   opt_bash_malloc=no ; : ${CC:=shlicc2} ;; # for loadable builtins
-*-beos*)       opt_bash_malloc=no ;;   # they say it's suitable
-*-cygwin*)     opt_bash_malloc=no ;;   # Cygnus's CYGWIN environment
-*-opennt*|*-interix*)  opt_bash_malloc=no ;;   # Interix, now owned by Microsoft
-esac
-
-# memory scrambling on free()
-case "${host_os}" in
-sco3.2v5*|sco3.2v4*)   opt_memscramble=no ;;
-*)                     opt_memscramble=yes ;;
-esac
-
-dnl
-dnl macros for the bash debugger
-dnl
-AM_PATH_LISPDIR
-AC_ARG_VAR(DEBUGGER_START_FILE, [location of bash debugger initialization file])
-
-dnl arguments to configure
-dnl packages
-AC_ARG_WITH(afs, AC_HELP_STRING([--with-afs], [if you are running AFS]), opt_afs=$withval)
-AC_ARG_WITH(bash-malloc, AC_HELP_STRING([--with-bash-malloc], [use the Bash version of malloc]), opt_bash_malloc=$withval)
-AC_ARG_WITH(curses, AC_HELP_STRING([--with-curses], [use the curses library instead of the termcap library]), opt_curses=$withval)
-AC_ARG_WITH(gnu-malloc, AC_HELP_STRING([--with-gnu-malloc], [synonym for --with-bash-malloc]), opt_bash_malloc=$withval)
-AC_ARG_WITH(installed-readline, AC_HELP_STRING([--with-installed-readline], [use a version of the readline library that is already installed]), opt_with_installed_readline=$withval)
-AC_ARG_WITH(purecov, AC_HELP_STRING([--with-purecov], [configure to postprocess with pure coverage]), opt_purecov=$withval)
-AC_ARG_WITH(purify, AC_HELP_STRING([--with-purify], [configure to postprocess with purify]), opt_purify=$withval)
-
-if test "$opt_bash_malloc" = yes; then
-       MALLOC_TARGET=malloc
-       MALLOC_SRC=malloc.c
-
-       MALLOC_LIB='-lmalloc'
-       MALLOC_LIBRARY='$(ALLOC_LIBDIR)/libmalloc.a'
-       MALLOC_LDFLAGS='-L$(ALLOC_LIBDIR)'
-       MALLOC_DEP='$(MALLOC_LIBRARY)'
-
-       AC_DEFINE(USING_BASH_MALLOC)
-else
-       MALLOC_LIB=
-       MALLOC_LIBRARY=
-       MALLOC_LDFLAGS=
-       MALLOC_DEP=     
-fi
-
-if test "$opt_purify" = yes; then
-       PURIFY="purify "
-       AC_DEFINE(DISABLE_MALLOC_WRAPPERS)
-else
-       PURIFY=
-fi
-
-if test "$opt_purecov" = yes; then
-       PURIFY="${PURIFY}purecov"
-fi
-
-if test "$opt_afs" = yes; then
-       AC_DEFINE(AFS)
-fi
-
-if test "$opt_curses" = yes; then
-       prefer_curses=yes
-fi
-
-if test -z "${DEBUGGER_START_FILE}"; then
-       DEBUGGER_START_FILE='${datadir}/bashdb/bashdb-main.inc'
-fi
-
-dnl optional shell features in config.h.in
-opt_minimal_config=no
-
-opt_job_control=yes
-opt_alias=yes
-opt_readline=yes
-opt_history=yes
-opt_bang_history=yes
-opt_dirstack=yes
-opt_restricted=yes
-opt_process_subst=yes
-opt_prompt_decoding=yes
-opt_select=yes
-opt_help=yes
-opt_array_variables=yes
-opt_dparen_arith=yes
-opt_extended_glob=yes
-opt_brace_expansion=yes
-opt_disabled_builtins=no
-opt_command_timing=yes
-opt_xpg_echo=no
-opt_strict_posix=no
-opt_cond_command=yes
-opt_cond_regexp=yes
-opt_coproc=yes
-opt_arith_for_command=yes
-opt_net_redirs=yes
-opt_progcomp=yes
-opt_separate_help=no
-opt_multibyte=yes
-opt_debugger=yes
-opt_single_longdoc_strings=yes
-opt_casemod_attrs=yes
-opt_casemod_expansions=yes
-opt_extglob_default=no
-
-dnl options that affect how bash is compiled and linked
-opt_static_link=no
-opt_profiling=no
-
-dnl argument parsing for optional features
-AC_ARG_ENABLE(minimal-config, AC_HELP_STRING([--enable-minimal-config], [a minimal sh-like configuration]), opt_minimal_config=$enableval)
-
-dnl a minimal configuration turns everything off, but features can be
-dnl added individually
-if test $opt_minimal_config = yes; then
-       opt_job_control=no opt_alias=no opt_readline=no
-       opt_history=no opt_bang_history=no opt_dirstack=no
-       opt_restricted=no opt_process_subst=no opt_prompt_decoding=no
-       opt_select=no opt_help=no opt_array_variables=no opt_dparen_arith=no
-       opt_brace_expansion=no opt_disabled_builtins=no opt_command_timing=no
-       opt_extended_glob=no opt_cond_command=no opt_arith_for_command=no
-       opt_net_redirs=no opt_progcomp=no opt_separate_help=no
-       opt_multibyte=yes opt_cond_regexp=no opt_coproc=no
-       opt_casemod_attrs=no opt_casemod_expansions=no opt_extglob_default=no
-fi
-
-AC_ARG_ENABLE(alias, AC_HELP_STRING([--enable-alias], [enable shell aliases]), opt_alias=$enableval)
-AC_ARG_ENABLE(arith-for-command, AC_HELP_STRING([--enable-arith-for-command], [enable arithmetic for command]), opt_arith_for_command=$enableval)
-AC_ARG_ENABLE(array-variables, AC_HELP_STRING([--enable-array-variables], [include shell array variables]), opt_array_variables=$enableval)
-AC_ARG_ENABLE(bang-history, AC_HELP_STRING([--enable-bang-history], [turn on csh-style history substitution]), opt_bang_history=$enableval)
-AC_ARG_ENABLE(brace-expansion, AC_HELP_STRING([--enable-brace-expansion], [include brace expansion]), opt_brace_expansion=$enableval)
-AC_ARG_ENABLE(casemod-attributes, AC_HELP_STRING([--enable-casemod-attributes], [include case-modifying variable attributes]), opt_casemod_attrs=$enableval)
-AC_ARG_ENABLE(casemod-expansions, AC_HELP_STRING([--enable-casemod-expansions], [include case-modifying word expansions]), opt_casemod_expansions=$enableval)
-AC_ARG_ENABLE(command-timing, AC_HELP_STRING([--enable-command-timing], [enable the time reserved word and command timing]), opt_command_timing=$enableval)
-AC_ARG_ENABLE(cond-command, AC_HELP_STRING([--enable-cond-command], [enable the conditional command]), opt_cond_command=$enableval)
-AC_ARG_ENABLE(cond-regexp, AC_HELP_STRING([--enable-cond-regexp], [enable extended regular expression matching in conditional commands]), opt_cond_regexp=$enableval)
-AC_ARG_ENABLE(coprocesses, AC_HELP_STRING([--enable-coprocesses], [enable coprocess support and the coproc reserved word]), opt_coproc=$enableval)
-AC_ARG_ENABLE(debugger, AC_HELP_STRING([--enable-debugger], [enable support for bash debugger]), opt_debugger=$enableval)
-AC_ARG_ENABLE(directory-stack, AC_HELP_STRING([--enable-directory-stack], [enable builtins pushd/popd/dirs]), opt_dirstack=$enableval)
-AC_ARG_ENABLE(disabled-builtins, AC_HELP_STRING([--enable-disabled-builtins], [allow disabled builtins to still be invoked]), opt_disabled_builtins=$enableval)
-AC_ARG_ENABLE(dparen-arithmetic, AC_HELP_STRING([--enable-dparen-arithmetic], [include ((...)) command]), opt_dparen_arith=$enableval)
-AC_ARG_ENABLE(extended-glob, AC_HELP_STRING([--enable-extended-glob], [include ksh-style extended pattern matching]), opt_extended_glob=$enableval)
-AC_ARG_ENABLE(extended-glob-default, AC_HELP_STRING([--enable-extended-glob-default], [force extended pattern matching to be enabled by default]), opt_extglob_default=$enableval)
-AC_ARG_ENABLE(help-builtin, AC_HELP_STRING([--enable-help-builtin], [include the help builtin]), opt_help=$enableval)
-AC_ARG_ENABLE(history, AC_HELP_STRING([--enable-history], [turn on command history]), opt_history=$enableval)
-AC_ARG_ENABLE(job-control, AC_HELP_STRING([--enable-job-control], [enable job control features]), opt_job_control=$enableval)
-AC_ARG_ENABLE(multibyte, AC_HELP_STRING([--enable-multibyte], [enable multibyte characters if OS supports them]), opt_multibyte=$enableval)
-AC_ARG_ENABLE(net-redirections, AC_HELP_STRING([--enable-net-redirections], [enable /dev/tcp/host/port redirection]), opt_net_redirs=$enableval)
-AC_ARG_ENABLE(process-substitution, AC_HELP_STRING([--enable-process-substitution], [enable process substitution]), opt_process_subst=$enableval)
-AC_ARG_ENABLE(progcomp, AC_HELP_STRING([--enable-progcomp], [enable programmable completion and the complete builtin]), opt_progcomp=$enableval)
-AC_ARG_ENABLE(prompt-string-decoding, AC_HELP_STRING([--enable-prompt-string-decoding], [turn on escape character decoding in prompts]), opt_prompt_decoding=$enableval)
-AC_ARG_ENABLE(readline, AC_HELP_STRING([--enable-readline], [turn on command line editing]), opt_readline=$enableval)
-AC_ARG_ENABLE(restricted, AC_HELP_STRING([--enable-restricted], [enable a restricted shell]), opt_restricted=$enableval)
-AC_ARG_ENABLE(select, AC_HELP_STRING([--enable-select], [include select command]), opt_select=$enableval)
-AC_ARG_ENABLE(separate-helpfiles, AC_HELP_STRING([--enable-separate-helpfiles], [use external files for help builtin documentation]), opt_separate_help=$enableval)
-AC_ARG_ENABLE(single-help-strings, AC_HELP_STRING([--enable-single-help-strings], [store help documentation as a single string to ease translation]), opt_single_longdoc_strings=$enableval)
-AC_ARG_ENABLE(strict-posix-default, AC_HELP_STRING([--enable-strict-posix-default], [configure bash to be posix-conformant by default]), opt_strict_posix=$enableval)
-AC_ARG_ENABLE(usg-echo-default, AC_HELP_STRING([--enable-usg-echo-default], [a synonym for --enable-xpg-echo-default]), opt_xpg_echo=$enableval)
-AC_ARG_ENABLE(xpg-echo-default, AC_HELP_STRING([--enable-xpg-echo-default], [make the echo builtin expand escape sequences by default]), opt_xpg_echo=$enableval)
-
-dnl options that alter how bash is compiled and linked
-AC_ARG_ENABLE(mem-scramble, AC_HELP_STRING([--enable-mem-scramble], [scramble memory on calls to malloc and free]), opt_memscramble=$enableval)
-AC_ARG_ENABLE(profiling, AC_HELP_STRING([--enable-profiling], [allow profiling with gprof]), opt_profiling=$enableval)
-AC_ARG_ENABLE(static-link, AC_HELP_STRING([--enable-static-link], [link bash statically, for use as a root shell]), opt_static_link=$enableval)
-
-dnl opt_job_control is handled later, after BASH_JOB_CONTROL_MISSING runs
-
-dnl opt_readline and opt_history are handled later, because AC_PROG_CC needs
-dnl to be run before we can check the version of an already-installed readline
-dnl library
-
-if test $opt_alias = yes; then
-AC_DEFINE(ALIAS)
-fi
-if test $opt_dirstack = yes; then
-AC_DEFINE(PUSHD_AND_POPD)
-fi
-if test $opt_restricted = yes; then
-AC_DEFINE(RESTRICTED_SHELL)
-fi
-if test $opt_process_subst = yes; then
-AC_DEFINE(PROCESS_SUBSTITUTION)
-fi
-if test $opt_prompt_decoding = yes; then
-AC_DEFINE(PROMPT_STRING_DECODE)
-fi
-if test $opt_select = yes; then
-AC_DEFINE(SELECT_COMMAND)
-fi
-if test $opt_help = yes; then
-AC_DEFINE(HELP_BUILTIN)
-fi
-if test $opt_array_variables = yes; then
-AC_DEFINE(ARRAY_VARS)
-fi
-if test $opt_dparen_arith = yes; then
-AC_DEFINE(DPAREN_ARITHMETIC)
-fi
-if test $opt_brace_expansion = yes; then
-AC_DEFINE(BRACE_EXPANSION)
-fi
-if test $opt_disabled_builtins = yes; then
-AC_DEFINE(DISABLED_BUILTINS)
-fi
-if test $opt_command_timing = yes; then
-AC_DEFINE(COMMAND_TIMING)
-fi
-if test $opt_xpg_echo = yes ; then
-AC_DEFINE(DEFAULT_ECHO_TO_XPG)
-fi
-if test $opt_strict_posix = yes; then
-AC_DEFINE(STRICT_POSIX)
-fi
-if test $opt_extended_glob = yes ; then
-AC_DEFINE(EXTENDED_GLOB)
-fi
-if test $opt_extglob_default = yes; then
-AC_DEFINE(EXTGLOB_DEFAULT, 1)
-else
-AC_DEFINE(EXTGLOB_DEFAULT, 0)
-fi
-if test $opt_cond_command = yes ; then
-AC_DEFINE(COND_COMMAND)
-fi
-if test $opt_cond_regexp = yes ; then
-AC_DEFINE(COND_REGEXP)
-fi
-if test $opt_coproc = yes; then
-AC_DEFINE(COPROCESS_SUPPORT)
-fi
-if test $opt_arith_for_command = yes; then
-AC_DEFINE(ARITH_FOR_COMMAND)
-fi
-if test $opt_net_redirs = yes; then
-AC_DEFINE(NETWORK_REDIRECTIONS)
-fi
-if test $opt_progcomp = yes; then
-AC_DEFINE(PROGRAMMABLE_COMPLETION)
-fi
-if test $opt_multibyte = no; then
-AC_DEFINE(NO_MULTIBYTE_SUPPORT)
-fi
-if test $opt_debugger = yes; then
-AC_DEFINE(DEBUGGER)
-fi
-if test $opt_casemod_attrs = yes; then
-AC_DEFINE(CASEMOD_ATTRS)
-fi
-if test $opt_casemod_expansions = yes; then
-AC_DEFINE(CASEMOD_EXPANSIONS)
-fi
-
-if test $opt_memscramble = yes; then
-AC_DEFINE(MEMSCRAMBLE)
-fi
-
-if test "$opt_minimal_config" = yes; then
-       TESTSCRIPT=run-minimal
-else
-       TESTSCRIPT=run-all
-fi
-
-HELPDIR= HELPDIRDEFINE= HELPINSTALL=
-if test "$opt_separate_help" != no; then
-       if test "$opt_separate_help" = "yes" ; then
-               HELPDIR='${datadir}/bash'
-       else
-               HELPDIR=$opt_separate_help
-       fi
-       HELPDIRDEFINE='-H ${HELPDIR}'
-       HELPINSTALL='install-help'
-fi
-HELPSTRINGS=
-if test "$opt_single_longdoc_strings" != "yes"; then
-       HELPSTRINGS='-S'
-fi
-
-dnl now substitute in the values generated by arguments
-AC_SUBST(TESTSCRIPT)
-AC_SUBST(PURIFY)
-AC_SUBST(MALLOC_TARGET)
-AC_SUBST(MALLOC_SRC)
-
-AC_SUBST(MALLOC_LIB)
-AC_SUBST(MALLOC_LIBRARY)
-AC_SUBST(MALLOC_LDFLAGS)
-AC_SUBST(MALLOC_DEP)
-
-AC_SUBST(htmldir)
-
-AC_SUBST(HELPDIR)
-AC_SUBST(HELPDIRDEFINE)
-AC_SUBST(HELPINSTALL)
-AC_SUBST(HELPSTRINGS)
-
-echo ""
-echo "Beginning configuration for bash-$BASHVERS-$RELSTATUS for ${host_cpu}-${host_vendor}-${host_os}"
-echo ""
-
-dnl compilation checks
-dnl AC_PROG_CC sets $cross_compiling to `yes' if cross-compiling for a
-dnl different environment
-AC_PROG_CC
-
-dnl test for Unix variants
-AC_ISC_POSIX
-AC_MINIX
-
-AC_SYS_LARGEFILE
-
-dnl BEGIN changes for cross-building (currently cygwin, minGW, and
-dnl (obsolete) BeOS)
-
-SIGNAMES_O=
-SIGNAMES_H=lsignames.h
-
-dnl load up the cross-building cache file -- add more cases and cache
-dnl files as necessary
-
-dnl Note that host and target machine are the same, and different than the
-dnl build machine.
-dnl Set SIGNAMES_H based on whether or not we're cross-compiling.
-
-CROSS_COMPILE=
-if test "x$cross_compiling" = "xyes"; then
-    case "${host}" in
-    *-cygwin*)
-       cross_cache=${srcdir}/cross-build/cygwin32.cache
-       ;;
-    *-mingw*)
-       cross_cache=${srcdir}/cross-build/cygwin32.cache
-       ;;
-    i[[3456]]86-*-beos*)
-       cross_cache=${srcdir}/cross-build/x86-beos.cache
-       ;;
-    *) echo "configure: cross-compiling for $host is not supported" >&2
-       ;;
-    esac
-    if test -n "${cross_cache}" && test -r "${cross_cache}"; then
-       echo "loading cross-build cache file ${cross_cache}"
-       . ${cross_cache}
-    fi
-    unset cross_cache
-    SIGNAMES_O='signames.o'
-    CROSS_COMPILE='-DCROSS_COMPILING'
-    AC_SUBST(CROSS_COMPILE)
-fi
-AC_SUBST(SIGNAMES_H)
-AC_SUBST(SIGNAMES_O)
-
-if test -z "$CC_FOR_BUILD"; then
-    if test "x$cross_compiling" = "xno"; then
-       CC_FOR_BUILD='$(CC)'
-    else
-       CC_FOR_BUILD=gcc
-    fi
-fi
-AC_SUBST(CC_FOR_BUILD)
-
-dnl END changes for cross-building
-
-dnl We want these before the checks, so the checks can modify their values.
-test -z "$CFLAGS" && CFLAGS=-g auto_cflags=1
-
-dnl If we're using gcc and the user hasn't specified CFLAGS, add -O2 to CFLAGS.
-test -n "$GCC" && test -n "$auto_cflags" && CFLAGS="$CFLAGS -O2"
-
-dnl handle options that alter how bash is compiled and linked
-dnl these must come after the test for cc/gcc
-if test "$opt_profiling" = "yes"; then
-       PROFILE_FLAGS=-pg
-       case "$host_os" in
-       solaris2*)      ;;
-       *)              opt_static_link=yes ;;
-       esac
-       DEBUG= MALLOC_DEBUG=
-fi
-
-if test "$opt_static_link" = yes; then
-       # if we're using gcc, add `-static' to LDFLAGS, except on Solaris >= 2
-       if test -n "$GCC" || test "$ac_cv_prog_gcc" = "yes"; then
-               STATIC_LD="-static" 
-               case "$host_os" in
-               solaris2*)      ;;
-               *)              LDFLAGS="$LDFLAGS -static" ;;   # XXX experimental
-               esac
-       fi
-fi
-
-if test "X$cross_compiling" = "Xno"; then
-       CPPFLAGS_FOR_BUILD=${CPPFLAGS_FOR_BUILD-"$CPPFLAGS"}
-       LDFLAGS_FOR_BUILD=${LDFLAGS_FOR_BUILD-'$(LDFLAGS)'}
-else
-       CPPFLAGS_FOR_BUILD=${CPPFLAGS_FOR_BUILD-""}
-       LDFLAGS_FOR_BUILD=${LDFLAGS_FOR_BUILD-""}
-fi
-
-test -z "$CFLAGS_FOR_BUILD" && CFLAGS_FOR_BUILD="-g"
-
-AC_SUBST(CFLAGS)
-AC_SUBST(CPPFLAGS)
-AC_SUBST(LDFLAGS)
-AC_SUBST(STATIC_LD)
-
-AC_SUBST(CFLAGS_FOR_BUILD)
-AC_SUBST(CPPFLAGS_FOR_BUILD)
-AC_SUBST(LDFLAGS_FOR_BUILD)
-
-AC_PROG_GCC_TRADITIONAL
-
-dnl BEGIN READLINE and HISTORY LIBRARY SECTION
-dnl prepare to allow bash to be linked against an already-installed readline
-
-dnl first test that the readline version is new enough to link bash against
-if test "$opt_readline" = yes && test "$opt_with_installed_readline" != "no"
-then
-       # If the user specified --with-installed-readline=PREFIX and PREFIX
-       # is not `yes', set ac_cv_rl_prefix to PREFIX
-       test $opt_with_installed_readline != "yes" && ac_cv_rl_prefix=$opt_with_installed_readline
-
-       RL_LIB_READLINE_VERSION
-
-       case "$ac_cv_rl_version" in
-       5*|6*|7*|8*|9*) ;;
-       *)      opt_with_installed_readline=no 
-               AC_MSG_WARN([installed readline library is too old to be linked with bash])
-               AC_MSG_WARN([using private bash version])
-               ;;
-       esac
-fi
-
-TILDE_LIB=-ltilde
-if test $opt_readline = yes; then
-       AC_DEFINE(READLINE)
-       if test "$opt_with_installed_readline" != "no" ; then
-               case "$opt_with_installed_readline" in
-               yes)    RL_INCLUDE= ;;
-               *)      case "$RL_INCLUDEDIR" in
-                       /usr/include)   ;;
-                       *)              RL_INCLUDE='-I${RL_INCLUDEDIR}' ;;
-                       esac
-                       ;;
-               esac
-               READLINE_DEP=
-               READLINE_LIB=-lreadline
-               # section for OS versions that don't allow unresolved symbols
-               # to be compiled into dynamic libraries.
-               case "$host_os" in
-               cygwin*)        TILDE_LIB= ;;
-               esac
-       else
-               RL_LIBDIR='$(dot)/$(LIBSUBDIR)/readline'
-               READLINE_DEP='$(READLINE_LIBRARY)'
-               # section for OS versions that ship an older/broken version of
-               # readline as a standard dynamic library and don't allow a
-               # static version specified as -llibname to override the
-               # dynamic version
-               case "${host_os}" in
-               darwin[[89]]*|darwin10*) READLINE_LIB='${READLINE_LIBRARY}' ;;
-               *)              READLINE_LIB=-lreadline ;;
-               esac
-       fi
-else
-       RL_LIBDIR='$(dot)/$(LIBSUBDIR)/readline'
-       READLINE_LIB= READLINE_DEP=
-fi
-if test $opt_history = yes || test $opt_bang_history = yes; then
-       if test $opt_history = yes; then
-               AC_DEFINE(HISTORY)
-       fi
-       if test $opt_bang_history = yes; then
-               AC_DEFINE(BANG_HISTORY)
-       fi
-       if test "$opt_with_installed_readline" != "no"; then
-               HIST_LIBDIR=$RL_LIBDIR
-               HISTORY_DEP=
-               HISTORY_LIB=-lhistory
-               case "$opt_with_installed_readline" in
-               yes)    RL_INCLUDE= ;;
-               *)      case "$RL_INCLUDEDIR" in
-                       /usr/include)   ;;
-                       *)              RL_INCLUDE='-I${RL_INCLUDEDIR}' ;;
-                       esac
-                       ;;
-               esac
-       else
-               HIST_LIBDIR='$(dot)/$(LIBSUBDIR)/readline'
-               HISTORY_DEP='$(HISTORY_LIBRARY)'
-               # section for OS versions that ship an older version of
-               # readline as a standard dynamic library and don't allow a
-               # static version specified as -llibname to override the
-               # dynamic version
-               case "${host_os}" in
-               darwin[[89]]*|darwin10*) HISTORY_LIB='${HISTORY_LIBRARY}' ;;
-               *)              HISTORY_LIB=-lhistory ;;
-               esac
-       fi
-else
-       HIST_LIBDIR='$(dot)/$(LIBSUBDIR)/readline'
-       HISTORY_LIB= HISTORY_DEP=
-fi
-AC_SUBST(READLINE_LIB)
-AC_SUBST(READLINE_DEP)
-AC_SUBST(RL_LIBDIR)
-AC_SUBST(RL_INCLUDEDIR)
-AC_SUBST(RL_INCLUDE)
-AC_SUBST(HISTORY_LIB)
-AC_SUBST(HISTORY_DEP)
-AC_SUBST(HIST_LIBDIR)
-AC_SUBST(TILDE_LIB)
-
-dnl END READLINE and HISTORY LIBRARY SECTION
-
-dnl programs needed by the build and install process
-AC_PROG_INSTALL
-AC_CHECK_PROG(AR, ar, , ar)
-dnl Set default for ARFLAGS, since autoconf does not have a macro for it.
-dnl This allows people to set it when running configure or make
-test -n "$ARFLAGS" || ARFLAGS="cr"
-AC_PROG_RANLIB
-AC_PROG_YACC
-AC_PROG_MAKE_SET
-
-case "$host_os" in
-opennt*|interix*)      MAKE_SHELL="$INTERIX_ROOT/bin/sh" ;;
-*)                     MAKE_SHELL=/bin/sh ;;
-esac
-AC_SUBST(MAKE_SHELL)
-
-dnl this is similar to the expanded AC_PROG_RANLIB
-if test x$SIZE = x; then
-       if test x$ac_tool_prefix = x; then
-               SIZE=size
-       else
-               SIZE=${ac_tool_prefix}size
-               save_IFS=$IFS ; IFS=:
-               size_found=0
-               for dir in $PATH; do
-                       if test -x $dir/$SIZE ; then
-                               size_found=1
-                               break
-                       fi
-               done
-               if test $size_found -eq 0; then
-                       SIZE=:
-               fi
-               IFS=$save_IFS
-       fi
-fi
-AC_SUBST(SIZE)
-
-dnl Turn on any extensions available in the GNU C library.
-AC_DEFINE(_GNU_SOURCE, 1)
-
-dnl C compiler characteristics
-AC_C_CONST
-AC_C_INLINE
-AC_C_BIGENDIAN
-AC_C_STRINGIZE
-AC_C_LONG_DOUBLE
-AC_C_PROTOTYPES
-AC_C_CHAR_UNSIGNED
-AC_C_VOLATILE
-AC_C_RESTRICT
-
-dnl initialize GNU gettext
-AM_GNU_GETTEXT([no-libtool], [need-ngettext], [lib/intl])
-
-dnl header files
-AC_HEADER_DIRENT
-AC_HEADER_TIME
-
-BASH_HEADER_INTTYPES
-
-AC_CHECK_HEADERS(unistd.h stdlib.h stdarg.h varargs.h limits.h string.h \
-                memory.h locale.h termcap.h termio.h termios.h dlfcn.h \
-                stddef.h stdint.h netdb.h pwd.h grp.h strings.h regex.h \
-                syslog.h)
-AC_CHECK_HEADERS(sys/pte.h sys/stream.h sys/select.h sys/file.h \
-                sys/resource.h sys/param.h sys/socket.h sys/stat.h \
-                sys/time.h sys/times.h sys/types.h sys/wait.h)
-AC_CHECK_HEADERS(netinet/in.h arpa/inet.h)
-
-dnl sys/ptem.h requires definitions from sys/stream.h on systems where it
-dnl exists
-AC_CHECK_HEADER(sys/ptem.h, , ,[[
-#if HAVE_SYS_STREAM_H
-#  include <sys/stream.h>
-#endif
-]])
-
-dnl special checks for libc functions
-AC_FUNC_ALLOCA
-AC_FUNC_GETPGRP
-AC_FUNC_SETVBUF_REVERSED
-AC_FUNC_VPRINTF
-AC_FUNC_STRCOLL
-
-dnl if we're not using the bash malloc but require the C alloca, set things
-dnl up to build a libmalloc.a containing only alloca.o
-
-if test "$ac_cv_func_alloca_works" = "no" && test "$opt_bash_malloc" = "no"; then
-       MALLOC_TARGET=alloca
-       MALLOC_SRC=alloca.c
-
-       MALLOC_LIB='-lmalloc'
-       MALLOC_LIBRARY='$(ALLOC_LIBDIR)/libmalloc.a'
-       MALLOC_LDFLAGS='-L$(ALLOC_LIBDIR)'
-       MALLOC_DEP='$(MALLOC_LIBRARY)'
-fi
-
-dnl if vprintf is not in libc, see if it's defined in stdio.h
-if test "$ac_cv_func_vprintf" = no; then
-    AC_MSG_CHECKING(for declaration of vprintf in stdio.h)
-    AC_EGREP_HEADER([[int[     ]*vprintf[^a-zA-Z0-9]]],stdio.h,ac_cv_func_vprintf=yes)
-    AC_MSG_RESULT($ac_cv_func_vprintf)
-    if test $ac_cv_func_vprintf = yes; then
-       AC_DEFINE(HAVE_VPRINTF)
-    fi
-fi
-
-if test "$ac_cv_func_vprintf" = no && test "$ac_cv_func__doprnt" = "yes"; then
-  AC_LIBOBJ(vprint)
-fi
-
-dnl signal stuff
-AC_TYPE_SIGNAL
-
-dnl checks for certain version-specific system calls and libc functions
-AC_CHECK_FUNC(__setostype, AC_DEFINE(HAVE_SETOSTYPE))
-AC_CHECK_FUNC(wait3, AC_DEFINE(HAVE_WAIT3))
-AC_CHECK_FUNC(isinf, AC_DEFINE(HAVE_ISINF_IN_LIBC))
-AC_CHECK_FUNC(isnan, AC_DEFINE(HAVE_ISNAN_IN_LIBC))
-
-dnl checks for missing libc functions
-AC_CHECK_FUNC(mkfifo,AC_DEFINE(HAVE_MKFIFO),AC_DEFINE(MKFIFO_MISSING))
-
-dnl checks for system calls
-AC_CHECK_FUNCS(dup2 eaccess fcntl getdtablesize getgroups gethostname \
-               getpagesize getpeername getrlimit getrusage gettimeofday \
-               kill killpg lstat readlink sbrk select setdtablesize \
-               setitimer tcgetpgrp uname ulimit waitpid)
-AC_REPLACE_FUNCS(rename)
-
-dnl checks for c library functions
-AC_CHECK_FUNCS(bcopy bzero confstr fnmatch \
-               getaddrinfo gethostbyname getservbyname getservent inet_aton \
-               memmove pathconf putenv raise regcomp regexec \
-               setenv setlinebuf setlocale setvbuf siginterrupt strchr \
-               sysconf syslog tcgetattr times ttyname tzset unsetenv)
-
-AC_CHECK_FUNCS(vasprintf asprintf)
-AC_CHECK_FUNCS(isascii isblank isgraph isprint isspace isxdigit)
-AC_CHECK_FUNCS(getpwent getpwnam getpwuid)
-AC_REPLACE_FUNCS(getcwd memset)
-AC_REPLACE_FUNCS(strcasecmp strcasestr strerror strftime strnlen strpbrk strstr)
-AC_REPLACE_FUNCS(strtod strtol strtoul strtoll strtoull strtoimax strtoumax)
-AC_REPLACE_FUNCS(fdprintf)
-
-AC_CHECK_DECLS([confstr])
-AC_CHECK_DECLS([printf])
-AC_CHECK_DECLS([sbrk])
-AC_CHECK_DECLS([setregid])
-AC_CHECK_DECLS([strcpy])
-AC_CHECK_DECLS([strsignal])
-
-dnl Extra test to detect the horribly broken HP/UX 11.00 strtold(3)
-AC_CHECK_DECLS([strtold], [
-    AC_MSG_CHECKING([for broken strtold])
-    AC_CACHE_VAL(bash_cv_strtold_broken,
-       [AC_TRY_COMPILE(
-           [#include <stdlib.h>],
-           [int main() { long double r; char *foo, bar; r = strtold(foo, &bar);}],
-           bash_cv_strtold_broken=no, bash_cv_strtold_broken=yes,
-           [AC_MSG_WARN(cannot check for broken strtold if cross-compiling, defaulting to no)])
-       ]
-    )
-    AC_MSG_RESULT($bash_cv_strtold_broken)
-    if test "$bash_cv_strtold_broken" = "yes" ; then
-       AC_DEFINE(STRTOLD_BROKEN)
-    fi
-])
-    
-
-BASH_CHECK_DECL(strtoimax)
-BASH_CHECK_DECL(strtol)
-BASH_CHECK_DECL(strtoll)
-BASH_CHECK_DECL(strtoul)
-BASH_CHECK_DECL(strtoull)
-BASH_CHECK_DECL(strtoumax)
-
-AC_FUNC_MKTIME
-
-dnl
-dnl Checks for lib/intl and related code (uses some of the output from
-dnl AM_GNU_GETTEXT)
-dnl
-
-AC_CHECK_HEADERS([argz.h errno.h fcntl.h malloc.h stdio_ext.h])
-
-dnl AC_FUNC_MALLOC
-AC_FUNC_MMAP
-AC_CHECK_FUNCS([__argz_count __argz_next __argz_stringify dcgettext mempcpy \
-               munmap stpcpy strcspn strdup])
-
-INTL_DEP= INTL_INC= LIBINTL_H=
-if test "x$USE_INCLUDED_LIBINTL" = "xyes"; then
-       INTL_DEP='${INTL_LIBDIR}/libintl.a'
-       INTL_INC='-I${INTL_LIBSRC} -I${INTL_BUILDDIR}'
-       LIBINTL_H='${INTL_BUILDDIR}/libintl.h'
-fi
-AC_SUBST(INTL_DEP)
-AC_SUBST(INTL_INC)
-AC_SUBST(LIBINTL_H)
-
-dnl
-dnl End of checks needed by files in lib/intl
-dnl
-
-BASH_CHECK_MULTIBYTE
-
-dnl checks for the dynamic loading library functions in libc and libdl
-if test "$opt_static_link" != yes; then
-AC_CHECK_LIB(dl, dlopen)
-AC_CHECK_FUNCS(dlopen dlclose dlsym)
-fi
-
-dnl this defines HAVE_DECL_SYS_SIGLIST
-AC_DECL_SYS_SIGLIST
-
-dnl network functions -- check for inet_aton again
-if test "$ac_cv_func_inet_aton" != 'yes'; then
-BASH_FUNC_INET_ATON
-fi
-
-dnl libraries
-dnl this is reportedly no longer necessary for irix[56].?
-case "$host_os" in
-irix4*)        AC_CHECK_LIB(sun, getpwent) ;;
-esac
-
-dnl check for getpeername in the socket library only if it's not in libc
-if test "$ac_cv_func_getpeername" = no; then
-       BASH_CHECK_LIB_SOCKET
-fi
-dnl check for gethostbyname in socket libraries if it's not in libc
-if test "$ac_cv_func_gethostbyname" = no; then
-       BASH_FUNC_GETHOSTBYNAME
-fi
-
-dnl system types
-AC_TYPE_GETGROUPS
-AC_TYPE_OFF_T
-AC_TYPE_MODE_T
-AC_TYPE_UID_T
-AC_TYPE_PID_T
-AC_TYPE_SIZE_T
-AC_CHECK_TYPE(ssize_t, int)
-AC_CHECK_TYPE(time_t, long)
-
-BASH_TYPE_LONG_LONG
-BASH_TYPE_UNSIGNED_LONG_LONG
-
-AC_TYPE_SIGNAL
-BASH_TYPE_SIG_ATOMIC_T
-
-AC_CHECK_SIZEOF(char, 1)
-AC_CHECK_SIZEOF(short, 2)
-AC_CHECK_SIZEOF(int, 4)
-AC_CHECK_SIZEOF(long, 4)
-AC_CHECK_SIZEOF(char *, 4)
-AC_CHECK_SIZEOF(double, 8)
-AC_CHECK_SIZEOF([long long], 8)
-
-AC_CHECK_TYPE(u_int, [unsigned int])
-AC_CHECK_TYPE(u_long, [unsigned long])
-
-BASH_TYPE_BITS16_T
-BASH_TYPE_U_BITS16_T
-BASH_TYPE_BITS32_T
-BASH_TYPE_U_BITS32_T
-BASH_TYPE_BITS64_T
-
-BASH_TYPE_PTRDIFF_T
-
-dnl structures
-AC_HEADER_STAT
-
-dnl system services
-AC_SYS_INTERPRETER
-if test $ac_cv_sys_interpreter = yes; then
-AC_DEFINE(HAVE_HASH_BANG_EXEC)
-fi
-
-dnl Miscellaneous Bash tests
-if test "$ac_cv_func_lstat" = "no"; then
-BASH_FUNC_LSTAT
-fi
-
-dnl behavior of system calls and library functions
-BASH_FUNC_CTYPE_NONASCII
-BASH_FUNC_DUP2_CLOEXEC_CHECK
-BASH_SYS_PGRP_SYNC
-BASH_SYS_SIGNAL_VINTAGE
-
-dnl checking for the presence of certain library symbols
-BASH_SYS_ERRLIST
-BASH_SYS_SIGLIST
-BASH_UNDER_SYS_SIGLIST
-
-dnl various system types
-BASH_TYPE_SIGHANDLER
-BASH_CHECK_TYPE(clock_t, [#include <sys/times.h>], long)
-BASH_CHECK_TYPE(sigset_t, [#include <signal.h>], int)
-BASH_CHECK_TYPE(quad_t, , long, HAVE_QUAD_T)
-BASH_CHECK_TYPE(intmax_t, , $bash_cv_type_long_long)
-BASH_CHECK_TYPE(uintmax_t, , $bash_cv_type_unsigned_long_long)
-if test "$ac_cv_header_sys_socket_h" = "yes"; then
-BASH_CHECK_TYPE(socklen_t, [#include <sys/socket.h>], int, HAVE_SOCKLEN_T)
-fi
-BASH_TYPE_RLIMIT
-
-dnl presence and contents of structures used by system calls
-BASH_STRUCT_TERMIOS_LDISC
-BASH_STRUCT_TERMIO_LDISC
-BASH_STRUCT_DIRENT_D_INO
-BASH_STRUCT_DIRENT_D_FILENO
-BASH_STRUCT_DIRENT_D_NAMLEN
-BASH_STRUCT_WINSIZE
-BASH_STRUCT_TIMEVAL
-AC_CHECK_MEMBERS([struct stat.st_blocks])
-AC_STRUCT_TM
-AC_STRUCT_TIMEZONE
-BASH_STRUCT_TIMEZONE
-
-dnl presence and behavior of C library functions
-BASH_FUNC_STRSIGNAL
-BASH_FUNC_OPENDIR_CHECK
-BASH_FUNC_ULIMIT_MAXFDS
-BASH_FUNC_FPURGE
-BASH_FUNC_GETENV
-if test "$ac_cv_func_getcwd" = "yes"; then
-BASH_FUNC_GETCWD
-fi
-BASH_FUNC_POSIX_SETJMP
-BASH_FUNC_STRCOLL
-BASH_FUNC_SNPRINTF
-BASH_FUNC_VSNPRINTF
-
-dnl If putenv or unsetenv is not present, set the right define so the
-dnl prototype and declaration in lib/sh/getenv.c will be standard-conformant
-
-if test "$ac_cv_func_putenv" = "yes"; then
-BASH_FUNC_STD_PUTENV
-else
-AC_DEFINE(HAVE_STD_PUTENV)
-fi
-if test "$ac_cv_func_unsetenv" = "yes"; then
-BASH_FUNC_STD_UNSETENV
-else
-AC_DEFINE(HAVE_STD_UNSETENV)
-fi
-
-BASH_FUNC_PRINTF_A_FORMAT
-
-dnl presence and behavior of OS functions
-BASH_SYS_REINSTALL_SIGHANDLERS
-BASH_SYS_JOB_CONTROL_MISSING
-BASH_SYS_NAMED_PIPES
-
-dnl presence of certain CPP defines
-AC_HEADER_TIOCGWINSZ
-BASH_HAVE_TIOCSTAT
-BASH_HAVE_FIONREAD
-
-BASH_CHECK_WCONTINUED
-
-dnl miscellaneous
-BASH_CHECK_SPEED_T
-BASH_CHECK_GETPW_FUNCS
-BASH_CHECK_RTSIGS
-BASH_CHECK_SYS_SIGLIST
-
-dnl special checks
-case "$host_os" in
-hpux*) BASH_CHECK_KERNEL_RLIMIT ;;
-esac
-
-if test "$opt_readline" = yes; then
-dnl yuck
-case "$host_os" in
-aix*)  prefer_curses=yes ;;
-esac
-BASH_CHECK_LIB_TERMCAP
-fi
-AC_SUBST(TERMCAP_LIB)
-AC_SUBST(TERMCAP_DEP)
-
-BASH_CHECK_DEV_FD
-BASH_CHECK_DEV_STDIN
-BASH_SYS_DEFAULT_MAIL_DIR
-
-if test "$bash_cv_job_control_missing" = missing; then
-       opt_job_control=no
-fi
-
-if test "$opt_job_control" = yes; then
-AC_DEFINE(JOB_CONTROL)
-JOBS_O=jobs.o
-else
-JOBS_O=nojobs.o
-fi
-
-AC_SUBST(JOBS_O)
-
-dnl Defines that we want to propagate to the Makefiles in subdirectories,
-dnl like glob and readline
-
-LOCAL_DEFS=-DSHELL
-
-dnl use this section to possibly define more cpp variables, specify local
-dnl libraries, and specify any additional local cc or ld flags
-dnl
-dnl this should really go away someday
-
-case "${host_os}" in
-sysv4.2*)      AC_DEFINE(SVR4_2)
-               AC_DEFINE(SVR4) ;;
-sysv4*)                AC_DEFINE(SVR4) ;;
-sysv5*)                AC_DEFINE(SVR5) ;;
-hpux9*)                LOCAL_CFLAGS="-DHPUX9 -DHPUX" ;;
-hpux*)         LOCAL_CFLAGS=-DHPUX ;;
-dgux*)         LOCAL_CFLAGS=-D_DGUX_SOURCE; LOCAL_LIBS=-ldgc ;;
-isc*)          LOCAL_CFLAGS=-Disc386 ;;
-rhapsody*)     LOCAL_CFLAGS=-DRHAPSODY ;;
-darwin*)       LOCAL_CFLAGS=-DMACOSX ;;
-sco3.2v5*)     LOCAL_CFLAGS="-b elf -DWAITPID_BROKEN -DPATH_MAX=1024" ;;
-sco3.2v4*)     LOCAL_CFLAGS="-DMUST_UNBLOCK_CHLD -DPATH_MAX=1024" ;;
-sco3.2*)       LOCAL_CFLAGS=-DMUST_UNBLOCK_CHLD ;;
-sunos4*)       LOCAL_CFLAGS=-DSunOS4 ;;
-solaris2.5*)   LOCAL_CFLAGS="-DSunOS5 -DSOLARIS" ;;
-solaris2.8*)   LOCAL_CFLAGS=-DSOLARIS  ;;
-solaris2.9*)   LOCAL_CFLAGS=-DSOLARIS  ;;
-solaris2.10*)  LOCAL_CFLAGS=-DSOLARIS  ;;
-solaris2*)     LOCAL_CFLAGS=-DSOLARIS ;;
-lynxos*)       LOCAL_CFLAGS=-DRECYCLES_PIDS ;;
-linux*)                LOCAL_LDFLAGS=-rdynamic          # allow dynamic loading
-               case "`uname -r`" in
-               2.[[456789]]*|3*)       AC_DEFINE(PGRP_PIPE) ;;
-               esac ;;
-*qnx6*)                LOCAL_CFLAGS="-Dqnx -Dqnx6" LOCAL_LIBS="-lncurses" ;;
-*qnx*)         LOCAL_CFLAGS="-Dqnx -F -3s" LOCAL_LDFLAGS="-3s" LOCAL_LIBS="-lunix -lncurses" ;;
-powerux*)      LOCAL_LIBS="-lgen" ;;
-cygwin*)       LOCAL_CFLAGS=-DRECYCLES_PIDS ;;
-opennt*|interix*) LOCAL_CFLAGS="-DNO_MAIN_ENV_ARG -DBROKEN_DIRENT_D_INO -D_POSIX_SOURCE -D_ALL_SOURCE" ;;
-esac
-
-dnl Stanza for OS/compiler pair-specific flags
-case "${host_os}-${CC}" in
-aix4.2*-*gcc*) LOCAL_LDFLAGS="-Xlinker -bexpall -Xlinker -brtl" ;;
-aix4.2*)       LOCAL_LDFLAGS="-bexpall -brtl" ;;
-bsdi4*-*gcc*)  LOCAL_LDFLAGS="-rdynamic" ;;    # allow dynamic loading, like Linux
-esac
-
-dnl FreeBSD-3.x can have either a.out or ELF
-case "${host_os}" in
-freebsd[[3-9]]*)
-               if test -x /usr/bin/objformat && test "`/usr/bin/objformat`" = "elf" ; then
-                       LOCAL_LDFLAGS=-rdynamic # allow dynamic loading
-               fi ;;
-freebsdelf*)   LOCAL_LDFLAGS=-rdynamic ;;      # allow dynamic loading
-dragonfly*)    LOCAL_LDFLAGS=-rdynamic ;;      # allow dynamic loading
-esac
-
-case "$host_cpu" in
-*cray*)                LOCAL_CFLAGS="-DCRAY" ;; # shell var so config.h can use it
-esac
-
-case "$host_cpu-$host_os" in
-ibmrt-*bsd4*)  LOCAL_CFLAGS="-ma -U__STDC__" ;;
-esac
-
-case "$host_cpu-$host_vendor-$host_os" in
-m88k-motorola-sysv3)   LOCAL_CFLAGS=-DWAITPID_BROKEN ;;
-mips-pyramid-sysv4)    LOCAL_CFLAGS=-Xa ;;
-esac
-
-#
-# Shared object configuration section.  These values are generated by
-# ${srcdir}/support/shobj-conf
-#
-if test "$ac_cv_func_dlopen" = "yes" && test -f ${srcdir}/support/shobj-conf
-then
-       AC_MSG_CHECKING(shared object configuration for loadable builtins)
-       eval `${CONFIG_SHELL-/bin/sh} ${srcdir}/support/shobj-conf -C "${CC}" -c "${host_cpu}" -o "${host_os}" -v "${host_vendor}"`
-       AC_SUBST(SHOBJ_CC)
-       AC_SUBST(SHOBJ_CFLAGS)
-       AC_SUBST(SHOBJ_LD)
-       AC_SUBST(SHOBJ_LDFLAGS)
-       AC_SUBST(SHOBJ_XLDFLAGS)
-       AC_SUBST(SHOBJ_LIBS)
-       AC_SUBST(SHOBJ_STATUS)
-       AC_MSG_RESULT($SHOBJ_STATUS)
-fi
-
-# try to create a directory tree if the source is elsewhere
-# this should be packaged into a script accessible via ${srcdir}/support
-case "$srcdir" in
-.)     ;;
-*)     for d in doc tests support lib examples; do     # dirs
-               test -d $d || mkdir $d
-       done
-       for ld in readline glob tilde malloc sh termcap; do     # libdirs
-               test -d lib/$ld || mkdir lib/$ld
-       done
-       test -d examples/loadables || mkdir examples/loadables  # loadable builtins
-       test -d examples/loadables/perl || mkdir examples/loadables/perl
-       ;;
-esac
-
-BUILD_DIR=`pwd`
-case "$BUILD_DIR" in
-*\ *)  BUILD_DIR=`echo "$BUILD_DIR" | sed 's: :\\\\ :g'` ;;
-*)     ;;
-esac
-
-if test -z "$localedir"; then
-       localedir='${datarootdir}/locale'
-fi
-if test -z "$datarootdir"; then
-       datarootdir='${prefix}/share'
-fi
-
-AC_SUBST(PROFILE_FLAGS)
-
-AC_SUBST(incdir)
-AC_SUBST(BUILD_DIR)
-
-# Some versions of autoconf don't substitute these automatically
-AC_SUBST(datarootdir)
-AC_SUBST(localedir)
-
-AC_SUBST(YACC)
-AC_SUBST(AR)
-AC_SUBST(ARFLAGS)
-
-AC_SUBST(BASHVERS)
-AC_SUBST(RELSTATUS)
-AC_SUBST(DEBUG)
-AC_SUBST(MALLOC_DEBUG)
-
-AC_SUBST(host_cpu)
-AC_SUBST(host_vendor)
-AC_SUBST(host_os)
-
-AC_SUBST(LOCAL_LIBS)
-AC_SUBST(LOCAL_CFLAGS)
-AC_SUBST(LOCAL_LDFLAGS)
-AC_SUBST(LOCAL_DEFS)
-
-#AC_SUBST(ALLOCA_SOURCE)
-#AC_SUBST(ALLOCA_OBJECT)
-
-AC_OUTPUT([Makefile builtins/Makefile lib/readline/Makefile lib/glob/Makefile \
-         lib/intl/Makefile \
-         lib/malloc/Makefile lib/sh/Makefile lib/termcap/Makefile \
-         lib/tilde/Makefile doc/Makefile support/Makefile po/Makefile.in \
-         examples/loadables/Makefile examples/loadables/perl/Makefile],
-[
-# Makefile uses this timestamp file to record whether config.h is up to date.
-echo timestamp > stamp-h
-])
diff --git a/cross-build/cygwin32.cache.old b/cross-build/cygwin32.cache.old
deleted file mode 100644 (file)
index 640390f..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-# 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/ddd1~ b/ddd1~
deleted file mode 100644 (file)
index a0ce497..0000000
--- a/ddd1~
+++ /dev/null
@@ -1,125 +0,0 @@
-*** ../bash-4.0-patched/bashline.c     2009-01-08 09:29:24.000000000 -0500
---- bashline.c 2009-07-16 14:13:41.000000000 -0400
-***************
-*** 1387,1391 ****
-    /* If the word starts in `~', and there is no slash in the word, then
-       try completing this word as a username. */
-!   if (!matches && *text == '~' && !xstrchr (text, '/'))
-      matches = rl_completion_matches (text, rl_username_completion_function);
-  
---- 1387,1391 ----
-    /* If the word starts in `~', and there is no slash in the word, then
-       try completing this word as a username. */
-!   if (matches ==0 && *text == '~' && mbschr (text, '/') == 0)
-      matches = rl_completion_matches (text, rl_username_completion_function);
-  
-***************
-*** 2667,2675 ****
-    local_dirname = *dirname;
-  
-!   if (xstrchr (local_dirname, '$'))
-      should_expand_dirname = 1;
-    else
-      {
-!       t = xstrchr (local_dirname, '`');
-        if (t && unclosed_pair (local_dirname, strlen (local_dirname), "`") == 0)
-       should_expand_dirname = 1;
---- 2667,2675 ----
-    local_dirname = *dirname;
-  
-!   if (mbschr (local_dirname, '$'))
-      should_expand_dirname = 1;
-    else
-      {
-!       t = mbschr (local_dirname, '`');
-        if (t && unclosed_pair (local_dirname, strlen (local_dirname), "`") == 0)
-       should_expand_dirname = 1;
-***************
-*** 3226,3230 ****
-         *r++ = *++p;
-         if (*p == '\0')
-!          break;
-         continue;
-       }
---- 3226,3230 ----
-         *r++ = *++p;
-         if (*p == '\0')
-!          return ret;         /* XXX - was break; */
-         continue;
-       }
-***************
-*** 3272,3276 ****
-        /* OK, we have an unquoted character.  Check its presence in
-        rl_completer_word_break_characters. */
-!       if (xstrchr (rl_completer_word_break_characters, *s))
-       *r++ = '\\';
-        /* XXX -- check for standalone tildes here and backslash-quote them */
---- 3272,3276 ----
-        /* OK, we have an unquoted character.  Check its presence in
-        rl_completer_word_break_characters. */
-!       if (mbschr (rl_completer_word_break_characters, *s))
-       *r++ = '\\';
-        /* XXX -- check for standalone tildes here and backslash-quote them */
-***************
-*** 3314,3318 ****
-       quoted correctly using backslashes (a backslash-newline pair is
-       special to the shell parser). */
-!   if (*qcp == '\0' && cs == COMPLETE_BSQUOTE && xstrchr (s, '\n'))
-      cs = COMPLETE_SQUOTE;
-    else if (*qcp == '"')
---- 3314,3318 ----
-       quoted correctly using backslashes (a backslash-newline pair is
-       special to the shell parser). */
-!   if (*qcp == '\0' && cs == COMPLETE_BSQUOTE && mbschr (s, '\n'))
-      cs = COMPLETE_SQUOTE;
-    else if (*qcp == '"')
-***************
-*** 3322,3330 ****
-  #if defined (BANG_HISTORY)
-    else if (*qcp == '\0' && history_expansion && cs == COMPLETE_DQUOTE &&
-!         history_expansion_inhibited == 0 && xstrchr (s, '!'))
-      cs = COMPLETE_BSQUOTE;
-  
-    if (*qcp == '"' && history_expansion && cs == COMPLETE_DQUOTE &&
-!      history_expansion_inhibited == 0 && xstrchr (s, '!'))
-      {
-        cs = COMPLETE_BSQUOTE;
---- 3322,3330 ----
-  #if defined (BANG_HISTORY)
-    else if (*qcp == '\0' && history_expansion && cs == COMPLETE_DQUOTE &&
-!         history_expansion_inhibited == 0 && mbschr (s, '!'))
-      cs = COMPLETE_BSQUOTE;
-  
-    if (*qcp == '"' && history_expansion && cs == COMPLETE_DQUOTE &&
-!      history_expansion_inhibited == 0 && mbschr (s, '!'))
-      {
-        cs = COMPLETE_BSQUOTE;
-***************
-*** 3389,3393 ****
-    register int i;
-    intmax_t mi;
--   int save_point;
-    sh_parser_state_t ps;
-    char *cmd, *value, *l;
---- 3389,3392 ----
-***************
-*** 3433,3437 ****
-      VSETATTR (v, att_exported);
-    l = value_cell (v);
--   save_point = rl_point;
-    value = inttostr (rl_point, ibuf, sizeof (ibuf));
-    v = bind_int_variable ("READLINE_POINT", value);
---- 3432,3435 ----
-***************
-*** 3451,3455 ****
-      {
-        i = mi;
-!       if (i != save_point)
-       {
-         rl_point = i;
---- 3449,3453 ----
-      {
-        i = mi;
-!       if (i != rl_point)
-       {
-         rl_point = i;
diff --git a/doc/FAQ-4.1~ b/doc/FAQ-4.1~
deleted file mode 100644 (file)
index 5ea5e5f..0000000
+++ /dev/null
@@ -1,2199 +0,0 @@
-This is the Bash FAQ, version 4.10, for Bash version 4.1.
-
-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.ramey@case.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 Shell and Utilities standard'?
-A10) What is the bash `posix mode'?
-
-Section B:  The latest version
-
-B1) What's new in version 4.1?
-B2) Are there any user-visible incompatibilities between bash-4.1 and
-    previous bash versions?
-
-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?
-E12) Why don't negative offsets in substring expansion work like I expect?
-E13) Why does filename completion misbehave if a colon appears in the filename?
-E14) Why does quoting the pattern argument to the regular expression matching
-     conditional operator (=~) cause matching to stop working?
-E15) Tell me more about the shell compatibility level.
-
-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 4.1, first made available on XX January, 2010.
-
-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 4.1:
-
-ftp://ftp.gnu.org/pub/gnu/bash/bash-4.1.tar.gz
-ftp://ftp.cwru.edu/pub/bash/bash-4.1.tar.gz
-
-Formatted versions of the documentation are available with the URLs:
-
-ftp://ftp.gnu.org/pub/gnu/bash/bash-doc-4.1.tar.gz
-ftp://ftp.cwru.edu/pub/bash/bash-doc-4.1.tar.gz
-
-Any patches for the current version are available with the URL:
-
-ftp://ftp.cwru.edu/pub/bash/bash-4.1-patches/
-
-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 (now part of Red Hat) as part
-of their CYGWIN project.  For more information about the project, see
-http://www.cygwin.com/.
-
-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
-ports of bash-3.2 and bash-4.0 to the CYGWIN environment, and both
-are available as part of their current release.
-
-Bash-2.05b and later versions should require no local Cygnus changes to
-build and run under CYGWIN.
-
-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 began to work with bash-2.05, but I don't know the current status.
-
-Bash-3.0 compiles and runs with no modifications under Microsoft's Services
-for Unix (SFU), once known as Interix.  I do not anticipate any problems
-with building bash-4.1, but will gladly accept any patches that are needed.
-
-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 Shell and Utilities 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 was originally developed by
-IEEE Working Group 1003.2 (POSIX.2).  Today it has been merged with
-the original 1003.1 Working Group and is maintained by the Austin
-Group (a joint working group of the IEEE, The Open Group and
-ISO/IEC SC22/WG15).  Today the Shell and Utilities are a volume
-within the set of documents that make up IEEE Std 1003.1-2001, and
-thus now the former POSIX.2 (from 1992) is now part of the current
-POSIX.1 standard (POSIX 1003.1-2001). 
-
-The Shell and Utilities volume concentrates on the command
-interpreter interface and utility programs commonly executed from
-the command line or by other programs.  The standard is freely
-available on the web at http://www.UNIX-systems.org/version3/ . 
-Work continues at the Austin Group on maintenance issues; see
-http://www.opengroup.org/austin/ to join the discussions. 
-
-Bash is concerned with the aspects of the shell's behavior defined
-by the POSIX Shell and Utilities volume.  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 not
-devoted to the shell which are commonly (and in some cases must
-be) implemented as builtin commands, such as `read' and `test'. 
-POSIX 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 latest version of the POSIX Shell and Utilities standard is
-available (now updated to the 2004 Edition) as part of the Single
-UNIX Specification Version 3 at
-
-http://www.UNIX-systems.org/version3/
-
-A10)  What is the bash `posix mode'?
-
-Although bash is an implementation of the POSIX 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 4.1?
-
-Bash-4.1 is the first revision to the fourth major release of bash.
-
-Bash-4.1 contains the following new features (see the manual page for
-complete descriptions and the CHANGES and NEWS files in the bash-4.1
-distribution):
-
-o   Here-documents within $(...) command substitutions may once more be
-    delimited by the closing right paren, instead of requiring a newline.
-
-o   Bash's file status checks (executable, readable, etc.) now take file
-    system ACLs into account on file systems that support them.
-
-o   Bash now passes environment variables with names that are not valid
-    shell variable names through into the environment passed to child
-    processes.
-
-o   The `execute-unix-command' readline function now attempts to clear and
-    reuse the current line rather than move to a new one after the command
-    executes.
-
-o   `printf -v' can now assign values to array indices.
-
-o   New `complete -E' and `compopt -E' options that work on the "empty"
-    completion: completion attempted on an empty command line.
-
-o   New complete/compgen/compopt -D option to define a `default' completion:
-    a completion to be invoked on command for which no completion has been
-    defined.  If this function returns 124, programmable completion is
-    attempted again, allowing a user to dynamically build a set of completions
-    as completion is attempted by having the default completion function
-    install individual completion functions each time it is invoked.
-
-o   When displaying associative arrays, subscripts are now quoted.
-
-o   Changes to dabbrev-expand to make it more `emacs-like': no space appended
-    after matches, completions are not sorted, and most recent history entries
-    are presented first.
-
-o   The [[ and (( commands are now subject to the setting of `set -e' and the
-    ERR trap.
-
-o   The source/. builtin now removes NUL bytes from the file before attempting
-    to parse commands.
-
-o   There is a new configuration option (in config-top.h) that forces bash to
-    forward all history entries to syslog.
-
-o   A new variable $BASHOPTS to export shell options settable using `shopt' to
-    child processes.
-
-o   There is a new confgure option that forces the extglob option to be
-    enabled by default.
-
-o   New variable $BASH_XTRACEFD; when set to an integer bash will write xtrace
-    output to that file descriptor.
-
-o   If the optional left-hand-side of a redirection is of the form {var}, the
-    shell assigns the file descriptor used to $var or uses $var as the file
-    descriptor to move or close, depending on the redirection operator.
-
-o   The < and > operators to the [[ conditional command now do string
-    comparison according to the current locale.
-
-o   Programmable completion now uses the completion for `b' instead of `a'
-    when completion is attempted on a line like: a $(b c.
-
-o   Force extglob on temporarily when parsing the pattern argument to
-    the == and != operators to the [[ command, for compatibility.
-
-o   Changed the behavior of interrupting the wait builtin when a SIGCHLD is
-    received and a trap on SIGCHLD is set to be Posix-mode only.
-
-o   The read builtin has a new `-N nchars' option, which reads exactly NCHARS
-    characters, ignoring delimiters like newline.
-
-o   The mapfile/readarray builtin no longer stores the commands it invokes via
-    callbacks in the history list.
-
-o   There is a new `compat40' shopt option.
-
-o   The < and > operators to [[ do string comparisons using the current locale
-    only if the compatibility level is greater than 40 (set to 41 by default).
-
-o   New bindable readline function: menu-complete-backward.
-
-o   In the readline vi-mode insertion keymap, C-n is now bound to menu-complete
-    by default, and C-p to menu-complete-backward.
-
-o   When in readline vi command mode, repeatedly hitting ESC now does nothing,
-    even when ESC introduces a bound key sequence.  This is closer to how
-    historical vi behaves.
-
-o   New bindable readline function: skip-csi-sequence.  Can be used as a
-    default to consume key sequences generated by keys like Home and End
-    without having to bind all keys.
-
-o   New bindable readline variable: skip-completed-text, active when
-    completing in the middle of a word.  If enabled, it means that characters
-    in the completion that match characters in the remainder of the word are
-    "skipped" rather than inserted into the line.
-
-o   The pre-readline-6.0 version of menu completion is available as
-    "old-menu-complete" for users who do not like the readline-6.0 version.
-
-o   New bindable readline variable: echo-control-characters.  If enabled, and
-    the tty ECHOCTL bit is set, controls the echoing of characters
-    corresponding to keyboard-generated signals.
-
-o   New bindable readline variable: enable-meta-key.  Controls whether or not
-    readline sends the smm/rmm sequences if the terminal indicates it has a
-    meta key that enables eight-bit characters.
-
-A short feature history dating from Bash-2.0:
-
-Bash-4.0 contained the following new features:
-
-o   When using substring expansion on the positional parameters, a starting
-    index of 0 now causes $0 to be prefixed to the list.
-
-o   There is a new variable, $BASHPID, which always returns the process id of
-    the current shell.
-
-o   There is a new `autocd' option that, when enabled, causes bash to attempt
-    to `cd' to a directory name that is supplied as the first word of a
-    simple command.
-
-o   There is a new `checkjobs' option that causes the shell to check for and
-    report any running or stopped jobs at exit.
-
-o   The programmable completion code exports a new COMP_TYPE variable, set to
-    a character describing the type of completion being attempted.
-
-o   The programmable completion code exports a new COMP_KEY variable, set to
-    the character that caused the completion to be invoked (e.g., TAB).
-
-o   The programmable completion code now uses the same set of characters as
-    readline when breaking the command line into a list of words.
-
-o   The block multiplier for the ulimit -c and -f options is now 512 when in
-    Posix mode, as Posix specifies.
-
-o   Changed the behavior of the read builtin to save any partial input received
-    in the specified variable when the read builtin times out.  This also
-    results in variables specified as arguments to read to be set to the empty
-    string when there is no input available.  When the read builtin times out,
-    it returns an exit status greater than 128.
-
-o   The shell now has the notion of a `compatibility level', controlled by
-    new variables settable by `shopt'.  Setting this variable currently
-    restores the bash-3.1 behavior when processing quoted strings on the rhs
-    of the `=~' operator to the `[[' command.
-
-o   The `ulimit' builtin now has new -b (socket buffer size) and -T (number
-    of threads) options.
-
-o   There is a new `compopt' builtin that allows completion functions to modify
-    completion options for existing completions or the completion currently
-    being executed.
-
-o   The `read' builtin has a new -i option which inserts text into the reply
-    buffer when using readline.
-
-o   A new `-E' option to the complete builtin allows control of the default
-    behavior for completion on an empty line.
-
-o   There is now limited support for completing command name words containing
-    globbing characters.
-
-o   The `help' builtin now has a new -d option, to display a short description,
-    and a -m option, to print help information in a man page-like format.
-
-o   There is a new `mapfile' builtin to populate an array with lines from a
-    given file.
-
-o   If a command is not found, the shell attempts to execute a shell function
-    named `command_not_found_handle', supplying the command words as the
-    function arguments.
-
-o   There is a new shell option: `globstar'.  When enabled, the globbing code
-    treats `**' specially -- it matches all directories (and files within
-    them, when appropriate) recursively.
-
-o   There is a new shell option: `dirspell'.  When enabled, the filename
-    completion code performs spelling correction on directory names during
-    completion.
-
-o   The `-t' option to the `read' builtin now supports fractional timeout
-    values.
-
-o   Brace expansion now allows zero-padding of expanded numeric values and
-    will add the proper number of zeroes to make sure all values contain the
-    same number of digits.
-
-o   There is a new bash-specific bindable readline function: `dabbrev-expand'.
-    It uses menu completion on a set of words taken from the history list.
-
-o   The command assigned to a key sequence with `bind -x' now sets two new
-    variables in the environment of the executed command:  READLINE_LINE_BUFFER
-    and READLINE_POINT.  The command can change the current readline line
-    and cursor position by modifying READLINE_LINE_BUFFER and READLINE_POINT,
-    respectively.
-
-o   There is a new >>& redirection operator, which appends the standard output
-    and standard error to the named file.
-
-o   The parser now understands `|&' as a synonym for `2>&1 |', which redirects
-    the standard error for a command through a pipe.
-
-o   The new `;&' case statement action list terminator causes execution to
-    continue with the action associated with the next pattern in the
-    statement rather than terminating the command.
-
-o   The new `;;&' case statement action list terminator causes the shell to
-    test the next set of patterns after completing execution of the current
-    action, rather than terminating the command.
-
-o   The shell understands a new variable: PROMPT_DIRTRIM.  When set to an
-    integer value greater than zero, prompt expansion of \w and \W  will
-    retain only that number of trailing pathname components and replace
-    the intervening characters with `...'.
-
-o   There are new case-modifying word expansions: uppercase (^[^]) and
-    lowercase (,[,]).  They can work on either the first character or
-    array element, or globally.  They accept an optional shell pattern
-    that determines which characters to modify.  There is an optionally-
-    configured feature to include capitalization operators.
-
-o   The shell provides associative array variables, with the appropriate
-    support to create, delete, assign values to, and expand them.
-
-o   The `declare' builtin now has new -l (convert value to lowercase upon
-    assignment) and -u (convert value to uppercase upon assignment) options.
-    There is an optionally-configurable -c option to capitalize a value at
-    assignment.
-
-o   There is a new `coproc' reserved word that specifies a coprocess: an
-    asynchronous command run with two pipes connected to the creating shell.
-    Coprocs can be named.  The input and output file descriptors and the
-    PID of the coprocess are available to the calling shell in variables
-    with coproc-specific names.
-
-o   A value of 0 for the -t option to `read' now returns success if there is
-    input available to be read from the specified file descriptor.
-
-o   CDPATH and GLOBIGNORE are ignored when the shell is running in privileged
-    mode.
-
-o   New bindable readline functions shell-forward-word and shell-backward-word,
-    which move forward and backward words delimited by shell metacharacters
-    and honor shell quoting.
-
-o   New bindable readline functions shell-backward-kill-word and shell-kill-word
-    which kill words backward and forward, but use the same word boundaries
-    as shell-forward-word and shell-backward-word.
-
-Bash-3.2 contained the following new features:
-
-o Bash-3.2 now checks shell scripts for NUL characters rather than non-printing
-  characters when deciding whether or not a script is a binary file.
-
-o Quoting the string argument to the [[ command's  =~ (regexp) operator now
-  forces string matching, as with the other pattern-matching operators.
-
-Bash-3.1 contained the following new features:
-
-o Bash-3.1 may now be configured and built in a mode that enforces strict
-  POSIX compliance.
-
-o The `+=' assignment operator, which appends to the value of a string or
-  array variable, has been implemented.
-
-o It is now possible to ignore case when matching in contexts other than
-  filename generation using the new `nocasematch' shell option.
-
-Bash-3.0 contained the following new features:
-
-o Features to support the bash debugger have been implemented, and there
-  is a new `extdebug' option to turn the non-default options on
-
-o HISTCONTROL is now a colon-separated list of options and has been
-  extended with a new `erasedups' option that will result in only one
-  copy of a command being kept in the history list
-
-o Brace expansion has been extended with a new {x..y} form, producing
-  sequences of digits or characters
-
-o Timestamps are now kept with history entries, with an option to save
-  and restore them from the history file; there is a new HISTTIMEFORMAT
-  variable describing how to display the timestamps when listing history
-  entries
-
-o The `[[' command can now perform extended regular expression (egrep-like)
-  matching, with matched subexpressions placed in the BASH_REMATCH array
-  variable
-
-o A new `pipefail' option causes a pipeline to return a failure status if
-  any command in it fails
-
-o The `jobs', `kill', and `wait' builtins now accept job control notation
-  in their arguments even if job control is not enabled
-
-o The `gettext' package and libintl have been integrated, and the shell
-  messages may be translated into other languages
-
-Bash-2.05b introduced the following new features:
-
-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
-
-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-4.1 and
-    previous bash versions?
-
-There are a few incompatibilities between version 4.1 and previous
-versions.  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 (or bug-bash@gnu.org if you would like
-community discussion) 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, BASHPID, 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, PROMPT_DIRTRIM, BASHOPTS, BASH_XTRACEFD
-       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/-i/-N,
-                 readonly -a/-f/name=value, trap -l, set +o,
-                 set -b/-m/-o option/-h/-p/-B/-C/-H/-P,
-                 unset -f/-v, ulimit -i/-m/-p/-q/-u/-x,
-                 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, compopt, mapfile
-       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 and strict posix conformance
-       redirection to /dev/fd/N, /dev/stdin, /dev/stdout, /dev/stderr,
-               /dev/tcp/host/port, /dev/udp/host/port
-       debugger support, including `caller' builtin and new variables
-       RETURN trap
-       the `+=' assignment operator
-       autocd shell option and behavior
-       command-not-found hook with command_not_found_handle shell function
-       globstar shell option and `**' globbing behavior
-       |& synonym for `2>&1 |'
-       ;& and ;;& case action list terminators
-       case-modifying word expansions and variable attributes
-       associative arrays
-       coprocesses using the `coproc' reserved word and variables
-       shell assignment of a file descriptor used in a redirection to a variable
-
-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, BASHPID, 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_DIRTRIM
-       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/-N, 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 -i/-q/-u/-x, umask -S, alias -p,
-                 shopt, disown, printf, complete, compgen, compopt, mapfile
-       `!' 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'
-       debugger support, including the `caller' builtin
-       RETURN trap
-       Timestamps in history entries
-       {x..y} brace expansion
-       The `+=' assignment operator
-       autocd shell option and behavior
-       command-not-found hook with command_not_found_handle shell function
-       globstar shell option and `**' globbing behavior
-       |& synonym for `2>&1 |'
-       ;& and ;;& case action list terminators
-       case-modifying word expansions and variable attributes
-       associative arrays
-       coprocesses using the `coproc' reserved word and variables
-       shell assignment of a file descriptor used in a redirection to a variable
-
-Things ksh88 has or uses that bash does not:
-       tracked aliases (alias -t)
-       variables: ERRNO, FPATH, EDITOR, VISUAL
-       co-processes (bash uses different syntax)
-       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, newgrp, print,
-                 read -p/-s/var?prompt, set -A/-o gmacs/
-                 -o bgnice/-o markdirs/-o trackall/-o viraw/-s,
-                 typeset -H/-L/-R/-Z/-A/-ft/-fu/-fx/-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?
-
-This list is current through ksh93t+ (05/05/2009)
-
-New things in ksh-93 not in bash-4.1:
-       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
-       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 (match all instead of any)
-       exit statuses between 0 and 255
-       FPATH and PATH mixing
-       lexical scoping for local variables in `ksh' functions
-       no scoping for local variables in `POSIX' functions
-       $''  \C[.collating-element.] escape sequence
-       -C/-I invocation options
-       print -f (bash uses printf)
-       `fc' has been renamed to `hist'
-       `.' can execute shell functions
-       getopts -a
-       printf %B, %H, %P, %R, %T, %Z modifiers, output base for %d, `=' flag
-       read -n/-N differ/-v
-       set -o showme/-o multiline (bash default)
-       `sleep' and `getconf' builtins (bash has loadable versions)
-       typeset -n and `nameref' variables
-       [[ -R name ]] (checks whether or not name is a nameref)
-       typeset -C/-S/-T/-X/-h/-s
-       experimental `type' definitions (a la typedef) using typeset
-       negative subscripts for indexed array variables
-       array expansions ${array[sub1..sub2]} and ${!array[sub1..sub2]}
-       associative array assignments using `;' as element separator
-       command substitution $(n<#) expands to current byte offset for fd N
-       new '${ ' form of command substitution, executed in current shell
-       new >;/<>;/<#pat/<##pat/<#/># redirections
-       brace expansion printf-like formats 
-       [[ -v var ]] operators (checks whether or not var is set)
-
-New things in ksh-93 present in bash-4.1:
-       associative arrays
-       [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'
-       new $'...' and $"..." quoting
-       FIGNORE (but bash uses GLOBIGNORE), HISTCMD
-       brace expansion and set -B
-       changes to kill builtin
-       `command', `builtin', `disown' builtins
-       echo -e
-       exec -c/-a
-       read -A (bash uses read -a)
-        read -t/-d
-       trap -p
-       `.' restores the positional parameters when it completes
-       set -o notify/-C
-       set -o pipefail
-       set -G (-o globstar) and **
-       POSIX.2 `test'
-       umask -S
-       unalias -a
-       command and arithmetic substitution performed on PS1, PS4, and ENV
-       command name completion, TAB displaying possible completions
-       ENV processed only for interactive shells
-       The `+=' assignment operator
-       the `;&' case statement "fallthrough" pattern list terminator
-       csh-style history expansion and set -H
-       negative offsets in ${param:offset:length}
-       redirection operators preceded with {varname} to store fd number in varname
-       DEBUG can force skipping following command
-
-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.  Many Linux distributions
-use GNU `which', which is a C program that can understand shell
-aliases.
-
-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. 
-
-As of bash-3.1, bash does not report SIGPIPE errors by default.  You
-can build a version of bash that will report such errors.
-
-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, even a builtin or shell function,
-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 updated POSIX standard has 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'.
-
-E12) Why don't negative offsets in substring expansion work like I expect?
-
-When substring expansion of the form ${param:offset[:length} is used,
-an `offset' that evaluates to a number less than zero counts back from
-the end of the expanded value of $param.
-
-When a negative `offset' begins with a minus sign, however, unexpected things
-can happen.  Consider
-
-       a=12345678
-       echo ${a:-4}
-
-intending to print the last four characters of $a.  The problem is that
-${param:-word} already has a well-defined meaning: expand to word if the
-expanded value of param is unset or null, and $param otherwise.
-
-To use negative offsets that begin with a minus sign, separate the
-minus sign and the colon with a space.
-
-E13) Why does filename completion misbehave if a colon appears in the filename?
-
-Filename completion (and word completion in general) may appear to behave
-improperly if there is a colon in the word to be completed.
-
-The colon is special to readline's word completion code:  it is one of the
-characters that breaks words for the completer.  Readline uses these characters
-in sort of the same way that bash uses $IFS: they break or separate the words
-the completion code hands to the application-specific or default word
-completion functions.  The original intent was to make it easy to edit
-colon-separated lists (such as $PATH in bash) in various applications using
-readline for input.
-
-This is complicated by the fact that some versions of the popular
-`bash-completion' programmable completion package have problems with the
-default completion behavior in the presence of colons.  
-
-The current set of completion word break characters is available in bash as
-the value of the COMP_WORDBREAKS variable.  Removing `:' from that value is
-enough to make the colon not special to completion:
-
-COMP_WORDBREAKS=${COMP_WORDBREAKS//:}
-
-You can also quote the colon with a backslash to achieve the same result
-temporarily.
-
-E14) Why does quoting the pattern argument to the regular expression matching
-     conditional operator (=~) cause regexp matching to stop working?
-
-In versions of bash prior to bash-3.2, the effect of quoting the regular
-expression argument to the [[ command's =~ operator was not specified.
-The practical effect was that double-quoting the pattern argument required
-backslashes to quote special pattern characters, which interfered with the
-backslash processing performed by double-quoted word expansion and was
-inconsistent with how the == shell pattern matching operator treated
-quoted characters.
-
-In bash-3.2, the shell was changed to internally quote characters in single-
-and double-quoted string arguments to the =~ operator, which suppresses the
-special meaning of the characters special to regular expression processing
-(`.', `[', `\', `(', `), `*', `+', `?', `{', `|', `^', and `$') and forces
-them to be matched literally.  This is consistent with how the `==' pattern
-matching operator treats quoted portions of its pattern argument.
-
-Since the treatment of quoted string arguments was changed, several issues
-have arisen, chief among them the problem of white space in pattern arguments
-and the differing treatment of quoted strings between bash-3.1 and bash-3.2.
-Both problems may be solved by using a shell variable to hold the pattern.
-Since word splitting is not performed when expanding shell variables in all
-operands of the [[ command, this allows users to quote patterns as they wish
-when assigning the variable, then expand the values to a single string that
-may contain whitespace.  The first problem may be solved by using backslashes
-or any other quoting mechanism to escape the white space in the patterns.
-
-Bash-4.0 introduces the concept of a `compatibility level', controlled by
-several options to the `shopt' builtin.  If the `compat31' option is enabled,
-bash reverts to the bash-3.1 behavior with respect to quoting the rhs of
-the =~ operator.
-
-E15) Tell me more about the shell compatibility level.
-
-Bash-4.0 introduced the concept of a `shell compatibility level', specified
-as a set of options to the shopt builtin (compat31, compat32, compat40 at
-this writing).  There is only one current compatibility level -- each
-option is mutually exclusive.  This list does not mention behavior that is
-standard for a particular version (e.g., setting compat32 means that quoting
-the rhs of the regexp matching operator quotes special regexp characters in
-the word, which is default behavior in bash-3.2 and above).
-
-compat31 set
-       - the < and > operators to the [[ command do not consider the current
-         locale when comparing strings
-       - quoting the rhs of the regexp matching operator (=~) has no
-         special effect
-
-compat32 set
-       - the < and > operators to the [[ command do not consider the current
-         locale when comparing strings
-
-compat40 set
-       - the < and > operators to the [[ command do not consider the current
-         locale when comparing strings
-       - interrupting a command list such as "a ; b ; c" causes the execution
-         of the entire list to be aborted
-
-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 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.
-
-The script examples/scripts.noah/meta.bash encapsulates the bind
-commands in a shell function.
-
-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.  It's a variant of
-
-       echo .[!.]* ..?* *
-
-(The ..?* catches files with names of three or more characters beginning
-with `..')
-
-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
-of the third edition, published in March, 2005, is 0-596-00965-8.  Look for
-it in fine bookstores near you.  This edition of the book has been updated
-to cover bash-3.0.
-
-The GNU Bash Reference Manual has been published as a printed book by
-Network Theory Ltd (Paperback, ISBN: 0-9541617-7-7, Nov. 2006).  It covers
-bash-3.2 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. 
-
-Arnold Robbins and Nelson Beebe have written ``Classic Shell Scripting'',
-published by O'Reilly.  The first edition, with ISBN number 0-596-00595-4,
-was published in May, 2005.
-
-Chris F. A. Johnson, a frequent contributor to comp.unix.shell and
-gnu.bash.bug, has written ``Shell Scripting Recipes: A Problem-Solution
-Approach,'' a new book on shell scripting, concentrating on features of
-the POSIX standard helpful to shell script writers.  The first edition from
-Apress, with ISBN number 1-59059-471-1, was published in May, 2005.
-
-H3) What's coming in future versions?
-
-These are features I hope to include in a future version of bash.
-
-Rocky Bernstein's bash debugger (support is included with bash-4.0)
-
-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
-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 `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 2009.  Never make predictions. 
-
-This document is Copyright 1995-2009 by Chester Ramey.
-
-Permission is hereby granted, without written agreement and
-without license or royalty fees, to use, copy, and distribute
-this document for any purpose, provided that the above copyright
-notice appears in all copies of this document and that the
-contents of this document remain unaltered.
diff --git a/doc/FAQ.orig b/doc/FAQ.orig
deleted file mode 100644 (file)
index 1cff3c8..0000000
+++ /dev/null
@@ -1,1745 +0,0 @@
-This is the Bash FAQ, version 3.24, for Bash version 2.05b.
-
-This document contains a set of frequently-asked questions concerning
-Bash, the GNU Bourne-Again Shell.  Bash is a freely-available command
-interpreter with advanced features for both interactive use and shell
-programming.
-
-Another good source of basic information about shells is the collection
-of FAQ articles periodically posted to comp.unix.shell.
-
-Questions and comments concerning this document should be sent to
-chet@po.cwru.edu.
-
-This document is available for anonymous FTP with the URL
-
-ftp://ftp.cwru.edu/pub/bash/FAQ
-
-The Bash home page is http://cnswww.cns.cwru.edu/~chet/bash/bashtop.html
-
-----------
-Contents:
-
-Section A:  The Basics
-
-A1) What is it?
-A2) What's the latest version?
-A3) Where can I get it?
-A4) On what machines will bash run?
-A5) Will bash run on operating systems other than Unix?
-A6) How can I build bash with gcc?
-A7) How can I make bash my login shell?
-A8) I just changed my login shell to bash, and now I can't FTP into my
-    machine.  Why not?
-A9) What's the `POSIX 1003.2 standard'?
-A10) What is the bash `posix mode'?
-
-Section B:  The latest version
-
-B1) What's new in version 2.05b?
-B2) Are there any user-visible incompatibilities between bash-2.05b and
-    bash-1.14.7?
-
-Section C:  Differences from other Unix shells
-
-C1) How does bash differ from sh, the Bourne shell?
-C2) How does bash differ from the Korn shell, version ksh88?
-C3) Which new features in ksh-93 are not in bash, and which are?
-
-Section D:  Why does bash do some things differently than other Unix shells?
-
-D1) Why does bash run a different version of `command' than
-    `which command' says it will?
-D2) Why doesn't bash treat brace expansions exactly like csh?
-D3) Why doesn't bash have csh variable modifiers?
-D4) How can I make my csh aliases work when I convert to bash?
-D5) How can I pipe standard output and standard error from one command to
-    another, like csh does with `|&'?
-D6) Now that I've converted from ksh to bash, are there equivalents to
-    ksh features like autoloaded functions and the `whence' command?
-
-Section E:  Why does bash do certain things the way it does?
-
-E1) Why is the bash builtin `test' slightly different from /bin/test?
-E2) Why does bash sometimes say `Broken pipe'?
-E3) When I have terminal escape sequences in my prompt, why does bash
-    wrap lines at the wrong column?
-E4) If I pipe the output of a command into `read variable', why doesn't
-    the output show up in $variable when the read command finishes?
-E5) I have a bunch of shell scripts that use backslash-escaped characters
-    in arguments to `echo'.  Bash doesn't interpret these characters.  Why
-    not, and how can I make it understand them?
-E6) Why doesn't a while or for loop get suspended when I type ^Z?
-E7) What about empty for loops in Makefiles?
-E8) Why does the arithmetic evaluation code complain about `08'?
-E9) Why does the pattern matching expression [A-Z]* match files beginning
-    with every letter except `z'?
-E10) Why does `cd //' leave $PWD as `//'?
-E11) If I resize my xterm while another program is running, why doesn't bash
-     notice the change?
-
-Section F:  Things to watch out for on certain Unix versions
-
-F1) Why can't I use command line editing in my `cmdtool'?
-F2) I built bash on Solaris 2.  Why do globbing expansions and filename
-    completion chop off the first few characters of each filename?
-F3) Why does bash dump core after I interrupt username completion or
-    `~user' tilde expansion on a machine running NIS?
-F4) I'm running SVR4.2.  Why is the line erased every time I type `@'?
-F5) Why does bash report syntax errors when my C News scripts use a
-    redirection before a subshell command?
-F6) Why can't I use vi-mode editing on Red Hat Linux 6.1?
-F7) Why do bash-2.05a and  bash-2.05b fail to compile `printf.def' on
-    HP/UX 11.x?
-
-Section G:  How can I get bash to do certain common things?
-
-G1) How can I get bash to read and display eight-bit characters?
-G2) How do I write a function `x' to replace builtin command `x', but
-    still invoke the command from within the function?
-G3) How can I find the value of a shell variable whose name is the value
-    of another shell variable?
-G4) How can I make the bash `time' reserved word print timing output that
-    looks like the output from my system's /usr/bin/time?
-G5) How do I get the current directory into my prompt?
-G6) How can I rename "*.foo" to "*.bar"?
-G7) How can I translate a filename from uppercase to lowercase?
-G8) How can I write a filename expansion (globbing) pattern that will match
-    all files in the current directory except "." and ".."?
-
-Section H:  Where do I go from here?
-
-H1) How do I report bugs in bash, and where should I look for fixes and
-    advice?
-H2) What kind of bash documentation is there?
-H3) What's coming in future versions?
-H4) What's on the bash `wish list'?
-H5) When will the next release appear?
-
-----------
-Section A:  The Basics
-
-A1)  What is it?
-
-Bash is a Unix command interpreter (shell).  It is an implementation of
-the Posix 1003.2 shell standard, and resembles the Korn and System V
-shells.
-
-Bash contains a number of enhancements over those shells, both
-for interactive use and shell programming.  Features geared
-toward interactive use include command line editing, command
-history, job control, aliases, and prompt expansion.  Programming
-features include additional variable expansions, shell
-arithmetic, and a number of variables and options to control
-shell behavior.
-
-Bash was originally written by Brian Fox of the Free Software
-Foundation.  The current developer and maintainer is Chet Ramey
-of Case Western Reserve University.
-
-A2)  What's the latest version?
-
-The latest version is 2.05b, first made available on Wednesday, 17
-July, 2002.
-
-A3)  Where can I get it?
-
-Bash is the GNU project's shell, and so is available from the
-master GNU archive site, ftp.gnu.org, and its mirrors.  The
-latest version is also available for FTP from ftp.cwru.edu.
-The following URLs tell how to get version 2.05b:
-
-ftp://ftp.gnu.org/pub/gnu/bash/bash-2.05b.tar.gz
-ftp://ftp.cwru.edu/pub/bash/bash-2.05b.tar.gz
-
-Formatted versions of the documentation are available with the URLs:
-
-ftp://ftp.gnu.org/pub/gnu/bash/bash-doc-2.05b.tar.gz
-ftp://ftp.cwru.edu/pub/bash/bash-doc-2.05b.tar.gz
-
-A4)  On what machines will bash run?
-
-Bash has been ported to nearly every version of UNIX.  All you
-should have to do to build it on a machine for which a port
-exists is to type `configure' and then `make'.  The build process
-will attempt to discover the version of UNIX you have and tailor
-itself accordingly, using a script created by GNU autoconf.
-
-More information appears in the file `INSTALL' in the distribution.
-
-The Bash web page (http://cnswww.cns.cwru.edu/~chet/bash/bashtop.html)
-explains how to obtain binary versions of bash for most of the major
-commercial Unix systems.
-
-A5) Will bash run on operating systems other than Unix?
-
-Configuration specifics for Unix-like systems such as QNX and
-LynxOS are included in the distribution.  Bash-2.05 and later
-versions should compile and run on Minix 2.0 (patches were
-contributed), but I don't believe anyone has built bash-2.x on
-earlier Minix versions yet. 
-
-Bash has been ported to versions of Windows implementing the Win32
-programming interface.  This includes Windows 95 and Windows NT.
-The port was done by Cygnus Solutions as part of their CYGWIN
-project.  For more information about the project, look at the URLs
-
-http://www.cygwin.com/
-http://sourceware.cygnus.com/cygwin
-
-Cygnus originally ported bash-1.14.7, and that port was part of their
-early GNU-Win32 (the original name) releases.  Cygnus has also done a
-port of bash-2.05 to the CYGWIN environment, and it is available as
-part of their current release.
-
-Bash-2.05b should require no local Cygnus changes to build and run under
-CYGWIN.
-
-The Cygnus port works only on Intel machines.  There is a port of bash
-(I don't know which version) to the alpha/NT environment available from
-
-ftp://ftp.gnustep.org//pub/win32/bash-alpha-nt-1.01.tar.gz
-
-DJ Delorie has a port of bash-2.x which runs under MS-DOS, as part
-of the DJGPP project.  For more information on the project, see
-
-http://www.delorie.com/djgpp/
-
-I have been told that the original DJGPP port was done by Daisuke Aoyama.
-
-Mark Elbrecht <snowball3@bigfoot.com> has sent me notice that bash-2.04
-is available for DJGPP V2.  The files are available as:
-
-ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/bsh204b.zip binary
-ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/bsh204d.zip documentation
-ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/bsh204s.zip source
-
-Mark has begun to work with bash-2.05, but I don't know the status.
-
-Ports of bash-1.12 and bash-2.0 are available for OS/2 from
-
-ftp://hobbes.nmsu.edu/pub/os2/util/shell/bash_112.zip
-ftp://hobbes.nmsu.edu/pub/os2/util/shell/bash-2.0(253).zip
-
-I haven't looked at either, but the second appears to be a binary-only
-distribution.  Beware.
-
-I have received word that Bash (I'm not sure which version, but I
-believe that it's at least bash-2.02.1) is the standard shell on
-BeOS.
-
-A6) How can I build bash with gcc? 
-
-Bash configures to use gcc by default if it is available.  Read the
-file INSTALL in the distribution for more information.
-
-A7)  How can I make bash my login shell?
-
-Some machines let you use `chsh' to change your login shell.  Other
-systems use `passwd -s' or `passwd -e'.  If one of these works for
-you, that's all you need.  Note that many systems require the full
-pathname to a shell to appear in /etc/shells before you can make it
-your login shell.  For this, you may need the assistance of your
-friendly local system administrator. 
-
-If you cannot do this, you can still use bash as your login shell, but
-you need to perform some tricks.  The basic idea is to add a command
-to your login shell's startup file to replace your login shell with
-bash.
-
-For example, if your login shell is csh or tcsh, and you have installed
-bash in /usr/gnu/bin/bash, add the following line to ~/.login:
-
-       if ( -f /usr/gnu/bin/bash ) exec /usr/gnu/bin/bash --login
-
-(the `--login' tells bash that it is a login shell).
-
-It's not a good idea to put this command into ~/.cshrc, because every
-csh you run without the `-f' option, even ones started to run csh scripts,
-reads that file.  If you must put the command in ~/.cshrc, use something
-like
-
-       if ( $?prompt ) exec /usr/gnu/bin/bash --login
-
-to ensure that bash is exec'd only when the csh is interactive.
-
-If your login shell is sh or ksh, you have to do two things.
-
-First, create an empty file in your home directory named `.bash_profile'.
-The existence of this file will prevent the exec'd bash from trying to
-read ~/.profile, and re-execing itself over and over again.  ~/.bash_profile
-is the first file bash tries to read initialization commands from when
-it is invoked as a login shell.
-
-Next, add a line similar to the above to ~/.profile:
-
-       [ -f /usr/gnu/bin/bash ] && [ -x /usr/gnu/bin/bash ] && \
-               exec /usr/gnu/bin/bash --login
-
-This will cause login shells to replace themselves with bash running as
-a login shell.  Once you have this working, you can copy your initialization
-code from ~/.profile to ~/.bash_profile.
-
-I have received word that the recipe supplied above is insufficient for
-machines running CDE.  CDE has a maze of twisty little startup files, all
-slightly different.
-
-If you cannot change your login shell in the password file to bash, you
-will have to (apparently) live with CDE using the shell in the password
-file to run its startup scripts.  If you have changed your shell to bash,
-there is code in the CDE startup files (on Solaris, at least) that attempts
-to do the right thing.  It is, however, often broken, and may require that
-you use the $BASH_ENV trick described below.
-
-`dtterm' claims to use $SHELL as the default program to start, so if you
-can change $SHELL in the CDE startup files, you should be able to use bash
-in your terminal windows.
-
-Setting DTSOURCEPROFILE in ~/.dtprofile will cause the `Xsession' program
-to read your login shell's startup files.  You may be able to use bash for
-the rest of the CDE programs by setting SHELL to bash in ~/.dtprofile as
-well, but I have not tried this.
-
-You can use the above `exec' recipe to start bash when not logging in with
-CDE by testing the value of the DT variable:
-
-       if [ -n "$DT" ]; then
-               [ -f /usr/gnu/bin/bash ] && exec /usr/gnu/bin/bash --login
-       fi
-
-If CDE starts its shells non-interactively during login, the login shell
-startup files (~/.profile, ~/.bash_profile) will not be sourced at login.
-To get around this problem, append a line similar to the following to your
-~/.dtprofile:
-
-       BASH_ENV=${HOME}/.bash_profile ; export BASH_ENV
-
-and add the following line to the beginning of ~/.bash_profile:
-
-       unset BASH_ENV
-
-A8) I just changed my login shell to bash, and now I can't FTP into my
-   machine.  Why not?
-
-You must add the full pathname to bash to the file /etc/shells.  As
-noted in the answer to the previous question, many systems require
-this before you can make bash your login shell. 
-
-Most versions of ftpd use this file to prohibit `special' users
-such as `uucp' and `news' from using FTP. 
-
-A9)  What's the `POSIX 1003.2 standard'?
-
-POSIX is a name originally coined by Richard Stallman for a
-family of open system standards based on UNIX.  There are a
-number of aspects of UNIX under consideration for
-standardization, from the basic system services at the system
-call and C library level to applications and tools to system
-administration and management.  Each area of standardization is
-assigned to a working group in the 1003 series. 
-
-The POSIX Shell and Utilities standard has been developed by IEEE
-Working Group 1003.2 (POSIX.2).  It concentrates on the command
-interpreter interface and utility programs commonly executed from
-the command line or by other programs.  An initial version of the
-standard has been approved and published by the IEEE, and work is
-currently underway to update it. 
-
-Bash is concerned with the aspects of the shell's behavior
-defined by POSIX.2.  The shell command language has of course
-been standardized, including the basic flow control and program
-execution constructs, I/O redirection and pipelining, argument
-handling, variable expansion, and quoting. 
-
-The `special' builtins, which must be implemented as part of the
-shell to provide the desired functionality, are specified as
-being part of the shell; examples of these are `eval' and
-`export'.  Other utilities appear in the sections of POSIX.2 not
-devoted to the shell which are commonly (and in some cases must
-be) implemented as builtin commands, such as `read' and `test'. 
-POSIX.2 also specifies aspects of the shell's interactive
-behavior as part of the UPE, including job control and command
-line editing.  Only vi-style line editing commands have been
-standardized; emacs editing commands were left out due to
-objections.
-
-The Open Group has made an older version of its Single Unix
-Specification (version 2), which is very similar to POSIX.2,
-available on the web at
-
-http://www.opengroup.org/onlinepubs/007908799/
-
-The Single Unix Specification, version 3, is available on the web at
-
-http://www.opengroup.org/onlinepubs/007904975/
-
-A10)  What is the bash `posix mode'?
-
-Although bash is an implementation of the POSIX.2 shell
-specification, there are areas where the bash default behavior
-differs from that spec.  The bash `posix mode' changes the bash
-behavior in these areas so that it obeys the spec more closely. 
-
-Posix mode is entered by starting bash with the --posix or
-'-o posix' option or executing `set -o posix' after bash is running.
-
-The specific aspects of bash which change when posix mode is
-active are listed in the file POSIX in the bash distribution.
-They are also listed in a section in the Bash Reference Manual
-(from which that file is generated).
-
-Section B:  The latest version
-
-B1) What's new in version 2.05b?
-
-The raison d'etre for bash-2.05b is to make a second intermediate
-release containing the first of the new features to be available
-in bash-3.0 and get feedback on those features before proceeding.
-The major new feature is multibyte character support in both Bash
-and Readline.
-
-Bash-2.05b contains the following new features (see the manual page for
-complete descriptions and the CHANGES and NEWS files in the bash-2.05b
-distribution):
-
-o support for multibyte characters has been added to both bash and readline
-
-o the DEBUG trap is now run *before* simple commands, ((...)) commands,
-  [[...]] conditional commands, and for ((...)) loops
-
-o the shell now performs arithmetic in the largest integer size the machine
-  supports (intmax_t)
-
-o there is a new \D{...} prompt expansion; passes the `...' to strftime(3)
-  and inserts the result into the expanded prompt
-
-o there is a new `here-string' redirection operator:  <<< word
-
-o when displaying variables, function attributes and definitions are shown
-  separately, allowing them to be re-used as input (attempting to re-use
-  the old output would result in syntax errors).
-
-o `read' has a new `-u fd' option to read from a specified file descriptor
-
-o the bash debugger in examples/bashdb has been modified to work with the
-  new DEBUG trap semantics, the command set has been made more gdb-like,
-  and the changes to $LINENO make debugging functions work better
-
-o the expansion of $LINENO inside a shell function is only relative to the
-  function start if the shell is interactive -- if the shell is running a
-  script, $LINENO expands to the line number in the script.  This is as
-  POSIX-2001 requires
-
-
-A short feature history dating from Bash-2.0:
-
-Bash-2.05a introduced the following new features:
-
-o The `printf' builtin has undergone major work
-
-o There is a new read-only `shopt' option: login_shell, which is set by
-  login shells and unset otherwise
-
-o New `\A' prompt string escape sequence; expanding to time in 24-hour
-  HH:MM format
-
-o New `-A group/-g' option to complete and compgen; goes group name
-  completion
-
-o New [+-]O invocation option to set and unset `shopt' options at startup
-
-o ksh-like `ERR' trap
-
-o `for' loops now allow empty word lists after the `in' reserved word
-
-o new `hard' and `soft' arguments for the `ulimit' builtin
-
-o Readline can be configured to place the user at the same point on the line
-  when retrieving commands from the history list
-
-o Readline can be configured to skip `hidden' files (filenames with a leading
-  `.' on Unix) when performing completion
-
-Bash-2.05 introduced the following new features:
-
-o This version has once again reverted to using locales and strcoll(3) when
-  processing pattern matching bracket expressions, as POSIX requires. 
-o Added a new `--init-file' invocation argument as a synonym for `--rcfile',
-  per the new GNU coding standards.
-o The /dev/tcp and /dev/udp redirections now accept service names as well as
-  port numbers.
-o `complete' and `compgen' now take a `-o value' option, which controls some
-   of the aspects of that compspec.  Valid values are:
-
-        default - perform bash default completion if programmable
-                  completion produces no matches
-        dirnames - perform directory name completion if programmable
-                   completion produces no matches
-        filenames - tell readline that the compspec produces filenames,
-                    so it can do things like append slashes to
-                    directory names and suppress trailing spaces
-o A new loadable builtin, realpath, which canonicalizes and expands symlinks
-  in pathname arguments.
-o When `set' is called without options, it prints function defintions in a
-  way that allows them to be reused as input.  This affects `declare' and 
-  `declare -p' as well.  This only happens when the shell is not in POSIX
-   mode, since POSIX.2 forbids this behavior.
-
-Bash-2.04 introduced the following new features:
-
-o Programmable word completion with the new `complete' and `compgen' builtins;
-  examples are provided in examples/complete/complete-examples
-o `history' has a new `-d' option to delete a history entry
-o `bind' has a new `-x' option to bind key sequences to shell commands
-o The prompt expansion code has new `\j' and `\l' escape sequences
-o The `no_empty_cmd_completion' shell option, if enabled, inhibits
-  command completion when TAB is typed on an empty line
-o `help' has a new `-s' option to print a usage synopsis
-o New arithmetic operators: var++, var--, ++var, --var, expr1,expr2 (comma)
-o New ksh93-style arithmetic for command:
-       for ((expr1 ; expr2; expr3 )); do list; done
-o `read' has new options: `-t', `-n', `-d', `-s'
-o The redirection code handles several filenames specially:  /dev/fd/N,
-  /dev/stdin, /dev/stdout, /dev/stderr
-o The redirection code now recognizes /dev/tcp/HOST/PORT and
-  /dev/udp/HOST/PORT and tries to open a TCP or UDP socket, respectively,
-  to the specified port on the specified host
-o The ${!prefix*} expansion has been implemented
-o A new FUNCNAME variable, which expands to the name of a currently-executing
-  function
-o The GROUPS variable is no longer readonly
-o A new shopt `xpg_echo' variable, to control the behavior of echo with
-  respect to backslash-escape sequences at runtime
-o The NON_INTERACTIVE_LOGIN_SHELLS #define has returned
-
-The version of Readline released with Bash-2.04, Readline-4.1, had several
-new features as well:
-
-o Parentheses matching is always compiled into readline, and controllable
-  with the new `blink-matching-paren' variable
-o The history-search-forward and history-search-backward functions now leave
-  point at the end of the line when the search string is empty, like
-  reverse-search-history, and forward-search-history
-o A new function for applications:  rl_on_new_line_with_prompt()
-o New variables for applications:  rl_already_prompted, and rl_gnu_readline_p
-
-
-Bash-2.03 had very few new features, in keeping with the convention
-that odd-numbered releases provide mainly bug fixes.  A number of new
-features were added to Readline, mostly at the request of the Cygnus
-folks.
-
-A new shopt option, `restricted_shell', so that startup files can test
-       whether or not the shell was started in restricted mode
-Filename generation is now performed on the words between ( and ) in
-       compound array assignments (this is really a bug fix)
-OLDPWD is now auto-exported, as POSIX.2 requires
-ENV and BASH_ENV are read-only variables in a restricted shell
-Bash may now be linked against an already-installed Readline library,
-       as long as the Readline library is version 4 or newer
-All shells begun with the `--login' option will source the login shell
-       startup files, even if the shell is not interactive
-
-There were lots of changes to the version of the Readline library released
-along with Bash-2.03.  For a complete list of the changes, read the file
-CHANGES in the Bash-2.03 distribution.
-
-Bash-2.02 contained the following new features:
-
-a new version of malloc (based on the old GNU malloc code in previous
-       bash versions) that is more page-oriented, more conservative
-       with memory usage, does not `orphan' large blocks when they
-       are freed, is usable on 64-bit machines, and has allocation
-       checking turned on unconditionally
-POSIX.2-style globbing character classes ([:alpha:], [:alnum:], etc.)
-POSIX.2-style globbing equivalence classes
-POSIX.2-style globbing collating symbols
-the ksh [[...]] extended conditional command
-the ksh egrep-style extended pattern matching operators
-a new `printf' builtin
-the ksh-like $(<filename) command substitution, which is equivalent to
-       $(cat filename)
-new tilde prefixes that expand to directories from the directory stack
-new `**' arithmetic operator to do exponentiation
-case-insensitive globbing (filename expansion)
-menu completion a la tcsh
-`magic-space' history expansion function like tcsh
-the readline inputrc `language' has a new file inclusion directive ($include)
-
-Bash-2.01 contained only a few new features:
-
-new `GROUPS' builtin array variable containing the user's group list
-new bindable readline commands: history-and-alias-expand-line and
-       alias-expand-line
-
-Bash-2.0 contained extensive changes and new features from bash-1.14.7.
-Here's a short list:
-
-new `time' reserved word to time pipelines, shell builtins, and
-       shell functions
-one-dimensional arrays with a new compound assignment statement,
-        appropriate expansion constructs and modifications to some
-       of the builtins (read, declare, etc.) to use them
-new quoting syntaxes for ANSI-C string expansion and locale-specific
-       string translation
-new expansions to do substring extraction, pattern replacement, and
-       indirect variable expansion
-new builtins: `disown' and `shopt'
-new variables: HISTIGNORE, SHELLOPTS, PIPESTATUS, DIRSTACK, GLOBIGNORE,
-              MACHTYPE, BASH_VERSINFO
-special handling of many unused or redundant variables removed
-       (e.g., $notify, $glob_dot_filenames, $no_exit_on_failed_exec)
-dynamic loading of new builtin commands; many loadable examples provided
-new prompt expansions: \a, \e, \n, \H, \T, \@, \v, \V
-history and aliases available in shell scripts
-new readline variables: enable-keypad, mark-directories, input-meta,
-       visible-stats, disable-completion, comment-begin
-new readline commands to manipulate the mark and operate on the region
-new readline emacs mode commands and bindings for ksh-88 compatibility
-updated and extended builtins
-new DEBUG trap
-expanded (and now documented) restricted shell mode
-
-implementation stuff:  
-autoconf-based configuration
-nearly all of the bugs reported since version 1.14 have been fixed
-most builtins converted to use builtin `getopt' for consistency
-most builtins use -p option to display output in a reusable form
-       (for consistency)
-grammar tighter and smaller (66 reduce-reduce conflicts gone)
-lots of code now smaller and faster
-test suite greatly expanded
-
-B2) Are there any user-visible incompatibilities between bash-2.05b and
-    bash-1.14.7?
-
-There are a few incompatibilities between version 1.14.7 and version 2.05b.
-They are detailed in the file COMPAT in the bash distribution.  That file
-is not meant to be all-encompassing; send mail to bash-maintainers@gnu.org
-if if you find something that's not mentioned there.
-
-Section C:  Differences from other Unix shells
-
-C1) How does bash differ from sh, the Bourne shell?
-
-This is a non-comprehensive list of features that differentiate bash
-from the SVR4.2 shell.  The bash manual page explains these more
-completely.
-
-Things bash has that sh does not:
-       long invocation options
-       [+-]O invocation option
-       -l invocation option
-       `!' reserved word to invert pipeline return value
-       `time' reserved word to time pipelines and shell builtins
-       the `function' reserved word
-       the `select' compound command and reserved word
-       arithmetic for command: for ((expr1 ; expr2; expr3 )); do list; done
-       new $'...' and $"..." quoting
-       the $(...) form of command substitution
-       the $(<filename) form of command substitution, equivalent to
-               $(cat filename)
-       the ${#param} parameter value length operator
-       the ${!param} indirect parameter expansion operator
-       the ${!param*} prefix expansion operator
-       the ${param:offset[:length]} parameter substring operator
-       the ${param/pat[/string]} parameter pattern substitution operator
-       expansions to perform substring removal (${p%[%]w}, ${p#[#]w})
-       expansion of positional parameters beyond $9 with ${num}
-       variables: BASH, BASH_VERSION, BASH_VERSINFO, UID, EUID, REPLY,
-                  TIMEFORMAT, PPID, PWD, OLDPWD, SHLVL, RANDOM, SECONDS,
-                  LINENO, HISTCMD, HOSTTYPE, OSTYPE, MACHTYPE, HOSTNAME,
-                  ENV, PS3, PS4, DIRSTACK, PIPESTATUS, HISTSIZE, HISTFILE,
-                  HISTFILESIZE, HISTCONTROL, HISTIGNORE, GLOBIGNORE, GROUPS,
-                  PROMPT_COMMAND, FCEDIT, FIGNORE, IGNOREEOF, INPUTRC,
-                  SHELLOPTS, OPTERR, HOSTFILE, TMOUT, FUNCNAME, histchars,
-                  auto_resume
-       DEBUG trap
-       ERR trap
-       variable arrays with new compound assignment syntax
-       redirections: <>, &>, >|, <<<, [n]<&word-, [n]>&word-
-       prompt string special char translation and variable expansion
-       auto-export of variables in initial environment
-       command search finds functions before builtins
-       bash return builtin will exit a file sourced with `.'
-       builtins: cd -/-L/-P, exec -l/-c/-a, echo -e/-E, hash -d/-l/-p/-t.
-                 export -n/-f/-p/name=value, pwd -L/-P,
-                 read -e/-p/-a/-t/-n/-d/-s/-u,
-                 readonly -a/-f/name=value, trap -l, set +o,
-                 set -b/-m/-o option/-h/-p/-B/-C/-H/-P,
-                 unset -f/-v, ulimit -m/-p/-u,
-                 type -a/-p/-t/-f/-P, suspend -f, kill -n,
-                 test -o optname/s1 == s2/s1 < s2/s1 > s2/-nt/-ot/-ef/-O/-G/-S
-       bash reads ~/.bashrc for interactive shells, $ENV for non-interactive
-       bash restricted shell mode is more extensive
-       bash allows functions and variables with the same name
-       brace expansion
-       tilde expansion
-       arithmetic expansion with $((...)) and `let' builtin
-       the `[[...]]' extended conditional command
-       process substitution
-       aliases and alias/unalias builtins
-       local variables in functions and `local' builtin
-       readline and command-line editing with programmable completion
-       command history and history/fc builtins
-       csh-like history expansion
-       other new bash builtins: bind, command, compgen, complete, builtin,
-                                declare/typeset, dirs, enable, fc, help,
-                                history, logout, popd, pushd, disown, shopt,
-                                printf
-       exported functions
-       filename generation when using output redirection (command >a*)
-       POSIX.2-style globbing character classes
-       POSIX.2-style globbing equivalence classes
-       POSIX.2-style globbing collating symbols
-       egrep-like extended pattern matching operators
-       case-insensitive pattern matching and globbing
-       variable assignments preceding commands affect only that command,
-               even for builtins and functions
-       posix mode
-       redirection to /dev/fd/N, /dev/stdin, /dev/stdout, /dev/stderr,
-               /dev/tcp/host/port, /dev/udp/host/port
-
-Things sh has that bash does not:
-       uses variable SHACCT to do shell accounting
-       includes `stop' builtin (bash can use alias stop='kill -s STOP')
-       `newgrp' builtin
-       turns on job control if called as `jsh'
-       $TIMEOUT (like bash $TMOUT)
-       `^' is a synonym for `|'
-       new SVR4.2 sh builtins: mldmode, priv
-
-Implementation differences:
-       redirection to/from compound commands causes sh to create a subshell
-       bash does not allow unbalanced quotes; sh silently inserts them at EOF
-       bash does not mess with signal 11
-       sh sets (euid, egid) to (uid, gid) if -p not supplied and uid < 100
-       bash splits only the results of expansions on IFS, using POSIX.2
-               field splitting rules; sh splits all words on IFS
-       sh does not allow MAILCHECK to be unset (?)
-       sh does not allow traps on SIGALRM or SIGCHLD
-       bash allows multiple option arguments when invoked (e.g. -x -v);
-               sh allows only a single option argument (`sh -x -v' attempts
-               to open a file named `-v', and, on SunOS 4.1.4, dumps core.
-               On Solaris 2.4 and earlier versions, sh goes into an infinite
-               loop.)
-       sh exits a script if any builtin fails; bash exits only if one of
-               the POSIX.2 `special' builtins fails
-
-C2)  How does bash differ from the Korn shell, version ksh88?
-
-Things bash has or uses that ksh88 does not:
-       long invocation options
-       [-+]O invocation option
-       -l invocation option
-       `!' reserved word
-       arithmetic for command: for ((expr1 ; expr2; expr3 )); do list; done
-       arithmetic in largest machine-supported size (intmax_t)
-       posix mode and posix conformance
-       command hashing
-       tilde expansion for assignment statements that look like $PATH
-       process substitution with named pipes if /dev/fd is not available
-       the ${!param} indirect parameter expansion operator
-       the ${!param*} prefix expansion operator
-       the ${param:offset[:length]} parameter substring operator
-       the ${param/pat[/string]} parameter pattern substitution operator
-       variables: BASH, BASH_VERSION, BASH_VERSINFO, UID, EUID, SHLVL,
-                  TIMEFORMAT, HISTCMD, HOSTTYPE, OSTYPE, MACHTYPE,
-                  HISTFILESIZE, HISTIGNORE, HISTCONTROL, PROMPT_COMMAND,
-                  IGNOREEOF, FIGNORE, INPUTRC, HOSTFILE, DIRSTACK,
-                  PIPESTATUS, HOSTNAME, OPTERR, SHELLOPTS, GLOBIGNORE,
-                  GROUPS, FUNCNAME, histchars, auto_resume
-       prompt expansion with backslash escapes and command substitution
-       redirection: &> (stdout and stderr), <<<, [n]<&word-, [n]>&word-
-       more extensive and extensible editing and programmable completion
-       builtins: bind, builtin, command, declare, dirs, echo -e/-E, enable,
-                 exec -l/-c/-a, fc -s, export -n/-f/-p, hash, help, history,
-                 jobs -x/-r/-s, kill -s/-n/-l, local, logout, popd, pushd,
-                 read -e/-p/-a/-t/-n/-d/-s, readonly -a/-n/-f/-p,
-                 set -o braceexpand/-o histexpand/-o interactive-comments/
-                 -o notify/-o physical/-o posix/-o hashall/-o onecmd/
-                 -h/-B/-C/-b/-H/-P, set +o, suspend, trap -l, type,
-                 typeset -a/-F/-p, ulimit -u, umask -S, alias -p, shopt,
-                 disown, printf, complete, compgen
-       `!' csh-style history expansion
-       POSIX.2-style globbing character classes
-       POSIX.2-style globbing equivalence classes
-       POSIX.2-style globbing collating symbols
-       egrep-like extended pattern matching operators
-       case-insensitive pattern matching and globbing
-       `**' arithmetic operator to do exponentiation
-       redirection to /dev/fd/N, /dev/stdin, /dev/stdout, /dev/stderr
-       arrays of unlimited size
-       TMOUT is default timeout for `read' and `select'
-
-Things ksh88 has or uses that bash does not:
-       tracked aliases (alias -t)
-       variables: ERRNO, FPATH, EDITOR, VISUAL
-       co-processes (|&, >&p, <&p)
-       weirdly-scoped functions
-       typeset +f to list all function names without definitions
-       text of command history kept in a file, not memory
-       builtins: alias -x, cd old new, fc -e -, newgrp, print,
-                 read -p/-s/var?prompt, set -A/-o gmacs/
-                 -o bgnice/-o markdirs/-o nolog/-o trackall/-o viraw/-s,
-                 typeset -H/-L/-R/-Z/-A/-ft/-fu/-fx/-l/-u/-t, whence
-       using environment to pass attributes of exported variables
-       arithmetic evaluation done on arguments to some builtins
-       reads .profile from $PWD when invoked as login shell
-
-Implementation differences:
-       ksh runs last command of a pipeline in parent shell context
-       bash has brace expansion by default (ksh88 compile-time option)
-       bash has fixed startup file for all interactive shells; ksh reads $ENV
-       bash has exported functions
-       bash command search finds functions before builtins
-       bash waits for all commands in pipeline to exit before returning status
-       emacs-mode editing has some slightly different key bindings
-
-C3)  Which new features in ksh-93 are not in bash, and which are?
-
-New things in ksh-93 not in bash-2.05b:
-       associative arrays
-       floating point arithmetic and variables
-       math library functions
-       ${!name[sub]} name of subscript for associative array
-       `.' is allowed in variable names to create a hierarchical namespace
-       more extensive compound assignment syntax
-       discipline functions
-       `sleep' and `getconf' builtins (bash has loadable versions)
-       typeset -n and `nameref' variables
-       KEYBD trap
-       variables: .sh.edchar, .sh.edmode, .sh.edcol, .sh.edtext, .sh.version,
-                  .sh.name, .sh.subscript, .sh.value, .sh.match, HISTEDIT
-       backreferences in pattern matching (\N)
-       `&' operator in pattern lists for matching
-       print -f (bash uses printf)
-       `fc' has been renamed to `hist'
-       `.' can execute shell functions
-       exit statuses between 0 and 255
-       set -o pipefail
-       `+=' variable assignment operator
-       FPATH and PATH mixing
-       getopts -a
-       -I invocation option
-       DEBUG trap now executed before each simple command, instead of after
-       printf %H, %P, %T, %Z modifiers, output base for %d
-       lexical scoping for local variables in `ksh' functions
-       no scoping for local variables in `POSIX' functions
-
-New things in ksh-93 present in bash-2.05b:
-       [n]<&word- and [n]>&word- redirections (combination dup and close)
-        for (( expr1; expr2; expr3 )) ; do list; done - arithmetic for command
-        ?:, ++, --, `expr1 , expr2' arithmetic operators
-       expansions: ${!param}, ${param:offset[:len]}, ${param/pat[/str]},
-                   ${!param*}
-       compound array assignment
-       the `!' reserved word
-       loadable builtins -- but ksh uses `builtin' while bash uses `enable'
-       `command', `builtin', `disown' builtins
-       new $'...' and $"..." quoting
-       FIGNORE (but bash uses GLOBIGNORE), HISTCMD
-       set -o notify/-C
-       changes to kill builtin
-       read -A (bash uses read -a)
-        read -t/-d
-       trap -p
-       exec -c/-a
-       `.' restores the positional parameters when it completes
-       POSIX.2 `test'
-       umask -S
-       unalias -a
-       command and arithmetic substitution performed on PS1, PS4, and ENV
-       command name completion
-       ENV processed only for interactive shells
-
-Section D:  Why does bash do some things differently than other Unix shells?
-
-D1) Why does bash run a different version of `command' than
-    `which command' says it will?
-
-On many systems, `which' is actually a csh script that assumes
-you're running csh.  In tcsh, `which' and its cousin `where'
-are builtins.  On other Unix systems, `which' is a perl script
-that uses the PATH environment variable.
-
-The csh script version reads the csh startup files from your
-home directory and uses those to determine which `command' will
-be invoked.  Since bash doesn't use any of those startup files,
-there's a good chance that your bash environment differs from
-your csh environment.  The bash `type' builtin does everything
-`which' does, and will report correct results for the running
-shell.  If you're really wedded to the name `which', try adding
-the following function definition to your .bashrc:
-
-       which()
-       {
-               builtin type "$@"
-       }
-
-If you're moving from tcsh and would like to bring `where' along
-as well, use this function:
-
-       where()
-       {
-               builtin type -a "$@"
-       }
-
-D2) Why doesn't bash treat brace expansions exactly like csh?
-
-The only difference between bash and csh brace expansion is that
-bash requires a brace expression to contain at least one unquoted
-comma if it is to be expanded.  Any brace-surrounded word not
-containing an unquoted comma is left unchanged by the brace
-expansion code.  This affords the greatest degree of sh
-compatibility. 
-
-Bash, ksh, zsh, and pd-ksh all implement brace expansion this way. 
-
-D3) Why doesn't bash have csh variable modifiers?
-
-Posix has specified a more powerful, albeit somewhat more cryptic,
-mechanism cribbed from ksh, and bash implements it.
-
-${parameter%word}
-        Remove smallest suffix pattern.  The WORD is expanded to produce
-        a pattern.  It then expands to the value of PARAMETER, with the
-        smallest portion of the suffix matched by the pattern deleted.
-
-        x=file.c
-        echo ${x%.c}.o
-        -->file.o
-
-${parameter%%word}
-
-        Remove largest suffix pattern.  The WORD is expanded to produce
-        a pattern.  It then expands to the value of PARAMETER, with the
-        largest portion of the suffix matched by the pattern deleted.
-
-        x=posix/src/std
-        echo ${x%%/*}
-        -->posix
-
-${parameter#word}
-        Remove smallest prefix pattern.  The WORD is expanded to produce
-        a pattern.  It then expands to the value of PARAMETER, with the
-        smallest portion of the prefix matched by the pattern deleted.
-
-        x=$HOME/src/cmd
-        echo ${x#$HOME}
-        -->/src/cmd
-
-${parameter##word}
-        Remove largest prefix pattern.  The WORD is expanded to produce
-        a pattern.  It then expands to the value of PARAMETER, with the
-        largest portion of the prefix matched by the pattern deleted.
-
-        x=/one/two/three
-        echo ${x##*/}
-        -->three
-
-
-Given
-       a=/a/b/c/d
-       b=b.xxx
-
-       csh                     bash            result
-       ---                     ----            ------
-       $a:h                    ${a%/*}            /a/b/c
-       $a:t                    ${a##*/}           d
-       $b:r                    ${b%.*}            b
-       $b:e                    ${b##*.}           xxx
-
-
-D4) How can I make my csh aliases work when I convert to bash?
-
-Bash uses a different syntax to support aliases than csh does. 
-The details can be found in the documentation.  We have provided
-a shell script which does most of the work of conversion for you;
-this script can be found in ./examples/misc/aliasconv.sh.  Here is
-how you use it:
-  
-Start csh in the normal way for you.  (e.g., `csh')
-  
-Pipe the output of `alias' through `aliasconv.sh', saving the
-results into `bash_aliases':
-  
-       alias | bash aliasconv.sh >bash_aliases
-  
-Edit `bash_aliases', carefully reading through any created
-functions.  You will need to change the names of some csh specific
-variables to the bash equivalents.  The script converts $cwd to
-$PWD, $term to $TERM, $home to $HOME, $user to $USER, and $prompt
-to $PS1.  You may also have to add quotes to avoid unwanted
-expansion.
-
-For example, the csh alias:
-  
-       alias cd 'cd \!*; echo $cwd'
-  
-is converted to the bash function:
-
-       cd () { command cd "$@"; echo $PWD ; }
-
-The only thing that needs to be done is to quote $PWD:
-  
-       cd () { command cd "$@"; echo "$PWD" ; }
-  
-Merge the edited file into your ~/.bashrc.
-
-There is an additional, more ambitious, script in
-examples/misc/cshtobash that attempts to convert your entire csh
-environment to its bash equivalent.  This script can be run as
-simply `cshtobash' to convert your normal interactive
-environment, or as `cshtobash ~/.login' to convert your login
-environment. 
-
-D5) How can I pipe standard output and standard error from one command to
-    another, like csh does with `|&'?
-
-Use
-       command 2>&1 | command2
-
-The key is to remember that piping is performed before redirection, so
-file descriptor 1 points to the pipe when it is duplicated onto file
-descriptor 2.
-
-D6) Now that I've converted from ksh to bash, are there equivalents to
-    ksh features like autoloaded functions and the `whence' command?
-
-There are features in ksh-88 and ksh-93 that do not have direct bash
-equivalents.  Most, however, can be emulated with very little trouble.
-
-ksh-88 feature         Bash equivalent
---------------         ---------------
-compiled-in aliases    set up aliases in .bashrc; some ksh aliases are
-                       bash builtins (hash, history, type)
-coprocesses            named pipe pairs (one for read, one for write)
-typeset +f             declare -F
-cd, print, whence      function substitutes in examples/functions/kshenv
-autoloaded functions   examples/functions/autoload is the same as typeset -fu
-read var?prompt                read -p prompt var
-
-ksh-93 feature         Bash equivalent
---------------         ---------------
-sleep, getconf         Bash has loadable versions in examples/loadables
-${.sh.version}         $BASH_VERSION
-print -f               printf
-hist                   alias hist=fc
-$HISTEDIT              $FCEDIT
-
-Section E:  How can I get bash to do certain things, and why does bash do
-           things the way it does?
-
-E1) Why is the bash builtin `test' slightly different from /bin/test?
-
-The specific example used here is [ ! x -o x ], which is false.
-
-Bash's builtin `test' implements the Posix.2 spec, which can be
-summarized as follows (the wording is due to David Korn):
-   
-Here is the set of rules for processing test arguments.
-  
-    0 Args: False
-    1 Arg:  True iff argument is not null.
-    2 Args: If first arg is !, True iff second argument is null.
-           If first argument is unary, then true if unary test is true
-           Otherwise error.
-    3 Args: If second argument is a binary operator, do binary test of $1 $3
-           If first argument is !, negate two argument test of $2 $3
-           If first argument is `(' and third argument is `)', do the
-           one-argument test of the second argument.
-           Otherwise error.
-    4 Args: If first argument is !, negate three argument test of $2 $3 $4.
-           Otherwise unspecified
-    5 or more Args: unspecified.  (Historical shells would use their
-    current algorithm).
-   
-The operators -a and -o are considered binary operators for the purpose
-of the 3 Arg case.
-   
-As you can see, the test becomes (not (x or x)), which is false.
-
-E2) Why does bash sometimes say `Broken pipe'?
-
-If a sequence of commands appears in a pipeline, and one of the
-reading commands finishes before the writer has finished, the
-writer receives a SIGPIPE signal.  Many other shells special-case
-SIGPIPE as an exit status in the pipeline and do not report it. 
-For example, in:
-  
-      ps -aux | head
-  
-`head' can finish before `ps' writes all of its output, and ps
-will try to write on a pipe without a reader.  In that case, bash
-will print `Broken pipe' to stderr when ps is killed by a
-SIGPIPE. 
-
-You can build a version of bash that will not report SIGPIPE errors
-by uncommenting the definition of DONT_REPORT_SIGPIPE in the file
-config-top.h.
-
-E3) When I have terminal escape sequences in my prompt, why does bash
-    wrap lines at the wrong column?
-
-Readline, the line editing library that bash uses, does not know
-that the terminal escape sequences do not take up space on the
-screen.  The redisplay code assumes, unless told otherwise, that
-each character in the prompt is a `printable' character that
-takes up one character position on the screen. 
-
-You can use the bash prompt expansion facility (see the PROMPTING
-section in the manual page) to tell readline that sequences of
-characters in the prompt strings take up no screen space. 
-
-Use the \[ escape to begin a sequence of non-printing characters,
-and the \] escape to signal the end of such a sequence. 
-
-E4) If I pipe the output of a command into `read variable', why doesn't
-    the output show up in $variable when the read command finishes?
-
-This has to do with the parent-child relationship between Unix
-processes.  It affects all commands run in pipelines, not just
-simple calls to `read'.  For example, piping a command's output
-into a `while' loop that repeatedly calls `read' will result in
-the same behavior.
-
-Each element of a pipeline runs in a separate process, a child of
-the shell running the pipeline.  A subprocess cannot affect its
-parent's environment.  When the `read' command sets the variable
-to the input, that variable is set only in the subshell, not the
-parent shell.  When the subshell exits, the value of the variable
-is lost. 
-
-Many pipelines that end with `read variable' can be converted
-into command substitutions, which will capture the output of
-a specified command.  The output can then be assigned to a
-variable:
-
-       grep ^gnu /usr/lib/news/active | wc -l | read ngroup
-
-can be converted into
-
-       ngroup=$(grep ^gnu /usr/lib/news/active | wc -l)
-
-This does not, unfortunately, work to split the text among
-multiple variables, as read does when given multiple variable
-arguments.  If you need to do this, you can either use the
-command substitution above to read the output into a variable
-and chop up the variable using the bash pattern removal
-expansion operators or use some variant of the following
-approach.
-
-Say /usr/local/bin/ipaddr is the following shell script:
-
-#! /bin/sh
-host `hostname` | awk '/address/ {print $NF}'
-
-Instead of using
-
-       /usr/local/bin/ipaddr | read A B C D
-
-to break the local machine's IP address into separate octets, use
-
-       OIFS="$IFS"
-       IFS=.
-       set -- $(/usr/local/bin/ipaddr)
-       IFS="$OIFS"
-       A="$1" B="$2" C="$3" D="$4"
-
-Beware, however, that this will change the shell's positional
-parameters.  If you need them, you should save them before doing
-this.
-
-This is the general approach -- in most cases you will not need to
-set $IFS to a different value.
-
-Some other user-supplied alternatives include:
-
-read A B C D << HERE
-    $(IFS=.; echo $(/usr/local/bin/ipaddr))
-HERE
-
-and, where process substitution is available,
-
-read A B C D < <(IFS=.; echo $(/usr/local/bin/ipaddr))
-
-E5) I have a bunch of shell scripts that use backslash-escaped characters
-    in arguments to `echo'.  Bash doesn't interpret these characters.  Why
-    not, and how can I make it understand them?
-
-This is the behavior of echo on most Unix System V machines.
-
-The bash builtin `echo' is modeled after the 9th Edition
-Research Unix version of `echo'.  It does not interpret
-backslash-escaped characters in its argument strings by default;
-it requires the use of the -e option to enable the
-interpretation.  The System V echo provides no way to disable the
-special characters; the bash echo has a -E option to disable
-them. 
-
-There is a configuration option that will make bash behave like
-the System V echo and interpret things like `\t' by default.  Run
-configure with the --enable-xpg-echo-default option to turn this
-on.  Be aware that this will cause some of the tests run when you
-type `make tests' to fail.
-
-There is a shell option, `xpg_echo', settable with `shopt', that will
-change the behavior of echo at runtime.  Enabling this option turns
-on expansion of backslash-escape sequences.
-
-E6) Why doesn't a while or for loop get suspended when I type ^Z?
-
-This is a consequence of how job control works on Unix.  The only
-thing that can be suspended is the process group.  This is a single
-command or pipeline of commands that the shell forks and executes.
-
-When you run a while or for loop, the only thing that the shell forks
-and executes are any commands in the while loop test and commands in
-the loop bodies.  These, therefore, are the only things that can be
-suspended when you type ^Z.
-
-If you want to be able to stop the entire loop, you need to put it
-within parentheses, which will force the loop into a subshell that
-may be stopped (and subsequently restarted) as a single unit.
-
-E7) What about empty for loops in Makefiles?
-
-It's fairly common to see constructs like this in automatically-generated
-Makefiles:
-
-SUBDIRS = @SUBDIRS@
-
-       ...
-
-subdirs-clean:
-       for d in ${SUBDIRS}; do \
-               ( cd $$d && ${MAKE} ${MFLAGS} clean ) \
-       done
-
-When SUBDIRS is empty, this results in a command like this being passed to
-bash:
-
-       for d in ; do
-               ( cd $d && ${MAKE} ${MFLAGS} clean )
-       done
-
-In versions of bash before bash-2.05a, this was a syntax error.  If the
-reserved word `in' was present, a word must follow it before the semicolon
-or newline.  The language in the manual page referring to the list of words
-being empty referred to the list after it is expanded.  These versions of
-bash required that there be at least one word following the `in' when the
-construct was parsed.
-
-The idiomatic Makefile solution is something like:
-
-SUBDIRS = @SUBDIRS@
-
-subdirs-clean:
-       subdirs=$SUBDIRS ; for d in $$subdirs; do \
-               ( cd $$d && ${MAKE} ${MFLAGS} clean ) \
-       done
-
-The latest drafts of the updated POSIX standard have changed this:  the
-word list is no longer required.  Bash versions 2.05a and later accept
-the new syntax.
-
-E8) Why does the arithmetic evaluation code complain about `08'?
-
-The bash arithmetic evaluation code (used for `let', $(()), (()), and in
-other places), interprets a leading `0' in numeric constants as denoting
-an octal number, and a leading `0x' as denoting hexadecimal.  This is
-in accordance with the POSIX.2 spec, section 2.9.2.1, which states that
-arithmetic constants should be handled as signed long integers as defined
-by the ANSI/ISO C standard.
-
-The POSIX.2 interpretation committee has confirmed this:
-
-http://www.pasc.org/interps/unofficial/db/p1003.2/pasc-1003.2-173.html
-
-E9) Why does the pattern matching expression [A-Z]* match files beginning
-    with every letter except `z'?
-
-Bash-2.03, Bash-2.05 and later versions honor the current locale setting
-when processing ranges within pattern matching bracket expressions ([A-Z]). 
-This is what POSIX.2 and SUSv3/XPG6 specify. 
-
-The behavior of the matcher in bash-2.05 and later versions depends on the
-current LC_COLLATE setting.  Setting this variable to `C' or `POSIX' will
-result in the traditional behavior ([A-Z] matches all uppercase ASCII
-characters).  Many other locales, including the en_US locale (the default
-on many US versions of Linux) collate the upper and lower case letters like
-this:
-
-       AaBb...Zz
-
-which means that [A-Z] matches every letter except `z'.  Others collate like
-
-       aAbBcC...zZ
-
-which means that [A-Z] matches every letter except `a'.
-
-The portable way to specify upper case letters is [:upper:] instead of
-A-Z; lower case may be specified as [:lower:] instead of a-z.
-
-Look at the manual pages for setlocale(3), strcoll(3), and, if it is
-present, locale(1).  If you have locale(1), you can use it to find
-your current locale information even if you do not have any of the
-LC_ variables set.
-
-My advice is to put
-
-       export LC_COLLATE=C
-
-into /etc/profile and inspect any shell scripts run from cron for
-constructs like [A-Z].  This will prevent things like
-
-       rm [A-Z]*
-
-from removing every file in the current directory except those beginning
-with `z' and still allow individual users to change the collation order.
-Users may put the above command into their own profiles as well, of course.
-
-E10) Why does `cd //' leave $PWD as `//'?
-
-POSIX.2, in its description of `cd', says that *three* or more leading
-slashes may be replaced with a single slash when canonicalizing the
-current working directory.
-
-This is, I presume, for historical compatibility.  Certain versions of
-Unix, and early network file systems, used paths of the form
-//hostname/path to access `path' on server `hostname'.
-
-E11) If I resize my xterm while another program is running, why doesn't bash
-     notice the change?
-
-This is another issue that deals with job control.
-
-The kernel maintains a notion of a current terminal process group.  Members
-of this process group (processes whose process group ID is equal to the
-current terminal process group ID) receive terminal-generated signals like
-SIGWINCH.  (For more details, see the JOB CONTROL section of the bash
-man page.)
-
-If a terminal is resized, the kernel sends SIGWINCH to each member of
-the terminal's current process group (the `foreground' process group).
-
-When bash is running with job control enabled, each pipeline (which may be
-a single command) is run in its own process group, different from bash's
-process group.  This foreground process group receives the SIGWINCH; bash
-does not.  Bash has no way of knowing that the terminal has been resized.
-
-There is a `checkwinsize' option, settable with the `shopt' builtin, that
-will cause bash to check the window size and adjust its idea of the
-terminal's dimensions each time a process stops or exits and returns control
-of the terminal to bash.  Enable it with `shopt -s checkwinsize'.
-
-Section F:  Things to watch out for on certain Unix versions
-
-F1) Why can't I use command line editing in my `cmdtool'?
-
-The problem is `cmdtool' and bash fighting over the input.  When
-scrolling is enabled in a cmdtool window, cmdtool puts the tty in
-`raw mode' to permit command-line editing using the mouse for
-applications that cannot do it themselves.  As a result, bash and
-cmdtool each try to read keyboard input immediately, with neither
-getting enough of it to be useful.
-
-This mode also causes cmdtool to not implement many of the
-terminal functions and control sequences appearing in the
-`sun-cmd' termcap entry.  For a more complete explanation, see
-that file examples/suncmd.termcap in the bash distribution. 
-
-`xterm' is a better choice, and gets along with bash much more
-smoothly.
-
-If you must use cmdtool, you can use the termcap description in
-examples/suncmd.termcap.  Set the TERMCAP variable to the terminal
-description contained in that file, i.e.
-
-TERMCAP='Mu|sun-cmd:am:bs:km:pt:li#34:co#80:cl=^L:ce=\E[K:cd=\E[J:rs=\E[s:'
-
-Then export TERMCAP and start a new cmdtool window from that shell.
-The bash command-line editing should behave better in the new
-cmdtool.  If this works, you can put the assignment to TERMCAP
-in your bashrc file.
-
-F2) I built bash on Solaris 2.  Why do globbing expansions and filename
-    completion chop off the first few characters of each filename?
-
-This is the consequence of building bash on SunOS 5 and linking
-with the libraries in /usr/ucblib, but using the definitions
-and structures from files in /usr/include. 
-
-The actual conflict is between the dirent structure in
-/usr/include/dirent.h and the struct returned by the version of
-`readdir' in libucb.a (a 4.3-BSD style `struct direct'). 
-
-Make sure you've got /usr/ccs/bin ahead of /usr/ucb in your $PATH
-when configuring and building bash.  This will ensure that you
-use /usr/ccs/bin/cc or acc instead of /usr/ucb/cc and that you
-link with libc before libucb. 
-
-If you have installed the Sun C compiler, you may also need to
-put /usr/ccs/bin and /opt/SUNWspro/bin into your $PATH before
-/usr/ucb.
-
-F3) Why does bash dump core after I interrupt username completion or
-    `~user' tilde expansion on a machine running NIS?
-
-This is a famous and long-standing bug in the SunOS YP (sorry, NIS)
-client library, which is part of libc.
-
-The YP library code keeps static state -- a pointer into the data
-returned from the server.  When YP initializes itself (setpwent),
-it looks at this pointer and calls free on it if it's non-null. 
-So far, so good. 
-
-If one of the YP functions is interrupted during getpwent (the
-exact function is interpretwithsave()), and returns NULL, the
-pointer is freed without being reset to NULL, and the function
-returns.  The next time getpwent is called, it sees that this
-pointer is non-null, calls free, and the bash free() blows up
-because it's being asked to free freed memory. 
-
-The traditional Unix mallocs allow memory to be freed multiple
-times; that's probably why this has never been fixed.  You can
-run configure with the `--without-gnu-malloc' option to use
-the C library malloc and avoid the problem.
-
-F4) I'm running SVR4.2.  Why is the line erased every time I type `@'?
-
-The `@' character is the default `line kill' character in most
-versions of System V, including SVR4.2.  You can change this
-character to whatever you want using `stty'.  For example, to
-change the line kill character to control-u, type
-
-       stty kill ^U
-
-where the `^' and `U' can be two separate characters.
-
-F5) Why does bash report syntax errors when my C News scripts use a
-    redirection before a subshell command?
-
-The actual command in question is something like
-
-       < file ( command )
-
-According to the grammar given in the POSIX.2 standard, this construct
-is, in fact, a syntax error.  Redirections may only precede `simple
-commands'.  A subshell construct such as the above is one of the shell's
-`compound commands'.  A redirection may only follow a compound command.
-
-This affects the mechanical transformation of commands that use `cat'
-to pipe a file into a command (a favorite Useless-Use-Of-Cat topic on
-comp.unix.shell).  While most commands of the form
-
-       cat file | command
-
-can be converted to `< file command', shell control structures such as
-loops and subshells require `command < file'.
-
-The file CWRU/sh-redir-hack in the bash-2.05a distribution is an
-(unofficial) patch to parse.y that will modify the grammar to
-support this construct.  It will not apply with `patch'; you must
-modify parse.y by hand.  Note that if you apply this, you must
-recompile with -DREDIRECTION_HACK.  This introduces a large
-number of reduce/reduce conflicts into the shell grammar. 
-
-F6) Why can't I use vi-mode editing on Red Hat Linux 6.1?
-
-The short answer is that Red Hat screwed up.
-
-The long answer is that they shipped an /etc/inputrc that only works
-for emacs mode editing, and then screwed all the vi users by setting
-INPUTRC to /etc/inputrc in /etc/profile.
-
-The short fix is to do one of the following: remove or rename
-/etc/inputrc, set INPUTRC=~/.inputrc in ~/.bashrc (or .bash_profile,
-but make sure you export it if you do), remove the assignment to
-INPUTRC from /etc/profile, add
-
-        set keymap emacs
-
-to the beginning of /etc/inputrc, or bracket the key bindings in
-/etc/inputrc with these lines
-
-       $if mode=emacs
-               [...]
-       $endif
-
-F7) Why do bash-2.05a and bash-2.05b fail to compile `printf.def' on
-    HP/UX 11.x?
-
-HP/UX's support for long double is imperfect at best.
-
-GCC will support it without problems, but the HP C library functions
-like strtold(3) and printf(3) don't actually work with long doubles.
-HP implemented a `long_double' type as a 4-element array of 32-bit
-ints, and that is what the library functions use.  The ANSI C
-`long double' type is a 128-bit floating point scalar.
-
-The easiest fix, until HP fixes things up, is to edit the generated
-config.h and #undef the HAVE_LONG_DOUBLE line.  After doing that,
-the compilation should complete successfully.
-
-Section G:  How can I get bash to do certain common things?
-
-G1) How can I get bash to read and display eight-bit characters?
-
-This is a process requiring several steps.
-
-First, you must ensure that the `physical' data path is a full eight
-bits.  For xterms, for example, the `vt100' resources `eightBitInput'
-and `eightBitOutput' should be set to `true'.
-
-Once you have set up an eight-bit path, you must tell the kernel and
-tty driver to leave the eighth bit of characters alone when processing
-keyboard input.  Use `stty' to do this:
-
-       stty cs8 -istrip -parenb
-
-For old BSD-style systems, you can use
-
-       stty pass8
-
-You may also need
-
-       stty even odd
-
-Finally, you need to tell readline that you will be inputting and
-displaying eight-bit characters.  You use readline variables to do
-this.  These variables can be set in your .inputrc or using the bash
-`bind' builtin.  Here's an example using `bind':
-
-       bash$ bind 'set convert-meta off'
-       bash$ bind 'set meta-flag on'
-       bash$ bind 'set output-meta on'
-
-The `set' commands between the single quotes may also be placed
-in ~/.inputrc.
-
-G2) How do I write a function `x' to replace builtin command `x', but
-    still invoke the command from within the function?
-
-This is why the `command' and `builtin' builtins exist.  The
-`command' builtin executes the command supplied as its first
-argument, skipping over any function defined with that name.  The
-`builtin' builtin executes the builtin command given as its first
-argument directly. 
-
-For example, to write a function to replace `cd' that writes the
-hostname and current directory to an xterm title bar, use
-something like the following:
-
-       cd()
-       {
-               builtin cd "$@" && xtitle "$HOST: $PWD"
-       }
-
-This could also be written using `command' instead of `builtin';
-the version above is marginally more efficient. 
-
-G3) How can I find the value of a shell variable whose name is the value
-    of another shell variable?
-
-Versions of Bash newer than Bash-2.0 support this directly.  You can use 
-
-       ${!var}
-
-For example, the following sequence of commands will echo `z':
-
-       var1=var2
-       var2=z
-       echo ${!var1}
-
-For sh compatibility, use the `eval' builtin.  The important
-thing to remember is that `eval' expands the arguments you give
-it again, so you need to quote the parts of the arguments that
-you want `eval' to act on. 
-
-For example, this expression prints the value of the last positional
-parameter:
-
-       eval echo \"\$\{$#\}\"
-
-The expansion of the quoted portions of this expression will be
-deferred until `eval' runs, while the `$#' will be expanded
-before `eval' is executed.  In versions of bash later than bash-2.0,
-
-       echo ${!#}
-
-does the same thing.
-
-This is not the same thing as ksh93 `nameref' variables, though the syntax
-is similar.  I may add namerefs in a future bash version.
-
-G4) How can I make the bash `time' reserved word print timing output that
-     looks like the output from my system's /usr/bin/time?
-
-The bash command timing code looks for a variable `TIMEFORMAT' and
-uses its value as a format string to decide how to display the
-timing statistics.
-
-The value of TIMEFORMAT is a string with `%' escapes expanded in a
-fashion similar in spirit to printf(3).  The manual page explains
-the meanings of the escape sequences in the format string.
-
-If TIMEFORMAT is not set, bash acts as if the following assignment had
-been performed:
-
-       TIMEFORMAT=$'\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS'
-
-The POSIX.2 default time format (used by `time -p command') is
-
-       TIMEFORMAT=$'real %2R\nuser %2U\nsys %2S'
-
-The BSD /usr/bin/time format can be emulated with:
-
-       TIMEFORMAT=$'\t%1R real\t%1U user\t%1S sys'
-
-The System V /usr/bin/time format can be emulated with:
-
-       TIMEFORMAT=$'\nreal\t%1R\nuser\t%1U\nsys\t%1S'
-
-The ksh format can be emulated with:
-
-       TIMEFORMAT=$'\nreal\t%2lR\nuser\t%2lU\nsys\t%2lS'
-
-G5) How do I get the current directory into my prompt?
-
-Bash provides a number of backslash-escape sequences which are expanded
-when the prompt string (PS1 or PS2) is displayed.  The full list is in
-the manual page.
-
-The \w expansion gives the full pathname of the current directory, with
-a tilde (`~') substituted for the current value of $HOME.  The \W
-expansion gives the basename of the current directory.  To put the full
-pathname of the current directory into the path without any tilde
-subsitution, use $PWD.  Here are some examples:
-
-       PS1='\w$ '      # current directory with tilde
-       PS1='\W$ '      # basename of current directory
-       PS1='$PWD$ '    # full pathname of current directory
-
-The single quotes are important in the final example to prevent $PWD from
-being expanded when the assignment to PS1 is performed.
-
-G6) How can I rename "*.foo" to "*.bar"?
-
-Use the pattern removal functionality described in D3.  The following `for'
-loop will do the trick:
-
-       for f in *.foo; do
-               mv $f ${f%foo}bar
-       done
-
-G7) How can I translate a filename from uppercase to lowercase?
-
-The script examples/functions/lowercase, originally written by John DuBois,
-will do the trick.  The converse is left as an exercise.
-
-G8) How can I write a filename expansion (globbing) pattern that will match
-    all files in the current directory except "." and ".."?
-
-You must have set the `extglob' shell option using `shopt -s extglob' to use
-this:
-
-       echo .!(.|) *
-
-A solution that works without extended globbing is given in the Unix Shell
-FAQ, posted periodically to comp.unix.shell.
-
-Section H:  Where do I go from here?
-
-H1) How do I report bugs in bash, and where should I look for fixes and
-    advice?
-
-Use the `bashbug' script to report bugs.  It is built and
-installed at the same time as bash.  It provides a standard
-template for reporting a problem and automatically includes
-information about your configuration and build environment. 
-
-`bashbug' sends its reports to bug-bash@gnu.org, which
-is a large mailing list gatewayed to the usenet newsgroup gnu.bash.bug. 
-
-Bug fixes, answers to questions, and announcements of new releases
-are all posted to gnu.bash.bug.  Discussions concerning bash features
-and problems also take place there.
-
-To reach the bash maintainers directly, send mail to
-bash-maintainers@gnu.org.
-
-H2) What kind of bash documentation is there?
-
-First, look in the doc directory in the bash distribution.  It should
-contain at least the following files:
-
-bash.1         an extensive, thorough Unix-style manual page
-builtins.1     a manual page covering just bash builtin commands
-bashref.texi   a reference manual in GNU tex`info format
-bashref.info   an info version of the reference manual
-FAQ            this file
-article.ms     text of an article written for The Linux Journal
-readline.3     a man page describing readline
-
-Postscript, HTML, and ASCII files created from the above source are
-available in the documentation distribution.
-
-There is additional documentation available for anonymous FTP from host
-ftp.cwru.edu in the `pub/bash' directory.
-
-Cameron Newham and Bill Rosenblatt have written a book on bash, published
-by O'Reilly and Associates.  The book is based on Bill Rosenblatt's Korn
-Shell book.  The title is ``Learning the Bash Shell'', and the ISBN number
-is 1-56592-147-X.  Look for it in fine bookstores near you.  This book
-covers bash-1.14, but has an appendix describing some of the new features
-in bash-2.0.  
-
-A second edition of this book is available, published in January, 1998.
-The ISBN number is 1-56592-347-2.  Look for it in the same fine bookstores
-or on the web.
-
-The GNU Bash Reference Manual has been published as a printed book by
-Network Theory Ltd (Paperback, ISBN: 0-9541617-7-7, Feb 2003).  It covers
-bash-2.0 and is available from most online bookstores (see
-http://www.network-theory.co.uk/bash/manual/ for details).  The publisher
-will donate $1 to the Free Software Foundation for each copy sold. 
-
-H3) What's coming in future versions?
-
-These are features I hope to include in a future version of bash.
-
-a better bash debugger (a minimally-tested version is included with bash-2.05b)
-associative arrays
-co-processes, but with a new-style syntax that looks like function declaration
-
-H4) What's on the bash `wish list' for future versions?
-
-These are features that may or may not appear in a future version of bash.
-
-breaking some of the shell functionality into embeddable libraries
-a module system like zsh's, using dynamic loading like builtins
-better internationalization using GNU `gettext'
-date-stamped command history
-a bash programmer's guide with a chapter on creating loadable builtins
-a better loadable interface to perl with access to the shell builtins and
-       variables (contributions gratefully accepted)
-ksh93-like `nameref' variables
-ksh93-like `+=' variable assignment operator
-ksh93-like `xx.yy' variables (including some of the .sh.* variables) and
-       associated disipline functions
-Some of the new ksh93 pattern matching operators, like backreferencing
-
-H5) When will the next release appear?
-
-The next version will appear sometime in 2002.  Never make predictions. 
-
-
-This document is Copyright 1995-2003 by Chester Ramey.
-
-Permission is hereby granted, without written agreement and
-without license or royalty fees, to use, copy, and distribute
-this document for any purpose, provided that the above copyright
-notice appears in all copies of this document and that the
-contents of this document remain unaltered.
diff --git a/doc/bash.1~ b/doc/bash.1~
deleted file mode 100644 (file)
index 7441e04..0000000
+++ /dev/null
@@ -1,9592 +0,0 @@
-.\"
-.\" MAN PAGE COMMENTS to
-.\"
-.\"    Chet Ramey
-.\"    Case Western Reserve University
-.\"    chet@po.cwru.edu
-.\"
-.\"    Last Change: Wed Dec 23 16:29:14 EST 2009
-.\"
-.\" bash_builtins, strip all but Built-Ins section
-.if \n(zZ=1 .ig zZ
-.if \n(zY=1 .ig zY
-.TH BASH 1 "2009 December 23" "GNU Bash-4.1"
-.\"
-.\" 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]
-[file]
-.SH COPYRIGHT
-.if n Bash is Copyright (C) 1989-2009 by the Free Software Foundation, Inc.
-.if t Bash is Copyright \(co 1989-2009 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
-In addition to the single-character shell options documented in the
-description of the \fBset\fR builtin command, \fBbash\fR
-interprets the following options when it is invoked:
-.PP
-.PD 0
-.TP 10
-.BI \-c "\| string\^"
-If the
-.B \-c
-option is present, then commands are read from
-.IR string .
-If there are arguments after the
-.IR 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)
-and shell function tracing (see the description of the
-\fB\-o functrace\fP option to the
-.B set
-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).
-.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 file names 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 file name.
-.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 a network connection, as if 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
-\fIrshd\fP does not 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 ,
-.BR BASHOPTS ,
-.BR CDPATH ,
-and
-.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\(bv\(bv  &  &&  ;  ;;  (  )  |  |&    <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  do done elif else esac fi for function if in select then until while { } time [[ ]]
-.if t !    case    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, the standard error of \fIcommand\fP 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 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.
-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
-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 \(bv\(bv ,
-and optionally terminated by one of
-.BR ; ,
-.BR & ,
-or
-.BR <newline> .
-.PP
-Of these list operators,
-.B &&
-and
-.B \(bv\(bv
-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\(bv\(bv\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\(bv\(bv\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:
-.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.
-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 it 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 it to be matched as a
-string.
-Substrings matched by parenthesized subexpressions within the regular
-expression are saved in the array variable \fBBASH_REMATCH\fP.
-The element of \fBBASH_REMATCH\fP with index 0 is the portion of the string
-matching the entire regular expression.
-The element of \fBBASH_REMATCH\fP 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
-.if t \fIexpression1\fP \fB\(bv\(bv\fP \fIexpression2\fP
-.if n \fIexpression1\fP \fB||\fP \fIexpression2\fP
-True if either
-.I expression1
-or
-.I expression2
-is true.
-.PD
-.LP
-The \fB&&\fP and
-.if t \fB\(bv\(bv\fP
-.if n \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
-.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
-.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\fP; \fBdo\fP \fIlist\fP; \fBdone\fP
-.PD 0
-.TP
-\fBuntil\fP \fIlist\fP; \fBdo\fP \fIlist\fP; \fBdone\fP
-.PD
-The \fBwhile\fP command continuously executes the \fBdo\fP
-\fIlist\fP as long as the last command in \fIlist\fP returns
-an exit status of zero.  The \fBuntil\fP command is identical
-to the \fBwhile\fP command, except that the test is negated;
-the
-.B do
-.I list
-is executed as long as the last command in
-.I list
-returns a non-zero exit status.
-The exit status of the \fBwhile\fP and \fBuntil\fP commands
-is the exit status
-of the last \fBdo\fP \fIlist\fP command executed, 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 \fICOPROC\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 coproc 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 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
-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
-[ \fBfunction\fP ] \fIname\fP () \fIcompound\-command\fP [\fIredirection\fP]
-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.
-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 \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.
-.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 integer 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.
-.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 file name 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 file name 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
-\fBBASH_ARGC\fP.
-The shell sets \fBBASH_ARGC\fP 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 \fBBASH_ARGV\fP.
-The shell sets \fBBASH_ARGV\fP 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
-corresponding to each member of \fBFUNCNAME\fP.
-\fB${BASH_LINENO[\fP\fI$i\fP\fB]}\fP is the line number in the source
-file 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).
-The corresponding source file name is \fB${BASH_SOURCE[\fP\fI$i\fP\fB]}\fP.
-Use \fBLINENO\fP 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 corresponding
-to the elements in the \fBFUNCNAME\fP array variable.
-.TP
-.B BASH_SUBSHELL
-Incremented by one each time a subshell or subshell environment is spawned.
-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
-.PD 0
-.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 \fBMACHTYPE\fP.
-.PD
-.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
-\fBCOMP_WORDBREAKS\fP as described above.
-This variable is available only in shell functions invoked by the
-programmable completion facilities (see \fBProgrammable Completion\fP
-below).
-.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 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.
-.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 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 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_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 file name.
-.SM
-.B PATH
-is not used to search for the resultant file name.
-.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 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 \fBBASH_XTRACEFD\fP is unset or assigned
-a new value.
-Unsetting \fBBASH_XTRACEFD\fP or assigning it the empty string causes the
-trace output to be sent to the standard error.
-Note that setting \fPBASH_XTRACEFD\fP to 2 (the standard error file
-descriptor) and then unsetting it will result in the standard error
-being closed.
-.TP
-.B COLUMNS
-Used by the \fBselect\fP builtin command to determine the terminal width
-when printing selection lists.  Automatically set upon receipt of a 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).
-.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 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 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 \fBHISTCONTROL\fP 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
-.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
-.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 an interactive 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, by removing the oldest entries,
-to contain no more than that number of lines.  The default
-value is 500.  The history file is also truncated to this size after
-writing it when an interactive shell exits.
-.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
-.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
-.BR HISTIGNORE .
-.TP
-.B HISTSIZE
-The number of commands to remember in the command history (see
-.SM
-.B HISTORY
-below).  The default value is 500.
-.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 \fBLANG\fP 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 builtin command to determine the column length
-for printing selection lists.  Automatically set upon receipt of a SIGWINCH.
-.TP
-.B MAIL
-If this parameter is set to a file name and the
-.SM
-.B MAILPATH
-variable is not set,
-.B bash
-informs the user of the arrival of mail in the specified file.
-.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 file names to be checked for mail. 
-The message to be printed when mail arrives in a particular file
-may be specified by separating the file name 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 \fBPATH\fP 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/gnu/bin:/usr/local/bin:/usr/ucb:/bin:/usr/bin\fP.
-.if n ``/usr/gnu/bin:/usr/local/bin:/usr/ucb:/bin:/usr/bin''.
-.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
-.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
-.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\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.
-.TP
-.B TMOUT
-If set to a value greater than zero, \fBTMOUT\fP is treated as the
-default timeout for the \fBread\fP builtin.
-The \fBselect\fP command terminates if input does not arrive
-after \fBTMOUT\fP seconds when input is coming from a terminal.
-In an interactive shell, the value is interpreted as the
-number of seconds to wait for input after issuing the primary prompt.
-.B Bash
-terminates after waiting for that number of seconds if 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.
-.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
-greater than or equal to zero.  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 the bracket and subscript.
-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.
-.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.
-.PP
-An array variable is considered set if a subscript has been assigned a
-value.  The null string is a valid value.
-.PP
-The
-.B unset
-builtin is used to destroy arrays.  \fBunset\fP \fIname\fP[\fIsubscript\fP]
-destroys the array element at index \fIsubscript\fP.
-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.
-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.  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 file names 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.
-.PD
-.PP
-If the first character of \fIparameter\fP is an exclamation point (\fB!\fP),
-a level of variable indirection is introduced.
-\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 ${!\fIprefix\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,
-\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 \fIparameter\fP
-starting at the character specified by \fIoffset\fP.
-If \fIlength\fP is omitted, expands to the substring of
-\fIparameter\fP starting at the character specified by \fIoffset\fP.
-\fIlength\fP and \fIoffset\fP are arithmetic expressions (see
-.SM
-.B
-ARITHMETIC EVALUATION
-below).
-\fIlength\fP must evaluate to a number greater than or equal to zero.
-If \fIoffset\fP evaluates to a number less than zero, the value
-is used as an offset from the end of the value of \fIparameter\fP.
-If \fIparameter\fP is \fB@\fP, the result is \fIlength\fP positional
-parameters beginning at \fIoffset\fP.
-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.
-Substring expansion applied to an associative array produces undefined
-results.
-Note that a negative offset must be separated from the colon by at least
-one space to avoid being confused with the :- expansion.
-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.
-.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.
-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:
-.PP
-.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 expansion, string
-expansion, command substitution, and quote removal.
-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
-file names matching the pattern.
-If no matching file names 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 file names matching a
-.IR pattern .
-If
-.SM
-.B GLOBIGNORE
-is set, each matching file name that also matches one of the patterns in
-.SM
-.B GLOBIGNORE
-is removed from the list of matches.
-The file names
-.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 file names beginning with a
-.B ``.''
-will match.
-To get the old behavior of ignoring file names 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
-.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 sorts 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 value of the \fBLC_COLLATE\fP shell variable,
-if set.
-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
-.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 may also be used to open and close files for 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 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 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
-a TCP connection to the corresponding 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
-a UDP connection to the corresponding 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
-.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
-.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 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.  In the latter
-case, 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 is expanded and supplied 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.
-As a special case, if \fIn\fP is omitted, and \fIword\fP does not
-expand to one or more digits, 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 0
-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
-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.  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 integer 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 \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.
-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.
-.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 \-O \fIfile\fP
-True if \fIfile\fP exists and is owned by the effective user id.
-.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 \-S \fIfile\fP
-True if \fIfile\fP exists and is a socket.
-.TP
-.B \-N \fIfile\fP
-True if \fIfile\fP exists and has been modified since it was last read.
-.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
-\fIfile1\fP \fB\-ef\fP \fIfile2\fP
-True if \fIfile1\fP and \fIfile2\fP refer to the same device and
-inode numbers.
-.TP
-.B \-o \fIoptname\fP
-True if 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 \-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.
-.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:
-.sp 1
-.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 \fB$PPID\fP
-.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.
-.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 posix mode,
-Bash 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 file name 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 \fB$HOME\fP abbreviated with a tilde
-(uses the \fB$PROMPT_DIRTRIM\fP variable)
-.TP
-.B \eW
-the basename of the current working directory, with \fB$HOME\fP
-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 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, the number of entries in the history list 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 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, unless the leading `.' is
-supplied by the user in the filename to be completed.
-.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 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 Bash:
-.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 an argument,
-behave exactly like \fByank\-nth\-arg\fP.
-Successive calls to \fByank\-last\-arg\fP move back through the history
-list, inserting the last argument of each line in turn.
-The history expansion facilities are used to extract the last argument,
-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.
-.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 file names 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 file names 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 to 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 is the
-name of the command whose arguments are being completed, the
-second argument is the word being completed, and the third argument
-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.
-.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 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 \fBHISTSIZE\fP 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 .
-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 an interactive shell 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
-.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 not set, no truncation is performed.
-.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), 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.
-.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 line 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 starting with 
-.IR string .
-.TP
-.B !?\fIstring\fR\fB[?]\fR
-Refer to the most recent command 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 last 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 argument.
-.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 file name component, leaving only the head.
-.TP
-.B t
-Remove all leading file name 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, file names 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\-lpsvPSV\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
-.B READLINE_LINE
-variable to the contents of the \fBreadline\fP line buffer and the
-.B READLINE_POINT
-variable to the current location of the insertion point.
-If the executed command changes the value of
-.B READLINE_LINE
-or
-.BR READLINE_POINT ,
-those new values will be reflected in the editing state.
-.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|-P\fP] [\fIdir\fP]
-Change the current directory to \fIdir\fP.  The variable
-.SM
-.B HOME
-is the
-default
-.IR dir .
-The variable
-.SM
-.B CDPATH
-defines the search path for the directory containing
-.IR dir .
-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 says to use the physical directory structure instead of
-following symbolic links (see also the
-.B \-P
-option to the
-.B set
-builtin command); the
-.B \-L
-option forces symbolic links to be followed.  An argument of
-.B \-
-is equivalent to
-.SM
-.BR $OLDPWD .
-If a non-empty directory name from \fBCDPATH\fP 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
-.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 file name
-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 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\-G\fP \fIglobpat\fP
-The pathname expansion pattern \fIglobpat\fP is expanded to generate
-the possible completions.
-.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\-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 it finishes, the possible completions are retrieved from the value
-of the
-.SM
-.B COMPREPLY
-array variable.
-.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.
-.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.
-.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-execution 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.
-.PP
-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\-aAfFilrtux\fP] [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP] ...]
-.PD 0
-.TP
-\fBtypeset\fP [\fB\-aAfFilrtux\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 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" ") "
-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 \-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\fB will not
-remove the readonly attribute.
-When used in a function,
-makes each
-\fIname\fP local, as with the 
-.B local
-command.
-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 [+\fIn\fP] [\-\fIn\fP] [\fB\-cplv\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
-\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.
-.TP
-.B \-c
-Clears the directory stack by deleting all of the entries.
-.TP
-.B \-l
-Produces a longer listing; 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.
-.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, each
-.I jobspec
-is removed from the table of active jobs.
-If
-.I jobspec
-is not present, and neither \fB\-a\fB 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 always 0.
-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
-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)
-.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 shell option
-.B execfail
-is enabled, in which 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 all names that are exported in this shell 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
-Fix Command.  In the first form, a range of commands from
-.I first
-to
-.I last
-is selected from the history list.
-.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.
-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.
-\fBOPTIND\fP is set to the index of the first non-option argument,
-and \fBname\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]
-For each
-.IR name ,
-the full file name of the command is determined by searching
-the directories in
-.B $PATH
-and remembered.
-If the
-.B \-p
-option is supplied, no path search is performed, and
-.I filename
-is used as the full file name 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
-.RE
-The return status is 0 unless no command matches
-.IR pattern .
-.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 \fBHISTTIMEFORMAT\fP 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 use them as the current history.
-.TP
-.B \-w
-Write the current history 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 \fBHISTTIMEFORMAT\fP 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 \-p
-List only the process ID of the job's process group
-leader.
-.TP
-.B \-n
-Display information only about jobs that have changed status since
-the user was last notified of their status.
-.TP
-.B \-r
-Restrict output to running jobs.
-.TP
-.B \-s
-Restrict output to 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
-.BR "ARITHMETIC EVALUATION" ).
-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 \fBMAPFILE\fP 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 line 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 as an additional argument.
-\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 \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) formats, \fB%b\fP 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),
-and \fB%q\fP causes \fBprintf\fP to output the corresponding
-\fIargument\fP in a format that can be reused as shell input.
-.sp 1
-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 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.
-.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.
-.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.
-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 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 \fItimeout\fP is 0, \fBread\fP returns success if input is available on
-the specified file descriptor, failure 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), or an
-invalid file descriptor is supplied as the argument to \fB\-u\fP.
-.RE
-.TP
-\fBreadonly\fP [\fB\-aApf\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 no
-.I name
-arguments are given, or if the
-.B \-p
-option is supplied, a list of all readonly names is printed.
-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 exit with the return value specified by
-.IR n .
-If 
-.I n
-is omitted, the return status is that of the last command
-executed in the function body.  If 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 used outside a
-function and not during execution of a script by \fB.\fP\^,
-the return status is false.
-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\fP] [\fIarg\fP ...]
-.PD 0
-.TP
-\fBset\fP [\fB+abefhkmnptuvxBCEHPT\fP] [\fB+o\fP \fIoption\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 mode\fP, 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 \fIsubshell\fP command enclosed in parentheses,
-or one of the commands executed as part of a command list enclosed
-by braces (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 \(bv\(bv
-list except the command following the final \fB&&\fP or \fB\(bv\(bv\fP,
-any command in a pipeline but the last,
-or if the command's return value is
-being inverted with
-.BR ! .
-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
-.B "COMMAND EXECUTION ENVIRONMENT"
-above), and may cause
-subshells to exit before executing all the commands in the subshell.
-.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).  Background processes run in a separate process
-group and a line containing their exit status is printed
-upon their completion.
-.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 errtrace
-Same as
-.BR \-E .
-.TP 8
-.B functrace
-Same as
-.BR \-T .
-.TP 8
-.B errexit
-Same as
-.BR \-e .
-.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).
-.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 ,
-.BR BASHOPTS ,
-.BR CDPATH ,
-and
-.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 follow 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, the display is limited to
-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 file name 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 \fBJOB CONTROL\fP 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 conditional command's =~ operator.
-.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 conditional command's < and > operators.
-.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 conditional command's < and > operators
-and the effect of interrupting a command list.
-.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.
-\fBBASH_ARGC\fP and \fBBASH_ARGV\fP 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
-\fBERROR\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 \fBFIGNORE\fP 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 \fBFIGNORE\fP.
-This option is enabled by default.
-.TP 8
-.B globstar
-If set, the pattern \fB**\fP used in a pathname expansion context will
-match a 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
-.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 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 \fBPATH\fP 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
-.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 or 1 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.
-.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
-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.
-.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 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 simple command has 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 \(bv\(bv
-list, or if the command's return value is
-being inverted via
-.BR ! .
-These are the same conditions obeyed by the \fBerrexit\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, 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
-.TP
-.B \-x
-The maximum number of file locks
-.TP
-.B \-T
-The maximum number of threads
-.PD
-.PP
-If
-.I limit
-is given, it is the new value of the specified resource (the
-.B \-a
-option is display only).
-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] [\fIname\fP ...]
-For each
-.IR name ,
-remove the corresponding variable or function.
-If no options are supplied, or the
-.B \-v
-option is given, each
-.I name
-refers to a shell variable.
-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.
-Each unset variable or function is removed from the environment
-passed to subsequent commands.
-If any of
-.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 [\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
-.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
-.BR SHELL ,
-.BR PATH ,
-.BR ENV ,
-or
-.B BASH_ENV
-.IP \(bu
-specifying command names containing
-.B /
-.IP \(bu
-specifying a file name 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 \fBSHELLOPTS\fP 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
-.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/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@po.cwru.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/doc/bashref.texi~ b/doc/bashref.texi~
deleted file mode 100644 (file)
index d427c52..0000000
+++ /dev/null
@@ -1,7928 +0,0 @@
-\input texinfo.tex @c -*- texinfo -*-
-@c %**start of header
-@setfilename bashref.info
-@settitle Bash Reference Manual
-@c %**end of header
-
-@setchapternewpage odd
-
-@include version.texi
-
-@copying
-This text is a brief description of the features that are present in
-the Bash shell (version @value{VERSION}, @value{UPDATED}).
-
-This is Edition @value{EDITION}, last updated @value{UPDATED},
-of @cite{The GNU Bash Reference Manual},
-for @code{Bash}, Version @value{VERSION}.
-
-Copyright @copyright{} 1988--2009 Free Software Foundation, Inc.
-
-Permission is granted to make and distribute verbatim copies of
-this manual provided the copyright notice and this permission notice
-are preserved on all copies.
-
-@quotation
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.3 or
-any later version published by the Free Software Foundation; with no
-Invariant Sections, with the Front-Cover texts being ``A GNU Manual'',
-and with the Back-Cover Texts as in (a) below.  A copy of the license is
-included in the section entitled ``GNU Free Documentation License''.
-
-(a) The FSF's Back-Cover Text is: You are free to copy and modify
-this GNU manual.  Buying copies from GNU Press supports the FSF in
-developing GNU and promoting software freedom.''
-
-@end quotation
-@end copying
-
-@defcodeindex bt
-@defcodeindex rw
-@set BashFeatures
-
-@dircategory Basics
-@direntry
-* Bash: (bash).                     The GNU Bourne-Again SHell.
-@end direntry
-
-@finalout
-
-@titlepage
-@title Bash Reference Manual
-@subtitle Reference Documentation for Bash
-@subtitle Edition @value{EDITION}, for @code{Bash} Version @value{VERSION}.
-@subtitle @value{UPDATED-MONTH}
-@author Chet Ramey, Case Western Reserve University
-@author Brian Fox, Free Software Foundation
-
-@page
-@vskip 0pt plus 1filll
-@insertcopying
-
-@sp 1
-Published by the Free Software Foundation @*
-59 Temple Place, Suite 330, @*
-Boston, MA 02111-1307 @*
-USA @*
-
-@end titlepage
-
-@contents
-
-@ifnottex
-@node Top, Introduction, (dir), (dir)
-@top Bash Features
-
-This text is a brief description of the features that are present in
-the Bash shell (version @value{VERSION}, @value{UPDATED}).
-
-This is Edition @value{EDITION}, last updated @value{UPDATED},
-of @cite{The GNU Bash Reference Manual},
-for @code{Bash}, Version @value{VERSION}.
-
-Bash contains features that appear in other popular shells, and some
-features that only appear in Bash.  Some of the shells that Bash has
-borrowed concepts from are the Bourne Shell (@file{sh}), the Korn Shell
-(@file{ksh}), and the C-shell (@file{csh} and its successor,
-@file{tcsh}). The following menu breaks the features up into
-categories based upon which one of these other shells inspired the
-feature.
-
-This manual is meant as a brief introduction to features found in
-Bash.  The Bash manual page should be used as the definitive
-reference on shell behavior.
-
-@menu
-* Introduction::               An introduction to the shell.
-* Definitions::                        Some definitions used in the rest of this
-                               manual.
-* Basic Shell Features::       The shell "building blocks".
-* Shell Builtin Commands::     Commands that are a part of the shell.
-* Shell Variables::            Variables used or set by Bash.
-* Bash Features::              Features found only in Bash.
-* Job Control::                        What job control is and how Bash allows you
-                               to use it.
-* Command Line Editing::       Chapter describing the command line
-                               editing features.
-* Using History Interactively::        Command History Expansion
-* Installing Bash::            How to build and install Bash on your system.
-* Reporting Bugs::             How to report bugs in Bash.
-* Major Differences From The Bourne Shell::    A terse list of the differences
-                                               between Bash and historical
-                                               versions of /bin/sh.
-* GNU Free Documentation License::     Copying and sharing this documentation.
-* Indexes::                    Various indexes for this manual.
-@end menu
-@end ifnottex
-
-@node Introduction
-@chapter Introduction
-@menu
-* What is Bash?::              A short description of Bash.
-* What is a shell?::           A brief introduction to shells.
-@end menu
-
-@node What is Bash?
-@section What is Bash?
-
-Bash is the shell, or command language interpreter,
-for the @sc{gnu} operating system.
-The name is an acronym for the @samp{Bourne-Again SHell},
-a pun on Stephen Bourne, the author of the direct ancestor of
-the current Unix shell @code{sh}, 
-which appeared in the Seventh Edition Bell Labs Research version
-of Unix.
-
-Bash is largely compatible with @code{sh} and incorporates useful
-features from the Korn shell @code{ksh} and the C shell @code{csh}.
-It is intended to be a conformant implementation of the @sc{ieee}
-@sc{posix} Shell and Tools portion of the @sc{ieee} @sc{posix}
-specification (@sc{ieee} Standard 1003.1).
-It offers functional improvements over @code{sh} for both interactive and
-programming use.
-
-While the @sc{gnu} operating system provides other shells, including
-a version of @code{csh}, Bash is the default shell.
-Like other @sc{gnu} software, Bash is quite portable.  It currently runs
-on nearly every version of Unix and a few other operating systems @minus{}
-independently-supported ports exist for @sc{ms-dos}, @sc{os/2},
-and Windows platforms.
-
-@node What is a shell?
-@section What is a shell?
-
-At its base, a shell is simply a macro processor that executes
-commands.  The term macro processor means functionality where text
-and symbols are expanded to create larger expressions.
-
-A Unix shell is both a command interpreter and a programming
-language.  As a command interpreter, the shell provides the user
-interface to the rich set of @sc{gnu} utilities.  The programming
-language features allow these utilities to be combined.
-Files containing commands can be created, and become
-commands themselves.  These new commands have the same status as
-system commands in directories such as @file{/bin}, allowing users
-or groups to establish custom environments to automate their common
-tasks.
-
-Shells may be used interactively or non-interactively.  In
-interactive mode, they accept input typed from the keyboard.
-When executing non-interactively, shells execute commands read
-from a file.
-
-A shell allows execution of @sc{gnu} commands, both synchronously and
-asynchronously.
-The shell waits for synchronous commands to complete before accepting
-more input; asynchronous commands continue to execute in parallel
-with the shell while it reads and executes additional commands.
-The @dfn{redirection} constructs permit
-fine-grained control of the input and output of those commands.
-Moreover, the shell allows control over the contents of commands'
-environments.
-
-Shells also provide a small set of built-in
-commands (@dfn{builtins}) implementing functionality impossible
-or inconvenient to obtain via separate utilities.
-For example, @code{cd}, @code{break}, @code{continue}, and
-@code{exec}) cannot be implemented outside of the shell because
-they directly manipulate the shell itself.
-The @code{history}, @code{getopts}, @code{kill}, or @code{pwd}
-builtins, among others, could be implemented in separate utilities,
-but they are more convenient to use as builtin commands.
-All of the shell builtins are described in
-subsequent sections.
-
-While executing commands is essential, most of the power (and
-complexity) of shells is due to their embedded programming
-languages.  Like any high-level language, the shell provides
-variables, flow control constructs, quoting, and functions. 
-
-Shells offer features geared specifically for
-interactive use rather than to augment the programming language. 
-These interactive features include job control, command line
-editing, command history and aliases.  Each of these features is
-described in this manual.
-
-@node Definitions
-@chapter Definitions
-These definitions are used throughout the remainder of this manual.
-
-@table @code
-
-@item POSIX
-@cindex POSIX
-A family of open system standards based on Unix.  Bash
-is primarily concerned with the Shell and Utilities portion of the
-@sc{posix} 1003.1 standard. 
-
-@item blank
-A space or tab character.
-
-@item builtin
-@cindex builtin
-A command that is implemented internally by the shell itself, rather
-than by an executable program somewhere in the file system.
-
-@item control operator
-@cindex control operator
-A @code{token} that performs a control function.  It is a @code{newline}
-or one of the following:
-@samp{||}, @samp{&&}, @samp{&}, @samp{;}, @samp{;;},
-@samp{|}, @samp{|&}, @samp{(}, or @samp{)}.
-
-@item exit status
-@cindex exit status
-The value returned by a command to its caller.  The value is restricted
-to eight bits, so the maximum value is 255.
-
-@item field
-@cindex field
-A unit of text that is the result of one of the shell expansions.  After
-expansion, when executing a command, the resulting fields are used as
-the command name and arguments.
-
-@item filename
-@cindex filename
-A string of characters used to identify a file.
-
-@item job
-@cindex job
-A set of processes comprising a pipeline, and any processes descended
-from it, that are all in the same process group.
-
-@item job control
-@cindex job control
-A mechanism by which users can selectively stop (suspend) and restart
-(resume) execution of processes.
-
-@item metacharacter
-@cindex metacharacter
-A character that, when unquoted, separates words.  A metacharacter is
-a @code{blank} or one of the following characters:
-@samp{|}, @samp{&}, @samp{;}, @samp{(}, @samp{)}, @samp{<}, or
-@samp{>}.
-
-@item name
-@cindex name
-@cindex identifier
-A @code{word} consisting solely of letters, numbers, and underscores,
-and beginning with a letter or underscore.  @code{Name}s are used as
-shell variable and function names.
-Also referred to as an @code{identifier}.
-
-@item operator
-@cindex operator, shell
-A @code{control operator} or a @code{redirection operator}.
-@xref{Redirections}, for a list of redirection operators.
-Operators contain at least one unquoted @code{metacharacter}.
-
-@item process group
-@cindex process group
-A collection of related processes each having the same process
-group @sc{id}.
-
-@item process group ID
-@cindex process group ID
-A unique identifier that represents a @code{process group}
-during its lifetime.
-
-@item reserved word
-@cindex reserved word
-A @code{word} that has a special meaning to the shell.  Most reserved
-words introduce shell flow control constructs, such as @code{for} and
-@code{while}.
-
-@item return status
-@cindex return status
-A synonym for @code{exit status}.
-
-@item signal
-@cindex signal
-A mechanism by which a process may be notified by the kernel
-of an event occurring in the system.
-
-@item special builtin
-@cindex special builtin
-A shell builtin command that has been classified as special by the
-@sc{posix} standard.
-
-@item token
-@cindex token
-A sequence of characters considered a single unit by the shell.
-It is either a @code{word} or an @code{operator}.
-
-@item word
-@cindex word
-A sequence of characters treated as a unit by the shell.
-Words may not include unquoted @code{metacharacters}.
-@end table
-
-@node Basic Shell Features
-@chapter Basic Shell Features
-@cindex Bourne shell
-
-Bash is an acronym for @samp{Bourne-Again SHell}.
-The Bourne shell is
-the traditional Unix shell originally written by Stephen Bourne.
-All of the Bourne shell builtin commands are available in Bash,
-The rules for evaluation and quoting are taken from the @sc{posix}
-specification for the `standard' Unix shell.
-
-This chapter briefly summarizes the shell's `building blocks':
-commands, control structures, shell functions, shell @i{parameters},
-shell expansions,
-@i{redirections}, which are a way to direct input and output from
-and to named files, and how the shell executes commands.
-
-@menu
-* Shell Syntax::               What your input means to the shell.
-* Shell Commands::             The types of commands you can use.
-* Shell Functions::            Grouping commands by name.
-* Shell Parameters::           How the shell stores values.
-* Shell Expansions::           How Bash expands parameters and the various
-                               expansions available.
-* Redirections::               A way to control where input and output go.
-* Executing Commands::         What happens when you run a command.
-* Shell Scripts::              Executing files of shell commands.
-@end menu
-
-@node Shell Syntax
-@section Shell Syntax
-@menu
-* Shell Operation::    The basic operation of the shell.
-* Quoting::            How to remove the special meaning from characters.
-* Comments::           How to specify comments.
-@end menu
-
-When the shell reads input, it proceeds through a
-sequence of operations.  If the input indicates the beginning of a
-comment, the shell ignores the comment symbol (@samp{#}), and the rest
-of that line.
-                                
-Otherwise, roughly speaking,  the shell reads its input and
-divides the input into words and operators, employing the quoting rules
-to select which meanings to assign various words and characters.
-
-The shell then parses these tokens into commands and other constructs,
-removes the special meaning of certain words or characters, expands
-others, redirects input and output as needed, executes the specified
-command, waits for the command's exit status, and makes that exit status
-available for further inspection or processing.
-
-@node Shell Operation
-@subsection Shell Operation
-
-The following is a brief description of the shell's operation when it
-reads and executes a command.  Basically, the shell does the
-following:
-
-@enumerate
-@item
-Reads its input from a file (@pxref{Shell Scripts}), from a string
-supplied as an argument to the @option{-c} invocation option
-(@pxref{Invoking Bash}), or from the user's terminal.
-
-@item
-Breaks the input into words and operators, obeying the quoting rules
-described in @ref{Quoting}.  These tokens are separated by
-@code{metacharacters}.  Alias expansion is performed by this step
-(@pxref{Aliases}).
-
-@item
-Parses the tokens into simple and compound commands
-(@pxref{Shell Commands}).
-
-@item
-Performs the various shell expansions (@pxref{Shell Expansions}), breaking
-the expanded tokens into lists of filenames (@pxref{Filename Expansion})
-and commands and arguments.
-
-@item
-Performs any necessary redirections (@pxref{Redirections}) and removes
-the redirection operators and their operands from the argument list.
-
-@item
-Executes the command (@pxref{Executing Commands}).
-
-@item
-Optionally waits for the command to complete and collects its exit
-status (@pxref{Exit Status}).
-
-@end enumerate
-
-@node Quoting
-@subsection Quoting
-@cindex quoting
-@menu
-* Escape Character::   How to remove the special meaning from a single
-                       character.
-* Single Quotes::      How to inhibit all interpretation of a sequence
-                       of characters.
-* Double Quotes::      How to suppress most of the interpretation of a
-                       sequence of characters.
-* ANSI-C Quoting::     How to expand ANSI-C sequences in quoted strings.
-* Locale Translation:: How to translate strings into different languages.
-@end menu
-
-Quoting 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.
-
-Each of the shell metacharacters (@pxref{Definitions})
-has special meaning to the shell and must be quoted if it is to
-represent itself.
-When the command history expansion facilities are being used
-(@pxref{History Interaction}), the
-@var{history expansion} character, usually @samp{!}, must be quoted
-to prevent history expansion.  @xref{Bash History Facilities}, for
-more details concerning history expansion.
-
-There are three quoting mechanisms: the
-@var{escape character}, single quotes, and double quotes.
-
-@node Escape Character
-@subsubsection Escape Character
-A non-quoted backslash @samp{\} is the Bash escape character.
-It preserves the literal value of the next character that follows,
-with the exception of @code{newline}.  If a @code{\newline} pair
-appears, and the backslash itself is not quoted, the @code{\newline}
-is treated as a line continuation (that is, it is removed from
-the input stream and effectively ignored).
-
-@node Single Quotes
-@subsubsection Single Quotes
-
-Enclosing characters in single quotes (@samp{'}) 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.
-
-@node Double Quotes
-@subsubsection Double Quotes
-
-Enclosing characters in double quotes (@samp{"}) preserves the literal value
-of all characters within the quotes, with the exception of
-@samp{$}, @samp{`}, @samp{\},
-and, when history expansion is enabled, @samp{!}.
-The characters @samp{$} and @samp{`}
-retain their special meaning within double quotes (@pxref{Shell Expansions}).
-The backslash retains its special meaning only when followed by one of
-the following characters:
-@samp{$}, @samp{`}, @samp{"}, @samp{\}, or @code{newline}.
-Within double quotes, backslashes that are followed by one of these
-characters are removed.  Backslashes preceding characters without a
-special meaning are left unmodified.
-A double quote may be quoted within double quotes by preceding it with
-a backslash.
-If enabled, history expansion will be performed unless an @samp{!}
-appearing in double quotes is escaped using a backslash.
-The backslash preceding the @samp{!} is not removed.
-
-The special parameters @samp{*} and @samp{@@} have special meaning
-when in double quotes (@pxref{Shell Parameter Expansion}).
-
-@node ANSI-C Quoting
-@subsubsection ANSI-C Quoting
-@cindex quoting, ANSI
-
-Words of the form @code{$'@var{string}'} are treated specially.  The
-word expands to @var{string}, with backslash-escaped characters replaced
-as specified by the ANSI C standard.  Backslash escape sequences, if
-present, are decoded as follows:
-
-@table @code
-@item \a
-alert (bell)
-@item \b
-backspace
-@item \e
-an escape character (not ANSI C)
-@item \f
-form feed
-@item \n
-newline
-@item \r
-carriage return
-@item \t
-horizontal tab
-@item \v
-vertical tab
-@item \\
-backslash
-@item \'
-single quote
-@item \@var{nnn}
-the eight-bit character whose value is the octal value @var{nnn}
-(one to three digits)
-@item \x@var{HH}
-the eight-bit character whose value is the hexadecimal value @var{HH}
-(one or two hex digits)
-@item \c@var{x}
-a control-@var{x} character
-@end table
-
-@noindent
-The expanded result is single-quoted, as if the dollar sign had not
-been present.
-
-@node Locale Translation
-@subsubsection Locale-Specific Translation
-@cindex localization
-@cindex internationalization
-@cindex native languages
-@cindex translation, native languages
-
-A double-quoted string preceded by a dollar sign (@samp{$}) will cause
-the string to be translated according to the current locale.
-If the current locale is @code{C} or @code{POSIX}, the dollar sign
-is ignored.
-If the string is translated and replaced, the replacement is
-double-quoted.
-
-@vindex LC_MESSAGES
-@vindex TEXTDOMAIN
-@vindex TEXTDOMAINDIR
-Some systems use the message catalog selected by the @env{LC_MESSAGES}
-shell variable.  Others create the name of the message catalog from the
-value of the @env{TEXTDOMAIN} shell variable, possibly adding a
-suffix of @samp{.mo}.  If you use the @env{TEXTDOMAIN} variable, you
-may need to set the @env{TEXTDOMAINDIR} variable to the location of
-the message catalog files.  Still others use both variables in this
-fashion:
-@env{TEXTDOMAINDIR}/@env{LC_MESSAGES}/LC_MESSAGES/@env{TEXTDOMAIN}.mo.
-
-@node Comments
-@subsection Comments
-@cindex comments, shell
-
-In a non-interactive shell, or an interactive shell in which the
-@code{interactive_comments} option to the @code{shopt}
-builtin is enabled (@pxref{The Shopt Builtin}),
-a word beginning with @samp{#}
-causes that word and all remaining characters on that line to
-be ignored.  An interactive shell without the @code{interactive_comments}
-option enabled does not allow comments.  The @code{interactive_comments}
-option is on by default in interactive shells.
-@xref{Interactive Shells}, for a description of what makes
-a shell interactive.
-
-@node Shell Commands
-@section Shell Commands
-@cindex commands, shell
-
-A simple shell command such as @code{echo a b c} consists of the command
-itself followed by arguments, separated by spaces.
-
-More complex shell commands are composed of simple commands arranged together
-in a variety of ways: in a pipeline in which the output of one command
-becomes the input of a second, in a loop or conditional construct, or in
-some other grouping.
-
-@menu
-* Simple Commands::            The most common type of command.
-* Pipelines::                  Connecting the input and output of several
-                               commands.
-* Lists::                      How to execute commands sequentially.
-* Compound Commands::          Shell commands for control flow.
-* Coprocesses::                        Two-way communication between commands.
-@end menu
-
-@node Simple Commands
-@subsection Simple Commands
-@cindex commands, simple
-
-A simple command is the kind of command encountered most often.
-It's just a sequence of words separated by @code{blank}s, terminated
-by one of the shell's control operators (@pxref{Definitions}).  The
-first word generally specifies a command to be executed, with the
-rest of the words being that command's arguments.
-
-The return status (@pxref{Exit Status}) of a simple command is
-its exit status as provided
-by the @sc{posix} 1003.1 @code{waitpid} function, or 128+@var{n} if
-the command was terminated by signal @var{n}.
-
-@node Pipelines
-@subsection Pipelines
-@cindex pipeline
-@cindex commands, pipelines
-
-A @code{pipeline} is a sequence of simple commands separated by one of
-the control operators @samp{|} or @samp{|&}.
-
-@rwindex time
-@rwindex !
-@cindex command timing
-The format for a pipeline is
-@example
-[@code{time} [@code{-p}]] [@code{!}] @var{command1} [ [@code{|} or @code{|&}] @var{command2} @dots{}]
-@end example
-
-@noindent
-The output of each command in the pipeline is connected via a pipe
-to the input of the next command.
-That is, each command reads the previous command's output.  This
-connection is performed before any redirections specified by the
-command.
-
-If @samp{|&} is used, the standard error of @var{command1} is connected to
-@var{command2}'s standard input through the pipe; it is shorthand for
-@code{2>&1 |}.  This implicit redirection of the standard error is
-performed after any redirections specified by the command.
-
-The reserved word @code{time} causes timing statistics
-to be printed for the pipeline once it finishes.
-The statistics currently consist of elapsed (wall-clock) time and
-user and system time consumed by the command's execution.
-The @option{-p} option changes the output format to that specified
-by @sc{posix}.
-The @env{TIMEFORMAT} variable may be set to a format string that
-specifies how the timing information should be displayed.
-@xref{Bash Variables}, for a description of the available formats.
-The use of @code{time} as a reserved word permits the timing of
-shell builtins, shell functions, and pipelines.  An external
-@code{time} command cannot time these easily.
-
-If the pipeline is not executed asynchronously (@pxref{Lists}), the
-shell waits for all commands in the pipeline to complete.
-
-Each command in a pipeline is executed in its own subshell
-(@pxref{Command Execution Environment}).  The exit
-status of a pipeline is the exit status of the last command in the
-pipeline, unless the @code{pipefail} option is enabled
-(@pxref{The Set Builtin}).
-If @code{pipefail} 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 @samp{!} precedes the pipeline, the
-exit status 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.
-
-@node Lists
-@subsection Lists of Commands
-@cindex commands, lists
-
-A @code{list} is a sequence of one or more pipelines separated by one
-of the operators @samp{;}, @samp{&}, @samp{&&}, or @samp{||},
-and optionally terminated by one of @samp{;}, @samp{&}, or a
-@code{newline}.
-
-Of these list operators, @samp{&&} and @samp{||}
-have equal precedence, followed by @samp{;} and @samp{&},
-which have equal precedence.
-
-A sequence of one or more newlines may appear in a @code{list}
-to delimit commands, equivalent to a semicolon.
-
-If a command is terminated by the control operator @samp{&},
-the shell executes the command asynchronously in a subshell.
-This is known as executing the command in the @var{background}.
-The shell does not wait for the command to finish, and the return
-status is 0 (true).
-When job control is not active (@pxref{Job Control}),
-the standard input for asynchronous commands, in the absence of any
-explicit redirections, is redirected from @code{/dev/null}.
-
-Commands separated by a @samp{;} 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.
-
-@sc{and} and @sc{or} lists are sequences of one or more pipelines
-separated by the control operators @samp{&&} and @samp{||},
-respectively.  @sc{and} and @sc{or} lists are executed with left
-associativity.
-
-An @sc{and} list has the form
-@example
-@var{command1} && @var{command2}
-@end example
-
-@noindent
-@var{command2} is executed if, and only if, @var{command1}
-returns an exit status of zero.
-
-An @sc{or} list has the form
-@example
-@var{command1} || @var{command2}
-@end example
-
-@noindent
-@var{command2} is executed if, and only if, @var{command1}
-returns a non-zero exit status.
-
-The return status of
-@sc{and} and @sc{or} lists is the exit status of the last command
-executed in the list.
-
-@node Compound Commands
-@subsection Compound Commands
-@cindex commands, compound
-
-@menu
-* Looping Constructs::         Shell commands for iterative action.
-* Conditional Constructs::     Shell commands for conditional execution.
-* Command Grouping::           Ways to group commands.
-@end menu
-
-Compound commands are the shell programming constructs.
-Each construct begins with a reserved word or control operator and is
-terminated by a corresponding reserved word or operator.
-Any redirections (@pxref{Redirections}) associated with a compound command
-apply to all commands within that compound command unless explicitly overridden.
-
-Bash provides looping constructs, conditional commands, and mechanisms
-to group commands and execute them as a unit.
-
-@node Looping Constructs
-@subsubsection Looping Constructs
-@cindex commands, looping
-
-Bash supports the following looping constructs.
-
-Note that wherever a @samp{;} appears in the description of a
-command's syntax, it may be replaced with one or more newlines.
-
-@table @code
-@item until
-@rwindex until
-@rwindex do
-@rwindex done
-The syntax of the @code{until} command is:
-@example
-until @var{test-commands}; do @var{consequent-commands}; done
-@end example
-Execute @var{consequent-commands} as long as
-@var{test-commands} has an exit status which is not zero.
-The return status is the exit status of the last command executed
-in @var{consequent-commands}, or zero if none was executed.
-
-@item while
-@rwindex while
-The syntax of the @code{while} command is:
-@example
-while @var{test-commands}; do @var{consequent-commands}; done
-@end example
-
-Execute @var{consequent-commands} as long as
-@var{test-commands} has an exit status of zero.
-The return status is the exit status of the last command executed
-in @var{consequent-commands}, or zero if none was executed.
-
-@item for
-@rwindex for
-The syntax of the @code{for} command is:
-
-@example
-for @var{name} [ [in [@var{words} @dots{}] ] ; ] do @var{commands}; done
-@end example
-Expand @var{words}, and execute @var{commands} once for each member
-in the resultant list, with @var{name} bound to the current member.
-If @samp{in @var{words}} is not present, the @code{for} command
-executes the @var{commands} once for each positional parameter that is
-set, as if @samp{in "$@@"} had been specified
-(@pxref{Special Parameters}).
-The return status is the exit status of the last command that executes.
-If there are no items in the expansion of @var{words}, no commands are
-executed, and the return status is zero.
-
-An alternate form of the @code{for} command is also supported:
-
-@example
-for (( @var{expr1} ; @var{expr2} ; @var{expr3} )) ; do @var{commands} ; done
-@end example
-First, the arithmetic expression @var{expr1} is evaluated according
-to the rules described below (@pxref{Shell Arithmetic}).
-The arithmetic expression @var{expr2} is then evaluated repeatedly
-until it evaluates to zero.   
-Each time @var{expr2} evaluates to a non-zero value, @var{commands} are
-executed and the arithmetic expression @var{expr3} 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 @var{list}
-that is executed, or false if any of the expressions is invalid.
-
-@end table
-
-The @code{break} and @code{continue} builtins (@pxref{Bourne Shell Builtins})
-may be used to control loop execution.
-
-@node Conditional Constructs
-@subsubsection Conditional Constructs
-@cindex commands, conditional
-
-@table @code
-@item if
-@rwindex if
-@rwindex then
-@rwindex else
-@rwindex elif
-@rwindex fi
-The syntax of the @code{if} command is:
-
-@example
-if @var{test-commands}; then
-  @var{consequent-commands};
-[elif @var{more-test-commands}; then
-  @var{more-consequents};]
-[else @var{alternate-consequents};]
-fi
-@end example
-
-The @var{test-commands} list is executed, and if its return status is zero,
-the @var{consequent-commands} list is executed.
-If @var{test-commands} returns a non-zero status, each @code{elif} list
-is executed in turn, and if its exit status is zero,
-the corresponding @var{more-consequents} is executed and the   
-command completes.
-If @samp{else @var{alternate-consequents}} is present, and
-the final command in the final @code{if} or @code{elif} clause
-has a non-zero exit status, then @var{alternate-consequents} is executed.
-The return status is the exit status of the last command executed, or
-zero if no condition tested true.
-
-@item case
-@rwindex case
-@rwindex in
-@rwindex esac
-The syntax of the @code{case} command is:
-
-@example
-@code{case @var{word} in [ [(] @var{pattern} [| @var{pattern}]@dots{}) @var{command-list} ;;]@dots{} esac}
-@end example
-
-@code{case} will selectively execute the @var{command-list} corresponding to
-the first @var{pattern} that matches @var{word}.
-If the shell option @code{nocasematch}
-(see the description of @code{shopt} in @ref{The Shopt Builtin})
-is enabled, the match is performed without regard to the case
-of alphabetic characters.
-The @samp{|} is used to separate multiple patterns, and the @samp{)}
-operator terminates a pattern list.
-A list of patterns and an associated command-list is known
-as a @var{clause}.
-
-Each clause must be terminated with @samp{;;}, @samp{;&}, or @samp{;;&}.
-The @var{word} undergoes tilde expansion, parameter expansion, command
-substitution, arithmetic expansion, and quote removal before matching is
-attempted.  Each @var{pattern} undergoes tilde expansion, parameter
-expansion, command substitution, and arithmetic expansion.
-
-There may be an arbitrary number of @code{case} clauses, each terminated
-by a @samp{;;}, @samp{;&}, or @samp{;;&}.
-The first pattern that matches determines the
-command-list that is executed.
-
-Here is an example using @code{case} in a script that could be used to
-describe one interesting feature of an animal:
-
-@example
-echo -n "Enter the name of an animal: "
-read ANIMAL
-echo -n "The $ANIMAL has "
-case $ANIMAL in
-  horse | dog | cat) echo -n "four";;
-  man | kangaroo ) echo -n "two";;
-  *) echo -n "an unknown number of";;
-esac
-echo " legs."
-@end example
-
-@noindent
-
-If the @samp{;;} operator is used, no subsequent matches are attempted after
-the first pattern match.
-Using @samp{;&}  in place of @samp{;;} causes execution to continue with
-the @var{command-list} associated with the next clause, if any.
-Using @samp{;;&} in place of @samp{;;} causes the shell to test the patterns
-in the next clause, if any, and execute any associated @var{command-list}
-on a successful match.
-
-The return status is zero if no @var{pattern} is matched.  Otherwise, the
-return status is the exit status of the @var{command-list} executed.
-
-@item select
-@rwindex select
-
-The @code{select} construct allows the easy generation of menus.
-It has almost the same syntax as the @code{for} command:
-
-@example
-select @var{name} [in @var{words} @dots{}]; do @var{commands}; done
-@end example
-
-The list of words following @code{in} is expanded, generating a list
-of items.  The set of expanded words is printed on the standard
-error output stream, each preceded by a number.  If the
-@samp{in @var{words}} is omitted, the positional parameters are printed,
-as if @samp{in "$@@"} had been specified.
-The @env{PS3} prompt is then displayed and a line is read from the
-standard input.
-If the line consists of a number corresponding to one of the displayed
-words, then the value of @var{name} is set to that word.
-If the line is empty, the words and prompt are displayed again.
-If @code{EOF} is read, the @code{select} command completes.
-Any other value read causes @var{name} to be set to null.
-The line read is saved in the variable @env{REPLY}.
-
-The @var{commands} are executed after each selection until a
-@code{break} command is executed, at which
-point the @code{select} command completes.
-
-Here is an example that allows the user to pick a filename from the
-current directory, and displays the name and index of the file
-selected.
-
-@example
-select fname in *;
-do
-       echo you picked $fname \($REPLY\)
-       break;
-done
-@end example
-
-@item ((@dots{}))
-@example
-(( @var{expression} ))
-@end example
-
-The arithmetic @var{expression} is evaluated according to the rules
-described below (@pxref{Shell Arithmetic}).
-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
-@example
-let "@var{expression}"
-@end example
-@noindent
-@xref{Bash Builtins}, for a full description of the @code{let} builtin.
-
-@item [[@dots{}]]
-@rwindex [[
-@rwindex ]]
-@example
-[[ @var{expression} ]]
-@end example
-
-Return a status of 0 or 1 depending on the evaluation of
-the conditional expression @var{expression}.
-Expressions are composed of the primaries described below in
-@ref{Bash Conditional Expressions}.
-Word splitting and filename expansion are not performed on the words
-between the @samp{[[} and @samp{]]}; tilde expansion, parameter and
-variable expansion, arithmetic expansion, command substitution, process
-substitution, and quote removal are performed.
-Conditional operators such as @samp{-f} must be unquoted to be recognized
-as primaries.
-
-When used with @samp{[[}, The @samp{<} and @samp{>} operators sort
-lexicographically using the current locale.
-
-When the @samp{==} and @samp{!=} operators are used, the string to the
-right of the operator is considered a pattern and matched according
-to the rules described below in @ref{Pattern Matching}.
-If the shell option @code{nocasematch}
-(see the description of @code{shopt} in @ref{The Shopt Builtin})
-is enabled, the match is performed without regard to the case
-of alphabetic characters.
-The return value is 0 if the string matches (@samp{==}) or does not
-match (@samp{!=})the pattern, and 1 otherwise.
-Any part of the pattern may be quoted to force it to be matched as a
-string.
-
-An additional binary operator, @samp{=~}, is available, with the same
-precedence as @samp{==} and @samp{!=}.
-When it is used, the string to the right of the operator is considered
-an extended regular expression and matched accordingly (as in @i{regex}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 @code{nocasematch}
-(see the description of @code{shopt} in @ref{The Shopt Builtin})
-is enabled, the match is performed without regard to the case
-of alphabetic characters.
-Any part of the pattern may be quoted to force it to be matched as a
-string.
-Substrings matched by parenthesized subexpressions within the regular
-expression are saved in the array variable @code{BASH_REMATCH}.
-The element of @code{BASH_REMATCH} with index 0 is the portion of the string
-matching the entire regular expression.
-The element of @code{BASH_REMATCH} with index @var{n} is the portion of the
-string matching the @var{n}th parenthesized subexpression.
-
-Expressions may be combined using the following operators, listed
-in decreasing order of precedence:
-
-@table @code
-@item ( @var{expression} )
-Returns the value of @var{expression}.
-This may be used to override the normal precedence of operators.
-
-@item ! @var{expression}
-True if @var{expression} is false.
-
-@item @var{expression1} && @var{expression2}
-True if both @var{expression1} and @var{expression2} are true.
-
-@item @var{expression1} || @var{expression2}
-True if either @var{expression1} or @var{expression2} is true.
-@end table
-@noindent
-The @code{&&} and @code{||} operators do not evaluate @var{expression2} if the
-value of @var{expression1} is sufficient to determine the return
-value of the entire conditional expression.
-
-@end table
-
-@node Command Grouping
-@subsubsection Grouping Commands
-@cindex commands, grouping
-
-Bash provides two ways to group a list of commands to be executed
-as a unit.  When commands are grouped, redirections may be applied
-to the entire command list.  For example, the output of all the
-commands in the list may be redirected to a single stream.
-
-@table @code
-@item ()
-@example
-( @var{list} )
-@end example
-
-Placing a list of commands between parentheses causes a subshell
-environment to be created (@pxref{Command Execution Environment}), and each
-of the commands in @var{list} to be executed in that subshell.  Since the
-@var{list} is executed in a subshell, variable assignments do not remain in
-effect after the subshell completes. 
-
-@item @{@}
-@rwindex @{
-@rwindex @}
-@example
-@{ @var{list}; @}
-@end example
-
-Placing a list of commands between curly braces causes the list to
-be executed in the current shell context.  No subshell is created.
-The semicolon (or newline) following @var{list} is required.
-@end table
-
-In addition to the creation of a subshell, there is a subtle difference
-between these two constructs due to historical reasons.  The braces
-are @code{reserved words}, so they must be separated from the @var{list}
-by @code{blank}s or other shell metacharacters.
-The parentheses are @code{operators}, and are
-recognized as separate tokens by the shell even if they are not separated
-from the @var{list} by whitespace.
-
-The exit status of both of these constructs is the exit status of
-@var{list}.
-
-@node Coprocesses
-@subsection Coprocesses
-@cindex coprocess
-
-A @code{coprocess} is a shell command preceded by the @code{coproc}
-reserved word.
-A coprocess is executed asynchronously in a subshell, as if the command
-had been terminated with the @samp{&} control operator, with a two-way pipe
-established between the executing shell and the coprocess.
-
-The format for a coprocess is:
-@example
-@code{coproc} [@var{NAME}] @var{command} [@var{redirections}]
-@end example
-
-@noindent
-This creates a coprocess named @var{NAME}.
-If @var{NAME} is not supplied, the default name is @var{COPROC}.
-@var{NAME} must not be supplied if @var{command} is a simple
-command (@pxref{Simple Commands}); otherwise, it is interpreted as
-the first word of the simple command.
-
-When the coproc is executed, the shell creates an array variable
-(@pxref{Arrays})
-named @var{NAME} in the context of the executing shell.
-The standard output of @var{command}
-is connected via a pipe to a file descriptor in the executing shell,
-and that file descriptor is assigned to @var{NAME}[0].
-The standard input of @var{command}
-is connected via a pipe to a file descriptor in the executing shell,
-and that file descriptor is assigned to @var{NAME}[1].
-This pipe is established before any redirections specified by the
-command (@pxref{Redirections}).
-The file descriptors can be utilized as arguments to shell commands
-and redirections using standard word expansions.
-
-The process id of the shell spawned to execute the coprocess is
-available as the value of the variable @var{NAME}_PID.
-The @code{wait}
-builtin command may be used to wait for the coprocess to terminate.
-
-The return status of a coprocess is the exit status of @var{command}.
-
-@node Shell Functions
-@section Shell Functions
-@cindex shell function
-@cindex functions, shell
-
-Shell functions are a way to group commands for later execution
-using a single name for the group.  They are executed just like
-a "regular" command.
-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.
-Shell functions are executed in the current
-shell context; no new process is created to interpret them.
-
-Functions are declared using this syntax:
-@rwindex function
-@example
-[ @code{function} ] @var{name} () @var{compound-command} [ @var{redirections} ]
-@end example
-
-This defines a shell function named @var{name}.  The reserved
-word @code{function} is optional.
-If the @code{function} reserved
-word is supplied, the parentheses are optional.
-The @var{body} of the function is the compound command
-@var{compound-command} (@pxref{Compound Commands}).
-That command is usually a @var{list} enclosed between @{ and @}, but
-may be any compound command listed above.
-@var{compound-command} is executed whenever @var{name} is specified as the
-name of a command.
-Any redirections (@pxref{Redirections}) associated with the shell function
-are performed when the function is executed.
-
-A function definition may be deleted using the @option{-f} option to the
-@code{unset} builtin (@pxref{Bourne Shell Builtins}).
-
-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.
-
-Note that for historical reasons, in the most common usage the curly braces
-that surround the body of the function must be separated from the body by
-@code{blank}s or newlines.
-This is because the braces are reserved words and are only recognized
-as such when they are separated from the command list
-by whitespace or another shell metacharacter.
-Also, when using the braces, the @var{list} must be terminated by a semicolon,
-a @samp{&}, or a newline.
-
-When a function is executed, the arguments to the
-function become the positional parameters
-during its execution (@pxref{Positional Parameters}).
-The special parameter @samp{#} that expands to the number of
-positional parameters is updated to reflect the change.
-Special parameter @code{0} is unchanged.
-The first element of the @env{FUNCNAME} variable is set to the
-name of the function while the function is executing.
-
-All other aspects of the shell execution
-environment are identical between a function and its caller
-with these exceptions:
-the @env{DEBUG} and @env{RETURN} traps
-are not inherited unless the function has been given the
-@code{trace} attribute using the @code{declare} builtin or
-the @code{-o functrace} option has been enabled with
-the @code{set} builtin,
-(in which case all functions inherit the @env{DEBUG} and @env{RETURN} traps),
-and the @env{ERR} trap is not inherited unless the @code{-o errtrace}
-shell option has been enabled.
-@xref{Bourne Shell Builtins}, for the description of the
-@code{trap} builtin.
-
-If the builtin command @code{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 @code{RETURN} trap is executed
-before execution resumes.
-When a function completes, the values of the
-positional parameters and the special parameter @samp{#}
-are restored to the values they had prior to the function's
-execution.  If a numeric argument is given to @code{return},
-that is the function's return status; otherwise the function's
-return status is the exit status of the last command executed
-before the @code{return}.
-
-Variables local to the function may be declared with the
-@code{local} builtin.  These variables are visible only to
-the function and the commands it invokes.
-
-Function names and definitions may be listed with the
-@option{-f} option to the @code{declare} or @code{typeset}
-builtin commands (@pxref{Bash Builtins}).
-The @option{-F} option to @code{declare} or @code{typeset}
-will list the function names only
-(and optionally the source file and line number, if the @code{extdebug}
-shell option is enabled).
-Functions may be exported so that subshells
-automatically have them defined with the
-@option{-f} option to the @code{export} builtin
-(@pxref{Bourne Shell Builtins}).
-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.
-
-Functions may be recursive.  No limit is placed on the number of
-recursive  calls.
-
-@node Shell Parameters
-@section Shell Parameters
-@cindex parameters
-@cindex variable, shell
-@cindex shell variable
-
-@menu
-* Positional Parameters::      The shell's command-line arguments.
-* Special Parameters::         Parameters denoted by special characters.
-@end menu
-
-A @var{parameter} is an entity that stores values.
-It can be a @code{name}, a number, or one of the special characters
-listed below.
-A @var{variable} is a parameter denoted by a @code{name}.
-A variable has a @var{value} and zero or more @var{attributes}.
-Attributes are assigned using the @code{declare} builtin command
-(see the description of the @code{declare} builtin in @ref{Bash Builtins}).
-
-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 @code{unset} builtin command.
-
-A variable may be assigned to by a statement of the form
-@example
-@var{name}=[@var{value}]
-@end example
-@noindent
-If @var{value}
-is not given, the variable is assigned the null string.  All
-@var{value}s undergo tilde expansion, parameter and variable expansion,
-command substitution, arithmetic expansion, and quote
-removal (detailed below).  If the variable has its @code{integer}
-attribute set, then @var{value} 
-is evaluated as an arithmetic expression even if the @code{$((@dots{}))}
-expansion is not used (@pxref{Arithmetic Expansion}).
-Word splitting is not performed, with the exception
-of @code{"$@@"} as explained below.
-Filename expansion is not performed.
-Assignment statements may also appear as arguments to the
-@code{alias}, 
-@code{declare}, @code{typeset}, @code{export}, @code{readonly},
-and @code{local} builtin commands.
-
-In the context where an assignment statement is assigning a value  
-to a shell variable or array index (@pxref{Arrays}), the @samp{+=}
-operator can be used to   
-append to or add to the variable's previous value.
-When @samp{+=} is applied to a variable for which the integer attribute
-has been set, @var{value} is evaluated as an arithmetic expression and
-added to the variable's current value, which is also evaluated.
-When @samp{+=} is applied to an array variable using compound assignment
-(@pxref{Arrays}), the
-variable's value is not unset (as it is when using @samp{=}), 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, @var{value} is expanded and
-appended to the variable's value.
-
-@node Positional Parameters
-@subsection Positional Parameters
-@cindex parameters, positional
-
-A @var{positional parameter} is a parameter denoted by one or more
-digits, other than the single digit @code{0}.  Positional parameters are
-assigned from the shell's arguments when it is invoked,
-and may be reassigned using the @code{set} builtin command.
-Positional parameter @code{N} may be referenced as @code{$@{N@}}, or
-as @code{$N} when @code{N} consists of a single digit.
-Positional parameters may not be assigned to with assignment statements.
-The @code{set} and @code{shift} builtins are used to set and
-unset them (@pxref{Shell Builtin Commands}).
-The positional parameters are
-temporarily replaced when a shell function is executed
-(@pxref{Shell Functions}).
-
-When a positional parameter consisting of more than a single
-digit is expanded, it must be enclosed in braces.
-
-@node Special Parameters
-@subsection Special Parameters
-@cindex parameters, special
-
-The shell treats several parameters specially.  These parameters may
-only be referenced; assignment to them is not allowed.
-
-@vtable @code
-
-@item *
-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 @env{IFS}
-special variable.  That is, @code{"$*"} is equivalent
-to @code{"$1@var{c}$2@var{c}@dots{}"}, where @var{c}
-is the first character of the value of the @code{IFS}
-variable.
-If @env{IFS} is unset, the parameters are separated by spaces.
-If @env{IFS} is null, the parameters are joined without intervening
-separators.
-
-
-@item @@
-Expands to the positional parameters, starting from one.  When the
-expansion occurs within double quotes, each parameter expands to a
-separate word.  That is, @code{"$@@"} is equivalent to
-@code{"$1" "$2" @dots{}}.
-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, @code{"$@@"} and
-@code{$@@}
-expand to nothing (i.e., they are removed).
-
-@item #
-Expands to the number of positional parameters in decimal.
-
-@item ?
-Expands to the exit status of the most recently executed foreground
-pipeline.
-
-@item -
-(A hyphen.)  Expands to the current option flags as specified upon
-invocation, by the @code{set}
-builtin command, or those set by the shell itself
-(such as the @option{-i} option).
-
-@item $
-Expands to the process @sc{id} of the shell.  In a @code{()} subshell, it
-expands to the process @sc{id} of the invoking shell, not the subshell.
-
-@item !
-Expands to the process @sc{id} of the most recently executed background
-(asynchronous) command.
-
-@item 0
-Expands to the name of the shell or shell script.  This is set at
-shell initialization.  If Bash is invoked with a file of commands
-(@pxref{Shell Scripts}), @code{$0} is set to the name of that file.
-If Bash is started with the @option{-c} option (@pxref{Invoking Bash}),
-then @code{$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 Bash, as given by argument zero.
-
-@item _
-(An underscore.)
-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.
-@end vtable
-
-@node Shell Expansions
-@section Shell Expansions
-@cindex expansion
-
-Expansion is performed on the command line after it has been split into
-@code{token}s.  There are seven kinds of expansion performed:
-@itemize @bullet
-@item brace expansion
-@item tilde expansion
-@item parameter and variable expansion
-@item command substitution
-@item arithmetic expansion
-@item word splitting
-@item filename expansion
-@end itemize
-
-@menu
-* Brace Expansion::            Expansion of expressions within braces.
-* Tilde Expansion::            Expansion of the ~ character.
-* Shell Parameter Expansion::  How Bash expands variables to their values.
-* Command Substitution::       Using the output of a command as an argument.
-* Arithmetic Expansion::       How to use arithmetic in shell expansions.
-* Process Substitution::       A way to write and read to and from a
-                               command.
-* Word Splitting::     How the results of expansion are split into separate
-                       arguments.
-* Filename Expansion:: A shorthand for specifying filenames matching patterns.
-* Quote Removal::      How and when quote characters are removed from
-                       words.
-@end menu
-
-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 filename
-expansion.
-
-On systems that can support it, there is an additional expansion
-available: @var{process substitution}.  This is performed at the
-same time as parameter, variable, and arithmetic expansion and
-command substitution.
-
-Only brace expansion, word splitting, and filename 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
-@code{"$@@"} (@pxref{Special Parameters}) and @code{"$@{@var{name}[@@]@}"}
-(@pxref{Arrays}).
-
-After all expansions, @code{quote removal} (@pxref{Quote Removal})
-is performed.
-
-@node Brace Expansion
-@subsection Brace Expansion
-@cindex brace expansion
-@cindex expansion, brace
-
-Brace expansion is a mechanism by which arbitrary strings may be generated.
-This mechanism is similar to
-@var{filename expansion} (@pxref{Filename Expansion}),
-but the file names generated need not exist.
-Patterns to be brace expanded take the form of an optional @var{preamble},
-followed by either a series of comma-separated strings or a seqeunce expression
-between a pair of braces,
-followed by an optional @var{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.
-
-Brace expansions may be nested.
-The results of each expanded string are not sorted; left to right order
-is preserved.
-For example,
-@example
-bash$ echo a@{d,c,b@}e
-ade ace abe
-@end example
-
-A sequence expression takes the form @code{@{@var{x}..@var{y}[..@var{incr}]@}},
-where @var{x} and @var{y} are either integers or single characters,
-and @var{incr}, an optional increment, is an integer.
-When integers are supplied, the expression expands to each number between
-@var{x} and @var{y}, inclusive.
-Supplied integers may be prefixed with @samp{0} to force each term to have the
-same width.  When either @var{x} or @var{y} 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 @var{x} and @var{y}, inclusive.  Note that
-both @var{x} and @var{y} must be of the same type.
-When the increment is supplied, it is used as the difference between
-each term.  The default increment is 1 or -1 as appropriate.
-
-Brace expansion is performed before any other expansions,
-and any characters special to other expansions are preserved
-in the result.  It is strictly textual.  Bash
-does not apply any syntactic interpretation to the context of the
-expansion or the text between the braces.
-To avoid conflicts with parameter expansion, the string @samp{$@{}
-is not considered eligible for brace expansion.
-
-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 @{ or @samp{,} may be quoted with a backslash to prevent its
-being considered part of a brace expression.
-To avoid conflicts with parameter expansion, the string @samp{$@{}
-is not considered eligible for brace expansion.
-
-This construct is typically used as shorthand when the common
-prefix of the strings to be generated is longer than in the
-above example:
-@example
-mkdir /usr/local/src/bash/@{old,new,dist,bugs@}
-@end example
-or
-@example
-chown root /usr/@{ucb/@{ex,edit@},lib/@{ex?.?*,how_ex@}@}
-@end example
-
-@node Tilde Expansion
-@subsection Tilde Expansion
-@cindex tilde expansion
-@cindex expansion, tilde
-
-If a word begins with an unquoted tilde character (@samp{~}), all of the
-characters up to the first unquoted slash (or all characters,
-if there is no unquoted slash) are considered a @var{tilde-prefix}.
-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 @var{login name}.
-If this login name is the null string, the tilde is replaced with the
-value of the @env{HOME} shell variable.
-If @env{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.
-
-If the tilde-prefix is @samp{~+}, the value of
-the shell variable @env{PWD} replaces the tilde-prefix.
-If the tilde-prefix is @samp{~-}, the value of the shell variable
-@env{OLDPWD}, if it is set, is substituted.
-
-If the characters following the tilde in the tilde-prefix consist of a
-number @var{N}, optionally prefixed by a @samp{+} or a @samp{-},
-the tilde-prefix is replaced with the
-corresponding element from the directory stack, as it would be displayed
-by the @code{dirs} builtin invoked with the characters following tilde
-in the tilde-prefix as an argument (@pxref{The Directory Stack}).
-If the tilde-prefix, sans the tilde, consists of a number without a
-leading @samp{+} or @samp{-}, @samp{+} is assumed.
-
-If the login name is invalid, or the tilde expansion fails, the word is
-left unchanged.
-
-Each variable assignment is checked for unquoted tilde-prefixes immediately
-following a @samp{:} or the first @samp{=}.
-In these cases, tilde expansion is also performed.
-Consequently, one may use file names with tildes in assignments to
-@env{PATH}, @env{MAILPATH}, and @env{CDPATH},
-and the shell assigns the expanded value.
-
-The following table shows how Bash treats unquoted tilde-prefixes:
-
-@table @code
-@item ~
-The value of @code{$HOME}
-@item ~/foo
-@file{$HOME/foo}
-
-@item ~fred/foo
-The subdirectory @code{foo} of the home directory of the user
-@code{fred}
-
-@item ~+/foo
-@file{$PWD/foo}
-
-@item ~-/foo
-@file{$@{OLDPWD-'~-'@}/foo}
-
-@item ~@var{N}
-The string that would be displayed by @samp{dirs +@var{N}}
-
-@item ~+@var{N}
-The string that would be displayed by @samp{dirs +@var{N}}
-
-@item ~-@var{N}
-The string that would be displayed by @samp{dirs -@var{N}}
-
-@end table
-
-@node Shell Parameter Expansion
-@subsection Shell Parameter Expansion
-@cindex parameter expansion
-@cindex expansion, parameter
-
-The @samp{$} 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.
-
-When braces are used, the matching ending brace is the first @samp{@}}
-not escaped by a backslash or within a quoted string, and not within an
-embedded arithmetic expansion, command substitution, or parameter
-expansion.
-
-The basic form of parameter expansion is $@{@var{parameter}@}.
-The value of @var{parameter} is substituted.  The braces are required
-when @var{parameter}
-is a positional parameter with more than one digit,
-or when @var{parameter}
-is followed by a character that is not to be
-interpreted as part of its name.
-
-If the first character of @var{parameter} is an exclamation point (!),
-a level of variable indirection is introduced.
-Bash uses the value of the variable formed from the rest of
-@var{parameter} 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 @var{parameter} itself.
-This is known as @code{indirect expansion}.
-The exceptions to this are the expansions of $@{!@var{prefix*}@}
-and $@{!@var{name}[@@]@}
-described below.
-The exclamation point must immediately follow the left brace in order to
-introduce indirection.
-
-In each of the cases below, @var{word} is subject to tilde expansion,
-parameter expansion, command substitution, and arithmetic expansion.
-
-When not performing substring expansion, using the form described
-below, Bash tests for a parameter that is unset or null.
-Omitting the colon results in a test only for a parameter that is unset.
-Put another way, if the colon is included,
-the operator tests for both @var{parameter}'s existence and that its value
-is not null; if the colon is omitted, the operator tests only for existence.
-
-@table @code
-
-@item $@{@var{parameter}:@minus{}@var{word}@}
-If @var{parameter} is unset or null, the expansion of
-@var{word} is substituted.  Otherwise, the value of
-@var{parameter} is substituted.
-
-@item $@{@var{parameter}:=@var{word}@}
-If @var{parameter}
-is unset or null, the expansion of @var{word}
-is assigned to @var{parameter}.
-The value of @var{parameter} is then substituted. 
-Positional parameters and special parameters may not be assigned to
-in this way.
-
-@item $@{@var{parameter}:?@var{word}@}
-If @var{parameter}
-is null or unset, the expansion of @var{word} (or a message
-to that effect if @var{word}
-is not present) is written to the standard error and the shell, if it
-is not interactive, exits.  Otherwise, the value of @var{parameter} is
-substituted.
-
-@item $@{@var{parameter}:+@var{word}@}
-If @var{parameter}
-is null or unset, nothing is substituted, otherwise the expansion of
-@var{word} is substituted.
-
-@item $@{@var{parameter}:@var{offset}@}
-@itemx $@{@var{parameter}:@var{offset}:@var{length}@}
-Expands to up to @var{length} characters of @var{parameter}
-starting at the character specified by @var{offset}.
-If @var{length} is omitted, expands to the substring of
-@var{parameter} starting at the character specified by @var{offset}.
-@var{length} and @var{offset} are arithmetic expressions
-(@pxref{Shell Arithmetic}).
-This is referred to as Substring Expansion.
-
-@var{length} must evaluate to a number greater than or equal to zero.
-If @var{offset} evaluates to a number less than zero, the value
-is used as an offset from the end of the value of @var{parameter}.
-If @var{parameter} is @samp{@@}, the result is @var{length} positional
-parameters beginning at @var{offset}.
-If @var{parameter} is an indexed array name subscripted
-by @samp{@@} or @samp{*}, the result is the @var{length}
-members of the array beginning with @code{$@{@var{parameter}[@var{offset}]@}}.
-A negative @var{offset} is taken relative to one greater than the maximum
-index of the specified array.
-Substring expansion applied to an associative array produces undefined
-results.
-
-Note that a negative offset must be separated from the colon by at least
-one space to avoid being confused with the @samp{:-} expansion.
-Substring indexing is zero-based unless the positional parameters
-are used, in which case the indexing starts at 1 by default.
-If @var{offset} is 0, and the positional parameters are used, @code{$@@} is
-prefixed to the list.
-
-@item $@{!@var{prefix}*@}
-@itemx $@{!@var{prefix}@@@}
-Expands to the names of variables whose names begin with @var{prefix},
-separated by the first character of the @env{IFS} special variable.
-When @samp{@@} is used and the expansion appears within double quotes, each
-variable name expands to a separate word.
-
-@item $@{!@var{name}[@@]@}
-@itemx $@{!@var{name}[*]@}
-If @var{name} is an array variable, expands to the list of array indices
-(keys) assigned in @var{name}.
-If @var{name} is not an array, expands to 0 if @var{name} is set and null
-otherwise.
-When @samp{@@} is used and the expansion appears within double quotes, each
-key expands to a separate word.
-
-@item $@{#@var{parameter}@}
-The length in characters of the expanded value of @var{parameter} is
-substituted.
-If @var{parameter} is @samp{*} or @samp{@@}, the value substituted
-is the number of positional parameters.
-If @var{parameter} is an array name subscripted by @samp{*} or @samp{@@}, 
-the value substituted is the number of elements in the array.
-
-@item $@{@var{parameter}#@var{word}@}
-@itemx $@{@var{parameter}##@var{word}@}
-The @var{word}
-is expanded to produce a pattern just as in filename
-expansion (@pxref{Filename Expansion}).  If the pattern matches
-the beginning of the expanded value of @var{parameter},
-then the result of the expansion is the expanded value of @var{parameter}
-with the shortest matching pattern (the @samp{#} case) or the
-longest matching pattern (the @samp{##} case) deleted.
-If @var{parameter} is @samp{@@} or @samp{*},
-the pattern removal operation is applied to each positional
-parameter in turn, and the expansion is the resultant list.
-If @var{parameter} is an array variable subscripted with
-@samp{@@} or @samp{*},
-the pattern removal operation is applied to each member of the
-array in turn, and the expansion is the resultant list.
-
-@item $@{@var{parameter}%@var{word}@}
-@itemx $@{@var{parameter}%%@var{word}@}
-The @var{word} is expanded to produce a pattern just as in
-filename expansion.
-If the pattern matches a trailing portion of the expanded value of
-@var{parameter}, then the result of the expansion is the value of
-@var{parameter} with the shortest matching pattern (the @samp{%} case)
-or the longest matching pattern (the @samp{%%} case) deleted.
-If @var{parameter} is @samp{@@} or @samp{*},
-the pattern removal operation is applied to each positional
-parameter in turn, and the expansion is the resultant list.
-If @var{parameter}
-is an array variable subscripted with @samp{@@} or @samp{*},
-the pattern removal operation is applied to each member of the
-array in turn, and the expansion is the resultant list.
-
-@item $@{@var{parameter}/@var{pattern}/@var{string}@} 
-
-The @var{pattern} is expanded to produce a pattern just as in
-filename expansion.
-@var{Parameter} is expanded and the longest match of @var{pattern}
-against its value is replaced with @var{string}.
-If @var{pattern} begins with @samp{/}, all matches of @var{pattern} are
-replaced with @var{string}.  Normally only the first match is replaced.
-If @var{pattern} begins with @samp{#}, it must match at the beginning
-of the expanded value of @var{parameter}.
-If @var{pattern} begins with @samp{%}, it must match at the end
-of the expanded value of @var{parameter}.
-If @var{string} is null, matches of @var{pattern} are deleted
-and the @code{/} following @var{pattern} may be omitted.
-If @var{parameter} is @samp{@@} or @samp{*},
-the substitution operation is applied to each positional
-parameter in turn, and the expansion is the resultant list.
-If @var{parameter}
-is an array variable subscripted with @samp{@@} or @samp{*},
-the substitution operation is applied to each member of the
-array in turn, and the expansion is the resultant list.
-
-@item $@{@var{parameter}^@var{pattern}@}
-@itemx $@{@var{parameter}^^@var{pattern}@}
-@itemx $@{@var{parameter},@var{pattern}@}
-@itemx $@{@var{parameter},,@var{pattern}@}
-This expansion modifies the case of alphabetic characters in @var{parameter}.
-The @var{pattern} is expanded to produce a pattern just as in
-filename expansion.
-The @samp{^} operator converts lowercase letters matching @var{pattern}
-to uppercase; the @samp{,} operator converts matching uppercase letters
-to lowercase.
-The @samp{^^} and @samp{,,} expansions convert each matched character in the
-expanded value; the @samp{^} and @samp{,} expansions match and convert only
-the first character in the expanded value.
-If @var{pattern} is omitted, it is treated like a @samp{?}, which matches
-every character.
-If @var{parameter} is @samp{@@} or @samp{*},
-the case modification operation is applied to each positional
-parameter in turn, and the expansion is the resultant list.
-If @var{parameter}
-is an array variable subscripted with @samp{@@} or @samp{*},
-the case modification operation is applied to each member of the
-array in turn, and the expansion is the resultant list.
-
-@end table
-
-@node Command Substitution
-@subsection Command Substitution
-@cindex command substitution
-
-Command substitution allows the output of a command to replace
-the command itself.
-Command substitution occurs when a command is enclosed as follows:
-@example
-$(@var{command})
-@end example
-@noindent
-or
-@example
-`@var{command}`
-@end example
-
-@noindent
-Bash performs the expansion by executing @var{command} 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 @code{$(cat @var{file})} can be
-replaced by the equivalent but faster @code{$(< @var{file})}.
-
-When the old-style backquote form of substitution is used,
-backslash retains its literal meaning except when followed by
-@samp{$}, @samp{`}, or @samp{\}. 
-The first backquote not preceded by a backslash terminates the
-command substitution.
-When using the @code{$(@var{command})} form, all characters between
-the parentheses make up the command; none are treated specially.
-
-Command substitutions may be nested.  To nest when using the backquoted
-form, escape the inner backquotes with backslashes.
-
-If the substitution appears within double quotes, word splitting and
-filename expansion are not performed on the results.
-
-@node Arithmetic Expansion
-@subsection Arithmetic Expansion
-@cindex expansion, arithmetic
-@cindex arithmetic expansion
-
-Arithmetic expansion allows the evaluation of an arithmetic expression
-and the substitution of the result.  The format for arithmetic expansion is:
-
-@example
-$(( @var{expression} ))
-@end example
-
-The 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 expansion, command
-substitution, and quote removal.
-Arithmetic expansions may be nested. 
-
-The evaluation is performed according to the rules listed below
-(@pxref{Shell Arithmetic}).
-If the expression is invalid, Bash prints a message indicating
-failure to the standard error and no substitution occurs.
-
-@node Process Substitution
-@subsection Process Substitution
-@cindex process substitution
-
-Process substitution is supported on systems that support named
-pipes (@sc{fifo}s) or the @file{/dev/fd} method of naming open files.
-It takes the form of 
-@example
-<(@var{list})
-@end example
-@noindent
-or
-@example
->(@var{list})
-@end example
-@noindent
-The process @var{list} is run with its input or output connected to a
-@sc{fifo} or some file in @file{/dev/fd}.  The name of this file is
-passed as an argument to the current command as the result of the
-expansion.  If the @code{>(@var{list})} form is used, writing to
-the file will provide input for @var{list}.  If the
-@code{<(@var{list})} form is used, the file passed as an
-argument should be read to obtain the output of @var{list}.
-Note that no space may appear between the @code{<} or @code{>}
-and the left parenthesis, otherwise the construct would be interpreted
-as a redirection.
-
-When available, process substitution is performed simultaneously with
-parameter and variable expansion, command substitution, and arithmetic
-expansion.
-
-@node Word Splitting
-@subsection Word Splitting
-@cindex word splitting
-
-The shell scans the results of parameter expansion, command substitution,
-and arithmetic expansion that did not occur within double quotes for
-word splitting.
-
-The shell treats each character of @env{$IFS} as a delimiter, and splits
-the results of the other expansions into words on these characters.
-If @env{IFS} is unset, or its value is exactly @code{<space><tab><newline>},
-the default, then sequences of
-@code{ <space>}, @code{<tab>}, and @code{<newline>}
-at the beginning and end of the results of the previous
-expansions are ignored, and any sequence of @env{IFS}
-characters not at the beginning or end serves to delimit words.
-If @env{IFS} has a value other than the default, then sequences of
-the whitespace characters @code{space} and @code{tab}
-are ignored at the beginning and end of the
-word, as long as the whitespace character is in the
-value of @env{IFS} (an @env{IFS} whitespace character).
-Any character in @env{IFS} that is not @env{IFS}
-whitespace, along with any adjacent @env{IFS}
-whitespace characters, delimits a field.  A sequence of @env{IFS}
-whitespace characters is also treated as a delimiter.
-If the value of @env{IFS} is null, no word splitting occurs.
-
-Explicit null arguments (@code{""} or @code{''}) 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.
-
-Note that if no expansion occurs, no splitting
-is performed.
-
-@node Filename Expansion
-@subsection Filename Expansion
-@menu
-* Pattern Matching::   How the shell matches patterns.
-@end menu
-@cindex expansion, filename
-@cindex expansion, pathname
-@cindex filename expansion
-@cindex pathname expansion
-
-After word splitting, unless the @option{-f} option has been set
-(@pxref{The Set Builtin}), Bash scans each word for the characters
-@samp{*}, @samp{?}, and @samp{[}.
-If one of these characters appears, then the word is
-regarded as a @var{pattern},
-and replaced with an alphabetically sorted list of
-file names matching the pattern. If no matching file names are found,
-and the shell option @code{nullglob} is disabled, the word is left
-unchanged.
-If the @code{nullglob} option is set, and no matches are found, the word
-is removed.
-If the @code{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 @code{nocaseglob} is enabled, the match is performed
-without regard to the case of alphabetic characters.
-
-When a pattern is used for filename expansion, the character @samp{.}
-at the start of a filename or immediately following a slash
-must be matched explicitly, unless the shell option @code{dotglob} is set.
-When matching a file name, the slash character must always be
-matched explicitly.
-In other cases, the @samp{.} character is not treated specially.
-
-See the description of @code{shopt} in @ref{The Shopt Builtin},
-for a description of the @code{nocaseglob}, @code{nullglob},
-@code{failglob}, and @code{dotglob} options.
-
-The @env{GLOBIGNORE}
-shell variable may be used to restrict the set of filenames matching a
-pattern.  If @env{GLOBIGNORE}
-is set, each matching filename that also matches one of the patterns in
-@env{GLOBIGNORE} is removed from the list of matches.  The filenames
-@file{.} and @file{..}
-are always ignored when @env{GLOBIGNORE}
-is set and not null.
-However, setting @env{GLOBIGNORE} to a non-null value has the effect of
-enabling the @code{dotglob}
-shell option, so all other filenames beginning with a
-@samp{.} will match.
-To get the old behavior of ignoring filenames beginning with a
-@samp{.}, make @samp{.*} one of the patterns in @env{GLOBIGNORE}.
-The @code{dotglob} option is disabled when @env{GLOBIGNORE}
-is unset.
-
-@node Pattern Matching
-@subsubsection Pattern Matching
-@cindex pattern matching
-@cindex matching, pattern
-
-Any character that appears in a pattern, other than the special pattern
-characters described below, matches itself.
-The @sc{nul} character may not occur in a pattern.
-A backslash escapes the following character; the
-escaping backslash is discarded when matching.
-The special pattern characters must be quoted if they are to be matched
-literally.
-
-The special pattern characters have the following meanings:
-@table @code
-@item *
-Matches any string, including the null string.
-When the @code{globstar} shell option is enabled, and @samp{*} is used in
-a filename expansion context, two adjacent @samp{*}s used as a single
-pattern will match all files and zero or more directories and
-subdirectories.
-If followed by a @samp{/}, two adjacent @samp{*}s will match only
-directories and subdirectories.
-@item ?
-Matches any single character.
-@item [@dots{}]
-Matches any one of the enclosed characters.  A pair of characters
-separated by a hyphen denotes a @var{range expression};
-any character that sorts between those two characters, inclusive,
-using the current locale's collating sequence and character set,
-is matched.  If the first character following the
-@samp{[} is a @samp{!}  or a @samp{^}
-then any character not enclosed is matched.  A @samp{@minus{}}
-may be matched by including it as the first or last character
-in the set.  A @samp{]} may be matched by including it as the first
-character in the set.
-The sorting order of characters in range expressions is determined by
-the current locale and the value of the @env{LC_COLLATE} shell variable,
-if set.
-
-For example, in the default C locale, @samp{[a-dx-z]} is equivalent to
-@samp{[abcdxyz]}.  Many locales sort characters in dictionary order, and in
-these locales @samp{[a-dx-z]} is typically not equivalent to @samp{[abcdxyz]};
-it might be equivalent to @samp{[aBbCcDdxXyYz]}, for example.  To obtain
-the traditional interpretation of ranges in bracket expressions, you can
-force the use of the C locale by setting the @env{LC_COLLATE} or
-@env{LC_ALL} environment variable to the value @samp{C}.
-
-Within @samp{[} and @samp{]}, @var{character classes} can be specified
-using the syntax
-@code{[:}@var{class}@code{:]}, where @var{class} is one of the
-following classes defined in the @sc{posix} standard:
-@example
-alnum   alpha   ascii   blank   cntrl   digit   graph   lower
-print   punct   space   upper   word    xdigit
-@end example
-@noindent
-A character class matches any character belonging to that class.
-The @code{word} character class matches letters, digits, and the character
-@samp{_}.
-
-Within @samp{[} and @samp{]}, an @var{equivalence class} can be
-specified using the syntax @code{[=}@var{c}@code{=]}, which
-matches all characters with the same collation weight (as defined
-by the current locale) as the character @var{c}.
-
-Within @samp{[} and @samp{]}, the syntax @code{[.}@var{symbol}@code{.]}
-matches the collating symbol @var{symbol}.
-@end table
-
-If the @code{extglob} shell option is enabled using the @code{shopt}
-builtin, several extended pattern matching operators are recognized.
-In the following description, a @var{pattern-list} is a list of one
-or more patterns separated by a @samp{|}.
-Composite patterns may be formed using one or more of the following
-sub-patterns:
-
-@table @code
-@item ?(@var{pattern-list})
-Matches zero or one occurrence of the given patterns.
-
-@item *(@var{pattern-list})
-Matches zero or more occurrences of the given patterns.
-
-@item +(@var{pattern-list})
-Matches one or more occurrences of the given patterns.
-
-@item @@(@var{pattern-list})
-Matches one of the given patterns.
-
-@item !(@var{pattern-list})
-Matches anything except one of the given patterns.
-@end table
-
-@node Quote Removal
-@subsection Quote Removal
-
-After the preceding expansions, all unquoted occurrences of the
-characters @samp{\}, @samp{'}, and @samp{"} that did not
-result from one of the above expansions are removed.
-
-@node Redirections
-@section Redirections
-@cindex redirection
-
-Before a command is executed, its input and output
-may be @var{redirected}
-using a special notation interpreted by the shell.
-Redirection may also be used to open and close files for the
-current shell execution environment.  The following redirection
-operators may precede or appear anywhere within a
-simple command or may follow a command.
-Redirections are processed in the order they appear, from
-left to right.
-
-Each redirection that may be preceded by a file descriptor number
-may instead be preceded by a word of the form @{@var{varname}@}.
-In this case, for each redirection operator except
->&- and <&-, the shell will allocate a file descriptor greater
-than 10 and assign it to @{@var{varname}@}.  If >&- or <&- is preceded
-by @{@var{varname}@}, the value of @var{varname} defines the file
-descriptor to close.
-
-In the following descriptions, if the file descriptor number is
-omitted, and the first character of the redirection operator is
-@samp{<}, the redirection refers to the standard input (file
-descriptor 0).  If the first character of the redirection operator
-is @samp{>}, the redirection refers to the standard output (file
-descriptor 1).
-
-The word following the redirection operator in the following
-descriptions, unless otherwise noted, is subjected to brace expansion,
-tilde expansion, parameter expansion, command substitution, arithmetic
-expansion, quote removal, filename expansion, and word splitting.
-If it expands to more than one word, Bash reports an error.
-
-Note that the order of redirections is significant.  For example,
-the command
-@example
-ls > @var{dirlist} 2>&1
-@end example
-@noindent
-directs both standard output (file descriptor 1) and standard error
-(file descriptor 2) to the file @var{dirlist}, while the command
-@example
-ls 2>&1 > @var{dirlist}
-@end example
-@noindent
-directs only the standard output to file @var{dirlist},
-because the standard error was made a copy of the standard output
-before the standard output was redirected to @var{dirlist}.
-
-Bash handles several filenames specially when they are used in
-redirections, as described in the following table:
-
-@table @code
-@item /dev/fd/@var{fd}
-If @var{fd} is a valid integer, file descriptor @var{fd} is duplicated.
-
-@item /dev/stdin
-File descriptor 0 is duplicated.
-
-@item /dev/stdout
-File descriptor 1 is duplicated.
-
-@item /dev/stderr
-File descriptor 2 is duplicated.
-
-@item /dev/tcp/@var{host}/@var{port}
-If @var{host} is a valid hostname or Internet address, and @var{port}
-is an integer port number or service name, Bash attempts to open a TCP
-connection to the corresponding socket.
-
-@item /dev/udp/@var{host}/@var{port}
-If @var{host} is a valid hostname or Internet address, and @var{port}
-is an integer port number or service name, Bash attempts to open a UDP
-connection to the corresponding socket.
-
-@end table
-
-A failure to open or create a file causes the redirection to fail.
-
-Redirections using file descriptors greater than 9 should be used with
-care, as they may conflict with file descriptors the shell uses
-internally.
-
-@subsection Redirecting Input
-Redirection of input causes the file whose name results from
-the expansion of @var{word}
-to be opened for reading on file descriptor @code{n},
-or the standard input (file descriptor 0) if @code{n}
-is not specified.
-
-The general format for redirecting input is:
-@example
-[@var{n}]<@var{word}
-@end example
-
-@subsection Redirecting Output
-Redirection of output causes the file whose name results from
-the expansion of @var{word}
-to be opened for writing on file descriptor @var{n},
-or the standard output (file descriptor 1) if @var{n}
-is not specified.  If the file does not exist it is created;
-if it does exist it is truncated to zero size.
-
-The general format for redirecting output is:
-@example
-[@var{n}]>[|]@var{word}
-@end example
-
-If the redirection operator is @samp{>}, and the @code{noclobber}
-option to the @code{set} builtin has been enabled, the redirection
-will fail if the file whose name results from the expansion of
-@var{word} exists and is a regular file.
-If the redirection operator is @samp{>|}, or the redirection operator is
-@samp{>} and the @code{noclobber} option is not enabled, the redirection
-is attempted even if the file named by @var{word} exists.
-
-@subsection Appending Redirected Output
-Redirection of output in this fashion
-causes the file whose name results from
-the expansion of @var{word}
-to be opened for appending on file descriptor @var{n},
-or the standard output (file descriptor 1) if @var{n}
-is not specified.  If the file does not exist it is created.
-
-The general format for appending output is:
-@example
-[@var{n}]>>@var{word}
-@end example
-
-@subsection Redirecting Standard Output and Standard Error
-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 @var{word}.
-
-There are two formats for redirecting standard output and
-standard error:
-@example
-&>@var{word}
-@end example
-@noindent
-and
-@example
->&@var{word}
-@end example
-@noindent
-Of the two forms, the first is preferred.
-This is semantically equivalent to
-@example
->@var{word} 2>&1
-@end example
-
-@subsection Appending Standard Output and Standard Error
-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 @var{word}.
-
-The format for appending standard output and standard error is:
-@example
-&>>@var{word}
-@end example
-@noindent
-This is semantically equivalent to
-@example
->>@var{word} 2>&1
-@end example
-
-@subsection Here Documents
-This type of redirection instructs the shell to read input from the
-current source until a line containing only @var{word}
-(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.
-
-The format of here-documents is:
-@example
-<<[@minus{}]@var{word}
-        @var{here-document}
-@var{delimiter}
-@end example
-
-No parameter expansion, command substitution, arithmetic expansion,
-or filename expansion is performed on
-@var{word}.  If any characters in @var{word} are quoted, the
-@var{delimiter} is the result of quote removal on @var{word},
-and the lines in the here-document are not expanded.
-If @var{word} is unquoted,
-all lines of the here-document are subjected to parameter expansion,
-command substitution, and arithmetic expansion.  In the latter
-case, the character sequence @code{\newline} is ignored, and @samp{\}
-must be used to quote the characters
-@samp{\}, @samp{$}, and @samp{`}.
-
-If the redirection operator is @samp{<<-},
-then all leading tab characters are stripped from input lines and the
-line containing @var{delimiter}.
-This allows here-documents within shell scripts to be indented in a
-natural fashion.
-
-@subsection Here Strings
-A variant of here documents, the format is:
-@example
-<<< @var{word}
-@end example
-
-The @var{word} is expanded and supplied to the command on its standard
-input.
-
-@subsection Duplicating File Descriptors
-The redirection operator
-@example
-[@var{n}]<&@var{word}
-@end example
-@noindent
-is used to duplicate input file descriptors.
-If @var{word}
-expands to one or more digits, the file descriptor denoted by @var{n}
-is made to be a copy of that file descriptor.
-If the digits in @var{word} do not specify a file descriptor open for
-input, a redirection error occurs.
-If @var{word}
-evaluates to @samp{-}, file descriptor @var{n} is closed.  If
-@var{n} is not specified, the standard input (file descriptor 0) is used.
-
-The operator
-@example
-[@var{n}]>&@var{word}
-@end example
-@noindent
-is used similarly to duplicate output file descriptors.  If
-@var{n} is not specified, the standard output (file descriptor 1) is used.
-If the digits in @var{word} do not specify a file descriptor open for
-output, a redirection error occurs.
-As a special case, if @var{n} is omitted, and @var{word} does not
-expand to one or more digits, the standard output and standard
-error are redirected as described previously.
-
-@subsection Moving File Descriptors
-The redirection operator
-@example
-[@var{n}]<&@var{digit}-
-@end example
-@noindent
-moves the file descriptor @var{digit} to file descriptor @var{n},
-or the standard input (file descriptor 0) if @var{n} is not specified.
-@var{digit} is closed after being duplicated to @var{n}.
-
-Similarly, the redirection operator
-@example
-[@var{n}]>&@var{digit}-
-@end example
-@noindent
-moves the file descriptor @var{digit} to file descriptor @var{n},
-or the standard output (file descriptor 1) if @var{n} is not specified.
-
-@subsection Opening File Descriptors for Reading and Writing
-The redirection operator
-@example
-[@var{n}]<>@var{word}
-@end example
-@noindent
-causes the file whose name is the expansion of @var{word}
-to be opened for both reading and writing on file descriptor
-@var{n}, or on file descriptor 0 if @var{n}
-is not specified.  If the file does not exist, it is created.
-
-@node Executing Commands
-@section Executing Commands
-
-@menu
-* Simple Command Expansion::   How Bash expands simple commands before
-                               executing them.
-* Command Search and Execution::       How Bash finds commands and runs them.
-* Command Execution Environment::      The environment in which Bash
-                                       executes commands that are not
-                                       shell builtins.
-* Environment::                The environment given to a command.
-* Exit Status::                The status returned by commands and how Bash
-                       interprets it.
-* Signals::            What happens when Bash or a command it runs
-                       receives a signal.
-@end menu
-
-@node Simple Command Expansion
-@subsection Simple Command Expansion
-@cindex command expansion
-
-When a simple command is executed, the shell performs the following
-expansions, assignments, and redirections, from left to right.
-
-@enumerate
-@item
-The words that the parser has marked as variable assignments (those
-preceding the command name) and redirections are saved for later
-processing.
-
-@item
-The words that are not variable assignments or redirections are
-expanded (@pxref{Shell Expansions}).
-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.
-
-@item
-Redirections are performed as described above (@pxref{Redirections}).
-
-@item
-The text after the @samp{=} in each variable assignment undergoes tilde
-expansion, parameter expansion, command substitution, arithmetic expansion,
-and quote removal before being assigned to the variable.
-@end enumerate
-
-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.
-
-If no command name results, redirections are performed, but do not
-affect the current shell environment.  A redirection error causes the
-command to exit with a non-zero status.
-
-If there is a command name left after expansion, execution proceeds as
-described below.  Otherwise, the command exits.  If one of the 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.
-
-@node Command Search and Execution
-@subsection Command Search and Execution
-@cindex command execution
-@cindex command search
-
-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.
-
-@enumerate
-@item
-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 in @ref{Shell Functions}.
-
-@item
-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.
-
-@item
-If the name is neither a shell function nor a builtin,
-and contains no slashes, Bash searches each element of
-@env{$PATH} for a directory containing an executable file
-by that name.  Bash uses a hash table to remember the full
-pathnames of executable files to avoid multiple @env{PATH} searches
-(see the description of @code{hash} in @ref{Bourne Shell Builtins}).
-A full search of the directories in @env{$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 @code{command_not_found_handle}.
-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.
-
-@item
-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 supplied, if any.
-
-@item
-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
-@var{shell script} and the shell executes it as described in
-@ref{Shell Scripts}.
-
-@item
-If the command was not begun asynchronously, the shell waits for
-the command to complete and collects its exit status.
-
-@end enumerate
-
-@node Command Execution Environment
-@subsection Command Execution Environment
-@cindex execution environment
-
-The shell has an @var{execution environment}, which consists of the
-following:
-
-@itemize @bullet
-@item
-open files inherited by the shell at invocation, as modified by
-redirections supplied to the @code{exec} builtin
-
-@item
-the current working directory as set by @code{cd}, @code{pushd}, or
-@code{popd}, or inherited by the shell at invocation
-
-@item
-the file creation mode mask as set by @code{umask} or inherited from
-the shell's parent
-
-@item
-current traps set by @code{trap}
-
-@item
-shell parameters that are set by variable assignment or with @code{set}
-or inherited from the shell's parent in the environment
-
-@item
-shell functions defined during execution or inherited from the shell's
-parent in the environment
-
-@item
-options enabled at invocation (either by default or with command-line
-arguments) or by @code{set}
-
-@item
-options enabled by @code{shopt} (@pxref{The Shopt Builtin})
-
-@item
-shell aliases defined with @code{alias} (@pxref{Aliases})
-
-@item
-various process @sc{id}s, including those of background jobs
-(@pxref{Lists}), the value of @code{$$}, and the value of
-@env{$PPID}
-
-@end itemize
-
-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.
-
-@itemize @bullet
-@item
-the shell's open files, plus any modifications and additions specified
-by redirections to the command
-
-@item
-the current working directory
-
-@item
-the file creation mode mask
-
-@item
-shell variables and functions marked for export, along with variables
-exported for the command, passed in the environment (@pxref{Environment})
-
-@item
-traps caught by the shell are reset to the values inherited from the
-shell's parent, and traps ignored by the shell are ignored
-
-@end itemize
-
-A command invoked in this separate environment cannot affect the
-shell's execution environment. 
-
-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.
-
-Subshells spawned to execute command substitutions inherit the value of
-the @option{-e} option from the parent shell.  When not in @sc{posix} mode,
-Bash clears the @option{-e} option in such subshells.
-
-If a command is followed by a @samp{&} and job control is not active, the
-default standard input for the command is the empty file @file{/dev/null}.
-Otherwise, the invoked command inherits the file descriptors of the calling
-shell as modified by redirections.
-
-@node Environment
-@subsection Environment
-@cindex environment
-
-When a program is invoked it is given an array of strings
-called the @var{environment}.
-This is a list of name-value pairs, of the form @code{name=value}.
-
-Bash 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 @var{export}
-to child processes.  Executed commands inherit the environment.
-The @code{export} and @samp{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 @code{unset} and @samp{export -n}
-commands, plus any additions via the @code{export} and
-@samp{declare -x} commands.
-
-The environment for any simple command
-or function may be augmented temporarily by prefixing it with
-parameter assignments, as described in @ref{Shell Parameters}.
-These assignment statements affect only the environment seen
-by that command.
-
-If the @option{-k} option is set (@pxref{The Set Builtin}), then all
-parameter assignments are placed in the environment for a command,
-not just those that precede the command name.
-
-When Bash invokes an external command, the variable @samp{$_}
-is set to the full path name of the command and passed to that
-command in its environment.
-
-@node Exit Status
-@subsection Exit Status
-@cindex exit status
-
-The exit status of an executed command is the value returned by the
-@var{waitpid} 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.
-
-For the shell's purposes, a command which exits with a
-zero exit status has succeeded.
-A non-zero exit status indicates failure.
-This seemingly counter-intuitive scheme is used so there
-is one well-defined way to indicate success and a variety of
-ways to indicate various failure modes.
-When a command terminates on a fatal signal whose number is @var{N},
-Bash uses the value 128+@var{N} as the exit status.
-
-If a command is not found, the child process created to
-execute it returns a status of 127.  If a command is found  
-but is not executable, the return status is 126.
-
-If a command fails because of an error during expansion or redirection,
-the exit status is greater than zero.
-
-The exit status is used by the Bash conditional commands
-(@pxref{Conditional Constructs}) and some of the list
-constructs (@pxref{Lists}).
-
-All of the Bash builtins return an exit status of zero if they succeed
-and a non-zero status on failure, so they may be used by the
-conditional and list constructs.
-All builtins return an exit status of 2 to indicate incorrect usage.
-
-@node Signals
-@subsection Signals
-@cindex signal handling
-
-When Bash is interactive, in the absence of any traps, it ignores
-@code{SIGTERM} (so that @samp{kill 0} does not kill an interactive shell),
-and @code{SIGINT}
-is caught and handled (so that the @code{wait} builtin is interruptible).
-When Bash receives a @code{SIGINT}, it breaks out of any executing loops.
-In all cases, Bash ignores @code{SIGQUIT}.
-If job control is in effect (@pxref{Job Control}), Bash
-ignores @code{SIGTTIN}, @code{SIGTTOU}, and @code{SIGTSTP}.
-
-Non-builtin commands started by Bash have signal handlers set to the
-values inherited by the shell from its parent.
-When job control is not in effect, asynchronous commands
-ignore @code{SIGINT} and @code{SIGQUIT} in addition to these inherited
-handlers.
-Commands run as a result of
-command substitution ignore the keyboard-generated job control signals
-@code{SIGTTIN}, @code{SIGTTOU}, and @code{SIGTSTP}.
-
-The shell exits by default upon receipt of a @code{SIGHUP}.
-Before exiting, an interactive shell resends the @code{SIGHUP} to
-all jobs, running or stopped.
-Stopped jobs are sent @code{SIGCONT} to ensure that they receive
-the @code{SIGHUP}.
-To prevent the shell from sending the @code{SIGHUP} signal to a
-particular job, it should be removed
-from the jobs table with the @code{disown}
-builtin (@pxref{Job Control Builtins}) or marked
-to not receive @code{SIGHUP} using @code{disown -h}.
-
-If the  @code{huponexit} shell option has been set with @code{shopt}
-(@pxref{The Shopt Builtin}), Bash sends a @code{SIGHUP} to all jobs when
-an interactive login shell exits.
-
-If Bash 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 Bash is waiting for an asynchronous
-command via the @code{wait} builtin, the reception of a signal for
-which a trap has been set will cause the @code{wait} builtin to return
-immediately with an exit status greater than 128, immediately after
-which the trap is executed.
-
-@node Shell Scripts
-@section Shell Scripts
-@cindex shell script
-
-A shell script is a text file containing shell commands.  When such
-a file is used as the first non-option argument when invoking Bash,
-and neither the @option{-c} nor @option{-s} option is supplied
-(@pxref{Invoking Bash}), 
-Bash reads and executes commands from the file, then exits.  This
-mode of operation creates a non-interactive shell.  The shell first
-searches for the file in the current directory, and looks in the
-directories in @env{$PATH} if not found there.
-
-When Bash runs
-a shell script, it sets the special parameter @code{0} to the name
-of the file, rather than the name of the shell, and the positional
-parameters are set to the remaining arguments, if any are given.
-If no additional arguments are supplied, the positional parameters
-are unset.
-
-A shell script may be made executable by using the @code{chmod} command
-to turn on the execute bit.  When Bash finds such a file while
-searching the @env{$PATH} for a command, it spawns a subshell to
-execute it.  In other words, executing
-@example
-filename @var{arguments}
-@end example
-@noindent
-is equivalent to executing
-@example
-bash filename @var{arguments}
-@end example
-
-@noindent
-if @code{filename} is an executable shell script.
-This subshell reinitializes itself, so that the effect is as if a
-new shell had been invoked to interpret the script, with the
-exception that the locations of commands remembered by the parent
-(see the description of @code{hash} in @ref{Bourne Shell Builtins})
-are retained by the child.
-
-Most versions of Unix make this a part of the operating system's command
-execution mechanism.  If the first line of a script begins with
-the two characters @samp{#!}, the remainder of the line specifies
-an interpreter for the program.
-Thus, you can specify Bash, @code{awk}, Perl, or some other
-interpreter and write the rest of the script file in that language.
-
-The arguments to the interpreter
-consist of a single optional argument following the interpreter
-name on the first line of the script file, followed by the name of
-the script file, followed by the rest of the arguments.  Bash
-will perform this action on operating systems that do not handle it
-themselves.  Note that some older versions of Unix limit the interpreter
-name and argument to a maximum of 32 characters.
-
-Bash scripts often begin with @code{#! /bin/bash} (assuming that
-Bash has been installed in @file{/bin}), since this ensures that
-Bash will be used to interpret the script, even if it is executed
-under another shell.
-
-@node Shell Builtin Commands
-@chapter Shell Builtin Commands
-
-@menu
-* Bourne Shell Builtins::      Builtin commands inherited from the Bourne
-                               Shell.
-* Bash Builtins::              Table of builtins specific to Bash.
-* Modifying Shell Behavior::   Builtins to modify shell attributes and
-                               optional behavior.
-* Special Builtins::           Builtin commands classified specially by
-                               POSIX.
-@end menu
-
-Builtin commands are contained within the shell itself.
-When the name of a builtin command is used as the first word of
-a simple command (@pxref{Simple Commands}), the shell executes
-the command directly, without invoking another program.
-Builtin commands are necessary to implement functionality impossible
-or inconvenient to obtain with separate utilities.
-
-This section briefly describes the builtins which Bash inherits from
-the Bourne Shell, as well as the builtin commands which are unique
-to or have been extended in Bash.
-
-Several builtin commands are described in other chapters:  builtin
-commands which provide the Bash interface to the job control
-facilities (@pxref{Job Control Builtins}), the directory stack
-(@pxref{Directory Stack Builtins}), the command history
-(@pxref{Bash History Builtins}), and the programmable completion
-facilities (@pxref{Programmable Completion Builtins}).
-
-Many of the builtins have been extended by @sc{posix} or Bash.
-
-Unless otherwise noted, each builtin command documented as accepting
-options preceded by @samp{-} accepts @samp{--}
-to signify the end of the options.
-The @code{:}, @code{true}, @code{false}, and @code{test}
-builtins do not accept options and do not treat @samp{--} specially.
-The @code{exit}, @code{logout}, @code{break}, @code{continue}, @code{let},
-and @code{shift} builtins accept and process arguments beginning
-with @samp{-} without requiring @samp{--}.
-Other builtins that accept arguments but are not specified as accepting
-options interpret arguments beginning with @samp{-} as invalid options and
-require @samp{--} to prevent this interpretation.
-
-@node Bourne Shell Builtins
-@section Bourne Shell Builtins
-
-The following shell builtin commands are inherited from the Bourne Shell.
-These commands are implemented as specified by the @sc{posix} standard.
-
-@table @code
-@item :    @r{(a colon)}
-@btindex :
-@example
-: [@var{arguments}]
-@end example
-Do nothing beyond expanding @var{arguments} and performing redirections.
-The return status is zero.
-
-@item .    @r{(a period)}
-@btindex .
-@example
-. @var{filename} [@var{arguments}]
-@end example
-Read and execute commands from the @var{filename} argument in the
-current shell context.  If @var{filename} does not contain a slash,
-the @env{PATH} variable is used to find @var{filename}.
-When Bash is not in @sc{posix} mode, the current directory is searched
-if @var{filename} is not found in @env{$PATH}.
-If any @var{arguments} are supplied, they become the positional
-parameters when @var{filename} is executed.  Otherwise the positional
-parameters are unchanged.
-The return status is the exit status of the last command executed, or
-zero if no commands are executed.  If @var{filename} is not found, or
-cannot be read, the return status is non-zero.
-This builtin is equivalent to @code{source}.
-
-@item break
-@btindex break
-@example
-break [@var{n}]
-@end example
-Exit from a @code{for}, @code{while}, @code{until}, or @code{select} loop.
-If @var{n} is supplied, the @var{n}th enclosing loop is exited.
-@var{n} must be greater than or equal to 1.
-The return status is zero unless @var{n} is not greater than or equal to 1.
-
-@item cd
-@btindex cd
-@example
-cd [-L|-P] [@var{directory}]
-@end example
-Change the current working directory to @var{directory}.
-If @var{directory} is not given, the value of the @env{HOME} shell
-variable is used.
-If the shell variable @env{CDPATH} exists, it is used as a search path.
-If @var{directory} begins with a slash, @env{CDPATH} is not used.
-
-The @option{-P} option means to not follow symbolic links; symbolic
-links are followed by default or with the @option{-L} option.
-If @var{directory} is @samp{-}, it is equivalent to @env{$OLDPWD}.
-
-If a non-empty directory name from @env{CDPATH} is used, or if
-@samp{-} 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 status is zero if the directory is successfully changed,
-non-zero otherwise.
-
-@item continue
-@btindex continue
-@example
-continue [@var{n}]
-@end example
-Resume the next iteration of an enclosing @code{for}, @code{while},
-@code{until}, or @code{select} loop.
-If @var{n} is supplied, the execution of the @var{n}th enclosing loop
-is resumed.
-@var{n} must be greater than or equal to 1.
-The return status is zero unless @var{n} is not greater than or equal to 1.
-
-@item eval
-@btindex eval
-@example
-eval [@var{arguments}]
-@end example
-The arguments are concatenated together into a single command, which is
-then read and executed, and its exit status returned as the exit status
-of @code{eval}.
-If there are no arguments or only empty arguments, the return status is
-zero.
-
-@item exec
-@btindex exec
-@example
-exec [-cl] [-a @var{name}] [@var{command} [@var{arguments}]]
-@end example
-If @var{command}
-is supplied, it replaces the shell without creating a new process.
-If the @option{-l} option is supplied, the shell places a dash at the
-beginning of the zeroth argument passed to @var{command}.
-This is what the @code{login} program does.
-The @option{-c} option causes @var{command} to be executed with an empty
-environment.
-If @option{-a} is supplied, the shell passes @var{name} as the zeroth
-argument to @var{command}.
-If no @var{command} is specified, redirections may be used to affect
-the current shell environment.  If there are no redirection errors, the
-return status is zero; otherwise the return status is non-zero.
-
-@item exit
-@btindex exit
-@example
-exit [@var{n}]
-@end example
-Exit the shell, returning a status of @var{n} to the shell's parent.
-If @var{n} is omitted, the exit status is that of the last command executed.
-Any trap on @code{EXIT} is executed before the shell terminates.
-
-@item export
-@btindex export
-@example
-export [-fn] [-p] [@var{name}[=@var{value}]]
-@end example
-Mark each @var{name} to be passed to child processes
-in the environment.  If the @option{-f} option is supplied, the @var{name}s
-refer to shell functions; otherwise the names refer to shell variables.
-The @option{-n} option means to no longer mark each @var{name} for export.
-If no @var{names} are supplied, or if the @option{-p} option is given, a
-list of exported names is displayed.
-The @option{-p} option displays output in a form that may be reused as input.
-If a variable name is followed by =@var{value}, the value of
-the variable is set to @var{value}.
-
-The return status is zero unless an invalid option is supplied, one of
-the names is not a valid shell variable name, or @option{-f} is supplied
-with a name that is not a shell function.
-
-@item getopts
-@btindex getopts
-@example
-getopts @var{optstring} @var{name} [@var{args}]
-@end example
-@code{getopts} is used by shell scripts to parse positional parameters.
-@var{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 (@samp{:}) and question mark (@samp{?}) may not be
-used as option characters.
-Each time it is invoked, @code{getopts}
-places the next option in the shell variable @var{name}, initializing
-@var{name} if it does not exist,
-and the index of the next argument to be processed into the
-variable @env{OPTIND}.
-@env{OPTIND} is initialized to 1 each time the shell or a shell script
-is invoked.
-When an option requires an argument,
-@code{getopts} places that argument into the variable @env{OPTARG}.
-The shell does not reset @env{OPTIND} automatically; it must be manually
-reset between multiple calls to @code{getopts} within the same shell
-invocation if a new set of parameters is to be used.
-
-When the end of options is encountered, @code{getopts} exits with a
-return value greater than zero.
-@env{OPTIND} is set to the index of the first non-option argument,
-and @code{name} is set to @samp{?}.
-
-@code{getopts}
-normally parses the positional parameters, but if more arguments are
-given in @var{args}, @code{getopts} parses those instead.
-
-@code{getopts} can report errors in two ways.  If the first character of
-@var{optstring} is a colon, @var{silent}
-error reporting is used.  In normal operation diagnostic messages
-are printed when invalid options or missing option arguments are
-encountered.
-If the variable @env{OPTERR}
-is set to 0, no error messages will be displayed, even if the first
-character of @code{optstring} is not a colon.
-
-If an invalid option is seen,
-@code{getopts} places @samp{?} into @var{name} and, if not silent,
-prints an error message and unsets @env{OPTARG}.
-If @code{getopts} is silent, the option character found is placed in
-@env{OPTARG} and no diagnostic message is printed.
-
-If a required argument is not found, and @code{getopts}
-is not silent, a question mark (@samp{?}) is placed in @var{name},
-@code{OPTARG} is unset, and a diagnostic message is printed.
-If @code{getopts} is silent, then a colon (@samp{:}) is placed in
-@var{name} and @env{OPTARG} is set to the option character found.
-
-@item hash
-@btindex hash
-@example
-hash [-r] [-p @var{filename}] [-dt] [@var{name}]
-@end example
-Remember the full pathnames of commands specified as @var{name} arguments,
-so they need not be searched for on subsequent invocations.
-The commands are found by searching through the directories listed in
-@env{$PATH}.
-The @option{-p} option inhibits the path search, and @var{filename} is
-used as the location of @var{name}.
-The @option{-r} option causes the shell to forget all remembered locations.
-The @option{-d} option causes the shell to forget the remembered location
-of each @var{name}.
-If the @option{-t} option is supplied, the full pathname to which each
-@var{name} corresponds is printed.  If multiple @var{name} arguments are
-supplied with @option{-t} the @var{name} is printed before the hashed
-full pathname.
-The @option{-l} option causes output to be displayed in a format
-that may be reused as input.
-If no arguments are given, or if only @option{-l} is supplied,
-information about remembered commands is printed.
-The return status is zero unless a @var{name} is not found or an invalid
-option is supplied.
-
-@item pwd
-@btindex pwd
-@example
-pwd [-LP]
-@end example
-Print the absolute pathname of the current working directory.
-If the @option{-P} option is supplied, the pathname printed will not
-contain symbolic links.
-If the @option{-L} option is supplied, the pathname printed may contain
-symbolic links.
-The return status is zero unless an error is encountered while
-determining the name of the current directory or an invalid option
-is supplied.
-
-@item readonly
-@btindex readonly
-@example
-readonly [-aApf] [@var{name}[=@var{value}]] @dots{}
-@end example
-Mark each @var{name} as readonly.
-The values of these names may not be changed by subsequent assignment.
-If the @option{-f} option is supplied, each @var{name} refers to a shell
-function.
-The @option{-a} option means each @var{name} refers to an indexed
-array variable; the @option{-A} option means each @var{name} refers
-to an associative array variable.
-If no @var{name} arguments are given, or if the @option{-p}
-option is supplied, a list of all readonly names is printed.
-The @option{-p} option causes output to be displayed in a format that
-may be reused as input.
-If a variable name is followed by =@var{value}, the value of
-the variable is set to @var{value}.
-The return status is zero unless an invalid option is supplied, one of
-the @var{name} arguments is not a valid shell variable or function name,
-or the @option{-f} option is supplied with a name that is not a shell function.
-
-@item return
-@btindex return
-@example
-return [@var{n}]
-@end example
-Cause a shell function to exit with the return value @var{n}.
-If @var{n} is not supplied, the return value is the exit status of the
-last command executed in the function.
-This may also be used to terminate execution of a script being executed
-with the @code{.} (or @code{source}) builtin, returning either @var{n} or
-the exit status of the last command executed within the script as the exit
-status of the script.
-Any command associated with the @code{RETURN} trap is executed
-before execution resumes after the function or script.
-The return status is non-zero if @code{return} is used outside a function
-and not during the execution of a script by @code{.} or @code{source}.
-
-@item shift
-@btindex shift
-@example
-shift [@var{n}]
-@end example
-Shift the positional parameters to the left by @var{n}.
-The positional parameters from @var{n}+1 @dots{} @code{$#} are
-renamed to @code{$1} @dots{} @code{$#}-@var{n}.
-Parameters represented by the numbers @code{$#} to @code{$#}-@var{n}+1
-are unset.
-@var{n} must be a non-negative number less than or equal to @code{$#}.
-If @var{n} is zero or greater than @code{$#}, the positional parameters
-are not changed.
-If @var{n} is not supplied, it is assumed to be 1.
-The return status is zero unless @var{n} is greater than @code{$#} or
-less than zero, non-zero otherwise.
-
-@item test
-@itemx [
-@btindex test
-@btindex [
-Evaluate a conditional expression @var{expr}.
-Each operator and operand must be a separate argument.
-Expressions are composed of the primaries described below in
-@ref{Bash Conditional Expressions}.
-@code{test} does not accept any options, nor does it accept and ignore
-an argument of @option{--} as signifying the end of options.
-
-When the @code{[} form is used, the last argument to the command must
-be a @code{]}.
-
-Expressions may be combined using the following operators, listed in
-decreasing order of precedence.
-The evaluation depends on the number of arguments; see below.
-
-@table @code
-@item ! @var{expr}
-True if @var{expr} is false.
-
-@item ( @var{expr} )
-Returns the value of @var{expr}.
-This may be used to override the normal precedence of operators.
-
-@item @var{expr1} -a @var{expr2}
-True if both @var{expr1} and @var{expr2} are true.
-
-@item @var{expr1} -o @var{expr2}
-True if either @var{expr1} or @var{expr2} is true.
-@end table
-
-The @code{test} and @code{[} builtins evaluate conditional
-expressions using a set of rules based on the number of arguments.
-
-@table @asis
-@item 0 arguments
-The expression is false.
-
-@item 1 argument
-The expression is true if and only if the argument is not null.
-
-@item 2 arguments
-If the first argument is @samp{!}, the expression is true if and
-only if the second argument is null.
-If the first argument is one of the unary conditional operators
-(@pxref{Bash Conditional Expressions}), the expression
-is true if the unary test is true.
-If the first argument is not a valid unary operator, the expression is
-false.
-
-@item 3 arguments
-If the second argument is one of the binary conditional
-operators (@pxref{Bash Conditional Expressions}), the
-result of the expression is the result of the binary test using the
-first and third arguments as operands.
-The @samp{-a} and @samp{-o} operators are considered binary operators
-when there are three arguments.
-If the first argument is @samp{!}, the value is the negation of
-the two-argument test using the second and third arguments.
-If the first argument is exactly @samp{(} and the third argument is
-exactly @samp{)}, the result is the one-argument test of the second
-argument.
-Otherwise, the expression is false.
-
-@item 4 arguments
-If the first argument is @samp{!}, 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.
-
-@item 5 or more arguments
-The expression is parsed and evaluated according to precedence
-using the rules listed above.
-@end table
-
-@item times
-@btindex times
-@example
-times
-@end example
-Print out the user and system times used by the shell and its children.
-The return status is zero.
-
-@item trap
-@btindex trap
-@example
-trap [-lp] [@var{arg}] [@var{sigspec} @dots{}]
-@end example
-The commands in @var{arg} are to be read and executed when the
-shell receives signal @var{sigspec}.  If @var{arg} is absent (and
-there is a single @var{sigspec}) or
-equal to @samp{-}, each specified signal's disposition is reset
-to the value it had when the shell was started.
-If @var{arg} is the null string, then the signal specified by
-each @var{sigspec} is ignored by the shell and commands it invokes.
-If @var{arg} is not present and @option{-p} has been supplied,
-the shell displays the trap commands associated with each @var{sigspec}.
-If no arguments are supplied, or
-only @option{-p} is given, @code{trap} prints the list of commands
-associated with each signal number in a form that may be reused as
-shell input.
-The @option{-l} option causes the shell to print a list of signal names
-and their corresponding numbers.
-Each @var{sigspec} is either a signal name or a signal number.
-Signal names are case insensitive and the @code{SIG} prefix is optional.
-
-If a @var{sigspec}
-is @code{0} or @code{EXIT}, @var{arg} is executed when the shell exits.
-If a @var{sigspec} is @code{DEBUG}, the command @var{arg} is executed
-before every simple command, @code{for} command, @code{case} command,
-@code{select} command, every arithmetic @code{for} command, and before
-the first command executes in a shell function.
-Refer to the description of the @code{extdebug} option to the
-@code{shopt} builtin (@pxref{The Shopt Builtin}) for details of its
-effect on the @code{DEBUG} trap.
-If a @var{sigspec} is @code{RETURN}, the command @var{arg} is executed
-each time a shell function or a script executed with the @code{.} or
-@code{source} builtins finishes executing.
-
-If a @var{sigspec} is @code{ERR}, the command @var{arg} 
-is executed whenever a simple command has a non-zero exit status,
-subject to the following conditions.
-The @code{ERR} trap is not executed if the failed command is part of the
-command list immediately following an @code{until} or @code{while} keyword,
-part of the test following the @code{if} or @code{elif} reserved words,
-part of a command executed in a @code{&&} or @code{||} list,
-or if the command's return
-status is being inverted using @code{!}.
-These are the same conditions obeyed by the @code{errexit} option.
-
-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 zero unless a @var{sigspec} does not specify a
-valid signal.
-
-@item umask
-@btindex umask
-@example
-umask [-p] [-S] [@var{mode}]
-@end example
-Set the shell process's file creation mask to @var{mode}.  If
-@var{mode} begins with a digit, it is interpreted as an octal number;
-if not, it is interpreted as a symbolic mode mask similar
-to that accepted by the @code{chmod} command.  If @var{mode} is
-omitted, the current value of the mask is printed.  If the @option{-S}
-option is supplied without a @var{mode} argument, the mask is printed
-in a symbolic format.
-If the  @option{-p} option is supplied, and @var{mode}
-is omitted, the output is in a form that may be reused as input.
-The return status is zero if the mode is successfully changed or if
-no @var{mode} argument is supplied, and non-zero otherwise.
-
-Note that when the mode is interpreted as an octal number, each number
-of the umask is subtracted from @code{7}.  Thus, a umask of @code{022}
-results in permissions of @code{755}.
-
-@item unset
-@btindex unset
-@example
-unset [-fv] [@var{name}]
-@end example
-Each variable or function @var{name} is removed.
-If no options are supplied, or the @option{-v} option is given, each
-@var{name} refers to a shell variable. 
-If the @option{-f} option is given, the @var{name}s refer to shell
-functions, and the function definition is removed.
-Readonly variables and functions may not be unset.
-The return status is zero unless a @var{name} is readonly.
-@end table
-
-@node Bash Builtins
-@section Bash Builtin Commands
-
-This section describes builtin commands which are unique to
-or have been extended in Bash.
-Some of these commands are specified in the @sc{posix} standard.
-
-@table @code
-
-@item alias
-@btindex alias
-@example
-alias [@code{-p}] [@var{name}[=@var{value}] @dots{}]
-@end example
-
-Without arguments or with the @option{-p} option, @code{alias} prints
-the list of aliases on the standard output in a form that allows
-them to be reused as input.
-If arguments are supplied, an alias is defined for each @var{name}
-whose @var{value} is given.  If no @var{value} is given, the name
-and value of the alias is printed.
-Aliases are described in @ref{Aliases}.
-
-@item bind
-@btindex bind
-@example
-bind [-m @var{keymap}] [-lpsvPSV]
-bind [-m @var{keymap}] [-q @var{function}] [-u @var{function}] [-r @var{keyseq}]
-bind [-m @var{keymap}] -f @var{filename}
-bind [-m @var{keymap}] -x @var{keyseq:shell-command}
-bind [-m @var{keymap}] @var{keyseq:function-name}
-bind @var{readline-command}
-@end example
-
-Display current Readline (@pxref{Command Line Editing})
-key and function bindings,
-bind a key sequence to a Readline function or macro,
-or set a Readline variable.
-Each non-option argument is a command as it would appear in a
-Readline initialization file (@pxref{Readline Init File}),
-but each binding or command must be passed as a separate argument;  e.g.,
-@samp{"\C-x\C-r":re-read-init-file}.
-
-Options, if supplied, have the following meanings:
-
-@table @code
-@item -m @var{keymap}
-Use @var{keymap} as the keymap to be affected by
-the subsequent bindings.  Acceptable @var{keymap}
-names are
-@code{emacs},
-@code{emacs-standard},
-@code{emacs-meta},
-@code{emacs-ctlx},
-@code{vi},
-@code{vi-move},
-@code{vi-command}, and
-@code{vi-insert}.
-@code{vi} is equivalent to @code{vi-command};
-@code{emacs} is equivalent to @code{emacs-standard}.
-
-@item -l
-List the names of all Readline functions.
-
-@item -p
-Display Readline function names and bindings in such a way that they
-can be used as input or in a Readline initialization file.
-
-@item -P
-List current Readline function names and bindings.
-
-@item -v
-Display Readline variable names and values in such a way that they
-can be used as input or in a Readline initialization file.
-
-@item -V
-List current Readline variable names and values.
-
-@item -s
-Display Readline key sequences bound to macros and the strings they output
-in such a way that they can be used as input or in a Readline
-initialization file.
-
-@item -S
-Display Readline key sequences bound to macros and the strings they output.
-
-@item -f @var{filename}
-Read key bindings from @var{filename}.
-
-@item -q @var{function}
-Query about which keys invoke the named @var{function}.
-
-@item -u @var{function}
-Unbind all keys bound to the named @var{function}.
-
-@item -r @var{keyseq}
-Remove any current binding for @var{keyseq}.
-
-@item -x @var{keyseq:shell-command}
-Cause @var{shell-command} to be executed whenever @var{keyseq} is
-entered.
-When @var{shell-command} is executed, the shell sets the
-@code{READLINE_LINE} variable to the contents of the Readline line
-buffer and the @code{READLINE_POINT} variable to the current location
-of the insertion point.
-If the executed command changes the value of @code{READLINE_LINE} or
-@code{READLINE_POINT}, those new values will be reflected in the
-editing state.
-@end table
-
-@noindent
-The return status is zero unless an invalid option is supplied or an
-error occurs.
-
-@item builtin
-@btindex builtin
-@example
-builtin [@var{shell-builtin} [@var{args}]]
-@end example
-Run a shell builtin, passing it @var{args}, and return its exit status.
-This is useful when defining a shell function with the same
-name as a shell builtin, retaining the functionality of the builtin within
-the function.
-The return status is non-zero if @var{shell-builtin} is not a shell
-builtin command.
-
-@item caller
-@btindex caller
-@example
-caller [@var{expr}]
-@end example
-Returns the context of any active subroutine call (a shell function or
-a script executed with the @code{.} or @code{source} builtins).
-
-Without @var{expr}, @code{caller} displays the line number and source
-filename of the current subroutine call.
-If a non-negative integer is supplied as @var{expr}, @code{caller} 
-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 @var{expr} does not correspond to a valid position in the
-call stack.
-
-@item command
-@btindex command
-@example
-command [-pVv] @var{command} [@var{arguments} @dots{}]
-@end example
-Runs @var{command} with @var{arguments} ignoring any shell function
-named @var{command}.
-Only shell builtin commands or commands found by searching the
-@env{PATH} are executed.
-If there is a shell function named @code{ls}, running @samp{command ls}
-within the function will execute the external command @code{ls}
-instead of calling the function recursively.
-The @option{-p} option means to use a default value for @env{PATH}
-that is guaranteed to find all of the standard utilities.
-The return status in this case is 127 if @var{command} cannot be
-found or an error occurred, and the exit status of @var{command}
-otherwise.
-
-If either the @option{-V} or @option{-v} option is supplied, a
-description of @var{command} is printed.  The @option{-v} option
-causes a single word indicating the command or file name used to
-invoke @var{command} to be displayed; the @option{-V} option produces
-a more verbose description.  In this case, the return status is
-zero if @var{command} is found, and non-zero if not.
-
-@item declare
-@btindex declare
-@example
-declare [-aAfFilrtux] [-p] [@var{name}[=@var{value}] @dots{}]
-@end example
-
-Declare variables and give them attributes.  If no @var{name}s
-are given, then display the values of variables instead. 
-
-The @option{-p} option will display the attributes and values of each
-@var{name}.
-When @option{-p} is used with @var{name} arguments, additional options
-are ignored.
-
-When @option{-p} is supplied without @var{name} arguments, @code{declare}
-will display the attributes and values of all variables having the
-attributes specified by the additional options.
-If no other options are supplied with @option{-p}, @code{declare} will
-display the attributes and values of all shell variables.  The @option{-f}
-option will restrict the display to shell functions.
-
-The @option{-F} option inhibits the display of function definitions;
-only the function name and attributes are printed.
-If the @code{extdebug} shell option is enabled using @code{shopt}
-(@pxref{The Shopt Builtin}), the source file name and line number where
-the function is defined are displayed as well.
-@option{-F} implies @option{-f}.
-The following options can be used to restrict output to variables with
-the specified attributes or to give variables attributes:
-
-@table @code
-@item -a
-Each @var{name} is an indexed array variable (@pxref{Arrays}).
-
-@item -A
-Each @var{name} is an associative array variable (@pxref{Arrays}).
-
-@item -f
-Use function names only.
-
-@item -i
-The variable is to be treated as
-an integer; arithmetic evaluation (@pxref{Shell Arithmetic}) is
-performed when the variable is assigned a value.
-
-@item -l
-When the variable is assigned a value, all upper-case characters are
-converted to lower-case.
-The upper-case attribute is disabled.
-
-@item -r
-Make @var{name}s readonly.  These names cannot then be assigned values
-by subsequent assignment statements or unset.
-
-@item -t
-Give each @var{name} the @code{trace} attribute.
-Traced functions inherit the @code{DEBUG} and @code{RETURN} traps from
-the calling shell.
-The trace attribute has no special meaning for variables.
-
-@item -u
-When the variable is assigned a value, all lower-case characters are
-converted to upper-case.
-The lower-case attribute is disabled.
-
-@item -x
-Mark each @var{name} for export to subsequent commands via
-the environment.
-@end table
-
-Using @samp{+} instead of @samp{-} turns off the attribute instead,
-with the exceptions that @samp{+a}
-may not be used to destroy an array variable and @samp{+r} will not
-remove the readonly attribute.
-When used in a function, @code{declare} makes each @var{name} local,
-as with the @code{local} command.  If a variable name is followed by
-=@var{value}, the value of the variable is set to @var{value}.
-
-The return status is zero unless an invalid option is encountered,
-an attempt is made to define a function using @samp{-f foo=bar},
-an attempt is made to assign a value to a readonly variable,
-an attempt is made to assign a value to an array variable without
-using the compound assignment syntax (@pxref{Arrays}),
-one of the @var{names} 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 @option{-f}.
-
-@item echo
-@btindex echo
-@example
-echo [-neE] [@var{arg} @dots{}]
-@end example
-Output the @var{arg}s, separated by spaces, terminated with a
-newline.
-The return status is always 0.
-If @option{-n} is specified, the trailing newline is suppressed.
-If the @option{-e} option is given, interpretation of the following
-backslash-escaped characters is enabled.
-The @option{-E} option disables the interpretation of these escape characters,
-even on systems where they are interpreted by default.
-The @code{xpg_echo} shell option may be used to
-dynamically determine whether or not @code{echo} expands these
-escape characters by default.
-@code{echo} does not interpret @option{--} to mean the end of options.
-
-@code{echo} interprets the following escape sequences:
-@table @code
-@item \a
-alert (bell)
-@item \b
-backspace
-@item \c
-suppress further output
-@item \e
-escape
-@item \f
-form feed
-@item \n
-new line
-@item \r
-carriage return
-@item \t 
-horizontal tab
-@item \v
-vertical tab
-@item \\
-backslash
-@item \0@var{nnn}
-the eight-bit character whose value is the octal value @var{nnn}
-(zero to three octal digits)
-@item \x@var{HH}
-the eight-bit character whose value is the hexadecimal value @var{HH}
-(one or two hex digits)
-@end table
-
-@item enable
-@btindex enable
-@example
-enable [-a] [-dnps] [-f @var{filename}] [@var{name} @dots{}]
-@end example
-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 @option{-n} is used, the @var{name}s become disabled.  Otherwise
-@var{name}s are enabled.  For example, to use the @code{test} binary
-found via @env{$PATH} instead of the shell builtin version, type
-@samp{enable -n test}.
-
-If the @option{-p} option is supplied, or no @var{name} arguments appear,
-a list of shell builtins is printed.  With no other arguments, the list
-consists of all enabled shell builtins.
-The @option{-a} option means to list
-each builtin with an indication of whether or not it is enabled. 
-
-The @option{-f} option means to load the new builtin command @var{name}
-from shared object @var{filename}, on systems that support dynamic loading.
-The @option{-d} option will delete a builtin loaded with @option{-f}.
-
-If there are no options, a list of the shell builtins is displayed.
-The @option{-s} option restricts @code{enable} to the @sc{posix} special
-builtins.  If @option{-s} is used with @option{-f}, the new builtin becomes
-a special builtin (@pxref{Special Builtins}).
-
-The return status is zero unless a @var{name} is not a shell builtin
-or there is an error loading a new builtin from a shared object.
-
-@item help
-@btindex help
-@example
-help [-dms] [@var{pattern}]
-@end example
-Display helpful information about builtin commands.
-If @var{pattern} is specified, @code{help} gives detailed help
-on all commands matching @var{pattern}, otherwise a list of
-the builtins is printed.
-
-Options, if supplied, have the following meanings:
-
-@table @code
-@item -d
-Display a short description of each @var{pattern}
-@item -m
-Display the description of each @var{pattern} in a manpage-like format
-@item -s
-Display only a short usage synopsis for each @var{pattern}
-@end table
-
-The return status is zero unless no command matches @var{pattern}.
-
-@item let
-@btindex let
-@example
-let @var{expression} [@var{expression}]
-@end example
-The @code{let} builtin allows arithmetic to be performed on shell
-variables.  Each @var{expression} is evaluated according to the
-rules given below in @ref{Shell Arithmetic}.  If the
-last @var{expression} evaluates to 0, @code{let} returns 1;
-otherwise 0 is returned.
-
-@item local
-@btindex local
-@example
-local [@var{option}] @var{name}[=@var{value}] @dots{}
-@end example
-For each argument, a local variable named @var{name} is created,
-and assigned @var{value}.
-The @var{option} can be any of the options accepted by @code{declare}.
-@code{local} can only be used within a function; it makes the variable
-@var{name} have a visible scope restricted to that function and its
-children.  The return status is zero unless @code{local} is used outside
-a function, an invalid @var{name} is supplied, or @var{name} is a
-readonly variable.
-
-@item logout
-@btindex logout
-@example
-logout [@var{n}]
-@end example
-Exit a login shell, returning a status of @var{n} to the shell's
-parent.
-
-@item mapfile
-@btindex mapfile
-@example
-mapfile [-n @var{count}] [-O @var{origin}] [-s @var{count}] [-t] [-u @var{fd}] [
--C @var{callback}] [-c @var{quantum}] [@var{array}]
-@end example
-Read lines from the standard input into the indexed array variable @var{array},
-or from file descriptor @var{fd}
-if the @option{-u} option is supplied.
-The variable @code{MAPFILE} is the default @var{array}.
-Options, if supplied, have the following meanings:
-@table @code
-
-@item -n
-Copy at most @var{count} lines.  If @var{count} is 0, all lines are copied.
-@item -O
-Begin assigning to @var{array} at index @var{origin}.
-The default index is 0.
-@item -s
-Discard the first @var{count} lines read.
-@item -t
-Remove a trailing line from each line read.
-@item -u
-Read lines from file descriptor @var{fd} instead of the standard input.
-@item -C
-Evaluate @var{callback} each time @var{quantum}P lines are read.
-The @option{-c} option specifies @var{quantum}.
-@item -c
-Specify the number of lines read between each call to @var{callback}.
-@end table
-
-If @option{-C} is specified without @option{-c}, 
-the default quantum is 5000.
-When @var{callback}  is evaluated, it is supplied the index of the next
-array element to be assigned as an additional argument.
-@var{callback} is evaluated after the line is read but before the 
-array element is assigned.
-
-If not supplied with an explicit origin, @code{mapfile} will clear @var{array}
-before assigning to it.
-
-@code{mapfile} returns successfully unless an invalid option or option
-argument is supplied, @var{array} is invalid or unassignable, or @var{array}
-is not an indexed array.
-
-@item printf
-@btindex printf
-@example
-printf [-v @var{var}] @var{format} [@var{arguments}]
-@end example
-Write the formatted @var{arguments} to the standard output under the
-control of the @var{format}.
-The @var{format} 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
-@var{argument}.
-In addition to the standard @code{printf(1)} formats, @samp{%b} causes
-@code{printf} to expand backslash escape sequences in the corresponding
-@var{argument},
-(except that @samp{\c} terminates output, backslashes in
-@samp{\'}, @samp{\"}, and @samp{\?} are not removed, and octal escapes
-beginning with @samp{\0} may contain up to four digits),
-and @samp{%q} causes @code{printf} to output the
-corresponding @var{argument} in a format that can be reused as shell input.
-
-The @option{-v} option causes the output to be assigned to the variable
-@var{var} rather than being printed to the standard output.
-
-The @var{format} is reused as necessary to consume all of the @var{arguments}.
-If the @var{format} requires more @var{arguments} 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.
-
-@item read
-@btindex read
-@example
-read [-ers] [-a @var{aname}] [-d @var{delim}] [-i @var{text}] [-n @var{nchars}] [-N @var{nchars}] [-p @var{prompt}] [-t @var{timeout}] [-u @var{fd}] [@var{name} @dots{}]
-@end example
-One line is read from the standard input, or from the file descriptor
-@var{fd} supplied as an argument to the @option{-u} option, and the first word
-is assigned to the first @var{name}, the second word to the second @var{name},
-and so on, with leftover words and their intervening separators assigned
-to the last @var{name}.
-If there are fewer words read from the input stream than names,
-the remaining names are assigned empty values.
-The characters in the value of the @env{IFS} variable
-are used to split the line into words.
-The backslash character @samp{\} may be used to remove any special
-meaning for the next character read and for line continuation.
-If no names are supplied, the line read is assigned to the
-variable @env{REPLY}.
-The return code is zero, unless end-of-file is encountered, @code{read}
-times out (in which case the return code is greater than 128), or an
-invalid file descriptor is supplied as the argument to @option{-u}.
-
-Options, if supplied, have the following meanings:
-
-@table @code
-@item -a @var{aname}
-The words are assigned to sequential indices of the array variable
-@var{aname}, starting at 0.
-All elements are removed from @var{aname} before the assignment.
-Other @var{name} arguments are ignored.
-
-@item -d @var{delim}
-The first character of @var{delim} is used to terminate the input line,
-rather than newline.
-
-@item -e
-Readline (@pxref{Command Line Editing}) is used to obtain the line.
-Readline uses the current (or default, if line editing was not previously
-active) editing settings.
-
-@item -i @var{text}
-If Readline is being used to read the line, @var{text} is placed into
-the editing buffer before editing begins.
-
-@item -n @var{nchars}
-@code{read} returns after reading @var{nchars} characters rather than
-waiting for a complete line of input, but honor a delimiter if fewer
-than @var{nchars} characters are read before the delimiter.
-
-@item -N @var{nchars}
-@code{read} returns after reading exactly @var{nchars} characters rather
-than waiting for a complete line of input, unless EOF is encountered or
-@code{read} times out.
-Delimiter characters encountered in the input are
-not treated specially and do not cause @code{read} to return until
-@var{nchars} characters are read.
-
-@item -p @var{prompt}
-Display @var{prompt}, without a trailing newline, before attempting
-to read any input.
-The prompt is displayed only if input is coming from a terminal.
-
-@item -r
-If this option is given, 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.
-
-@item -s
-Silent mode.  If input is coming from a terminal, characters are
-not echoed.
-
-@item -t @var{timeout}
-Cause @code{read} to time out and return failure if a complete line of
-input is not read within @var{timeout} seconds.
-@var{timeout}  may be a decimal number with a fractional portion following
-the decimal point.
-This option is only effective if @code{read} is reading input from a
-terminal, pipe, or other special file; it has no effect when reading
-from regular files.
-If @var{timeout} is 0, @code{read} returns success if input is available on
-the specified file descriptor, failure otherwise.
-The exit status is greater than 128 if the timeout is exceeded.
-
-@item -u @var{fd}
-Read input from file descriptor @var{fd}.
-
-@end table
-
-@item readarray
-@btindex readarray
-@example
-readarray [-n @var{count}] [-O @var{origin}] [-s @var{count}] [-t] [-u @var{fd}] [
--C @var{callback}] [-c @var{quantum}] [@var{array}]
-@end example
-Read lines from the standard input into the indexed array variable @var{array},
-or from file descriptor @var{fd}
-if the @option{-u} option is supplied.
-
-A synonym for @code{mapfile}.
-
-@item source
-@btindex source
-@example
-source @var{filename}
-@end example
-A synonym for @code{.} (@pxref{Bourne Shell Builtins}).
-
-@item type
-@btindex type
-@example
-type [-afptP] [@var{name} @dots{}]
-@end example
-For each @var{name}, indicate how it would be interpreted if used as a
-command name.
-
-If the @option{-t} option is used, @code{type} prints a single word
-which is one of @samp{alias}, @samp{function}, @samp{builtin},
-@samp{file} or @samp{keyword},
-if @var{name} is an alias, shell function, shell builtin,
-disk file, or shell reserved word, respectively.
-If the @var{name} is not found, then nothing is printed, and
-@code{type} returns a failure status.
-
-If the @option{-p} option is used, @code{type} either returns the name
-of the disk file that would be executed, or nothing if @option{-t}
-would not return @samp{file}.
-
-The @option{-P} option forces a path search for each @var{name}, even if
-@option{-t} would not return @samp{file}.
-
-If a command is hashed, @option{-p} and @option{-P} print the hashed value,
-not necessarily the file that appears first in @code{$PATH}.
-
-If the @option{-a} option is used, @code{type} returns all of the places
-that contain an executable named @var{file}.
-This includes aliases and functions, if and only if the @option{-p} option
-is not also used.
-
-If the @option{-f} option is used, @code{type} does not attempt to find
-shell functions, as with the @code{command} builtin.
-
-The return status is zero if all of the @var{names} are found, non-zero
-if any are not found.
-
-@item typeset
-@btindex typeset
-@example
-typeset [-afFrxi] [-p] [@var{name}[=@var{value}] @dots{}]
-@end example
-The @code{typeset} command is supplied for compatibility with the Korn
-shell; however, it has been deprecated in favor of the @code{declare}
-builtin command.
-
-@item ulimit
-@btindex ulimit
-@example
-ulimit [-abcdefilmnpqrstuvxHST] [@var{limit}]
-@end example
-@code{ulimit} provides control over the resources available to processes
-started by the shell, on systems that allow such control.  If an
-option is given, it is interpreted as follows:
-@table @code
-@item -S
-Change and report the soft limit associated with a resource.
-
-@item -H
-Change and report the hard limit associated with a resource.
-
-@item -a
-All current limits are reported.
-
-@item -b
-The maximum socket buffer size.
-
-@item -c
-The maximum size of core files created.
-
-@item -d
-The maximum size of a process's data segment.
-
-@item -e
-The maximum scheduling priority ("nice").
-
-@item -f
-The maximum size of files written by the shell and its children.
-
-@item -i
-The maximum number of pending signals.
-
-@item -l
-The maximum size that may be locked into memory.
-
-@item -m
-The maximum resident set size (many systems do not honor this limit).
-
-@item -n
-The maximum number of open file descriptors (most systems do not
-allow this value to be set).
-
-@item -p
-The pipe buffer size.
-
-@item -q
-The maximum number of bytes in POSIX message queues.
-
-@item -r
-The maximum real-time scheduling priority.
-
-@item -s
-The maximum stack size.
-
-@item -t
-The maximum amount of cpu time in seconds.
-
-@item -u
-The maximum number of processes available to a single user.
-
-@item -v
-The maximum amount of virtual memory available to the process.
-
-@item -x
-The maximum number of file locks.
-
-@item -T
-The maximum number of threads.
-
-@end table
-
-If @var{limit} is given, it is the new value of the specified resource;
-the special @var{limit} values @code{hard}, @code{soft}, and
-@code{unlimited} stand for the current hard limit, the current soft limit,
-and no limit, respectively.
-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.
-Otherwise, the current value of the soft limit for the specified resource
-is printed, unless the @option{-H} option is supplied.
-When setting new limits, if neither @option{-H} nor @option{-S} is supplied,
-both the hard and soft limits are set.
-If no option is given, then @option{-f} is assumed.  Values are in 1024-byte
-increments, except for @option{-t}, which is in seconds, @option{-p},
-which is in units of 512-byte blocks, and @option{-n} and @option{-u}, which
-are unscaled values.
-
-The return status is zero unless an invalid option or argument is supplied,
-or an error occurs while setting a new limit.
-
-@item unalias
-@btindex unalias
-@example
-unalias [-a] [@var{name} @dots{} ]
-@end example
-
-Remove each @var{name} from the list of aliases.  If @option{-a} is
-supplied, all aliases are removed.
-Aliases are described in @ref{Aliases}.
-
-@end table
-
-@node Modifying Shell Behavior
-@section Modifying Shell Behavior
-@menu
-* The Set Builtin::            Change the values of shell attributes and
-                               positional parameters.
-* The Shopt Builtin::          Modify shell optional behavior.
-@end menu
-
-@node The Set Builtin
-@subsection The Set Builtin
-
-This builtin is so complicated that it deserves its own section.  @code{set}
-allows you to change the values of shell options and set the positional
-parameters, or to display the names and values of shell variables.
-
-@table @code
-@item set
-@btindex set
-@example
-set [--abefhkmnptuvxBCEHPT] [-o @var{option}] [@var{argument} @dots{}]
-set [+abefhkmnptuvxBCEHPT] [+o @var{option}] [@var{argument} @dots{}]
-@end example
-
-If no options or arguments are supplied, @code{set} displays the names
-and values of all shell variables and functions, sorted according to the
-current locale, in a format that may be reused as input
-for setting or resetting the currently-set variables.
-Read-only variables cannot be reset.
-In @sc{posix} mode, only shell variables are listed.
-
-When options are supplied, they set or unset shell attributes.
-Options, if specified, have the following meanings:
-
-@table @code
-@item -a
-Mark variables and function which are modified or created for export
-to the environment of subsequent commands.
-
-@item -b
-Cause the status of terminated background jobs to be reported
-immediately, rather than before printing the next primary prompt.
-
-@item -e
-Exit immediately if a pipeline (@pxref{Pipelines}), which may consist
-of a single simple command (@pxref{Simple Commands}),
-a subshell command enclosed in parentheses (@pxref{Command Grouping}),
-or one of the commands executed as part of a command list enclosed
-by braces (@pxref{Command Grouping})
-returns a non-zero status.
-The shell does not exit if the command that fails is part of the
-command list immediately following a @code{while} or @code{until} keyword,
-part of the test in an @code{if} statement,
-part of any command executed in a @code{&&} or @code{||} list except
-the command following the final @code{&&} or @code{||},
-any command in a pipeline but the last,
-or if the command's return status is being inverted with @code{!}.
-A trap on @code{ERR}, if set, is executed before the shell exits.
-
-This option applies to the shell environment and each subshell environment
-separately (@pxref{Command Execution Environment}), and may cause
-subshells to exit before executing all the commands in the subshell.
-
-@item -f
-Disable filename expansion (globbing).
-
-@item -h
-Locate and remember (hash) commands as they are looked up for execution.
-This option is enabled by default.
-
-@item -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.
-
-@item -m
-Job control is enabled (@pxref{Job Control}).
-
-@item -n
-Read commands but do not execute them; this may be used to check a
-script for syntax errors.
-This option is ignored by interactive shells.
-
-@item -o @var{option-name}
-
-Set the option corresponding to @var{option-name}:
-
-@table @code
-@item allexport
-Same as @code{-a}.
-
-@item braceexpand
-Same as @code{-B}.
-
-@item emacs
-Use an @code{emacs}-style line editing interface (@pxref{Command Line Editing}).
-This also affects the editing interface used for @code{read -e}.
-
-@item errexit
-Same as @code{-e}.
-
-@item errtrace
-Same as @code{-E}.
-
-@item functrace
-Same as @code{-T}.
-
-@item hashall
-Same as @code{-h}.
-
-@item histexpand
-Same as @code{-H}.
-
-@item history
-Enable command history, as described in @ref{Bash History Facilities}.
-This option is on by default in interactive shells.
-
-@item ignoreeof
-An interactive shell will not exit upon reading EOF.
-
-@item keyword
-Same as @code{-k}.
-
-@item monitor
-Same as @code{-m}.
-
-@item noclobber
-Same as @code{-C}.
-
-@item noexec
-Same as @code{-n}.
-
-@item noglob
-Same as @code{-f}.
-
-@item nolog
-Currently ignored.
-
-@item notify
-Same as @code{-b}.
-
-@item nounset
-Same as @code{-u}.
-
-@item onecmd
-Same as @code{-t}.
-
-@item physical
-Same as @code{-P}.
-
-@item 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.
-
-@item posix
-Change the behavior of Bash where the default operation differs
-from the @sc{posix} standard to match the standard
-(@pxref{Bash POSIX Mode}).
-This is intended to make Bash behave as a strict superset of that
-standard.
-
-@item privileged
-Same as @code{-p}.
-
-@item verbose
-Same as @code{-v}.
-
-@item vi
-Use a @code{vi}-style line editing interface.
-This also affects the editing interface used for @code{read -e}.
-
-@item xtrace
-Same as @code{-x}.
-@end table
-
-@item -p
-Turn on privileged mode.
-In this mode, the @env{$BASH_ENV} and @env{$ENV} files are not
-processed, shell functions are not inherited from the environment,
-and the @env{SHELLOPTS}, @env{BASHOPTS}, @env{CDPATH} and @env{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 @code{-p} option is not supplied, these actions
-are taken and the effective user id is set to the real user id.
-If the @code{-p} 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.
-
-@item -t
-Exit after reading and executing one command.
-
-@item -u
-Treat unset variables and parameters other than the special parameters
-@samp{@@} or @samp{*} as an error when performing parameter expansion.
-An error message will be written to the standard error, and a non-interactive
-shell will exit.
-
-@item -v
-Print shell input lines as they are read.
-
-@item -x
-Print a trace of simple commands, @code{for} commands, @code{case}
-commands, @code{select} commands, and arithmetic @code{for} commands
-and their arguments or associated word lists after they are
-expanded and before they are executed.  The value of the @env{PS4}
-variable is expanded and the resultant value is printed before
-the command and its expanded arguments.
-
-@item -B
-The shell will perform brace expansion (@pxref{Brace Expansion}).
-This option is on by default.
-
-@item -C
-Prevent output redirection using @samp{>}, @samp{>&}, and @samp{<>}
-from overwriting existing files.
-
-@item -E
-If set, any trap on @code{ERR} is inherited by shell functions, command
-substitutions, and commands executed in a subshell environment.
-The @code{ERR} trap is normally not inherited in such cases.
-
-@item -H
-Enable @samp{!} style history substitution (@pxref{History Interaction}).
-This option is on by default for interactive shells.
-
-@item -P
-If set, do not follow symbolic links when performing commands such as
-@code{cd} which change the current directory.  The physical directory
-is used instead.  By default, Bash follows
-the logical chain of directories when performing commands
-which change the current directory.
-
-For example, if @file{/usr/sys} is a symbolic link to @file{/usr/local/sys}
-then:
-@example
-$ cd /usr/sys; echo $PWD
-/usr/sys
-$ cd ..; pwd
-/usr
-@end example
-
-@noindent
-If @code{set -P} is on, then:
-@example
-$ cd /usr/sys; echo $PWD
-/usr/local/sys
-$ cd ..; pwd
-/usr/local
-@end example
-
-@item -T
-If set, any trap on @code{DEBUG} and @code{RETURN} are inherited by
-shell functions, command substitutions, and commands executed
-in a subshell environment.
-The @code{DEBUG} and @code{RETURN} traps are normally not inherited
-in such cases.
-
-@item --
-If no arguments follow this option, then the positional parameters are
-unset.  Otherwise, the positional parameters are set to the
-@var{arguments}, even if some of them begin with a @samp{-}.
-
-@item -
-Signal the end of options, cause all remaining @var{arguments}
-to be assigned to the positional parameters.  The @option{-x}
-and @option{-v}  options are turned off.
-If there are no arguments, the positional parameters remain unchanged.
-@end table
-
-Using @samp{+} rather than @samp{-} causes these options to be
-turned off.  The options can also be used upon invocation of the
-shell.  The current set of options may be found in @code{$-}.
-
-The remaining N @var{arguments} are positional parameters and are
-assigned, in order, to @code{$1}, @code{$2}, @dots{}  @code{$N}.
-The special parameter @code{#} is set to N.
-
-The return status is always zero unless an invalid option is supplied.
-@end table
-
-@node The Shopt Builtin
-@subsection The Shopt Builtin
-
-This builtin allows you to change additional shell optional behavior.
-
-@table @code
-
-@item shopt
-@btindex shopt
-@example
-shopt [-pqsu] [-o] [@var{optname} @dots{}]
-@end example
-Toggle the values of variables controlling optional shell behavior.
-With no options, or with the @option{-p} option, a list of all settable
-options is displayed, with an indication of whether or not each is set.
-The @option{-p} option causes output to be displayed in a form that
-may be reused as input.
-Other options have the following meanings:
-
-@table @code
-@item -s
-Enable (set) each @var{optname}.
-
-@item -u
-Disable (unset) each @var{optname}.
-
-@item -q
-Suppresses normal output; the return status
-indicates whether the @var{optname} is set or unset.
-If multiple @var{optname} arguments are given with @option{-q},
-the return status is zero if all @var{optnames} are enabled;
-non-zero otherwise.
-
-@item -o
-Restricts the values of
-@var{optname} to be those defined for the @option{-o} option to the
-@code{set} builtin (@pxref{The Set Builtin}).
-@end table
-
-If either @option{-s} or @option{-u}
-is used with no @var{optname} arguments, the display is limited to
-those options which are set or unset, respectively.
-
-Unless otherwise noted, the @code{shopt} options are disabled (off)
-by default.
-
-The return status when listing options is zero if all @var{optnames}
-are enabled, non-zero otherwise.  When setting or unsetting options,
-the return status is zero unless an @var{optname} is not a valid shell
-option.
-
-The list of @code{shopt} options is:
-@table @code
-
-@item autocd
-If set, a command name that is the name of a directory is executed as if
-it were the argument to the @code{cd} command.
-This option is only used by interactive shells.
-
-@item cdable_vars
-If this is set, an argument to the @code{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.
-
-@item cdspell
-If set, minor errors in the spelling of a directory component in a
-@code{cd} command will be corrected.
-The errors checked for are transposed characters,
-a missing character, and a character too many.
-If a correction is found, the corrected path is printed,
-and the command proceeds.
-This option is only used by interactive shells.
-
-@item checkhash
-If this is set, Bash 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.
-
-@item checkjobs
-If set, Bash 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 (@pxref{Job Control}).
-The shell always postpones exiting if any jobs are stopped.
-
-@item checkwinsize
-If set, Bash checks the window size after each command
-and, if necessary, updates the values of    
-@env{LINES} and @env{COLUMNS}.
-
-@item cmdhist
-If set, 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.
-
-@item compat31
-If set, Bash
-changes its behavior to that of version 3.1 with respect to quoted
-arguments to the conditional command's =~ operator.
-
-@item dirspell
-If set, Bash
-attempts spelling correction on directory names during word completion 
-if the directory name initially supplied does not exist.
-
-@item dotglob
-If set, Bash includes filenames beginning with a `.' in
-the results of filename expansion.
-
-@item execfail
-If this is set, a non-interactive shell will not exit if
-it cannot execute the file specified as an argument to the @code{exec}
-builtin command.  An interactive shell does not exit if @code{exec}
-fails.
-
-@item expand_aliases
-If set, aliases are expanded as described below under Aliases,
-@ref{Aliases}.
-This option is enabled by default for interactive shells.
-
-@item extdebug
-If set, behavior intended for use by debuggers is enabled:
-
-@enumerate
-@item
-The @option{-F} option to the @code{declare} builtin (@pxref{Bash Builtins})
-displays the source file name and line number corresponding to each function
-name supplied as an argument.
-
-@item
-If the command run by the @code{DEBUG} trap returns a non-zero value, the
-next command is skipped and not executed.
-
-@item
-If the command run by the @code{DEBUG} trap returns a value of 2, and the
-shell is executing in a subroutine (a shell function or a shell script
-executed by the @code{.} or @code{source} builtins), a call to
-@code{return} is simulated.
-
-@item
-@code{BASH_ARGC} and @code{BASH_ARGV} are updated as described in their
-descriptions (@pxref{Bash Variables}).
-
-@item
-Function tracing is enabled:  command substitution, shell functions, and
-subshells invoked with @code{( @var{command} )} inherit the
-@code{DEBUG} and @code{RETURN} traps.
-
-@item
-Error tracing is enabled:  command substitution, shell functions, and
-subshells invoked with @code{( @var{command} )} inherit the
-@code{ERROR} trap.
-@end enumerate
-
-@item extglob
-If set, the extended pattern matching features described above
-(@pxref{Pattern Matching}) are enabled.
-
-@item extquote
-If set, @code{$'@var{string}'} and @code{$"@var{string}"} quoting is  
-performed within @code{$@{@var{parameter}@}} expansions                     
-enclosed in double quotes.  This option is enabled by default. 
-
-@item failglob
-If set, patterns which fail to match filenames during filename expansion
-result in an expansion error.
-
-@item force_fignore
-If set, the suffixes specified by the @env{FIGNORE} shell variable
-cause words to be ignored when performing word completion even if
-the ignored words are the only possible completions.
-@xref{Bash Variables}, for a description of @env{FIGNORE}.
-This option is enabled by default.
-
-@item globstar
-If set, the pattern @samp{**} used in a filename expansion context will
-match a files and zero or more directories and subdirectories.
-If the pattern is followed by a @samp{/}, only directories and
-subdirectories match.
-
-@item gnu_errfmt
-If set, shell error messages are written in the standard @sc{gnu} error
-message format.
-
-@item histappend
-If set, the history list is appended to the file named by the value
-of the @env{HISTFILE}
-variable when the shell exits, rather than overwriting the file.
-
-@item histreedit
-If set, and Readline
-is being used, a user is given the opportunity to re-edit a
-failed history substitution.
-
-@item histverify
-If set, and 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 Readline editing buffer, allowing further modification.
-
-@item hostcomplete
-If set, and Readline is being used, Bash will attempt to perform
-hostname completion when a word containing a @samp{@@} is being
-completed (@pxref{Commands For Completion}).  This option is enabled
-by default.
-
-@item huponexit
-If set, Bash will send @code{SIGHUP} to all jobs when an interactive
-login shell exits (@pxref{Signals}).
-
-@item interactive_comments
-Allow a word beginning with @samp{#}
-to cause that word and all remaining characters on that
-line to be ignored in an interactive shell.
-This option is enabled by default.
-
-@item lithist
-If enabled, and the @code{cmdhist}
-option is enabled, multi-line commands are saved to the history with
-embedded newlines rather than using semicolon separators where possible.
-
-@item login_shell
-The shell sets this option if it is started as a login shell
-(@pxref{Invoking Bash}).
-The value may not be changed.
-
-@item mailwarn
-If set, and a file that Bash is checking for mail has been  
-accessed since the last time it was checked, the message
-@code{"The mail in @var{mailfile} has been read"} is displayed.
-
-@item no_empty_cmd_completion
-If set, and Readline is being used, Bash will not attempt to search
-the @env{PATH} for possible completions when completion is attempted
-on an empty line.
-
-@item nocaseglob
-If set, Bash matches filenames in a case-insensitive fashion when
-performing filename expansion.
-
-@item nocasematch
-If set, Bash matches patterns in a case-insensitive fashion when
-performing matching while executing @code{case} or @code{[[}
-conditional commands.
-
-@item nullglob
-If set, Bash allows filename patterns which match no
-files to expand to a null string, rather than themselves.
-
-@item progcomp
-If set, the programmable completion facilities
-(@pxref{Programmable Completion}) are enabled.
-This option is enabled by default.
-
-@item promptvars
-If set, prompt strings undergo
-parameter expansion, command substitution, arithmetic
-expansion, and quote removal after being expanded
-as described below (@pxref{Printing a Prompt}).
-This option is enabled by default.
-
-@item restricted_shell
-The shell sets this option if it is started in restricted mode
-(@pxref{The Restricted Shell}).
-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.
-
-@item shift_verbose
-If this is set, the @code{shift}
-builtin prints an error message when the shift count exceeds the
-number of positional parameters.
-
-@item sourcepath
-If set, the @code{source} builtin uses the value of @env{PATH}
-to find the directory containing the file supplied as an argument.
-This option is enabled by default.
-
-@item xpg_echo
-If set, the @code{echo} builtin expands backslash-escape sequences
-by default.
-
-@end table
-
-@noindent
-The return status when listing options is zero if all @var{optnames}
-are enabled, non-zero otherwise.
-When setting or unsetting options, the return status is zero unless an
-@var{optname} is not a valid shell option.
-
-@end table
-
-@node Special Builtins
-@section Special Builtins
-@cindex special builtin
-
-For historical reasons, the @sc{posix} standard has classified
-several builtin commands as @emph{special}.
-When Bash is executing in @sc{posix} mode, the special builtins
-differ from other builtin commands in three respects:
-
-@enumerate
-@item
-Special builtins are found before shell functions during command lookup.
-
-@item
-If a special builtin returns an error status, a non-interactive shell exits.
-
-@item
-Assignment statements preceding the command stay in effect in the shell
-environment after the command completes.
-@end enumerate
-
-When Bash is not executing in @sc{posix} mode, these builtins behave no
-differently than the rest of the Bash builtin commands.
-The Bash @sc{posix} mode is described in @ref{Bash POSIX Mode}. 
-
-These are the @sc{posix} special builtins:
-@example
-@w{break : . continue eval exec exit export readonly return set}
-@w{shift trap unset}
-@end example
-
-@node Shell Variables
-@chapter Shell Variables
-
-@menu
-* Bourne Shell Variables::     Variables which Bash uses in the same way
-                               as the Bourne Shell.
-* Bash Variables::             List of variables that exist in Bash.
-@end menu
-
-This chapter describes the shell variables that Bash uses.
-Bash automatically assigns default values to a number of variables.
-
-@node Bourne Shell Variables
-@section Bourne Shell Variables
-
-Bash uses certain shell variables in the same way as the Bourne shell.
-In some cases, Bash assigns a default value to the variable.
-
-@vtable @code
-
-@item CDPATH
-A colon-separated list of directories used as a search path for
-the @code{cd} builtin command.
-
-@item HOME
-The current user's home directory; the default for the @code{cd} builtin
-command.
-The value of this variable is also used by tilde expansion
-(@pxref{Tilde Expansion}).
-
-@item IFS
-A list of characters that separate fields; used when the shell splits
-words as part of expansion.
-
-@item MAIL
-If this parameter is set to a filename and the @env{MAILPATH} variable
-is not set, Bash informs the user of the arrival of mail in
-the specified file.
-
-@item MAILPATH
-A colon-separated list of filenames which the shell periodically checks
-for new mail.
-Each list entry can specify the message that is printed when new mail
-arrives in the mail file by separating the file name from the message with
-a @samp{?}.
-When used in the text of the message, @code{$_} expands to the name of
-the current mail file.
-
-@item OPTARG
-The value of the last option argument processed by the @code{getopts} builtin.
-
-@item OPTIND
-The index of the last option argument processed by the @code{getopts} builtin.
-
-@item PATH
-A colon-separated list of directories in which the shell looks for
-commands.
-A zero-length (null) directory name in the value of @code{PATH} indicates the
-current directory.
-A null directory name may appear as two adjacent colons, or as an initial
-or trailing colon.
-
-
-@item PS1
-The primary prompt string.  The default value is @samp{\s-\v\$ }.
-@xref{Printing a Prompt}, for the complete list of escape
-sequences that are expanded before @env{PS1} is displayed.
-
-@item PS2
-The secondary prompt string.  The default value is @samp{> }.
-
-@end vtable
-
-@node Bash Variables
-@section Bash Variables
-
-These variables are set or used by Bash, but other shells
-do not normally treat them specially.
-
-A few variables used by Bash are described in different chapters:
-variables for controlling the job control facilities
-(@pxref{Job Control Variables}).
-
-@vtable @code
-
-@item BASH
-The full pathname used to execute the current instance of Bash.
-
-@item BASHOPTS
-A colon-separated list of enabled shell options.  Each word in
-the list is a valid argument for the @option{-s} option to the
-@code{shopt} builtin command (@pxref{The Shopt Builtin}).
-The options appearing in @env{BASHOPTS} are those reported
-as @samp{on} by @samp{shopt}.
-If this variable is in the environment when Bash
-starts up, each shell option in the list will be enabled before
-reading any startup files.  This variable is readonly.
-
-@item BASHPID
-Expands to the process id of the current Bash process.
-This differs from @code{$$} under certain circumstances, such as subshells
-that do not require Bash to be re-initialized.
-
-@item BASH_ALIASES
-An associative array variable whose members correspond to the internal
-list of aliases as maintained by the @code{alias} builtin
-(@pxref{Bourne Shell Builtins}).
-Elements added to this array appear in the alias list; unsetting array
-elements cause aliases to be removed from the alias list.
-
-@item BASH_ARGC
-An array variable whose values are the number of parameters in each
-frame of the current bash execution call stack.  The number of
-parameters to the current subroutine (shell function or script executed
-with @code{.} or @code{source}) is at the top of the stack.  When a
-subroutine is executed, the number of parameters passed is pushed onto
-@code{BASH_ARGC}.
-The shell sets @code{BASH_ARGC} only when in extended debugging mode
-(see @ref{The Shopt Builtin}
-for a description of the @code{extdebug} option to the @code{shopt}
-builtin).
-
-@item BASH_ARGV
-An array variable containing all of the parameters in the current bash
-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 @code{BASH_ARGV}.
-The shell sets @code{BASH_ARGV} only when in extended debugging mode
-(see @ref{The Shopt Builtin}
-for a description of the @code{extdebug} option to the @code{shopt}
-builtin).
-
-@item BASH_CMDS
-An associative array variable whose members correspond to the internal
-hash table of commands as maintained by the @code{hash} builtin
-(@pxref{Bourne Shell Builtins}).
-Elements added to this array appear in the hash table; unsetting array
-elements cause commands to be removed from the hash table.
-
-@item 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.
-
-@item BASH_ENV
-If this variable is set when Bash is invoked to execute a shell
-script, its value is expanded and used as the name of a startup file
-to read before executing the script.  @xref{Bash Startup Files}.
-
-@item BASH_EXECUTION_STRING
-The command argument to the @option{-c} invocation option.
-
-@item BASH_LINENO
-An array variable whose members are the line numbers in source files
-corresponding to each member of @var{FUNCNAME}.
-@code{$@{BASH_LINENO[$i]@}} is the line number in the source file where
-@code{$@{FUNCNAME[$i]@}} was called (or @code{$@{BASH_LINENO[$i-1]@}} if
-referenced within another shell function).
-The corresponding source file name is @code{$@{BASH_SOURCE[$i]@}}.
-Use @code{LINENO} to obtain the current line number.
-
-@item BASH_REMATCH
-An array variable whose members are assigned by the @samp{=~} binary
-operator to the @code{[[} conditional command
-(@pxref{Conditional Constructs}).
-The element with index 0 is the portion of the string
-matching the entire regular expression.
-The element with index @var{n} is the portion of the
-string matching the @var{n}th parenthesized subexpression.
-This variable is read-only.
-
-@item BASH_SOURCE
-An array variable whose members are the source filenames corresponding
-to the elements in the @code{FUNCNAME} array variable.
-
-@item BASH_SUBSHELL
-Incremented by one each time a subshell or subshell environment is spawned.
-The initial value is 0.
-
-@item BASH_VERSINFO
-A readonly array variable (@pxref{Arrays})
-whose members hold version information for this instance of Bash.
-The values assigned to the array members are as follows:
-
-@table @code
-
-@item BASH_VERSINFO[0]
-The major version number (the @var{release}).
-
-@item BASH_VERSINFO[1]
-The minor version number (the @var{version}).
-
-@item BASH_VERSINFO[2]
-The patch level.
-
-@item BASH_VERSINFO[3]
-The build version.
-
-@item BASH_VERSINFO[4]
-The release status (e.g., @var{beta1}).
-
-@item BASH_VERSINFO[5]
-The value of @env{MACHTYPE}.
-
-@end table
-
-@item BASH_VERSION
-The version number of the current instance of Bash.
-
-@item BASH_XTRACEFD
-If set to an integer corresponding to a valid file descriptor, Bash
-will write the trace output generated when @samp{set -x}
-is enabled to that file descriptor.
-This allows tracing output to be separated from diagnostic and error
-messages.
-The file descriptor is closed when @code{BASH_XTRACEFD} is unset or assigned
-a new value.
-Unsetting @code{BASH_XTRACEFD} or assigning it the empty string causes the
-trace output to be sent to the standard error.
-Note that setting @code{BASH_XTRACEFD} to 2 (the standard error file
-descriptor) and then unsetting it will result in the standard error
-being closed.
-
-@item COLUMNS
-Used by the @code{select} builtin command to determine the terminal width
-when printing selection lists.  Automatically set upon receipt of a
-@code{SIGWINCH}.
-
-@item COMP_CWORD
-An index into @env{$@{COMP_WORDS@}} of the word containing the current
-cursor position.
-This variable is available only in shell functions invoked by the
-programmable completion facilities (@pxref{Programmable Completion}).
-
-@item COMP_LINE
-The current command line.
-This variable is available only in shell functions and external
-commands invoked by the
-programmable completion facilities (@pxref{Programmable Completion}).
-
-@item 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 @code{$@{#COMP_LINE@}}.
-This variable is available only in shell functions and external
-commands invoked by the
-programmable completion facilities (@pxref{Programmable Completion}).
-
-@item COMP_TYPE
-Set to an integer value corresponding to the type of completion attempted
-that caused a completion function to be called:
-@var{TAB}, for normal completion,
-@samp{?}, for listing completions after successive tabs,
-@samp{!}, for listing alternatives on partial word completion,
-@samp{@@}, to list completions if the word is not unmodified,
-or
-@samp{%}, for menu completion.
-This variable is available only in shell functions and external
-commands invoked by the
-programmable completion facilities (@pxref{Programmable Completion}).
-
-@item COMP_KEY
-The key (or final key of a key sequence) used to invoke the current
-completion function.
-
-@item COMP_WORDBREAKS
-The set of characters that the Readline library treats as word
-separators when performing word completion.
-If @code{COMP_WORDBREAKS} is unset, it loses its special properties,
-even if it is subsequently reset.
-
-@item COMP_WORDS
-An array variable consisting of the individual
-words in the current command line.
-The line is split into words as Readline would split it, using
-@code{COMP_WORDBREAKS} as described above.
-This variable is available only in shell functions invoked by the
-programmable completion facilities (@pxref{Programmable Completion}).
-
-@item COMPREPLY
-An array variable from which Bash reads the possible completions
-generated by a shell function invoked by the programmable completion
-facility (@pxref{Programmable Completion}).
-
-@item DIRSTACK
-An array variable containing the current contents of the directory stack.
-Directories appear in the stack in the order they are displayed by the
-@code{dirs} builtin.
-Assigning to members of this array variable may be used to modify
-directories already in the stack, but the @code{pushd} and @code{popd}
-builtins must be used to add and remove directories.
-Assignment to this variable will not change the current directory.
-If @env{DIRSTACK} is unset, it loses its special properties, even if
-it is subsequently reset.
-
-@item EMACS
-If Bash finds this variable in the environment when the shell
-starts with value @samp{t}, it assumes that the shell is running in an
-emacs shell buffer and disables line editing.
-
-@item EUID
-The numeric effective user id of the current user.  This variable
-is readonly.
-
-@item FCEDIT
-The editor used as a default by the @option{-e} option to the @code{fc}
-builtin command.
-
-@item FIGNORE
-A colon-separated list of suffixes to ignore when performing
-filename completion.
-A file name whose suffix matches one of the entries in 
-@env{FIGNORE}
-is excluded from the list of matched file names.  A sample
-value is @samp{.o:~}
-
-@item 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 is @code{"main"}.
-This variable exists only when a shell function is executing.
-Assignments to @env{FUNCNAME} have no effect and return an error status.
-If @env{FUNCNAME} is unset, it loses its special properties, even if
-it is subsequently reset.
-
-@item GLOBIGNORE
-A colon-separated list of patterns defining the set of filenames to
-be ignored by filename expansion.
-If a filename matched by a filename expansion pattern also matches one
-of the patterns in @env{GLOBIGNORE}, it is removed from the list
-of matches.
-
-@item GROUPS
-An array variable containing the list of groups of which the current    
-user is a member.
-Assignments to @env{GROUPS} have no effect and return an error status.
-If @env{GROUPS} is unset, it loses its special properties, even if it is
-subsequently reset.
-
-@item histchars
-Up to three characters which control history expansion, quick
-substitution, and tokenization (@pxref{History Interaction}).
-The first character is the
-@var{history expansion} character, that is, the character which signifies the
-start of a history expansion, normally @samp{!}.  The second character is the
-character which signifies `quick substitution' when seen as the first
-character on a line, normally @samp{^}.  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, usually @samp{#}.  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.
-
-@item HISTCMD
-The history number, or index in the history list, of the current
-command.  If @env{HISTCMD} is unset, it loses its special properties,
-even if it is subsequently reset.
-
-@item HISTCONTROL
-A colon-separated list of values controlling how commands are saved on
-the history list.
-If the list of values includes @samp{ignorespace}, lines which begin
-with a space character are not saved in the history list.
-A value of @samp{ignoredups} causes lines which match the previous
-history entry to not be saved.
-A value of @samp{ignoreboth} is shorthand for
-@samp{ignorespace} and @samp{ignoredups}.
-A value of @samp{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 @env{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 @env{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
-@env{HISTCONTROL}.
-
-@item HISTFILE
-The name of the file to which the command history is saved.  The
-default value is @file{~/.bash_history}.
-
-@item 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, by removing the oldest entries,
-to contain no more than that number of lines.
-The history file is also truncated to this size after
-writing it when an interactive shell exits.
-The default value is 500.
-
-@item 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 @samp{*} is appended).  Each pattern is tested
-against the line after the checks specified by @env{HISTCONTROL}
-are applied.  In addition to the normal shell pattern matching
-characters, @samp{&} matches the previous history line.  @samp{&}
-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
-@env{HISTIGNORE}.
-
-@env{HISTIGNORE} subsumes the function of @env{HISTCONTROL}.  A
-pattern of @samp{&} is identical to @code{ignoredups}, and a
-pattern of @samp{[ ]*} is identical to @code{ignorespace}. 
-Combining these two patterns, separating them with a colon,
-provides the functionality of @code{ignoreboth}. 
-
-@item HISTSIZE
-The maximum number of commands to remember on the history list.
-The default value is 500.
-
-@item HISTTIMEFORMAT
-If this variable is set and not null, its value is used as a format string
-for @var{strftime} to print the time stamp associated with each history
-entry displayed by the @code{history} 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.
-
-@item HOSTFILE
-Contains the name of a file in the same format as @file{/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, Bash adds the contents of the new file to the
-existing list.
-If @env{HOSTFILE} is set, but has no value, or does not name a readable file,
-Bash attempts to read 
-@file{/etc/hosts} to obtain the list of possible hostname completions.
-When @env{HOSTFILE} is unset, the hostname list is cleared.
-
-@item HOSTNAME
-The name of the current host.
-
-@item HOSTTYPE
-A string describing the machine Bash is running on.
-
-@item IGNOREEOF
-Controls the action of the shell on receipt of an @code{EOF} character
-as the sole input.  If set, the value denotes the number
-of consecutive @code{EOF} characters that can be read as the
-first character on an input line
-before the shell will exit.  If the variable exists but does not
-have a numeric value (or has no value) then the default is 10.
-If the variable does not exist, then @code{EOF} signifies the end of 
-input to the shell.  This is only in effect for interactive shells.
-
-@item INPUTRC
-The name of the Readline initialization file, overriding the default
-of @file{~/.inputrc}.
-
-@item LANG  
-Used to determine the locale category for any category not specifically
-selected with a variable starting with @code{LC_}.
-
-@item LC_ALL
-This variable overrides the value of @env{LANG} and any other
-@code{LC_} variable specifying a locale category.
-
-@item LC_COLLATE
-This variable determines the collation order used when sorting the
-results of filename expansion, and
-determines the behavior of range expressions, equivalence classes,
-and collating sequences within filename expansion and pattern matching
-(@pxref{Filename Expansion}).
-
-@item LC_CTYPE
-This variable determines the interpretation of characters and the
-behavior of character classes within filename expansion and pattern
-matching (@pxref{Filename Expansion}).
-
-@item LC_MESSAGES
-This variable determines the locale used to translate double-quoted
-strings preceded by a @samp{$} (@pxref{Locale Translation}).
-
-@item LC_NUMERIC
-This variable determines the locale category used for number formatting.
-
-@item LINENO
-The line number in the script or shell function currently executing.
-
-@item LINES
-Used by the @code{select} builtin command to determine the column length
-for printing selection lists.  Automatically set upon receipt of a
-@code{SIGWINCH}.
-
-@item MACHTYPE
-A string that fully describes the system type on which Bash
-is executing, in the standard @sc{gnu} @var{cpu-company-system} format.
-
-@item MAILCHECK
-How often (in seconds) that the shell should check for mail in the
-files specified in the @env{MAILPATH} or @env{MAIL} variables.
-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.
-
-@item OLDPWD
-The previous working directory as set by the @code{cd} builtin.
-
-@item OPTERR
-If set to the value 1, Bash displays error messages
-generated by the @code{getopts} builtin command.
-
-@item OSTYPE
-A string describing the operating system Bash is running on.
-
-@item PIPESTATUS
-An array variable (@pxref{Arrays})
-containing a list of exit status values from the processes
-in the most-recently-executed foreground pipeline (which may
-contain only a single command).
-
-@item POSIXLY_CORRECT
-If this variable is in the environment when @code{bash} starts, the shell
-enters @sc{posix} mode (@pxref{Bash POSIX Mode}) before reading the
-startup files, as if the @option{--posix} invocation option had been supplied.
-If it is set while the shell is running, @code{bash} enables @sc{posix} mode,
-as if the command
-@example
-@code{set -o posix}
-@end example
-@noindent
-had been executed.  
-
-@item PPID
-The process @sc{id} of the shell's parent process.  This variable
-is readonly.
-
-@item PROMPT_COMMAND
-If set, the value is interpreted as a command to execute
-before the printing of each primary prompt (@env{$PS1}).
-
-@item 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 @code{\w} and
-@code{\W} prompt string escapes (@pxref{Printing a Prompt}).
-Characters removed are replaced with an ellipsis.
-
-@item PS3
-The value of this variable is used as the prompt for the
-@code{select} command.  If this variable is not set, the
-@code{select} command prompts with @samp{#? }
-
-@item PS4
-The value is the prompt printed before the command line is echoed
-when the @option{-x} option is set (@pxref{The Set Builtin}).
-The first character of @env{PS4} is replicated multiple times, as
-necessary, to indicate multiple levels of indirection.
-The default is @samp{+ }.
-
-@item PWD
-The current working directory as set by the @code{cd} builtin.
-
-@item RANDOM
-Each time this parameter is referenced, a random integer
-between 0 and 32767 is generated.  Assigning a value to this
-variable seeds the random number generator.
-
-@item REPLY
-The default variable for the @code{read} builtin.
-
-@item SECONDS
-This variable expands to the number of seconds since the
-shell was started.  Assignment to this variable resets
-the count to the value assigned, and the expanded value
-becomes the value assigned plus the number of seconds
-since the assignment.
-
-@item SHELL
-The full pathname to the shell is kept in this environment variable.
-If it is not set when the shell starts,
-Bash assigns to it the full pathname of the current user's login shell.
-
-@item SHELLOPTS
-A colon-separated list of enabled shell options.  Each word in
-the list is a valid argument for the @option{-o} option to the
-@code{set} builtin command (@pxref{The Set Builtin}).
-The options appearing in @env{SHELLOPTS} are those reported
-as @samp{on} by @samp{set -o}.
-If this variable is in the environment when Bash
-starts up, each shell option in the list will be enabled before
-reading any startup files.  This variable is readonly.
-
-@item SHLVL
-Incremented by one each time a new instance of Bash is started.  This is
-intended to be a count of how deeply your Bash shells are nested.
-
-@item TIMEFORMAT
-The value of this parameter is used as a format string specifying
-how the timing information for pipelines prefixed with the @code{time}
-reserved word should be displayed.
-The @samp{%} 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. 
-
-@table @code
-
-@item %%
-A literal @samp{%}.
-
-@item %[@var{p}][l]R
-The elapsed time in seconds. 
-
-@item %[@var{p}][l]U
-The number of CPU seconds spent in user mode. 
-
-@item %[@var{p}][l]S
-The number of CPU seconds spent in system mode. 
-
-@item %P
-The CPU percentage, computed as (%U + %S) / %R. 
-@end table
-
-The optional @var{p} is a digit specifying the precision, 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 @var{p} greater than 3 are changed to 3.
-If @var{p} is not specified, the value 3 is used. 
-
-The optional @code{l} specifies a longer format, including minutes, of
-the form @var{MM}m@var{SS}.@var{FF}s.
-The value of @var{p} determines whether or not the fraction is included. 
-
-If this variable is not set, Bash acts as if it had the value
-@example
-@code{$'\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS'}
-@end example
-If the value is null, no timing information is displayed.
-A trailing newline is added when the format string is displayed.
-
-@item TMOUT
-If set to a value greater than zero, @code{TMOUT} is treated as the
-default timeout for the @code{read} builtin (@pxref{Bash Builtins}).
-The @code{select} command (@pxref{Conditional Constructs}) terminates
-if input does not arrive after @code{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 input after issuing the primary
-prompt when the shell is interactive.
-Bash terminates after that number of seconds if input does
-not arrive.
-
-@item TMPDIR
-If set, Bash uses its value as the name of a directory in which
-Bash creates temporary files for the shell's use.
-
-@item UID
-The numeric real user id of the current user.  This variable is readonly.
-
-@end vtable
-
-@node Bash Features
-@chapter Bash Features
-
-This section describes features unique to Bash.
-
-@menu
-* Invoking Bash::              Command line options that you can give
-                               to Bash.
-* Bash Startup Files::         When and how Bash executes scripts.
-* Interactive Shells::         What an interactive shell is.
-* Bash Conditional Expressions::       Primitives used in composing expressions for
-                               the @code{test} builtin.
-* Shell Arithmetic::           Arithmetic on shell variables.
-* Aliases::                    Substituting one command for another.
-* Arrays::                     Array Variables.
-* The Directory Stack::                History of visited directories.
-* Printing a Prompt::          Controlling the PS1 string.
-* The Restricted Shell::       A more controlled mode of shell execution.
-* Bash POSIX Mode::            Making Bash behave more closely to what
-                               the POSIX standard specifies.
-@end menu
-
-@node Invoking Bash
-@section Invoking Bash
-
-@example
-bash [long-opt] [-ir] [-abefhkmnptuvxdBCDHP] [-o @var{option}] [-O @var{shopt_option}] [@var{argument} @dots{}]
-bash [long-opt] [-abefhkmnptuvxdBCDHP] [-o @var{option}] [-O @var{shopt_option}] -c @var{string} [@var{argument} @dots{}]
-bash [long-opt] -s [-abefhkmnptuvxdBCDHP] [-o @var{option}] [-O @var{shopt_option}] [@var{argument} @dots{}]
-@end example
-
-In addition to the single-character shell command-line options
-(@pxref{The Set Builtin}), there are several multi-character
-options that you can use.  These options must appear on the command
-line before the single-character options to be recognized. 
-
-@table @code
-@item --debugger
-Arrange for the debugger profile to be executed before the shell
-starts.  Turns on extended debugging mode (see @ref{The Shopt Builtin}
-for a description of the @code{extdebug} option to the @code{shopt}
-builtin) and shell function tracing
-(see @ref{The Set Builtin} for a description of the @code{-o functrace}
-option).
-
-@item --dump-po-strings
-A list of all double-quoted strings preceded by @samp{$}
-is printed on the standard output
-in the @sc{gnu} @code{gettext} PO (portable object) file format.
-Equivalent to @option{-D} except for the output format.
-
-@item --dump-strings
-Equivalent to @option{-D}.
-
-@item --help
-Display a usage message on standard output and exit successfully.
-
-@item --init-file @var{filename}
-@itemx --rcfile @var{filename}
-Execute commands from @var{filename} (instead of @file{~/.bashrc})
-in an interactive shell.
-
-@item --login
-Equivalent to @option{-l}.
-
-@item --noediting
-Do not use the @sc{gnu} Readline library (@pxref{Command Line Editing})
-to read  command lines when the shell is interactive.
-
-@item --noprofile
-Don't load the system-wide startup file @file{/etc/profile}
-or any of the personal initialization files
-@file{~/.bash_profile}, @file{~/.bash_login}, or @file{~/.profile}
-when Bash is invoked as a login shell.
-
-@item --norc
-Don't read the @file{~/.bashrc} initialization file in an
-interactive shell.  This is on by default if the shell is
-invoked as @code{sh}.
-
-@item --posix
-Change the behavior of Bash where the default operation differs
-from the @sc{posix} standard to match the standard.  This
-is intended to make Bash behave as a strict superset of that
-standard.  @xref{Bash POSIX Mode}, for a description of the Bash
-@sc{posix} mode.
-
-@item --restricted
-Make the shell a restricted shell (@pxref{The Restricted Shell}).
-
-@item --verbose
-Equivalent to @option{-v}.  Print shell input lines as they're read.
-
-@item --version
-Show version information for this instance of
-Bash on the standard output and exit successfully.
-
-@end table
-
-There are several single-character options that may be supplied at
-invocation which are not available with the @code{set} builtin.
-
-@table @code
-@item -c @var{string}
-Read and execute commands from @var{string} after processing the
-options, then exit.  Any remaining arguments are assigned to the
-positional parameters, starting with @code{$0}.
-
-@item -i
-Force the shell to run interactively.  Interactive shells are
-described in @ref{Interactive Shells}.
-
-@item -l
-Make this shell act as if it had been directly invoked by login.
-When the shell is interactive, this is equivalent to starting a
-login shell with @samp{exec -l bash}.
-When the shell is not interactive, the login shell startup files will
-be executed.
-@samp{exec bash -l} or @samp{exec bash --login}
-will replace the current shell with a Bash login shell.
-@xref{Bash Startup Files}, for a description of the special behavior
-of a login shell.
-
-@item -r
-Make the shell a restricted shell (@pxref{The Restricted Shell}).
-
-@item -s
-If this 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.
-
-@item -D
-A list of all double-quoted strings preceded by @samp{$}
-is printed on the standard output.
-These are the strings that
-are subject to language translation when the current locale
-is not @code{C} or @code{POSIX} (@pxref{Locale Translation}).
-This implies the @option{-n} option; no commands will be executed.
-
-@item [-+]O [@var{shopt_option}]
-@var{shopt_option} is one of the shell options accepted by the
-@code{shopt} builtin (@pxref{The Shopt Builtin}).
-If @var{shopt_option} is present, @option{-O} sets the value of that option;
-@option{+O} unsets it.  
-If @var{shopt_option} is not supplied, the names and values of the shell
-options accepted by @code{shopt} are printed on the standard output.
-If the invocation option is @option{+O}, the output is displayed in a format
-that may be reused as input.
-
-@item --
-A @code{--} signals the end of options and disables further option
-processing.
-Any arguments after the @code{--} are treated as filenames and arguments.
-
-@end table
-
-@cindex login shell
-A @emph{login} shell is one whose first character of argument zero is
-@samp{-}, or one invoked with the @option{--login} option.
-
-@cindex interactive shell
-An @emph{interactive} shell is one started without non-option arguments,
-unless @option{-s} is specified,
-without specifying the @option{-c} option, and whose input and output are both
-connected to terminals (as determined by @code{isatty(3)}), or one
-started with the @option{-i} option.  @xref{Interactive Shells}, for more
-information.
-
-If arguments remain after option processing, and neither the
-@option{-c} nor the @option{-s}
-option has been supplied, the first argument is assumed to
-be the name of a file containing shell commands (@pxref{Shell Scripts}).
-When Bash is invoked in this fashion, @code{$0}
-is set to the name of the file, and the positional parameters
-are set to the remaining arguments.
-Bash reads and executes commands from this file, then exits.   
-Bash'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.
-
-@node Bash Startup Files
-@section Bash Startup Files
-@cindex startup files
-
-This section describes how Bash executes its startup files.
-If any of the files exist but cannot be read, Bash reports an error.
-Tildes are expanded in file names as described above under
-Tilde Expansion (@pxref{Tilde Expansion}).
-
-Interactive shells are described in @ref{Interactive Shells}.
-
-@subsubheading Invoked as an interactive login shell, or with @option{--login}
-
-When Bash is invoked as an interactive login shell, or as a
-non-interactive shell with the @option{--login} option, it first reads and
-executes commands from the file @file{/etc/profile}, if that file exists.
-After reading that file, it looks for @file{~/.bash_profile},
-@file{~/.bash_login}, and @file{~/.profile}, in that order, and reads
-and executes commands from the first one that exists and is readable.
-The @option{--noprofile} option may be used when the shell is started to
-inhibit this behavior.
-
-When a login shell exits, Bash reads and executes commands from
-the file @file{~/.bash_logout}, if it exists.
-
-@subsubheading Invoked as an interactive non-login shell
-
-When an interactive shell that is not a login shell is started, Bash
-reads and executes commands from @file{~/.bashrc}, if that file exists.
-This may be inhibited by using the @option{--norc} option.
-The @option{--rcfile @var{file}} option will force Bash to read and
-execute commands from @var{file} instead of @file{~/.bashrc}.
-
-So, typically, your @file{~/.bash_profile} contains the line
-@example
-@code{if [ -f ~/.bashrc ]; then . ~/.bashrc; fi}
-@end example
-@noindent
-after (or before) any login-specific initializations.
-
-@subsubheading Invoked non-interactively
-
-When Bash is started non-interactively, to run a shell script,
-for example, it looks for the variable @env{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.  Bash behaves as if the
-following command were executed:
-@example
-@code{if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi}
-@end example
-@noindent
-but the value of the @env{PATH} variable is not used to search for the
-file name.
-
-As noted above, if a non-interactive shell is invoked with the
-@option{--login} option, Bash attempts to read and execute commands from the
-login shell startup files. 
-
-@subsubheading Invoked with name @code{sh}
-
-If Bash is invoked with the name @code{sh}, it tries to mimic the
-startup behavior of historical versions of @code{sh} as closely as
-possible, while conforming to the @sc{posix} standard as well.
-
-When invoked as an interactive login shell, or as a non-interactive
-shell with the @option{--login} option, it first attempts to read
-and execute commands from @file{/etc/profile} and @file{~/.profile}, in
-that order.
-The @option{--noprofile} option may be used to inhibit this behavior.
-When invoked as an interactive shell with the name @code{sh}, Bash
-looks for the variable @env{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 @code{sh} does not attempt to read and execute
-commands from any other startup files, the @option{--rcfile} option has
-no effect.
-A non-interactive shell invoked with the name @code{sh} does not attempt
-to read any other startup files.
-
-When invoked as @code{sh}, Bash enters @sc{posix} mode after
-the startup files are read.
-
-@subsubheading Invoked in @sc{posix} mode
-
-When Bash is started in @sc{posix} mode, as with the
-@option{--posix} command line option, it follows the @sc{posix} standard
-for startup files.
-In this mode, interactive shells expand the @env{ENV} variable
-and commands are read and executed from the file whose name is the
-expanded value.
-No other startup files are read.
-
-@subsubheading Invoked by remote shell daemon
-
-Bash attempts to determine when it is being run with its standard input
-connected to a a network connection, as if by the remote shell
-daemon, usually @code{rshd}, or the secure shell daemon @code{sshd}.
-If Bash determines it is being run in
-this fashion, it reads and executes commands from @file{~/.bashrc}, if that
-file exists and is readable.
-It will not do this if invoked as @code{sh}.
-The @option{--norc} option may be used to inhibit this behavior, and the
-@option{--rcfile} option may be used to force another file to be read, but
-@code{rshd} does not generally invoke the shell with those options or
-allow them to be specified.
-
-@subsubheading Invoked with unequal effective and real @sc{uid/gid}s
-
-If Bash is started with the effective user (group) id not equal to the
-real user (group) id, and the @code{-p} option is not supplied, no startup
-files are read, shell functions are not inherited from the environment,
-the @env{SHELLOPTS}, @env{BASHOPTS}, @env{CDPATH}, and @env{GLOBIGNORE}
-variables, if they appear in the environment, are ignored, and the effective
-user id is set to the real user id.
-If the @code{-p} option is supplied at invocation, the startup behavior is
-the same, but the effective user id is not reset.
-
-@node Interactive Shells
-@section Interactive Shells
-@cindex interactive shell
-@cindex shell, interactive
-
-@menu
-* What is an Interactive Shell?::      What determines whether a shell is Interactive.
-* Is this Shell Interactive?:: How to tell if a shell is interactive.
-* Interactive Shell Behavior:: What changes in a interactive shell?
-@end menu
-
-@node What is an Interactive Shell?
-@subsection What is an Interactive Shell?
-
-An interactive shell
-is one started without non-option arguments, unless @option{-s} is
-specified, without specifying the @option{-c} option, and
-whose input and error output are both
-connected to terminals (as determined by @code{isatty(3)}),
-or one started with the @option{-i} option.
-
-An interactive shell generally reads from and writes to a user's
-terminal.
-
-The @option{-s} invocation option may be used to set the positional parameters
-when an interactive shell is started.
-
-@node Is this Shell Interactive?
-@subsection Is this Shell Interactive?
-
-To determine within a startup script whether or not Bash is
-running interactively,
-test the value of the @samp{-} special parameter.
-It contains @code{i} when the shell is interactive.  For example:
-
-@example
-case "$-" in
-*i*)   echo This shell is interactive ;;
-*)     echo This shell is not interactive ;;
-esac
-@end example
-
-Alternatively, startup scripts may examine the variable
-@env{PS1}; it is unset in non-interactive shells, and set in
-interactive shells.  Thus:
-
-@example
-if [ -z "$PS1" ]; then
-        echo This shell is not interactive
-else
-        echo This shell is interactive
-fi
-@end example
-
-@node Interactive Shell Behavior
-@subsection Interactive Shell Behavior
-
-When the shell is running interactively, it changes its behavior in
-several ways.
-
-@enumerate
-@item
-Startup files are read and executed as described in @ref{Bash Startup Files}.
-
-@item
-Job Control (@pxref{Job Control}) is enabled by default.  When job
-control is in effect, Bash ignores the keyboard-generated job control
-signals @code{SIGTTIN}, @code{SIGTTOU}, and @code{SIGTSTP}.
-
-@item
-Bash expands and displays @env{PS1} before reading the first line
-of a command, and expands and displays @env{PS2} before reading the
-second and subsequent lines of a multi-line command.
-
-@item
-Bash executes the value of the @env{PROMPT_COMMAND} variable as a command
-before printing the primary prompt, @env{$PS1}
-(@pxref{Bash Variables}).
-
-@item
-Readline (@pxref{Command Line Editing}) is used to read commands from
-the user's terminal.
-
-@item
-Bash inspects the value of the @code{ignoreeof} option to @code{set -o}
-instead of exiting immediately when it receives an @code{EOF} on its
-standard input when reading a command (@pxref{The Set Builtin}).
-
-@item
-Command history (@pxref{Bash History Facilities})
-and history expansion (@pxref{History Interaction})
-are enabled by default.
-Bash will save the command history to the file named by @env{$HISTFILE}
-when an interactive shell exits.
-
-@item
-Alias expansion (@pxref{Aliases}) is performed by default.
-
-@item
-In the absence of any traps, Bash ignores @code{SIGTERM}
-(@pxref{Signals}).
-
-@item
-In the absence of any traps, @code{SIGINT} is caught and handled
-((@pxref{Signals}).
-@code{SIGINT} will interrupt some shell builtins.
-
-@item
-An interactive login shell sends a @code{SIGHUP} to all jobs on exit
-if the @code{huponexit} shell option has been enabled (@pxref{Signals}).
-
-@item
-The @option{-n} invocation option is ignored, and @samp{set -n} has
-no effect (@pxref{The Set Builtin}).
-
-@item
-Bash will check for mail periodically, depending on the values of the
-@env{MAIL}, @env{MAILPATH}, and @env{MAILCHECK} shell variables
-(@pxref{Bash Variables}).
-
-@item
-Expansion errors due to references to unbound shell variables after
-@samp{set -u} has been enabled will not cause the shell to exit
-(@pxref{The Set Builtin}).
-
-@item
-The shell will not exit on expansion errors caused by @var{var} being unset
-or null in @code{$@{@var{var}:?@var{word}@}} expansions
-(@pxref{Shell Parameter Expansion}).
-
-@item
-Redirection errors encountered by shell builtins will not cause the
-shell to exit.
-
-@item
-When running in @sc{posix} mode, a special builtin returning an error
-status will not cause the shell to exit (@pxref{Bash POSIX Mode}).
-
-@item
-A failed @code{exec} will not cause the shell to exit
-(@pxref{Bourne Shell Builtins}).
-
-@item
-Parser syntax errors will not cause the shell to exit.
-
-@item
-Simple spelling correction for directory arguments to the @code{cd}
-builtin is enabled by default (see the description of the @code{cdspell}
-option to the @code{shopt} builtin in @ref{The Shopt Builtin}).
-
-@item
-The shell will check the value of the @env{TMOUT} variable and exit
-if a command is not read within the specified number of seconds after
-printing @env{$PS1} (@pxref{Bash Variables}).
-
-@end enumerate
-
-@node Bash Conditional Expressions
-@section Bash Conditional Expressions
-@cindex expressions, conditional
-
-Conditional expressions are used by the @code{[[} compound command
-and the @code{test} and @code{[} builtin commands.
-
-Expressions may be unary or binary.
-Unary expressions are often used to examine the status of a file.
-There are string operators and numeric comparison operators as well.
-If the @var{file} argument to one of the primaries is of the form
-@file{/dev/fd/@var{N}}, then file descriptor @var{N} is checked.
-If the @var{file} argument to one of the primaries is one of
-@file{/dev/stdin}, @file{/dev/stdout}, or @file{/dev/stderr}, file
-descriptor 0, 1, or 2, respectively, is checked.
-
-When used with @samp{[[}, The @samp{<} and @samp{>} operators sort
-lexicographically using the current locale.
-
-Unless otherwise specified, primaries that operate on files follow symbolic
-links and operate on the target of the link, rather than the link itself.
-
-@table @code
-@item -a @var{file}
-True if @var{file} exists.
-
-@item -b @var{file}
-True if @var{file} exists and is a block special file.
-
-@item -c @var{file}
-True if @var{file} exists and is a character special file.
-
-@item -d @var{file}
-True if @var{file} exists and is a directory.
-
-@item -e @var{file}
-True if @var{file} exists.
-
-@item -f @var{file}
-True if @var{file} exists and is a regular file.
-
-@item -g @var{file}
-True if @var{file} exists and its set-group-id bit is set.
-
-@item -h @var{file}
-True if @var{file} exists and is a symbolic link.
-
-@item -k @var{file}
-True if @var{file} exists and its "sticky" bit is set.
-
-@item -p @var{file}
-True if @var{file} exists and is a named pipe (FIFO).
-
-@item -r @var{file}
-True if @var{file} exists and is readable.
-
-@item -s @var{file}
-True if @var{file} exists and has a size greater than zero.
-
-@item -t @var{fd}
-True if file descriptor @var{fd} is open and refers to a terminal.
-
-@item -u @var{file}
-True if @var{file} exists and its set-user-id bit is set.
-
-@item -w @var{file}
-True if @var{file} exists and is writable.
-
-@item -x @var{file}
-True if @var{file} exists and is executable.
-
-@item -O @var{file}
-True if @var{file} exists and is owned by the effective user id.
-
-@item -G @var{file}
-True if @var{file} exists and is owned by the effective group id.
-
-@item -L @var{file}
-True if @var{file} exists and is a symbolic link.
-
-@item -S @var{file}
-True if @var{file} exists and is a socket.
-
-@item -N @var{file}
-True if @var{file} exists and has been modified since it was last read.
-
-@item @var{file1} -nt @var{file2}
-True if @var{file1} is newer (according to modification date)
-than @var{file2}, or if @var{file1} exists and @var{file2} does not.
-
-@item @var{file1} -ot @var{file2}
-True if @var{file1} is older than @var{file2},
-or if @var{file2} exists and @var{file1} does not.
-
-@item @var{file1} -ef @var{file2}
-True if @var{file1} and @var{file2} refer to the same device and
-inode numbers.
-
-@item -o @var{optname}
-True if shell option @var{optname} is enabled.
-The list of options appears in the description of the @option{-o}
-option to the @code{set} builtin (@pxref{The Set Builtin}).
-
-@item -z @var{string}
-True if the length of @var{string} is zero.
-
-@item -n @var{string}
-@itemx @var{string}
-True if the length of @var{string} is non-zero.
-
-@item @var{string1} == @var{string2}
-@itemx @var{string1} = @var{string2}
-True if the strings are equal.
-@samp{=} should be used with the @code{test} command for @sc{posix} conformance.
-
-@item @var{string1} != @var{string2}
-True if the strings are not equal.
-
-@item @var{string1} < @var{string2}
-True if @var{string1} sorts before @var{string2} lexicographically.
-
-@item @var{string1} > @var{string2}
-True if @var{string1} sorts after @var{string2} lexicographically.
-
-@item @var{arg1} OP @var{arg2}
-@code{OP} is one of 
-@samp{-eq}, @samp{-ne}, @samp{-lt}, @samp{-le}, @samp{-gt}, or @samp{-ge}.
-These arithmetic binary operators return true if @var{arg1}
-is equal to, not equal to, less than, less than or equal to,
-greater than, or greater than or equal to @var{arg2},
-respectively.  @var{Arg1} and @var{arg2}
-may be positive or negative integers.
-
-@end table
-
-@node Shell Arithmetic
-@section Shell Arithmetic
-@cindex arithmetic, shell
-@cindex shell arithmetic
-@cindex expressions, arithmetic
-@cindex evaluation, arithmetic
-@cindex arithmetic evaluation
-
-The shell allows arithmetic expressions to be evaluated, as one of
-the shell expansions or by the @code{let} and the @option{-i} option
-to the @code{declare} builtins.
-
-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. 
-
-@table @code
-
-@item @var{id}++ @var{id}--
-variable post-increment and post-decrement 
-
-@item ++@var{id} --@var{id}
-variable pre-increment and pre-decrement
-
-@item - +
-unary minus and plus
-
-@item ! ~
-logical and bitwise negation
-
-@item **
-exponentiation
-
-@item * / %
-multiplication, division, remainder
-
-@item + -
-addition, subtraction
-
-@item << >>
-left and right bitwise shifts
-
-@item <= >= < >
-comparison
-
-@item == !=
-equality and inequality
-
-@item &
-bitwise AND
-
-@item ^
-bitwise exclusive OR
-
-@item |
-bitwise OR
-
-@item &&
-logical AND
-
-@item ||
-logical OR
-
-@item expr ? expr : expr
-conditional operator
-
-@item = *= /= %= += -= <<= >>= &= ^= |=
-assignment
-
-@item expr1 , expr2
-comma
-@end table
-
-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  
-@var{integer} attribute using @samp{declare -i} is assigned a value.
-A null value evaluates to 0.
-A shell variable need not have its integer attribute turned on
-to be used in an expression.
-
-Constants with a leading 0 are interpreted as octal numbers.
-A leading @samp{0x} or @samp{0X} denotes hexadecimal.  Otherwise,
-numbers take the form [@var{base}@code{#}]@var{n}, where @var{base}
-is a decimal number between 2 and 64 representing the arithmetic
-base, and @var{n} is a number in that base.  If @var{base}@code{#} is
-omitted, then base 10 is used.
-The digits greater than 9 are represented by the lowercase letters,
-the uppercase letters, @samp{@@}, and @samp{_}, in that order.
-If @var{base} is less than or equal to 36, lowercase and uppercase
-letters may be used interchangeably to represent numbers between 10
-and 35.
-
-Operators are evaluated in order of precedence.  Sub-expressions in
-parentheses are evaluated first and may override the precedence
-rules above.
-
-@node Aliases
-@section Aliases
-@cindex alias expansion
-
-@var{Aliases} 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 @code{alias} and @code{unalias} builtin commands.
-
-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 @samp{/}, @samp{$}, @samp{`}, @samp{=} and any of the
-shell metacharacters 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 @code{ls} to @code{"ls -F"},
-for instance, and Bash does not try to recursively expand the
-replacement text. If the last character of the alias value is a
-space or tab character, then the next command word following the
-alias is also checked for alias expansion.
-
-Aliases are created and listed with the @code{alias}
-command, and removed with the @code{unalias} command.
-
-There is no mechanism for using arguments in the replacement text,
-as in @code{csh}.
-If arguments are needed, a shell function should be used
-(@pxref{Shell Functions}).
-
-Aliases are not expanded when the shell is not interactive,
-unless the @code{expand_aliases} shell option is set using
-@code{shopt} (@pxref{The Shopt Builtin}).
-
-The rules concerning the definition and use of aliases are
-somewhat confusing.  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 @code{alias}
-in compound commands.
-
-For almost every purpose, shell functions are preferred over aliases.
-
-@node Arrays
-@section Arrays
-@cindex arrays
-
-Bash provides one-dimensional indexed and associative array variables.
-Any variable may be used as an indexed array;
-the @code{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 (@pxref{Shell Arithmetic}) and are zero-based;
-associative arrays use arbitrary strings.
-
-An indexed array is created automatically if any variable is assigned to
-using the syntax
-@example
-name[@var{subscript}]=@var{value}
-@end example
-
-@noindent
-The @var{subscript}
-is treated as an arithmetic expression that must evaluate to a number
-greater than or equal to zero.  To explicitly declare an array, use
-@example
-declare -a @var{name}
-@end example
-@noindent
-The syntax
-@example
-declare -a @var{name}[@var{subscript}]
-@end example
-@noindent
-is also accepted; the @var{subscript} is ignored.
-
-Associative arrays are created using
-@example
-declare -A @var{name}.
-@end example
-
-Attributes may be
-specified for an array variable using the @code{declare} and
-@code{readonly} builtins.  Each attribute applies to all members of
-an array.
-
-Arrays are assigned to using compound assignments of the form
-@example
-name=(value@var{1} @dots{} value@var{n})
-@end example
-@noindent
-where each
-@var{value} is of the form @code{[@var{subscript}]=}@var{string}.
-Indexed array assignments do not require the bracket and subscript.
-When assigning to indexed arrays, if
-the optional subscript is 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.
-
-When assigning to an associative array, the subscript is required.
-
-This syntax is also accepted by the @code{declare}
-builtin.  Individual array elements may be assigned to using the
-@code{name[}@var{subscript}@code{]=}@var{value} syntax introduced above.
-
-Any element of an array may be referenced using
-@code{$@{name[}@var{subscript}@code{]@}}.
-The braces are required to avoid
-conflicts with the shell's filename expansion operators.  If the
-@var{subscript} is @samp{@@} or @samp{*}, the word expands to all members
-of the array @var{name}.  These subscripts differ only when the word
-appears within double quotes.
-If the word is double-quoted,
-@code{$@{name[*]@}} expands to a single word with
-the value of each array member separated by the first character of the
-@env{IFS} variable, and @code{$@{name[@@]@}} expands each element of
-@var{name} to a separate word.  When there are no array members,
-@code{$@{name[@@]@}} 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 @samp{@@} and @samp{*}. 
-@code{$@{#name[}@var{subscript}@code{]@}} expands to the length of
-@code{$@{name[}@var{subscript}@code{]@}}.
-If @var{subscript} is @samp{@@} or
-@samp{*}, the expansion is the number of elements in the array. 
-Referencing an array variable without a subscript is equivalent to
-referencing with a subscript of 0. 
-
-An array variable is considered set if a subscript has been assigned a
-value.  The null string is a valid value.
-
-The @code{unset} builtin is used to destroy arrays.
-@code{unset} @var{name}[@var{subscript}]
-destroys the array element at index @var{subscript}.
-Care must be taken to avoid unwanted side effects caused by filename
-expansion.
-@code{unset} @var{name}, where @var{name} is an array, removes the
-entire array. A subscript of @samp{*} or @samp{@@} also removes the
-entire array.
-
-The @code{declare}, @code{local}, and @code{readonly}
-builtins each accept a @option{-a} option to specify an indexed
-array and a @option{-A} option to specify an associative array.
-The @code{read} builtin accepts a @option{-a}
-option to assign a list of words read from the standard input
-to an array, and can read values from the standard input into
-individual array elements.  The @code{set} and @code{declare}
-builtins display array values in a way that allows them to be
-reused as input.
-
-@node The Directory Stack
-@section The Directory Stack
-@cindex directory stack
-
-@menu
-* Directory Stack Builtins::           Bash builtin commands to manipulate
-                                       the directory stack.
-@end menu
-
-The directory stack is a list of recently-visited directories.  The
-@code{pushd} builtin adds directories to the stack as it changes
-the current directory, and the @code{popd} builtin removes specified
-directories from the stack and changes the current directory to
-the directory removed.  The @code{dirs} builtin displays the contents
-of the directory stack.
-
-The contents of the directory stack are also visible
-as the value of the @env{DIRSTACK} shell variable.
-
-@node Directory Stack Builtins
-@subsection Directory Stack Builtins
-
-@table @code
-
-@item dirs
-@btindex dirs
-@example
-dirs [+@var{N} | -@var{N}] [-clpv]
-@end example
-Display the list of currently remembered directories.  Directories
-are added to the list with the @code{pushd} command; the
-@code{popd} command removes directories from the list.
-@table @code
-@item +@var{N}
-Displays the @var{N}th directory (counting from the left of the
-list printed by @code{dirs} when invoked without options), starting
-with zero.
-@item -@var{N}
-Displays the @var{N}th directory (counting from the right of the
-list printed by @code{dirs} when invoked without options), starting
-with zero.
-@item -c
-Clears the directory stack by deleting all of the elements.
-@item -l
-Produces a longer listing; the default listing format uses a 
-tilde to denote the home directory.
-@item -p
-Causes @code{dirs} to print the directory stack with one entry per
-line.
-@item -v
-Causes @code{dirs} to print the directory stack with one entry per
-line, prefixing each entry with its index in the stack.
-@end table
-
-@item popd
-@btindex popd
-@example
-popd [+@var{N} | -@var{N}] [-n]
-@end example
-
-Remove the top entry from the directory stack, and @code{cd}
-to the new top directory.
-When no arguments are given, @code{popd}
-removes the top directory from the stack and
-performs a @code{cd} to the new top directory.  The
-elements are numbered from 0 starting at the first directory listed with
-@code{dirs}; i.e., @code{popd} is equivalent to @code{popd +0}.
-@table @code
-@item +@var{N}
-Removes the @var{N}th directory (counting from the left of the
-list printed by @code{dirs}), starting with zero.
-@item -@var{N}
-Removes the @var{N}th directory (counting from the right of the
-list printed by @code{dirs}), starting with zero.
-@item -n
-Suppresses the normal change of directory when removing directories
-from the stack, so that only the stack is manipulated.
-@end table
-
-@btindex pushd
-@item pushd
-@example
-pushd [-n] [@var{+N} | @var{-N} | @var{dir} ]
-@end example
-
-Save the current directory on the top of the directory stack
-and then @code{cd} to @var{dir}.
-With no arguments, @code{pushd} exchanges the top two directories.
-
-@table @code
-@item -n
-Suppresses the normal change of directory when adding directories
-to the stack, so that only the stack is manipulated.
-@item +@var{N}
-Brings the @var{N}th directory (counting from the left of the
-list printed by @code{dirs}, starting with zero) to the top of
-the list by rotating the stack.
-@item -@var{N}
-Brings the @var{N}th directory (counting from the right of the
-list printed by @code{dirs}, starting with zero) to the top of
-the list by rotating the stack.
-@item @var{dir}
-Makes the current working directory be the top of the stack, and then
-executes the equivalent of `@code{cd} @var{dir}'.
-@code{cd}s to @var{dir}.
-@end table
-
-@end table
-
-@node Printing a Prompt
-@section Controlling the Prompt
-@cindex prompting
-
-The value of the variable @env{PROMPT_COMMAND} is examined just before
-Bash prints each primary prompt.  If @env{PROMPT_COMMAND} is set and
-has a non-null value, then the
-value is executed just as if it had been typed on the command line.
-
-In addition, the following table describes the special characters which
-can appear in the prompt variables:
-
-@table @code
-@item \a
-A bell character.
-@item \d
-The date, in "Weekday Month Date" format (e.g., "Tue May 26").
-@item \D@{@var{format}@}
-The @var{format} is passed to @code{strftime}(3) and the result is inserted
-into the prompt string; an empty @var{format} results in a locale-specific
-time representation.  The braces are required.
-@item \e
-An escape character.
-@item \h
-The hostname, up to the first `.'.
-@item \H
-The hostname.
-@item \j
-The number of jobs currently managed by the shell.
-@item \l
-The basename of the shell's terminal device name.
-@item \n
-A newline.
-@item \r
-A carriage return.
-@item \s
-The name of the shell, the basename of @code{$0} (the portion
-following the final slash).
-@item \t
-The time, in 24-hour HH:MM:SS format.
-@item \T
-The time, in 12-hour HH:MM:SS format.
-@item \@@
-The time, in 12-hour am/pm format.
-@item \A
-The time, in 24-hour HH:MM format.
-@item \u
-The username of the current user.
-@item \v
-The version of Bash (e.g., 2.00)          
-@item \V
-The release of Bash, version + patchlevel (e.g., 2.00.0)
-@item \w
-The current working directory, with @env{$HOME} abbreviated with a tilde
-(uses the @env{$PROMPT_DIRTRIM} variable).
-@item \W
-The basename of @env{$PWD}, with @env{$HOME} abbreviated with a tilde.
-@item \!
-The history number of this command.
-@item \#
-The command number of this command.
-@item \$
-If the effective uid is 0, @code{#}, otherwise @code{$}.
-@item \@var{nnn}
-The character whose ASCII code is the octal value @var{nnn}.
-@item \\
-A backslash.
-@item \[
-Begin a sequence of non-printing characters.  This could be used to
-embed a terminal control sequence into the prompt.
-@item \]
-End a sequence of non-printing characters.
-@end table
-
-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
-(@pxref{Bash History Facilities}), 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
-@code{promptvars} shell option (@pxref{Bash Builtins}).
-
-@node The Restricted Shell
-@section The Restricted Shell
-@cindex restricted shell
-
-If Bash is started with the name @code{rbash}, or the
-@option{--restricted}
-or
-@option{-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.
-A restricted shell behaves identically to @code{bash}
-with the exception that the following are disallowed or not performed:
-
-@itemize @bullet
-@item
-Changing directories with the @code{cd} builtin.
-@item
-Setting or unsetting the values of the @env{SHELL}, @env{PATH},
-@env{ENV}, or @env{BASH_ENV} variables.
-@item
-Specifying command names containing slashes.
-@item
-Specifying a filename containing a slash as an argument to the @code{.}
-builtin command.
-@item
-Specifying a filename containing a slash as an argument to the @option{-p}
-option to the @code{hash} builtin command.
-@item
-Importing function definitions from the shell environment at startup.
-@item
-Parsing the value of @env{SHELLOPTS} from the shell environment at startup.
-@item
-Redirecting output using the @samp{>}, @samp{>|}, @samp{<>}, @samp{>&},
-@samp{&>}, and @samp{>>} redirection operators.
-@item
-Using the @code{exec} builtin to replace the shell with another command.
-@item
-Adding or deleting builtin commands with the
-@option{-f} and @option{-d} options to the @code{enable} builtin.
-@item
-Using the @code{enable} builtin command to enable disabled shell builtins.
-@item
-Specifying the @option{-p} option to the @code{command} builtin.
-@item
-Turning off restricted mode with @samp{set +r} or @samp{set +o restricted}.
-@end itemize
-
-These restrictions are enforced after any startup files are read.
-
-When a command that is found to be a shell script is executed
-(@pxref{Shell Scripts}), @code{rbash} turns off any restrictions in
-the shell spawned to execute the script.
-
-@node Bash POSIX Mode
-@section Bash POSIX Mode
-@cindex POSIX Mode
-
-Starting Bash with the @option{--posix} command-line option or executing
-@samp{set -o posix} while Bash is running will cause Bash to conform more
-closely to the @sc{posix} standard by changing the behavior to
-match that specified by @sc{posix} in areas where the Bash default differs.
-
-When invoked as @code{sh}, Bash enters @sc{posix} mode after reading the
-startup files.
-
-The following list is what's changed when `@sc{posix} mode' is in effect:
-
-@enumerate
-@item
-When a command in the hash table no longer exists, Bash will re-search
-@env{$PATH} to find the new location.  This is also available with
-@samp{shopt -s checkhash}.
-
-@item
-The message printed by the job control code and builtins when a job
-exits with a non-zero status is `Done(status)'.
-
-@item
-The message printed by the job control code and builtins when a job
-is stopped is `Stopped(@var{signame})', where @var{signame} is, for
-example, @code{SIGTSTP}.
-
-@item
-The @code{bg} builtin uses the required format to describe each job placed
-in the background, which does not include an indication of whether the job
-is the current or previous job.
-
-@item
-Reserved words appearing in a context where reserved words are recognized
-do not undergo alias expansion.
-
-@item
-The @sc{posix} @env{PS1} and @env{PS2} expansions of @samp{!} to
-the history number and @samp{!!} to @samp{!} are enabled,
-and parameter expansion is performed on the values of @env{PS1} and
-@env{PS2} regardless of the setting of the @code{promptvars} option.
-
-@item
-The @sc{posix} startup files are executed (@env{$ENV}) rather than
-the normal Bash files.
-
-@item
-Tilde expansion is only performed on assignments preceding a command
-name, rather than on all assignment statements on the line.
-
-@item
-The default history file is @file{~/.sh_history} (this is the
-default value of @env{$HISTFILE}).
-
-@item
-The output of @samp{kill -l} prints all the signal names on a single line,
-separated by spaces, without the @samp{SIG} prefix.
-
-@item
-The @code{kill} builtin does not accept signal names with a @samp{SIG}
-prefix.
-
-@item
-Non-interactive shells exit if @var{filename} in @code{.} @var{filename}
-is not found.
-
-@item
-Non-interactive shells exit if a syntax error in an arithmetic expansion
-results in an invalid expression.
-
-@item
-Redirection operators do not perform filename expansion on the word
-in the redirection unless the shell is interactive.
-
-@item
-Redirection operators do not perform word splitting on the word in the
-redirection.
-
-@item
-Function names must be valid shell @code{name}s.  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 invalid name
-causes a fatal syntax error in non-interactive shells.
-
-@item
-@sc{posix} special builtins are found before shell functions
-during command lookup.
-
-@item
-If a @sc{posix} special builtin returns an error status, a
-non-interactive shell exits.  The fatal errors are those listed in
-the POSIX standard, and include things like passing incorrect options,
-redirection errors, variable assignment errors for assignments preceding
-the command name, and so on.
-
-@item
-If @env{CDPATH} is set, the @code{cd} builtin will not implicitly
-append the current directory to it.  This means that @code{cd} will
-fail if no valid directory name can be constructed from
-any of the entries in @env{$CDPATH}, even if the a directory with
-the same name as the name given as an argument to @code{cd} exists
-in the current directory.
-
-@item
-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 readonly variable.
-
-@item
-A non-interactive shell exits with an error status if the iteration
-variable in a @code{for} statement or the selection variable in a
-@code{select} statement is a readonly variable.
-
-@item
-Process substitution is not available.
-
-@item
-Assignment statements preceding @sc{posix} special builtins
-persist in the shell environment after the builtin completes.
-
-@item
-Assignment statements preceding shell function calls persist in the
-shell environment after the function returns, as if a @sc{posix}
-special builtin command had been executed.
-
-@item
-The @code{export} and @code{readonly} builtin commands display their
-output in the format required by @sc{posix}.
-
-@item
-The @code{trap} builtin displays signal names without the leading
-@code{SIG}.
-
-@item
-The @code{trap} builtin doesn't check the first argument for a possible
-signal specification and revert the signal handling to the original
-disposition if it is, unless that argument consists solely of digits and
-is a valid signal number.  If users want to reset the handler for a given
-signal to the original disposition, they should use @samp{-} as the
-first argument.
-
-@item
-The @code{.} and @code{source} builtins do not search the current directory
-for the filename argument if it is not found by searching @env{PATH}.
-
-@item
-Subshells spawned to execute command substitutions inherit the value of
-the @option{-e} option from the parent shell.  When not in @sc{posix} mode,
-Bash clears the @option{-e} option in such subshells.
-
-@item
-Alias expansion is always enabled, even in non-interactive shells.
-
-@item
-When the @code{alias} builtin displays alias definitions, it does not
-display them with a leading @samp{alias } unless the @option{-p} option
-is supplied.
-
-@item
-When the @code{set} builtin is invoked without options, it does not display
-shell function names and definitions.
-
-@item
-When the @code{set} builtin is invoked without options, it displays
-variable values without quotes, unless they contain shell metacharacters,
-even if the result contains nonprinting characters.
-
-@item
-When the @code{cd} builtin is invoked in @var{logical} mode, and the pathname
-constructed from @code{$PWD} and the directory name supplied as an argument
-does not refer to an existing directory, @code{cd} will fail instead of
-falling back to @var{physical} mode.
-
-@item
-When the @code{pwd} builtin is supplied the @option{-P} option, it resets
-@code{$PWD} to a pathname containing no symlinks.
-
-@item
-The @code{pwd} builtin verifies that the value it prints is the same as the
-current directory, even if it is not asked to check the file system with the
-@option{-P} option.
-
-@item
-When listing the history, the @code{fc} builtin does not include an
-indication of whether or not a history entry has been modified.
-
-@item
-The default editor used by @code{fc} is @code{ed}.
-
-@item
-The @code{type} and @code{command} builtins will not report a non-executable
-file as having been found, though the shell will attempt to execute such a
-file if it is the only so-named file found in @code{$PATH}.
-
-@item
-The @code{vi} editing mode will invoke the @code{vi} editor directly when
-the @samp{v} command is run, instead of checking @code{$VISUAL} and
-@code{$EDITOR}.
-
-@item
-When the @code{xpg_echo} option is enabled, Bash does not attempt to interpret
-any arguments to @code{echo} as options.  Each argument is displayed, after
-escape characters are converted.
-
-@item
-The @code{ulimit} builtin uses a block size of 512 bytes for the @option{-c}
-and @option{-f} options.
-
-@item
-The arrival of @code{SIGCHLD}  when a trap is set on @code{SIGCHLD} does
-not interrupt the @code{wait} builtin and cause it to return immediately.
-The trap command is run once for each child that exits.
-
-@end enumerate
-
-There is other @sc{posix} behavior that Bash does not implement by
-default even when in @sc{posix} mode.
-Specifically:
-
-@enumerate
-
-@item
-The @code{fc} builtin checks @code{$EDITOR} as a program to edit history
-entries if @code{FCEDIT} is unset, rather than defaulting directly to
-@code{ed}.  @code{fc} uses @code{ed} if @code{EDITOR} is unset.
-
-@item
-As noted above, Bash requires the @code{xpg_echo} option to be enabled for
-the @code{echo} builtin to be fully conformant.
-
-@end enumerate
-
-Bash can be configured to be @sc{posix}-conformant by default, by specifying
-the @option{--enable-strict-posix-default} to @code{configure} when building
-(@pxref{Optional Features}).
-
-@node Job Control
-@chapter Job Control
-
-This chapter discusses what job control is, how it works, and how
-Bash allows you to access its facilities.
-
-@menu
-* Job Control Basics::         How job control works.
-* Job Control Builtins::       Bash builtin commands used to interact
-                               with job control.
-* Job Control Variables::      Variables Bash uses to customize job
-                               control.
-@end menu
-
-@node Job Control Basics
-@section Job Control Basics
-@cindex job control
-@cindex foreground
-@cindex background
-@cindex suspending jobs
-
-Job control
-refers to the ability to selectively stop (suspend)
-the execution of processes and continue (resume)
-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 Bash.
-
-The shell associates a @var{job} with each pipeline.  It keeps a
-table of currently executing jobs, which may be listed with the
-@code{jobs} command.  When Bash starts a job
-asynchronously, it prints a line that looks
-like:
-@example
-[1] 25647
-@end example
-@noindent
-indicating that this job is job number 1 and that the process @sc{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.  Bash uses the @var{job} abstraction as the
-basis for job control. 
-
-To facilitate the implementation of the user interface to job
-control, the operating system maintains the notion of a current terminal
-process group @sc{id}.  Members of this process group (processes whose
-process group @sc{id} is equal to the current terminal process group
-@sc{id}) receive keyboard-generated signals such as @code{SIGINT}. 
-These processes are said to be in the foreground.  Background
-processes are those whose process group @sc{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 @code{stty tostop}, write to the terminal.
-Background processes which attempt to
-read from (write to when @code{stty tostop} is in effect) the
-terminal are sent a @code{SIGTTIN} (@code{SIGTTOU})
-signal by the kernel's terminal driver,
-which, unless caught, suspends the process. 
-
-If the operating system on which Bash is running supports
-job control, Bash contains facilities to use it.  Typing the
-@var{suspend} character (typically @samp{^Z}, Control-Z) while a
-process is running causes that process to be stopped and returns
-control to Bash.  Typing the @var{delayed suspend} character
-(typically @samp{^Y}, Control-Y) causes the process to be stopped
-when it attempts to read input from the terminal, and control to
-be returned to Bash.  The user then manipulates the state of
-this job, using the @code{bg} command to continue it in the
-background, the @code{fg} command to continue it in the
-foreground, or the @code{kill} command to kill it.  A @samp{^Z}
-takes effect immediately, and has the additional side effect of
-causing pending output and typeahead to be discarded. 
-
-There are a number of ways to refer to a job in the shell.  The
-character @samp{%} introduces a job specification (@var{jobspec}).
-
-Job number @code{n} may be referred to as @samp{%n}.
-The symbols @samp{%%} and  @samp{%+} refer to the shell's notion of the
-current job, which is the last job stopped while it was in the foreground
-or started in the background.
-A single @samp{%} (with no accompanying job specification) also refers
-to the current job.
-The previous job may be referenced using @samp{%-}.
-If there is only a single job, @samp{%+} and @samp{%-} can both be used
-to refer to that job.
-In output pertaining to jobs (e.g., the output of the @code{jobs}
-command), the current job is always flagged with a @samp{+}, and the
-previous job with a @samp{-}. 
-
-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, @samp{%ce} refers
-to a stopped @code{ce} job. Using @samp{%?ce}, on the
-other hand, refers to any job containing the string @samp{ce} in
-its command line.  If the prefix or substring matches more than one job,
-Bash reports an error.
-
-Simply naming a job can be used to bring it into the foreground:
-@samp{%1} is a synonym for @samp{fg %1}, bringing job 1 from the
-background into the foreground.  Similarly, @samp{%1 &} resumes
-job 1 in the background, equivalent to @samp{bg %1}
-
-The shell learns immediately whenever a job changes state. 
-Normally, 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 @option{-b} option to the @code{set} builtin is enabled,
-Bash reports such changes immediately (@pxref{The Set Builtin}).
-Any trap on @code{SIGCHLD} is executed for each child process
-that exits.
-
-If an attempt to exit Bash is made while jobs are stopped, (or running, if
-the @code{checkjobs} option is enabled -- see @ref{The Shopt Builtin}), the
-shell prints a warning message, and if the @code{checkjobs} option is
-enabled, lists the jobs and their statuses.
-The @code{jobs} command may then be used to inspect their status.
-If a second attempt to exit is made without an intervening command,
-Bash does not print another warning, and any stopped jobs are terminated.
-
-@node Job Control Builtins
-@section Job Control Builtins
-
-@table @code
-
-@item bg
-@btindex bg
-@example
-bg [@var{jobspec} @dots{}]
-@end example
-Resume each suspended job @var{jobspec} in the background, as if it
-had been started with @samp{&}.
-If @var{jobspec} is not supplied, the current job is used.
-The return status is zero unless it is run when job control is not
-enabled, or, when run with job control enabled, any
-@var{jobspec} was not found or specifies a job
-that was started without job control.
-
-@item fg
-@btindex fg
-@example
-fg [@var{jobspec}]
-@end example
-Resume the job @var{jobspec} in the foreground and make it the current job.
-If @var{jobspec} is not supplied, the current job is used.
-The return status is that of the command placed into the foreground,
-or non-zero if run when job control is disabled or, when run with
-job control enabled, @var{jobspec} does not specify a valid job or
-@var{jobspec} specifies a job that was started without job control.
-
-@item jobs
-@btindex jobs
-@example
-jobs [-lnprs] [@var{jobspec}]
-jobs -x @var{command} [@var{arguments}]
-@end example
-
-The first form lists the active jobs.  The options have the
-following meanings:
-
-@table @code
-@item -l
-List process @sc{id}s in addition to the normal information.
-
-@item -n
-Display information only about jobs that have changed status since
-the user was last notified of their status.
-
-@item -p
-List only the process @sc{id} of the job's process group leader.
-
-@item -r
-Restrict output to running jobs.
-
-@item -s
-Restrict output to stopped jobs.
-@end table
-
-If @var{jobspec} is given,
-output is restricted to information about that job. 
-If @var{jobspec} is not supplied, the status of all jobs is
-listed.
-
-If the @option{-x} option is supplied, @code{jobs} replaces any
-@var{jobspec} found in @var{command} or @var{arguments} with the
-corresponding process group @sc{id}, and executes @var{command},
-passing it @var{argument}s, returning its exit status. 
-
-@item kill
-@btindex kill
-@example
-kill [-s @var{sigspec}] [-n @var{signum}] [-@var{sigspec}] @var{jobspec} or @var{pid}
-kill -l [@var{exit_status}]
-@end example
-Send a signal specified by @var{sigspec} or @var{signum} to the process
-named by job specification @var{jobspec} or process @sc{id} @var{pid}.
-@var{sigspec} is either a case-insensitive signal name such as
-@code{SIGINT} (with or without the @code{SIG} prefix)
-or a signal number; @var{signum} is a signal number.
-If @var{sigspec} and @var{signum} are not present, @code{SIGTERM} is used.
-The @option{-l} option lists the signal names.
-If any arguments are supplied when @option{-l} is given, the names of the
-signals corresponding to the arguments are listed, and the return status
-is zero.
-@var{exit_status} is a number specifying a signal number or the exit
-status of a process terminated by a signal.
-The return status is zero if at least one signal was successfully sent,
-or non-zero if an error occurs or an invalid option is encountered.
-
-@item wait
-@btindex wait
-@example
-wait [@var{jobspec} or @var{pid} ...]
-@end example
-Wait until the child process specified by each process @sc{id} @var{pid}
-or job specification @var{jobspec} exits and return the exit status of the
-last command waited for.
-If a job spec is given, all processes in the job are waited for.
-If no arguments are given, all currently active child processes are
-waited for, and the return status is zero.
-If neither @var{jobspec} nor @var{pid} specifies an active child process
-of the shell, the return status is 127.
-
-@item disown
-@btindex disown
-@example
-disown [-ar] [-h] [@var{jobspec} @dots{}]
-@end example
-Without options, each @var{jobspec} is removed from the table of
-active jobs.
-If the @option{-h} option is given, the job is not removed from the table,
-but is marked so that @code{SIGHUP} is not sent to the job if the shell
-receives a @code{SIGHUP}.
-If @var{jobspec} is not present, and neither the @option{-a} nor @option{-r}
-option is supplied, the current job is used.
-If no @var{jobspec} is supplied, the @option{-a} option means to remove or
-mark all jobs; the @option{-r} option without a @var{jobspec}
-argument restricts operation to running jobs.
-
-@item suspend
-@btindex suspend
-@example
-suspend [-f]
-@end example
-Suspend the execution of this shell until it receives a
-@code{SIGCONT} signal.
-A login shell cannot be suspended; the @option{-f}
-option can be used to override this and force the suspension.
-
-@end table
-
-When job control is not active, the @code{kill} and @code{wait}
-builtins do not accept @var{jobspec} arguments.  They must be
-supplied process @sc{id}s.
-
-@node Job Control Variables
-@section Job Control Variables
-
-@vtable @code
-
-@item auto_resume
-This variable controls how the shell interacts with the user and
-job control.  If this variable exists then single word simple
-commands without redirections are treated as candidates for resumption
-of an existing job.  There is no ambiguity allowed; if there is
-more than one job beginning with the string typed, then
-the most recently accessed job will be selected.
-The name of a stopped job, in this context, is the command line
-used to start it.  If this variable is set to the value @samp{exact},
-the string supplied must match the name of a stopped job exactly;
-if set to @samp{substring},
-the string supplied needs to match a substring of the name of a
-stopped job.  The @samp{substring} value provides functionality
-analogous to the @samp{%?} job @sc{id} (@pxref{Job Control Basics}).
-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 @samp{%} job @sc{id}.
-
-@end vtable
-
-@set readline-appendix
-@set history-appendix
-@cindex Readline, how to use
-@include rluser.texi
-@cindex History, how to use
-@include hsuser.texi
-@clear readline-appendix
-@clear history-appendix
-
-@node Installing Bash
-@chapter Installing Bash
-
-This chapter provides basic instructions for installing Bash on
-the various supported platforms.  The distribution supports the
-@sc{gnu} operating systems, nearly every version of Unix, and several
-non-Unix systems such as BeOS and Interix.
-Other independent ports exist for
-@sc{ms-dos}, @sc{os/2}, and Windows platforms.
-
-@menu
-* Basic Installation:: Installation instructions.
-* Compilers and Options::      How to set special options for various
-                               systems.
-* Compiling For Multiple Architectures::       How to compile Bash for more
-                                               than one kind of system from
-                                               the same source tree.
-* Installation Names:: How to set the various paths used by the installation.
-* Specifying the System Type:: How to configure Bash for a particular system.
-* Sharing Defaults::   How to share default configuration values among GNU
-                       programs.
-* Operation Controls:: Options recognized by the configuration program.
-* Optional Features::  How to enable and disable optional features when
-                       building Bash.
-@end menu
-
-@node Basic Installation
-@section Basic Installation
-@cindex installation
-@cindex configuration
-@cindex Bash installation
-@cindex Bash configuration
-
-These are installation instructions for Bash.
-
-The simplest way to compile Bash is:
-
-@enumerate
-@item
-@code{cd} to the directory containing the source code and type
-@samp{./configure} to configure Bash for your system.  If you're
-using @code{csh} on an old version of System V, you might need to
-type @samp{sh ./configure} instead to prevent @code{csh} from trying
-to execute @code{configure} itself.
-
-Running @code{configure} takes some time.
-While running, it prints messages telling which features it is
-checking for.
-
-@item
-Type @samp{make} to compile Bash and build the @code{bashbug} bug
-reporting script.
-
-@item
-Optionally, type @samp{make tests} to run the Bash test suite.
-
-@item
-Type @samp{make install} to install @code{bash} and @code{bashbug}.
-This will also install the manual pages and Info file.
-
-@end enumerate
-
-The @code{configure} shell script attempts to guess correct
-values for various system-dependent variables used during
-compilation.  It uses those values to create a @file{Makefile} in
-each directory of the package (the top directory, the
-@file{builtins}, @file{doc}, and @file{support} directories,
-each directory under @file{lib}, and several others).  It also creates a
-@file{config.h} file containing system-dependent definitions. 
-Finally, it creates a shell script named @code{config.status} that you
-can run in the future to recreate the current configuration, a
-file @file{config.cache} that saves the results of its tests to
-speed up reconfiguring, and a file @file{config.log} containing
-compiler output (useful mainly for debugging @code{configure}). 
-If at some point
-@file{config.cache} contains results you don't want to keep, you
-may remove or edit it. 
-
-To find out more about the options and arguments that the
-@code{configure} script understands, type 
-
-@example
-bash-2.04$ ./configure --help
-@end example
-
-@noindent
-at the Bash prompt in your Bash source directory.
-
-If you need to do unusual things to compile Bash, please
-try to figure out how @code{configure} could check whether or not
-to do them, and mail diffs or instructions to
-@email{bash-maintainers@@gnu.org} so they can be
-considered for the next release.
-
-The file @file{configure.in} is used to create @code{configure}
-by a program called Autoconf.  You only need
-@file{configure.in} if you want to change it or regenerate
-@code{configure} using a newer version of Autoconf.  If
-you do this, make sure you are using Autoconf version 2.50 or
-newer.
-
-You can remove the program binaries and object files from the
-source code directory by typing @samp{make clean}.  To also remove the
-files that @code{configure} created (so you can compile Bash for
-a different kind of computer), type @samp{make distclean}.
-
-@node Compilers and Options
-@section Compilers and Options
-
-Some systems require unusual options for compilation or linking
-that the @code{configure} script does not know about.  You can
-give @code{configure} initial values for variables by setting
-them in the environment.  Using a Bourne-compatible shell, you
-can do that on the command line like this:
-
-@example
-CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
-@end example
-
-On systems that have the @code{env} program, you can do it like this:
-
-@example
-env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
-@end example
-
-The configuration process uses GCC to build Bash if it
-is available.
-
-@node Compiling For Multiple Architectures
-@section Compiling For Multiple Architectures
-
-You can compile Bash for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory.  To do this, you must use a version of @code{make} that
-supports the @code{VPATH} variable, such as GNU @code{make}.
-@code{cd} to the
-directory where you want the object files and executables to go and run
-the @code{configure} script from the source directory.  You may need to
-supply the @option{--srcdir=PATH} argument to tell @code{configure} where the
-source files are.  @code{configure} automatically checks for the
-source code in the directory that @code{configure} is in and in `..'.
-
-If you have to use a @code{make} that does not supports the @code{VPATH}
-variable, you can compile Bash for one architecture at a
-time in the source code directory.  After you have installed
-Bash for one architecture, use @samp{make distclean} before
-reconfiguring for another architecture.
-
-Alternatively, if your system supports symbolic links, you can use the
-@file{support/mkclone} script to create a build tree which has
-symbolic links back to each file in the source directory.  Here's an
-example that creates a build directory in the current directory from a
-source directory @file{/usr/gnu/src/bash-2.0}:
-
-@example
-bash /usr/gnu/src/bash-2.0/support/mkclone -s /usr/gnu/src/bash-2.0 .
-@end example
-
-@noindent
-The @code{mkclone} script requires Bash, so you must have already built
-Bash for at least one architecture before you can create build
-directories for other architectures.
-
-@node Installation Names
-@section Installation Names
-
-By default, @samp{make install} will install into
-@file{/usr/local/bin}, @file{/usr/local/man}, etc.  You can
-specify an installation prefix other than @file{/usr/local} by
-giving @code{configure} the option @option{--prefix=@var{PATH}},
-or by specifying a value for the @code{DESTDIR} @samp{make}
-variable when running @samp{make install}.
-
-You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files. 
-If you give @code{configure} the option
-@option{--exec-prefix=@var{PATH}}, @samp{make install} will use
-@var{PATH} as the prefix for installing programs and libraries.
-Documentation and other data files will still use the regular prefix. 
-
-@node Specifying the System Type
-@section Specifying the System Type
-
-There may be some features @code{configure} can not figure out
-automatically, but need to determine by the type of host Bash
-will run on.  Usually @code{configure} can figure that
-out, but if it prints a message saying it can not guess the host
-type, give it the @option{--host=TYPE} option.  @samp{TYPE} can
-either be a short name for the system type, such as @samp{sun4},
-or a canonical name with three fields: @samp{CPU-COMPANY-SYSTEM}
-(e.g., @samp{i386-unknown-freebsd4.2}).
-
-See the file @file{support/config.sub} for the possible
-values of each field. 
-
-@node Sharing Defaults
-@section Sharing Defaults
-
-If you want to set default values for @code{configure} scripts to
-share, you can create a site shell script called
-@code{config.site} that gives default values for variables like
-@code{CC}, @code{cache_file}, and @code{prefix}.  @code{configure}
-looks for @file{PREFIX/share/config.site} if it exists, then
-@file{PREFIX/etc/config.site} if it exists.  Or, you can set the
-@code{CONFIG_SITE} environment variable to the location of the site
-script.  A warning: the Bash @code{configure} looks for a site script,
-but not all @code{configure} scripts do.
-
-@node Operation Controls
-@section Operation Controls
-
-@code{configure} recognizes the following options to control how it
-operates.
-
-@table @code
-
-@item --cache-file=@var{file}
-Use and save the results of the tests in
-@var{file} instead of @file{./config.cache}.  Set @var{file} to
-@file{/dev/null} to disable caching, for debugging
-@code{configure}. 
-
-@item --help
-Print a summary of the options to @code{configure}, and exit.
-
-@item --quiet
-@itemx --silent
-@itemx -q
-Do not print messages saying which checks are being made.
-
-@item --srcdir=@var{dir}
-Look for the Bash source code in directory @var{dir}.  Usually
-@code{configure} can determine that directory automatically.
-
-@item --version
-Print the version of Autoconf used to generate the @code{configure}
-script, and exit.
-@end table
-
-@code{configure} also accepts some other, not widely used, boilerplate
-options.  @samp{configure --help} prints the complete list.
-
-@node Optional Features
-@section Optional Features
-
-The Bash @code{configure} has a number of @option{--enable-@var{feature}}
-options, where @var{feature} indicates an optional part of Bash.
-There are also several @option{--with-@var{package}} options,
-where @var{package} is something like @samp{bash-malloc} or @samp{purify}.
-To turn off the default use of a package, use
-@option{--without-@var{package}}.  To configure Bash without a feature
-that is enabled by default, use @option{--disable-@var{feature}}.
-
-Here is a complete list of the @option{--enable-} and
-@option{--with-} options that the Bash @code{configure} recognizes. 
-
-@table @code
-@item --with-afs
-Define if you are using the Andrew File System from Transarc.
-
-@item --with-bash-malloc
-Use the Bash version of
-@code{malloc} in the directory @file{lib/malloc}.  This is not the same
-@code{malloc} that appears in @sc{gnu} libc, but an older version
-originally derived from the 4.2 @sc{bsd} @code{malloc}.  This @code{malloc}
-is very fast, but wastes some space on each allocation.
-This option is enabled by default.
-The @file{NOTES} file contains a list of systems for
-which this should be turned off, and @code{configure} disables this
-option automatically for a number of systems.
-
-@item --with-curses
-Use the curses library instead of the termcap library.  This should
-be supplied if your system has an inadequate or incomplete termcap
-database.
-
-@item --with-gnu-malloc
-A synonym for @code{--with-bash-malloc}.
-
-@item --with-installed-readline[=@var{PREFIX}]
-Define this to make Bash link with a locally-installed version of Readline
-rather than the version in @file{lib/readline}.  This works only with
-Readline 5.0 and later versions.  If @var{PREFIX} is @code{yes} or not
-supplied, @code{configure} uses the values of the make variables
-@code{includedir} and @code{libdir}, which are subdirectories of @code{prefix}
-by default, to find the installed version of Readline if it is not in
-the standard system include and library directories.
-If @var{PREFIX} is @code{no}, Bash links with the version in
-@file{lib/readline}.
-If @var{PREFIX} is set to any other value, @code{configure} treats it as
-a directory pathname and looks for
-the installed version of Readline in subdirectories of that directory
-(include files in @var{PREFIX}/@code{include} and the library in
-@var{PREFIX}/@code{lib}).
-
-@item --with-purify
-Define this to use the Purify memory allocation checker from Rational
-Software.
-
-@item --enable-minimal-config
-This produces a shell with minimal features, close to the historical
-Bourne shell.
-@end table
-
-There are several @option{--enable-} options that alter how Bash is
-compiled and linked, rather than changing run-time features.
-
-@table @code
-@item --enable-largefile
-Enable support for @uref{http://www.sas.com/standards/large_file/x_open.20Mar96.html,
-large files} if the operating system requires special compiler options
-to build programs which can access large files.  This is enabled by
-default, if the operating system provides large file support.
-
-@item --enable-profiling
-This builds a Bash binary that produces profiling information to be
-processed by @code{gprof} each time it is executed.
-
-@item --enable-static-link
-This causes Bash to be linked statically, if @code{gcc} is being used.
-This could be used to build a version to use as root's shell.
-@end table
-
-The @samp{minimal-config} option can be used to disable all of
-the following options, but it is processed first, so individual
-options may be enabled using @samp{enable-@var{feature}}. 
-
-All of the following options except for @samp{disabled-builtins} and
-@samp{xpg-echo-default} are
-enabled by default, unless the operating system does not provide the
-necessary support.
-
-@table @code
-@item --enable-alias
-Allow alias expansion and include the @code{alias} and @code{unalias}
-builtins (@pxref{Aliases}).
-
-@item --enable-arith-for-command
-Include support for the alternate form of the @code{for} command
-that behaves like the C language @code{for} statement
-(@pxref{Looping Constructs}).
-
-@item --enable-array-variables
-Include support for one-dimensional array shell variables
-(@pxref{Arrays}).
-
-@item --enable-bang-history
-Include support for @code{csh}-like history substitution
-(@pxref{History Interaction}).
-
-@item --enable-brace-expansion
-Include @code{csh}-like brace expansion
-( @code{b@{a,b@}c} @expansion{} @code{bac bbc} ).
-See @ref{Brace Expansion}, for a complete description.
-
-@item --enable-casemod-attributes
-Include support for case-modifying attributes in the @code{declare} builtin
-and assignment statements.  Variables with the @var{uppercase} attribute,
-for example, will have their values converted to uppercase upon assignment.
-
-@item --enable-casemod-expansion
-Include support for case-modifying word expansions.
-
-@item --enable-command-timing
-Include support for recognizing @code{time} as a reserved word and for
-displaying timing statistics for the pipeline following @code{time}
-(@pxref{Pipelines}).
-This allows pipelines as well as shell builtins and functions to be timed.
-
-@item --enable-cond-command
-Include support for the @code{[[} conditional command.
-(@pxref{Conditional Constructs}).
-
-@item --enable-cond-regexp
-Include support for matching POSIX regular expressions using the
-@samp{=~} binary operator in the @code{[[} conditional command.
-(@pxref{Conditional Constructs}).
-
-@item --enable-coprocesses
-Include support for coprocesses and the @code{coproc} reserved word
-(@pxref{Pipelines}).
-
-@item --enable-debugger
-Include support for the bash debugger (distributed separately).
-
-@item --enable-directory-stack
-Include support for a @code{csh}-like directory stack and the
-@code{pushd}, @code{popd}, and @code{dirs} builtins
-(@pxref{The Directory Stack}).
-
-@item --enable-disabled-builtins
-Allow builtin commands to be invoked via @samp{builtin xxx}
-even after @code{xxx} has been disabled using @samp{enable -n xxx}.
-See @ref{Bash Builtins}, for details of the @code{builtin} and
-@code{enable} builtin commands.
-
-@item --enable-dparen-arithmetic
-Include support for the @code{((@dots{}))} command
-(@pxref{Conditional Constructs}).
-
-@item --enable-extended-glob
-Include support for the extended pattern matching features described
-above under @ref{Pattern Matching}.
-
-@item --enable-extended-glob-default
-Set the default value of the @var{extglob} shell option described
-above under @ref{The Shopt Builtin} to be enabled.
-
-@item --enable-help-builtin
-Include the @code{help} builtin, which displays help on shell builtins and
-variables (@pxref{Bash Builtins}).
-
-@item --enable-history
-Include command history and the @code{fc} and @code{history}
-builtin commands (@pxref{Bash History Facilities}).
-
-@item --enable-job-control
-This enables the job control features (@pxref{Job Control}),
-if the operating system supports them.
-
-@item --enable-multibyte
-This enables support for multibyte characters if the operating
-system provides the necessary support.
-
-@item --enable-net-redirections
-This enables the special handling of filenames of the form
-@code{/dev/tcp/@var{host}/@var{port}} and
-@code{/dev/udp/@var{host}/@var{port}}
-when used in redirections (@pxref{Redirections}).
-
-@item --enable-process-substitution
-This enables process substitution (@pxref{Process Substitution}) if
-the operating system provides the necessary support.
-
-@item --enable-progcomp
-Enable the programmable completion facilities
-(@pxref{Programmable Completion}).
-If Readline is not enabled, this option has no effect.
-
-@item --enable-prompt-string-decoding
-Turn on the interpretation of a number of backslash-escaped characters
-in the @env{$PS1}, @env{$PS2}, @env{$PS3}, and @env{$PS4} prompt
-strings.  See @ref{Printing a Prompt}, for a complete list of prompt
-string escape sequences.
-
-@item --enable-readline
-Include support for command-line editing and history with the Bash
-version of the Readline library (@pxref{Command Line Editing}).
-
-@item --enable-restricted
-Include support for a @dfn{restricted shell}.  If this is enabled, Bash,
-when called as @code{rbash}, enters a restricted mode.  See
-@ref{The Restricted Shell}, for a description of restricted mode.
-
-@item --enable-select
-Include the @code{select} builtin, which allows the generation of simple
-menus (@pxref{Conditional Constructs}).
-
-@item --enable-separate-helpfiles
-Use external files for the documentation displayed by the @code{help} builtin
-instead of storing the text internally.
-
-@item --enable-single-help-strings
-Store the text displayed by the @code{help} builtin as a single string for
-each help topic.  This aids in translating the text to different languages.
-You may need to disable this if your compiler cannot handle very long string
-literals.
-
-@item --enable-strict-posix-default
-Make Bash @sc{posix}-conformant by default (@pxref{Bash POSIX Mode}).
-
-@item --enable-usg-echo-default
-A synonym for @code{--enable-xpg-echo-default}.
-
-@item --enable-xpg-echo-default
-Make the @code{echo} builtin expand backslash-escaped characters by default,
-without requiring the @option{-e} option.
-This sets the default value of the @code{xpg_echo} shell option to @code{on},
-which makes the Bash @code{echo} behave more like the version specified in
-the Single Unix Specification, version 3.
-@xref{Bash Builtins}, for a description of the escape sequences that
-@code{echo} recognizes.
-
-@end table
-
-The file @file{config-top.h} contains C Preprocessor
-@samp{#define} statements for options which are not settable from
-@code{configure}.
-Some of these are not meant to be changed; beware of the consequences if
-you do.
-Read the comments associated with each definition for more
-information about its effect.
-
-@node Reporting Bugs
-@appendix Reporting Bugs
-
-Please report all bugs you find in Bash.
-But first, you should
-make sure that it really is a bug, and that it appears in the latest
-version of Bash.
-The latest version of Bash is always available for FTP from
-@uref{ftp://ftp.gnu.org/pub/gnu/bash/}.
-
-Once you have determined that a bug actually exists, use the
-@code{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 @email{bug-bash@@gnu.org} or posted to the Usenet
-newsgroup @code{gnu.bash.bug}.
-
-All bug reports should include:
-@itemize @bullet
-@item
-The version number of Bash.
-@item
-The hardware and operating system.
-@item
-The compiler used to compile Bash.
-@item
-A description of the bug behaviour.
-@item
-A short script or `recipe' which exercises the bug and may be used
-to reproduce it.
-@end itemize
-
-@noindent
-@code{bashbug} inserts the first three items automatically into
-the template it provides for filing a bug report.
-
-Please send all reports concerning this manual to
-@email{chet.ramey@@case.edu}.
-
-@node Major Differences From The Bourne Shell
-@appendix Major Differences From The Bourne Shell
-
-Bash implements essentially the same grammar, parameter and
-variable expansion, redirection, and quoting as the Bourne Shell. 
-Bash uses the @sc{posix} standard as the specification of
-how these features are to be implemented.  There are some
-differences between the traditional Bourne shell and Bash; this
-section quickly details the differences of significance.  A
-number of these differences are explained in greater depth in
-previous sections.
-This section uses the version of @code{sh} included in SVR4.2 (the
-last version of the historical Bourne shell) as the baseline reference.
-
-@itemize @bullet
-
-@item
-Bash is @sc{posix}-conformant, even where the @sc{posix} specification
-differs from traditional @code{sh} behavior (@pxref{Bash POSIX Mode}).
-
-@item
-Bash has multi-character invocation options (@pxref{Invoking Bash}).
-
-@item
-Bash has command-line editing (@pxref{Command Line Editing}) and
-the @code{bind} builtin.
-
-@item
-Bash provides a programmable word completion mechanism
-(@pxref{Programmable Completion}), and builtin commands
-@code{complete}, @code{compgen}, and @code{compopt}, to
-manipulate it.
-
-@item
-Bash has command history (@pxref{Bash History Facilities}) and the
-@code{history} and @code{fc} builtins to manipulate it.
-The Bash history list maintains timestamp information and uses the
-value of the @code{HISTTIMEFORMAT} variable to display it.
-
-@item
-Bash implements @code{csh}-like history expansion
-(@pxref{History Interaction}).
-
-@item
-Bash has one-dimensional array variables (@pxref{Arrays}), and the
-appropriate variable expansions and assignment syntax to use them.
-Several of the Bash builtins take options to act on arrays.
-Bash provides a number of built-in array variables.
-
-@item
-The @code{$'@dots{}'} quoting syntax, which expands ANSI-C
-backslash-escaped characters in the text between the single quotes,
-is supported (@pxref{ANSI-C Quoting}).
-
-@item
-Bash supports the @code{$"@dots{}"} quoting syntax to do
-locale-specific translation of the characters between the double
-quotes.  The @option{-D}, @option{--dump-strings}, and @option{--dump-po-strings}
-invocation options list the translatable strings found in a script
-(@pxref{Locale Translation}).
-
-@item
-Bash implements the @code{!} keyword to negate the return value of
-a pipeline (@pxref{Pipelines}).
-Very useful when an @code{if} statement needs to act only if a test fails.
-The Bash @samp{-o pipefail} option to @code{set} will cause a pipeline to
-return a failure status if any command fails.
-
-@item
-Bash has the @code{time} reserved word and command timing (@pxref{Pipelines}).
-The display of the timing statistics may be controlled with the
-@env{TIMEFORMAT} variable.
-
-@item
-Bash implements the @code{for (( @var{expr1} ; @var{expr2} ; @var{expr3} ))}
-arithmetic for command, similar to the C language (@pxref{Looping Constructs}).
-
-@item
-Bash includes the @code{select} compound command, which allows the
-generation of simple menus (@pxref{Conditional Constructs}).
-
-@item
-Bash includes the @code{[[} compound command, which makes conditional
-testing part of the shell grammar (@pxref{Conditional Constructs}), including
-optional regular expression matching.
-
-@item
-Bash provides optional case-insensitive matching for the @code{case} and
-@code{[[} constructs.
-
-@item
-Bash includes brace expansion (@pxref{Brace Expansion}) and tilde
-expansion (@pxref{Tilde Expansion}).
-
-@item
-Bash implements command aliases and the @code{alias} and @code{unalias}
-builtins (@pxref{Aliases}).
-
-@item
-Bash provides shell arithmetic, the @code{((} compound command
-(@pxref{Conditional Constructs}),
-and arithmetic expansion (@pxref{Shell Arithmetic}).
-
-@item
-Variables present in the shell's initial environment are automatically
-exported to child processes.  The Bourne shell does not normally do
-this unless the variables are explicitly marked using the @code{export}
-command.
-
-@item
-Bash supports the @samp{+=} assignment operator, which appends to the value
-of the variable named on the left hand side.
-
-@item
-Bash includes the @sc{posix} pattern removal @samp{%}, @samp{#}, @samp{%%}
-and @samp{##} expansions to remove leading or trailing substrings from
-variable values (@pxref{Shell Parameter Expansion}).
-
-@item
-The expansion @code{$@{#xx@}}, which returns the length of @code{$@{xx@}},
-is supported (@pxref{Shell Parameter Expansion}).
-
-@item
-The expansion @code{$@{var:}@var{offset}@code{[:}@var{length}@code{]@}},
-which expands to the substring of @code{var}'s value of length
-@var{length}, beginning at @var{offset}, is present
-(@pxref{Shell Parameter Expansion}).
-
-@item
-The expansion
-@code{$@{var/[/]}@var{pattern}@code{[/}@var{replacement}@code{]@}},
-which matches @var{pattern} and replaces it with @var{replacement} in
-the value of @code{var}, is available (@pxref{Shell Parameter Expansion}).
-
-@item
-The expansion @code{$@{!@var{prefix@}*}} expansion, which expands to
-the names of all shell variables whose names begin with @var{prefix},
-is available (@pxref{Shell Parameter Expansion}).
-
-@item
-Bash has @var{indirect} variable expansion using @code{$@{!word@}}
-(@pxref{Shell Parameter Expansion}).
-
-@item
-Bash can expand positional parameters beyond @code{$9} using
-@code{$@{@var{num}@}}.
-
-@item
-The @sc{posix} @code{$()} form of command substitution
-is implemented (@pxref{Command Substitution}),
-and preferred to the Bourne shell's @code{``} (which
-is also implemented for backwards compatibility).
-
-@item
-Bash has process substitution (@pxref{Process Substitution}).
-
-@item
-Bash automatically assigns variables that provide information about the
-current user (@env{UID}, @env{EUID}, and @env{GROUPS}), the current host
-(@env{HOSTTYPE}, @env{OSTYPE}, @env{MACHTYPE}, and @env{HOSTNAME}),
-and the instance of Bash that is running (@env{BASH},
-@env{BASH_VERSION}, and @env{BASH_VERSINFO}).  @xref{Bash Variables},
-for details.
-
-@item
-The @env{IFS} variable is used to split only the results of expansion,
-not all words (@pxref{Word Splitting}).
-This closes a longstanding shell security hole.
-
-@item
-Bash implements the full set of @sc{posix} filename expansion operators,
-including @var{character classes}, @var{equivalence classes}, and
-@var{collating symbols} (@pxref{Filename Expansion}).
-
-@item
-Bash implements extended pattern matching features when the @code{extglob}
-shell option is enabled (@pxref{Pattern Matching}).
-
-@item
-It is possible to have a variable and a function with the same name;
-@code{sh} does not separate the two name spaces.
-
-@item
-Bash functions are permitted to have local variables using the
-@code{local} builtin, and thus useful recursive functions may be written
-(@pxref{Bash Builtins}).
-
-@item
-Variable assignments preceding commands affect only that command, even
-builtins and functions (@pxref{Environment}).
-In @code{sh}, all variable assignments 
-preceding commands are global unless the command is executed from the
-file system.
-
-@item
-Bash performs filename expansion on filenames specified as operands
-to input and output redirection operators (@pxref{Redirections}).
-
-@item
-Bash contains the @samp{<>} redirection operator, allowing a file to be
-opened for both reading and writing, and the @samp{&>} redirection
-operator, for directing standard output and standard error to the same
-file (@pxref{Redirections}).
-
-@item
-Bash includes the @samp{<<<} redirection operator, allowing a string to
-be used as the standard input to a command.
-
-@item
-Bash implements the @samp{[n]<&@var{word}} and @samp{[n]>&@var{word}}
-redirection operators, which move one file descriptor to another.
-
-@item
-Bash treats a number of filenames specially when they are
-used in redirection operators (@pxref{Redirections}).
-
-@item
-Bash can open network connections to arbitrary machines and services
-with the redirection operators (@pxref{Redirections}).
-
-@item
-The @code{noclobber} option is available to avoid overwriting existing
-files with output redirection (@pxref{The Set Builtin}).
-The @samp{>|} redirection operator may be used to override @code{noclobber}.
-
-@item
-The Bash @code{cd} and @code{pwd} builtins (@pxref{Bourne Shell Builtins})
-each take @option{-L} and @option{-P} options to switch between logical and
-physical modes.
-
-@item
-Bash allows a function to override a builtin with the same name, and provides
-access to that builtin's functionality within the function via the
-@code{builtin} and @code{command} builtins (@pxref{Bash Builtins}).
-
-@item
-The @code{command} builtin allows selective disabling of functions
-when command lookup is performed (@pxref{Bash Builtins}).
-
-@item
-Individual builtins may be enabled or disabled using the @code{enable}
-builtin (@pxref{Bash Builtins}).
-
-@item
-The Bash @code{exec} builtin takes additional options that allow users
-to control the contents of the environment passed to the executed
-command, and what the zeroth argument to the command is to be
-(@pxref{Bourne Shell Builtins}).
-
-@item
-Shell functions may be exported to children via the environment
-using @code{export -f} (@pxref{Shell Functions}).
-
-@item
-The Bash @code{export}, @code{readonly}, and @code{declare} builtins can
-take a @option{-f} option to act on shell functions, a @option{-p} option to
-display variables with various attributes set in a format that can be
-used as shell input, a @option{-n} option to remove various variable
-attributes, and @samp{name=value} arguments to set variable attributes
-and values simultaneously.
-
-@item
-The Bash @code{hash} builtin allows a name to be associated with
-an arbitrary filename, even when that filename cannot be found by
-searching the @env{$PATH}, using @samp{hash -p}
-(@pxref{Bourne Shell Builtins}).
-
-@item
-Bash includes a @code{help} builtin for quick reference to shell
-facilities (@pxref{Bash Builtins}).
-
-@item
-The @code{printf} builtin is available to display formatted output
-(@pxref{Bash Builtins}).
-
-@item
-The Bash @code{read} builtin (@pxref{Bash Builtins})
-will read a line ending in @samp{\} with
-the @option{-r} option, and will use the @env{REPLY} variable as a
-default if no non-option arguments are supplied.
-The Bash @code{read} builtin
-also accepts a prompt string with the @option{-p} option and will use
-Readline to obtain the line when given the @option{-e} option.
-The @code{read} builtin also has additional options to control input:
-the @option{-s} option will turn off echoing of input characters as
-they are read, the @option{-t} option will allow @code{read} to time out
-if input does not arrive within a specified number of seconds, the
-@option{-n} option will allow reading only a specified number of
-characters rather than a full line, and the @option{-d} option will read
-until a particular character rather than newline.
-
-@item
-The @code{return} builtin may be used to abort execution of scripts
-executed with the @code{.} or @code{source} builtins
-(@pxref{Bourne Shell Builtins}).
-
-@item
-Bash includes the @code{shopt} builtin, for finer control of shell
-optional capabilities (@pxref{The Shopt Builtin}), and allows these options
-to be set and unset at shell invocation (@pxref{Invoking Bash}).
-
-@item
-Bash has much more optional behavior controllable with the @code{set}
-builtin (@pxref{The Set Builtin}).
-
-@item
-The @samp{-x} (@code{xtrace}) option displays commands other than
-simple commands when performing an execution trace
-(@pxref{The Set Builtin}).
-
-@item
-The @code{test} builtin (@pxref{Bourne Shell Builtins})
-is slightly different, as it implements the @sc{posix} algorithm,
-which specifies the behavior based on the number of arguments.
-
-@item
-Bash includes the @code{caller} builtin, which displays the context of
-any active subroutine call (a shell function or a script executed with
-the @code{.} or @code{source} builtins).  This supports the bash
-debugger.
-
-@item
-The @code{trap} builtin (@pxref{Bourne Shell Builtins}) allows a
-@code{DEBUG} pseudo-signal specification, similar to @code{EXIT}.
-Commands specified with a @code{DEBUG} trap are executed before every
-simple command, @code{for} command, @code{case} command,
-@code{select} command, every arithmetic @code{for} command, and before
-the first command executes in a shell function.
-The @code{DEBUG} trap is not inherited by shell functions unless the
-function has been given the @code{trace} attribute or the
-@code{functrace} option has been enabled using the @code{shopt} builtin.
-The @code{extdebug} shell option has additional effects on the
-@code{DEBUG} trap.
-
-The @code{trap} builtin (@pxref{Bourne Shell Builtins}) allows an
-@code{ERR} pseudo-signal specification, similar to @code{EXIT} and @code{DEBUG}.
-Commands specified with an @code{ERR} trap are executed after a simple
-command fails, with a few exceptions.
-The @code{ERR} trap is not inherited by shell functions unless the
-@code{-o errtrace} option to the @code{set} builtin is enabled.
-
-The @code{trap} builtin (@pxref{Bourne Shell Builtins}) allows a
-@code{RETURN} pseudo-signal specification, similar to
-@code{EXIT} and @code{DEBUG}.
-Commands specified with an @code{RETURN} trap are executed before
-execution resumes after a shell function or a shell script executed with
-@code{.} or @code{source} returns.
-The @code{RETURN} trap is not inherited by shell functions unless the
-function has been given the @code{trace} attribute or the
-@code{functrace} option has been enabled using the @code{shopt} builtin.
-
-@item
-The Bash @code{type} builtin is more extensive and gives more information
-about the names it finds (@pxref{Bash Builtins}).
-
-@item
-The Bash @code{umask} builtin permits a @option{-p} option to cause
-the output to be displayed in the form of a @code{umask} command
-that may be reused as input (@pxref{Bourne Shell Builtins}).
-
-@item
-Bash implements a @code{csh}-like directory stack, and provides the
-@code{pushd}, @code{popd}, and @code{dirs} builtins to manipulate it
-(@pxref{The Directory Stack}).
-Bash also makes the directory stack visible as the value of the
-@env{DIRSTACK} shell variable.
-
-@item
-Bash interprets special backslash-escaped characters in the prompt
-strings when interactive (@pxref{Printing a Prompt}).
-
-@item
-The Bash restricted mode is more useful (@pxref{The Restricted Shell});
-the SVR4.2 shell restricted mode is too limited.
-
-@item
-The @code{disown} builtin can remove a job from the internal shell
-job table (@pxref{Job Control Builtins}) or suppress the sending
-of @code{SIGHUP} to a job when the shell exits as the result of a
-@code{SIGHUP}.
-
-@item
-Bash includes a number of features to support a separate debugger for
-shell scripts.
-
-@item
-The SVR4.2 shell has two privilege-related builtins
-(@code{mldmode} and @code{priv}) not present in Bash.
-
-@item
-Bash does not have the @code{stop} or @code{newgrp} builtins.
-
-@item
-Bash does not use the @env{SHACCT} variable or perform shell accounting.
-
-@item
-The SVR4.2 @code{sh} uses a @env{TIMEOUT} variable like Bash uses
-@env{TMOUT}.
-
-@end itemize
-
-@noindent
-More features unique to Bash may be found in @ref{Bash Features}.
-
-
-@appendixsec Implementation Differences From The SVR4.2 Shell
-
-Since Bash is a completely new implementation, it does not suffer from
-many of the limitations of the SVR4.2 shell.  For instance:
-
-@itemize @bullet
-
-@item
-Bash does not fork a subshell when redirecting into or out of
-a shell control structure such as  an @code{if} or @code{while}
-statement.
-
-@item
-Bash does not allow unbalanced quotes.  The SVR4.2 shell will silently
-insert a needed closing quote at @code{EOF} under certain circumstances.
-This can be the cause of some hard-to-find errors.
-
-@item
-The SVR4.2 shell uses a baroque memory management scheme based on
-trapping @code{SIGSEGV}.  If the shell is started from a process with
-@code{SIGSEGV} blocked (e.g., by using the @code{system()} C library
-function call), it misbehaves badly.
-
-@item
-In a questionable attempt at security, the SVR4.2 shell,
-when invoked without the @option{-p} option, will alter its real
-and effective @sc{uid} and @sc{gid} if they are less than some
-magic threshold value, commonly 100.
-This can lead to unexpected results.
-
-@item
-The SVR4.2 shell does not allow users to trap @code{SIGSEGV},
-@code{SIGALRM}, or @code{SIGCHLD}.
-
-@item
-The SVR4.2 shell does not allow the @env{IFS}, @env{MAILCHECK},
-@env{PATH}, @env{PS1}, or @env{PS2} variables to be unset.
-
-@item
-The SVR4.2 shell treats @samp{^} as the undocumented equivalent of
-@samp{|}.
-
-@item
-Bash allows multiple option arguments when it is invoked (@code{-x -v});
-the SVR4.2 shell allows only one option argument (@code{-xv}).  In
-fact, some versions of the shell dump core if the second argument begins
-with a @samp{-}.
-
-@item
-The SVR4.2 shell exits a script if any builtin fails; Bash exits
-a script only if one of the @sc{posix} special builtins fails, and
-only for certain failures, as enumerated in the @sc{posix} standard.
-
-@item 
-The SVR4.2 shell behaves differently when invoked as @code{jsh}
-(it turns on job control).
-@end itemize
-
-@node GNU Free Documentation License
-@appendix GNU Free Documentation License
-
-@include fdl.texi
-
-@node Indexes
-@appendix Indexes
-
-@menu
-* Builtin Index::              Index of Bash builtin commands.
-* Reserved Word Index::                Index of Bash reserved words.
-* Variable Index::             Quick reference helps you find the
-                               variable you want.
-* Function Index::             Index of bindable Readline functions.
-* Concept Index::              General index for concepts described in
-                               this manual.
-@end menu
-
-@node Builtin Index
-@appendixsec Index of Shell Builtin Commands
-@printindex bt
-
-@node Reserved Word Index
-@appendixsec Index of Shell Reserved Words
-@printindex rw
-
-@node Variable Index
-@appendixsec Parameter and Variable Index
-@printindex vr
-
-@node Function Index
-@appendixsec Function Index
-@printindex fn
-
-@node Concept Index
-@appendixsec Concept Index
-@printindex cp
-
-@bye
diff --git a/doc/version.texi~ b/doc/version.texi~
deleted file mode 100644 (file)
index aea8988..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-@ignore
-Copyright (C) 1988-2009 Free Software Foundation, Inc.
-@end ignore
-
-@set LASTCHANGE Fri Oct  9 12:07:41 EDT 2009
-
-@set EDITION 4.1
-@set VERSION 4.1
-@set UPDATED 9 October 2009
-@set UPDATED-MONTH October 2009
diff --git a/error.c~ b/error.c~
deleted file mode 100644 (file)
index 8744806..0000000
--- a/error.c~
+++ /dev/null
@@ -1,454 +0,0 @@
-/* error.c -- Functions for handling errors. */
-
-/* Copyright (C) 1993-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/>.
-*/
-
-#include "config.h"
-
-#include "bashtypes.h"
-#include <fcntl.h>
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#if defined (PREFER_STDARG)
-#  include <stdarg.h>
-#else
-#  include <varargs.h>
-#endif
-
-#include <stdio.h>
-
-#include <errno.h>
-#if !defined (errno)
-extern int errno;
-#endif /* !errno */
-
-#include "bashansi.h"
-#include "bashintl.h"
-
-#include "shell.h"
-#include "flags.h"
-#include "input.h"
-
-#if defined (HISTORY)
-#  include "bashhist.h"
-#endif
-
-extern int executing_line_number __P((void));
-
-extern char *shell_name;
-#if defined (JOB_CONTROL)
-extern pid_t shell_pgrp;
-extern int give_terminal_to __P((pid_t, int));
-#endif /* JOB_CONTROL */
-
-#if defined (ARRAY_VARS)
-extern const char * const bash_badsub_errmsg;
-#endif
-
-static void error_prolog __P((int));
-
-/* The current maintainer of the shell.  You change this in the
-   Makefile. */
-#if !defined (MAINTAINER)
-#define MAINTAINER "bash-maintainers@gnu.org"
-#endif
-
-const char * const the_current_maintainer = MAINTAINER;
-
-int gnu_error_format = 0;
-
-static void
-error_prolog (print_lineno)
-     int print_lineno;
-{
-  char *ename;
-  int line;
-
-  ename = get_name_for_error ();
-  line = (print_lineno && interactive_shell == 0) ? executing_line_number () : -1;
-
-  if (line > 0)
-    fprintf (stderr, "%s:%s%d: ", ename, gnu_error_format ? "" : _(" line "), line);
-  else
-    fprintf (stderr, "%s: ", ename);
-}
-
-/* Return the name of the shell or the shell script for error reporting. */
-char *
-get_name_for_error ()
-{
-  char *name;
-#if defined (ARRAY_VARS)
-  SHELL_VAR *bash_source_v;
-  ARRAY *bash_source_a;
-#endif
-
-  name = (char *)NULL;
-  if (interactive_shell == 0)
-    {
-#if defined (ARRAY_VARS)
-      bash_source_v = find_variable ("BASH_SOURCE");
-      if (bash_source_v && array_p (bash_source_v) &&
-         (bash_source_a = array_cell (bash_source_v)))
-       name = array_reference (bash_source_a, 0);
-      if (name == 0 || *name == '\0')  /* XXX - was just name == 0 */
-#endif
-       name = dollar_vars[0];
-    }
-  if (name == 0 && shell_name && *shell_name)
-    name = base_pathname (shell_name);
-  if (name == 0)
-#if defined (PROGRAM)
-    name = PROGRAM;
-#else
-    name = "bash";
-#endif
-
-  return (name);
-}
-
-/* Report an error having to do with FILENAME.  This does not use
-   sys_error so the filename is not interpreted as a printf-style
-   format string. */
-void
-file_error (filename)
-     const char *filename;
-{
-  report_error ("%s: %s", filename, strerror (errno));
-}
-
-void
-#if defined (PREFER_STDARG)
-programming_error (const char *format, ...)
-#else
-programming_error (format, va_alist)
-     const char *format;
-     va_dcl
-#endif
-{
-  va_list args;
-  char *h;
-
-#if defined (JOB_CONTROL)
-  give_terminal_to (shell_pgrp, 0);
-#endif /* JOB_CONTROL */
-
-  SH_VA_START (args, format);
-
-  vfprintf (stderr, format, args);
-  fprintf (stderr, "\n");
-  va_end (args);
-
-#if defined (HISTORY)
-  if (remember_on_history)
-    {
-      h = last_history_line ();
-      fprintf (stderr, _("last command: %s\n"), h ? h : "(null)");
-    }
-#endif
-
-#if 0
-  fprintf (stderr, "Report this to %s\n", the_current_maintainer);
-#endif
-
-  fprintf (stderr, _("Aborting..."));
-  fflush (stderr);
-
-  abort ();
-}
-
-/* Print an error message and, if `set -e' has been executed, exit the
-   shell.  Used in this file by file_error and programming_error.  Used
-   outside this file mostly to report substitution and expansion errors,
-   and for bad invocation options. */
-void
-#if defined (PREFER_STDARG)
-report_error (const char *format, ...)
-#else
-report_error (format, va_alist)
-     const char *format;
-     va_dcl
-#endif
-{
-  va_list args;
-
-  error_prolog (1);
-
-  SH_VA_START (args, format);
-
-  vfprintf (stderr, format, args);
-  fprintf (stderr, "\n");
-
-  va_end (args);
-  if (exit_immediately_on_error)
-    exit_shell (1);
-}
-
-void
-#if defined (PREFER_STDARG)
-fatal_error (const char *format, ...)
-#else
-fatal_error (format, va_alist)
-     const char *format;
-     va_dcl
-#endif
-{
-  va_list args;
-
-  error_prolog (0);
-
-  SH_VA_START (args, format);
-
-  vfprintf (stderr, format, args);
-  fprintf (stderr, "\n");
-
-  va_end (args);
-  sh_exit (2);
-}
-
-void
-#if defined (PREFER_STDARG)
-internal_error (const char *format, ...)
-#else
-internal_error (format, va_alist)
-     const char *format;
-     va_dcl
-#endif
-{
-  va_list args;
-
-  error_prolog (1);
-
-  SH_VA_START (args, format);
-
-  vfprintf (stderr, format, args);
-  fprintf (stderr, "\n");
-
-  va_end (args);
-}
-
-void
-#if defined (PREFER_STDARG)
-internal_warning (const char *format, ...)
-#else
-internal_warning (format, va_alist)
-     const char *format;
-     va_dcl
-#endif
-{
-  va_list args;
-
-  error_prolog (1);
-  fprintf (stderr, _("warning: "));
-
-  SH_VA_START (args, format);
-
-  vfprintf (stderr, format, args);
-  fprintf (stderr, "\n");
-
-  va_end (args);
-}
-
-void
-#if defined (PREFER_STDARG)
-sys_error (const char *format, ...)
-#else
-sys_error (format, va_alist)
-     const char *format;
-     va_dcl
-#endif
-{
-  int e;
-  va_list args;
-
-  e = errno;
-  error_prolog (0);
-
-  SH_VA_START (args, format);
-
-  vfprintf (stderr, format, args);
-  fprintf (stderr, ": %s\n", strerror (e));
-
-  va_end (args);
-}
-
-/* An error from the parser takes the general form
-
-       shell_name: input file name: line number: message
-
-   The input file name and line number are omitted if the shell is
-   currently interactive.  If the shell is not currently interactive,
-   the input file name is inserted only if it is different from the
-   shell name. */
-void
-#if defined (PREFER_STDARG)
-parser_error (int lineno, const char *format, ...)
-#else
-parser_error (lineno, format, va_alist)
-     int lineno;
-     const char *format;
-     va_dcl
-#endif
-{
-  va_list args;
-  char *ename, *iname;
-
-  ename = get_name_for_error ();
-  iname = yy_input_name ();
-
-  if (interactive)
-    fprintf (stderr, "%s: ", ename);
-  else if (interactive_shell)
-    fprintf (stderr, "%s: %s:%s%d: ", ename, iname, gnu_error_format ? "" : _(" line "), lineno);
-  else if (STREQ (ename, iname))
-    fprintf (stderr, "%s:%s%d: ", ename, gnu_error_format ? "" : _(" line "), lineno);
-  else
-    fprintf (stderr, "%s: %s:%s%d: ", ename, iname, gnu_error_format ? "" : _(" line "), lineno);
-
-  SH_VA_START (args, format);
-
-  vfprintf (stderr, format, args);
-  fprintf (stderr, "\n");
-
-  va_end (args);
-
-  if (exit_immediately_on_error)
-    exit_shell (last_command_exit_value = 2);
-}
-
-#ifdef DEBUG
-void
-#if defined (PREFER_STDARG)
-itrace (const char *format, ...)
-#else
-itrace (format, va_alist)
-     const char *format;
-     va_dcl
-#endif
-{
-  va_list args;
-
-  fprintf(stderr, "TRACE: pid %ld: ", (long)getpid());
-
-  SH_VA_START (args, format);
-
-  vfprintf (stderr, format, args);
-  fprintf (stderr, "\n");
-
-  va_end (args);
-
-  fflush(stderr);
-}
-
-/* A trace function for silent debugging -- doesn't require a control
-   terminal. */
-void
-#if defined (PREFER_STDARG)
-trace (const char *format, ...)
-#else
-trace (format, va_alist)
-     const char *format;
-     va_dcl
-#endif
-{
-  va_list args;
-  static FILE *tracefp = (FILE *)NULL;
-
-  if (tracefp == NULL)
-    tracefp = fopen("/tmp/bash-trace.log", "a+");
-
-  if (tracefp == NULL)
-    tracefp = stderr;
-  else
-    fcntl (fileno (tracefp), F_SETFD, 1);     /* close-on-exec */
-
-  fprintf(tracefp, "TRACE: pid %ld: ", (long)getpid());
-
-  SH_VA_START (args, format);
-
-  vfprintf (tracefp, format, args);
-  fprintf (tracefp, "\n");
-
-  va_end (args);
-
-  fflush(tracefp);
-}
-
-#endif /* DEBUG */
-
-/* **************************************************************** */
-/*                                                                 */
-/*                 Common error reporting                          */
-/*                                                                 */
-/* **************************************************************** */
-
-
-static const char * const cmd_error_table[] = {
-       N_("unknown command error"),    /* CMDERR_DEFAULT */
-       N_("bad command type"),         /* CMDERR_BADTYPE */
-       N_("bad connector"),            /* CMDERR_BADCONN */
-       N_("bad jump"),                 /* CMDERR_BADJUMP */
-       0
-};
-
-void
-command_error (func, code, e, flags)
-     const char *func;
-     int code, e, flags;       /* flags currently unused */
-{
-  if (code > CMDERR_LAST)
-    code = CMDERR_DEFAULT;
-
-  programming_error ("%s: %s: %d", func, _(cmd_error_table[code]), e);
-}
-
-char *
-command_errstr (code)
-     int code;
-{
-  if (code > CMDERR_LAST)
-    code = CMDERR_DEFAULT;
-
-  return (_(cmd_error_table[code]));
-}
-
-#ifdef ARRAY_VARS
-void
-err_badarraysub (s)
-     const char *s;
-{
-  report_error ("%s: %s", s, _(bash_badsub_errmsg));
-}
-#endif
-
-void
-err_unboundvar (s)
-     const char *s;
-{
-  report_error (_("%s: unbound variable"), s);
-}
-
-void
-err_readonly (s)
-     const char *s;
-{
-  report_error (_("%s: readonly variable"), s);
-}
diff --git a/examples/loadables/Makefile.in.save b/examples/loadables/Makefile.in.save
deleted file mode 100644 (file)
index f6208f5..0000000
+++ /dev/null
@@ -1,238 +0,0 @@
-#
-# 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/examples/scripts/adventure.sh.save1 b/examples/scripts/adventure.sh.save1
deleted file mode 100755 (executable)
index 4e22393..0000000
+++ /dev/null
@@ -1,549 +0,0 @@
-#!/bin/bash
-#      ash -- "Adventure shell"
-#      last edit:      86/04/21        D A Gwyn
-#      SCCS ID:        @(#)ash.sh      1.4
-
-OPATH=$PATH
-
-ask()
-{
-       echo -n "$@" '[y/n] '
-       read ans
-
-       case "$ans" in
-       y*|Y*)
-               return 0
-               ;;
-       *)
-               return 1
-               ;;
-       esac
-}
-       
-CAT=${PAGER:-more}
-
-ash_inst()
-{
-       cat <<- EOF
-
-                       Instructions for the Adventure shell
-
-       Welcome to the Adventure shell!  In this exploration of the UNIX file
-       system, I will act as your eyes and hands.  As you move around, I will
-       describe whatever is visible and will carry out your commands.  The
-       general form of a command is
-               Verb Object Extra_stuff.
-       Most commands pay no attention to the "Extra_stuff", and many do not
-       need an "Object".  A typical command is
-               get all
-       which picks up all files in the current "room" (directory).  You can
-       find out what you are carrying by typing the command
-               inventory
-       The command "help" results in a full description of all commands that I
-       understand.  To quit the Adventure shell, type
-               quit
-
-       There are UNIX monsters lurking in the background.  These are also
-       known as "commands with arguments".
-
-       Good luck!
-       EOF
-}
-
-ash_help()
-{
-echo "I understand the following commands (synonyms in parentheses):"
-echo ""
-
-echo "change OBJECT to NEW_NAME       changes the name of the object"
-echo "clone OBJECT as NEW_NAME        duplicates the object"
-echo "drop OBJECTS                    leaves the objects in the room"
-echo "enter (go) PASSAGE              takes the labeled passage"
-echo "examine OBJECTS                 describes the objects in detail"
-echo "feed OBJECT to MONSTER          stuffs the object into a UNIX monster"
-echo "get (take) OBJECTS              picks up the specified objects"
-echo "gripe (bug)                     report a problem with the Adventure shell"
-echo "help                            prints this summary"
-echo "inventory (i)                   tells what you are carrying"
-echo "kill (destroy) OBJECTS          destroys the objects"
-echo "look (l)                        describes the room, including hidden objects"
-echo "open (read) OBJECT              shows the contents of an object"
-echo "quit (exit)                     leaves the Adventure shell"
-echo "resurrect OBJECTS               attempts to restore dead objects"
-echo "steal OBJECT from MONSTER       obtains the object from a UNIX monster"
-echo "throw OBJECT at daemon          feeds the object to the printer daemon"
-echo "up                              takes the overhead passage"
-echo "wake MONSTER                    awakens a UNIX monster"
-echo "where (w)                       tells you where you are"
-echo "xyzzy                           moves you to your home"
-}
-       
-MAINT=chet@ins.cwru.edu
-
-PATH=/usr/ucb:/bin:/usr/bin:/usr/local/bin:.
-export PATH
-
-trap 'echo Ouch!' 2 3
-#trap '' 18                    # disable Berkeley job control
-
-ash_lk(){ echo " $1 " | fgrep " $2 " >&- 2>&-; }
-ash_pr(){ echo $* | tr ' ' '\012' | pr -5 -t -w75 -l$[ ( $# + 4 ) / 5 ]; }
-ash_rm(){ echo " $1 " | sed -e "s/ $2 / /" -e 's/^ //' -e 's/ $//'; }
-
-# enable history, bang history expansion, and emacs editing
-set -o history
-set -o histexpand
-set -o emacs
-
-cd
-LIM=.limbo                     # $HOME/$LIM contains "destroyed" objects
-mkdir $LIM >&- 2>&-
-KNAP=.knapsack                 # $HOME/$KNAP contains objects being "carried"
-if [ ! -d $KNAP ]
-then   mkdir $KNAP >&- 2>&-
-       if [ $? = 0 ]
-       then    echo 'You found a discarded empty knapsack.'
-       else    echo 'You have no knapsack to carry things in.'
-               exit 1
-       fi
-else   echo 'One moment while I peek in your old knapsack...'
-fi
-
-kn=`echo \`ls -a $KNAP | sed -e '/^\.$/d' -e '/^\.\.$/d'\``
-
-if ask 'Welcome to the Adventure shell!  Do you need instructions?'
-then
-       ash_inst
-       echo -n 'Type a newline to continue: '
-       read
-fi
-
-wiz=false
-cha=false
-prev=$LIM
-while :
-do     room=`pwd`
-       if [ $room != $prev ]
-       then    if [ $room = $HOME ]
-               then    echo 'You are in your own home.'
-               else    echo "You have entered $room."
-               fi
-               exs=
-               obs=
-               hexs=
-               hobs=
-               f=false
-               for i in `ls -a`
-               do      case $i in
-                       .|..)   ;;
-                       .*)     if [ -f $i ]
-                               then    hobs="$hobs $i"
-                               elif [ -d $i ]
-                               then    hexs="$hexs $i"
-                               else    f=true
-                               fi
-                               ;;
-                       *)      if [ -f $i ]
-                               then    obs="$obs $i"
-                               elif [ -d $i ]
-                               then    exs="$exs $i"
-                               else    f=true
-                               fi
-                               ;;
-                       esac
-               done
-               if [ "$obs" ]
-               then    echo 'This room contains:'
-                       ash_pr $obs
-               else    echo 'The room looks empty.'
-               fi
-               if [ "$exs" ]
-               then    echo 'There are exits labeled:'
-                       ash_pr $exs
-                       echo 'as well as a passage overhead.'
-               else    echo 'There is a passage overhead.'
-               fi
-               if sh -c $f
-               then    echo 'There are shadowy figures in the corner.'
-               fi
-               prev=$room
-       fi
-
-       read -e -p '-advsh> ' verb obj x        # prompt is '-advsh> '
-       if [ $? != 0 ]
-       then    verb=quit               # EOF
-       fi
-
-       case $verb in
-       change)         if [ "$obj" ]
-                       then    if ash_lk "$obs $hobs" "$obj"
-                               then    set -- $x
-                                       case "$1" in
-                                       to)     if [ "$2" ]
-                                               then    if [ -f $2 ]
-                                                       then    echo "You must destroy $2 first."
-                                                               set --
-                                                       fi
-                                                       if [ "$2" ]
-                                                       then    if mv $obj $2 >&- 2>&-
-                                                               then    echo "The $obj shimmers and turns into $2."
-                                                                       obs=`ash_rm "$2 $obs" "$obj"`
-                                                               else    echo "There is a cloud of smoke but the $obj is unchanged."
-                                                               fi
-                                                       fi
-                                               else    echo 'To what?'
-                                               fi
-                                               ;;
-                                       *)      echo "Change $obj to what?"
-                                               ;;
-                                       esac
-                               else    if ash_lk "$kn" "$obj"
-                                       then    echo 'You must drop it first.'
-                                       else    echo "I see no $obj here."
-                                       fi
-                               fi
-                       else    echo 'Change what?'
-                       fi
-                       ;;
-       clone)          if [ "$obj" ]
-                       then    if ash_lk "$obs $hobs" "$obj"
-                               then    if [ ! -r $obj ]
-                                       then    echo "The $obj does not wish to be cloned."
-                                       else    set -- $x
-                                               case "$1" in
-                                               as)     if [ "$2" ]
-                                                       then    if [ -f $2 ]
-                                                               then    echo "You must destroy $2 first."
-                                                               else    if cp $obj $2 >&- 2>&-
-                                                                       then    echo "Poof!  When the smoke clears, you see the new $2."
-                                                                               obs="$obs $2"
-                                                                       else    echo 'You hear a dull thud but no clone appears.'
-                                                                       fi
-                                                               fi
-                                                       else    echo 'As what?'
-                                                       fi
-                                                       ;;
-                                               *)      echo "Clone $obj as what?"
-                                                       ;;
-                                               esac
-                                       fi
-                               else    if ash_lk "$kn" "$obj"
-                                       then    echo 'You must drop it first.'
-                                       else    echo "I see no $obj here."
-                                       fi
-                               fi
-                       else    echo 'Clone what?'
-                       fi
-                       ;;
-       drop)           if [ "$obj" ]
-                       then    for it in $obj $x
-                               do      if ash_lk "$kn" "$it"
-                                       then    if [ -w $it ]
-                                               then    echo "You must destroy $it first."
-                                               else    if mv $HOME/$KNAP/$it $it >&- 2>&-
-                                                       then    echo "$it: dropped."
-                                                               kn=`ash_rm "$kn" "$it"`
-                                                               obs=`echo $it $obs`
-                                                       else    echo "The $it is caught in your knapsack."
-                                                       fi
-                                               fi
-                                       else    echo "You're not carrying the $it!"
-                                       fi
-                               done
-                       else    echo 'Drop what?'
-                       fi
-                       ;;
-       enter|go)       if [ "$obj" ]
-                       then    if [ $obj != up ]
-                               then    if ash_lk "$exs $hexs" "$obj"
-                                       then    if [ -x $obj ]
-                                               then    if cd $obj
-                                                       then    echo 'You squeeze through the passage.'
-                                                       else    echo "You can't go that direction."
-                                                       fi
-                                               else    echo 'An invisible force blocks your way.'
-                                               fi
-                                       else    echo 'I see no such passage.'
-                                       fi
-                               else    if cd ..
-                                       then    echo 'You struggle upwards.'
-                                       else    echo "You can't reach that high."
-                                       fi
-                               fi
-                       else    echo 'Which passage?'
-                       fi
-                       ;;
-       examine)        if [ "$obj" ]
-                       then    if [ $obj = all ]
-                               then    $obj=`echo $obs $exs`
-                                       x=
-                               fi
-                               for it in $obj $x
-                               do      if ash_lk "$obs $hobs $exs $hexs" "$it"
-                                       then    echo "Upon close inspection of the $it, you see:"
-                                               ls -ld $it 2>&-
-                                               if [ $? != 0 ]
-                                               then    echo "-- when you look directly at the $it, it vanishes."
-                                               fi
-                                       else    if ash_lk "$kn" "$it"
-                                               then    echo 'You must drop it first.'
-                                               else    echo "I see no $it here."
-                                               fi
-                                       fi
-                               done
-                       else    echo 'Examine what?'
-                       fi
-                       ;;
-       feed)           if [ "$obj" ]
-                       then    if ash_lk "$obs $hobs" "$obj"
-                               then    set -- $x
-                                       case "$1" in
-                                       to)     if [ "$2" ]
-                                               then    shift
-                                                       if PATH=$OPATH $* <$obj 2>&-
-                                                       then    echo "The $1 monster devours your $obj."
-                                                               if rm -f $obj >&- 2>&-
-                                                               then    obs=`ash_rm "$obs" "$obj"`
-                                                               else    echo 'But he spits it back up.'
-                                                               fi
-                                                       else    echo "The $1 monster holds his nose in disdain."
-                                                       fi
-                                               else    echo 'To what?'
-                                               fi
-                                               ;;
-                                       *)      echo "Feed $obj to what?"
-                                               ;;
-                                       esac
-                               else    if ash_lk "$kn" "$obj"
-                                       then    echo 'You must drop it first.'
-                                       else    echo "I see no $obj here."
-                                       fi
-                               fi
-                       else    echo 'Feed what?'
-                       fi
-                       ;;
-       get|take)       if [ "$obj" ]
-                       then    if [ $obj = all ]
-                               then    obj="$obs"
-                                       x=
-                               fi
-                               for it in $obj $x
-                               do      if ash_lk "$obs $hobs" "$it"
-                                       then    if ash_lk "$kn" "$it"
-                                               then    echo 'You already have one.'
-                                               else    if mv $it $HOME/$KNAP/$it >&- 2>&-
-                                                       then    echo "$it: taken."
-                                                               kn="$it $kn"
-                                                               obs=`ash_rm "$obs" "$it"`
-                                                       else    echo "The $it is too heavy."
-                                                       fi
-                                               fi
-                                       else    echo "I see no $it here."
-                                       fi
-                               done
-                       else    echo 'Get what?'
-                       fi
-                       ;;
-       gripe|bug)      echo 'Please describe the problem and your situation at the time it failed.\nEnd the bug report with a line containing just a Ctrl-D.'
-                       cat | mail $MAINT -s 'ash bug'
-                       echo 'Thank you!'
-                       ;;
-       help)           ash_help
-                       ;;
-       inventory|i)    if [ "$kn" ]
-                       then    echo 'Your knapsack contains:'
-                               ash_pr $kn
-                       else    echo 'You are poverty-stricken.'
-                       fi
-                       ;;
-       kill|destroy)   if [ "$obj" ]
-                       then    if [ $obj = all ]
-                               then    x=
-                                       if ask "Do you really want to attempt to $verb them all?"
-                                       then    obj=`echo $obs`
-                                       else    echo 'Chicken!'
-                                               obj=
-                                       fi
-                               fi
-                               for it in $obj $x
-                               do      if ash_lk "$obs $hobs" "$it"
-                                       then    if mv $it $HOME/$LIM <&- >&- 2>&-
-                                               then    if [ $verb = kill ]
-                                                       then    echo "The $it cannot defend himself; he dies."
-                                                       else    echo "You have destroyed the $it; it vanishes."
-                                                       fi
-                                                       obs=`ash_rm "$obs" "$it"`
-                                               else    if [ $verb = kill ]
-                                                       then    echo "Your feeble blows are no match for the $it."
-                                                       else    echo "The $it is indestructible."
-                                                       fi
-                                               fi
-                                       else    if ash_lk "$kn" "$it"
-                                               then    echo "You must drop the $it first."
-                                                       found=false
-                                               else    echo "I see no $it here."
-                                               fi
-                                       fi
-                               done
-                       else    echo 'Kill what?'
-                       fi
-                       ;;
-       look|l)         obs=`echo $obs $hobs`
-                       hobs=
-                       if [ "$obs" ]
-                       then    echo 'The room contains:'
-                               ash_pr $obs
-                       else    echo 'The room is empty.'
-                       fi
-                       exs=`echo $exs $hexs`
-                       hexs=
-                       if [ "$exs" ]
-                       then    echo 'There are exits plainly labeled:'
-                               ash_pr $exs
-                               echo 'and a passage directly overhead.'
-                       else    echo 'The only exit is directly overhead.'
-                       fi
-                       ;;
-       magic)          if [ "$obj" = mode ]
-                       then    if sh -c $cha
-                               then    echo 'You had your chance and you blew it.'
-                               else    if ask 'Are you a wizard?'
-                                       then    echo -n 'Prove it!  Say the magic word: '
-                                               read obj
-                                               if [ "$obj" = armadillo ]
-                                               then    echo 'Yes, master!!'
-                                                       wiz=true
-                                               else    echo "Homie says: I don't think so"
-                                                       cha=true
-                                               fi
-                                       else    echo "I didn't think so."
-                                       fi
-                               fi
-                       else    echo 'Nice try.'
-                       fi
-                       ;;
-       open|read)      if [ "$obj" ]
-                       then    if ash_lk "$obs $hobs" "$obj"
-                               then    if [ -r $obj ]
-                                       then    if [ -s $obj ]
-                                               then    echo "Opening the $obj reveals:"
-                                                       $CAT < $obj
-                                                       if [ $? != 0 ]
-                                                       then    echo '-- oops, you lost the contents!'
-                                                       fi
-                                               else    echo "There is nothing inside the $obj."
-                                               fi
-                                       else    echo "You do not have the proper tools to open the $obj."
-                                       fi
-                               else    if ash_lk "$kn" "$obj"
-                                       then    echo 'You must drop it first.'
-                                               found=false
-                                       else    echo "I see no $obj here."
-                                       fi
-                               fi
-                       else    echo 'Open what?'
-                       fi
-                       ;;
-       quit|exit)      if ask 'Do you really want to quit now?'
-                       then    if [ "$kn" ]
-                               then    echo 'The contents of your knapsack will still be there next time.'
-                               fi
-                               rm -rf $HOME/$LIM
-                               echo 'See you later!'
-                               exit 0
-                       fi
-                       ;;
-       resurrect)      if [ "$obj" ]
-                       then    for it in $obj $x
-                               do      if ash_lk "$obs $hobs" "$it"
-                                       then    echo "The $it is already alive and well."
-                                       else    if mv $HOME/$LIM/$it $it <&- >&- 2>&-
-                                               then    echo "The $it staggers to his feet."
-                                                       obs=`echo $it $obs`
-                                               else    echo "There are sparks but no $it appears."
-                                               fi
-                                       fi
-                               done
-                       else    echo 'Resurrect what?'
-                       fi
-                       ;;
-       steal)          if [ "$obj" ]
-                       then    if ash_lk "$obs $hobs" "$obj"
-                               then    echo 'There is already one here.'
-                               else    set -- $x
-                                       case "$1" in
-                                       from)   if [ "$2" ]
-                                               then    shift
-                                                       if PATH=$OPATH $* >$obj 2>&-
-                                                       then    echo "The $1 monster drops the $obj."
-                                                               obs=`echo $obj $obs`
-                                                       else    echo "The $1 monster runs away as you approach."
-                                                               rm -f $obj >&- 2>&-
-                                                       fi
-                                               else    echo 'From what?'
-                                               fi
-                                               ;;
-                                       *)      echo "Steal $obj from what?"
-                                               ;;
-                                       esac
-                               fi
-                       else    echo 'Steal what?'
-                       fi
-                       ;;
-       throw)          if [ "$obj" ]
-                       then    if ash_lk "$obs $hobs" "$obj"
-                               then    set -- $x
-                                       case "$1" in
-                                       at)     case "$2" in
-                                               daemon) if sh -c "lpr -r $obj"
-                                                       then    echo "The daemon catches the $obj, turns it into paper,\nand leaves it in the basket."
-                                                               obs=`ash_rm "$obs" "$obj"`
-                                                       else    echo "The daemon is nowhere to be found."
-                                                       fi
-                                                       ;;
-                                               *)      echo 'At what?'
-                                                       ;;
-                                               esac
-                                               ;;
-                                       *)      echo "Throw $obj at what?"
-                                               ;;
-                                       esac
-                               else    if ash_lk "$kn" "$obj"
-                                       then    echo 'It is in your knapsack.'
-                                               found=false
-                                       else    echo "I see no $obj here."
-                                       fi
-                               fi
-                       else    echo 'Throw what?'
-                       fi
-                       ;;
-       u|up)           if cd ..
-                       then    echo 'You pull yourself up a level.'
-                       else    echo "You can't reach that high."
-                       fi
-                       ;;
-       wake)           if [ "$obj" ]
-                       then    echo "You awaken the $obj monster:"
-                               PATH=$OPATH $obj $x
-                               echo 'The monster slithers back into the darkness.'
-                       else    echo 'Wake what?'
-                       fi
-                       ;;
-       w|where)        echo "You are in $room."
-                       ;;
-       xyzzy)          if cd
-                       then    echo 'A strange feeling comes over you.'
-                       else    echo 'Your spell fizzles out.'
-                       fi
-                       ;;
-       *)              if [ "$verb" ]
-                       then    if sh -c $wiz
-                               then    PATH=$OPATH $verb $obj $x
-                               else    echo "I don't know how to \"$verb\"."
-                                       echo 'Type "help" for assistance.'
-                               fi
-                       else    echo 'Say something!'
-                       fi
-                       ;;
-       esac
-done
diff --git a/execute_cmd.c~ b/execute_cmd.c~
deleted file mode 100644 (file)
index 58eab4e..0000000
+++ /dev/null
@@ -1,5003 +0,0 @@
-/* execute_cmd.c -- Execute a COMMAND structure. */
-
-/* Copyright (C) 1987-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/>.
-*/
-
-#include "config.h"
-
-#if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX)
-  #pragma alloca
-#endif /* _AIX && RISC6000 && !__GNUC__ */
-
-#include <stdio.h>
-#include "chartypes.h"
-#include "bashtypes.h"
-#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H)
-#  include <sys/file.h>
-#endif
-#include "filecntl.h"
-#include "posixstat.h"
-#include <signal.h>
-#ifndef _MINIX
-#  include <sys/param.h>
-#endif
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include "posixtime.h"
-
-#if defined (HAVE_SYS_RESOURCE_H) && !defined (RLIMTYPE)
-#  include <sys/resource.h>
-#endif
-
-#if defined (HAVE_SYS_TIMES_H) && defined (HAVE_TIMES)
-#  include <sys/times.h>
-#endif
-
-#include <errno.h>
-
-#if !defined (errno)
-extern int errno;
-#endif
-
-#include "bashansi.h"
-#include "bashintl.h"
-
-#include "memalloc.h"
-#include "shell.h"
-#include <y.tab.h>     /* use <...> so we pick it up from the build directory */
-#include "flags.h"
-#include "builtins.h"
-#include "hashlib.h"
-#include "jobs.h"
-#include "execute_cmd.h"
-#include "findcmd.h"
-#include "redir.h"
-#include "trap.h"
-#include "pathexp.h"
-#include "hashcmd.h"
-
-#if defined (COND_COMMAND)
-#  include "test.h"
-#endif
-
-#include "builtins/common.h"
-#include "builtins/builtext.h" /* list of builtins */
-
-#include <glob/strmatch.h>
-#include <tilde/tilde.h>
-
-#if defined (BUFFERED_INPUT)
-#  include "input.h"
-#endif
-
-#if defined (ALIAS)
-#  include "alias.h"
-#endif
-
-#if defined (HISTORY)
-#  include "bashhist.h"
-#endif
-
-extern int posixly_correct;
-extern int expand_aliases;
-extern int autocd;
-extern int breaking, continuing, loop_level;
-extern int parse_and_execute_level, running_trap, sourcelevel;
-extern int command_string_index, line_number;
-extern int dot_found_in_search;
-extern int already_making_children;
-extern int tempenv_assign_error;
-extern char *the_printed_command, *shell_name;
-extern pid_t last_command_subst_pid;
-extern sh_builtin_func_t *last_shell_builtin, *this_shell_builtin;
-extern char **subshell_argv, **subshell_envp;
-extern int subshell_argc;
-#if 0
-extern char *glob_argv_flags;
-#endif
-
-extern int close __P((int));
-
-/* Static functions defined and used in this file. */
-static void close_pipes __P((int, int));
-static void do_piping __P((int, int));
-static void bind_lastarg __P((char *));
-static int shell_control_structure __P((enum command_type));
-static void cleanup_redirects __P((REDIRECT *));
-
-#if defined (JOB_CONTROL)
-static int restore_signal_mask __P((sigset_t *));
-#endif
-
-static void async_redirect_stdin __P((void));
-
-static int builtin_status __P((int));
-
-static int execute_for_command __P((FOR_COM *));
-#if defined (SELECT_COMMAND)
-static int print_index_and_element __P((int, int, WORD_LIST *));
-static void indent __P((int, int));
-static void print_select_list __P((WORD_LIST *, int, int, int));
-static char *select_query __P((WORD_LIST *, int, char *, int));
-static int execute_select_command __P((SELECT_COM *));
-#endif
-#if defined (DPAREN_ARITHMETIC)
-static int execute_arith_command __P((ARITH_COM *));
-#endif
-#if defined (COND_COMMAND)
-static int execute_cond_node __P((COND_COM *));
-static int execute_cond_command __P((COND_COM *));
-#endif
-#if defined (COMMAND_TIMING)
-static int mkfmt __P((char *, int, int, time_t, int));
-static void print_formatted_time __P((FILE *, char *,
-                                     time_t, int, time_t, int,
-                                     time_t, int, int));
-static int time_command __P((COMMAND *, int, int, int, struct fd_bitmap *));
-#endif
-#if defined (ARITH_FOR_COMMAND)
-static intmax_t eval_arith_for_expr __P((WORD_LIST *, int *));
-static int execute_arith_for_command __P((ARITH_FOR_COM *));
-#endif
-static int execute_case_command __P((CASE_COM *));
-static int execute_while_command __P((WHILE_COM *));
-static int execute_until_command __P((WHILE_COM *));
-static int execute_while_or_until __P((WHILE_COM *, int));
-static int execute_if_command __P((IF_COM *));
-static int execute_null_command __P((REDIRECT *, int, int, int));
-static void fix_assignment_words __P((WORD_LIST *));
-static int execute_simple_command __P((SIMPLE_COM *, int, int, int, struct fd_bitmap *));
-static int execute_builtin __P((sh_builtin_func_t *, WORD_LIST *, int, int));
-static int execute_function __P((SHELL_VAR *, WORD_LIST *, int, struct fd_bitmap *, int, int));
-static int execute_builtin_or_function __P((WORD_LIST *, sh_builtin_func_t *,
-                                           SHELL_VAR *,
-                                           REDIRECT *, struct fd_bitmap *, int));
-static void execute_subshell_builtin_or_function __P((WORD_LIST *, REDIRECT *,
-                                                     sh_builtin_func_t *,
-                                                     SHELL_VAR *,
-                                                     int, int, int,
-                                                     struct fd_bitmap *,
-                                                     int));
-static void execute_disk_command __P((WORD_LIST *, REDIRECT *, char *,
-                                     int, int, int, struct fd_bitmap *, int));
-
-static char *getinterp __P((char *, int, int *));
-static void initialize_subshell __P((void));
-static int execute_in_subshell __P((COMMAND *, int, int, int, struct fd_bitmap *));
-#if defined (COPROCESS_SUPPORT)
-static int execute_coproc __P((COMMAND *, int, int, struct fd_bitmap *));
-#endif
-
-static int execute_pipeline __P((COMMAND *, int, int, int, struct fd_bitmap *));
-
-static int execute_connection __P((COMMAND *, int, int, int, struct fd_bitmap *));
-
-static int execute_intern_function __P((WORD_DESC *, COMMAND *));
-
-/* Set to 1 if fd 0 was the subject of redirection to a subshell.  Global
-   so that reader_loop can set it to zero before executing a command. */
-int stdin_redir;
-
-/* The name of the command that is currently being executed.
-   `test' needs this, for example. */
-char *this_command_name;
-
-/* The printed representation of the currently-executing command (same as
-   the_printed_command), except when a trap is being executed.  Useful for
-   a debugger to know where exactly the program is currently executing. */
-char *the_printed_command_except_trap;
-
-/* For catching RETURN in a function. */
-int return_catch_flag;
-int return_catch_value;
-procenv_t return_catch;
-
-/* The value returned by the last synchronous command. */
-int last_command_exit_value;
-
-/* Whether or not the last command (corresponding to last_command_exit_value)
-   was terminated by a signal, and, if so, which one. */
-int last_command_exit_signal;
-
-/* The list of redirections to perform which will undo the redirections
-   that I made in the shell. */
-REDIRECT *redirection_undo_list = (REDIRECT *)NULL;
-
-/* The list of redirections to perform which will undo the internal
-   redirections performed by the `exec' builtin.  These are redirections
-   that must be undone even when exec discards redirection_undo_list. */
-REDIRECT *exec_redirection_undo_list = (REDIRECT *)NULL;
-
-/* When greater than zero, value is the `level' of builtins we are
-   currently executing (e.g. `eval echo a' would have it set to 2). */
-int executing_builtin = 0;
-
-/* Non-zero if we are executing a command list (a;b;c, etc.) */
-int executing_list = 0;
-
-/* Non-zero if failing commands in a command substitution should not exit the
-   shell even if -e is set.  Used to pass the CMD_IGNORE_RETURN flag down to
-   commands run in command substitutions by parse_and_execute. */
-int comsub_ignore_return = 0;
-
-/* Non-zero if we have just forked and are currently running in a subshell
-   environment. */
-int subshell_environment;
-
-/* Count of nested subshells, like SHLVL.  Available via $BASH_SUBSHELL */
-int subshell_level = 0;
-
-/* Currently-executing shell function. */
-SHELL_VAR *this_shell_function;
-
-/* If non-zero, matches in case and [[ ... ]] are case-insensitive */
-int match_ignore_case = 0;
-
-struct stat SB;                /* used for debugging */
-
-static int special_builtin_failed;
-
-static COMMAND *currently_executing_command;
-
-/* The line number that the currently executing function starts on. */
-static int function_line_number;
-
-/* XXX - set to 1 if we're running the DEBUG trap and we want to show the line
-   number containing the function name.  Used by executing_line_number to
-   report the correct line number.  Kind of a hack. */
-static int showing_function_line;
-
-static int line_number_for_err_trap;
-
-/* A sort of function nesting level counter */
-static int funcnest = 0;
-int funcnest_max = 256;
-
-struct fd_bitmap *current_fds_to_close = (struct fd_bitmap *)NULL;
-
-#define FD_BITMAP_DEFAULT_SIZE 32
-
-/* Functions to allocate and deallocate the structures used to pass
-   information from the shell to its children about file descriptors
-   to close. */
-struct fd_bitmap *
-new_fd_bitmap (size)
-     int size;
-{
-  struct fd_bitmap *ret;
-
-  ret = (struct fd_bitmap *)xmalloc (sizeof (struct fd_bitmap));
-
-  ret->size = size;
-
-  if (size)
-    {
-      ret->bitmap = (char *)xmalloc (size);
-      memset (ret->bitmap, '\0', size);
-    }
-  else
-    ret->bitmap = (char *)NULL;
-  return (ret);
-}
-
-void
-dispose_fd_bitmap (fdbp)
-     struct fd_bitmap *fdbp;
-{
-  FREE (fdbp->bitmap);
-  free (fdbp);
-}
-
-void
-close_fd_bitmap (fdbp)
-     struct fd_bitmap *fdbp;
-{
-  register int i;
-
-  if (fdbp)
-    {
-      for (i = 0; i < fdbp->size; i++)
-       if (fdbp->bitmap[i])
-         {
-           close (i);
-           fdbp->bitmap[i] = 0;
-         }
-    }
-}
-
-/* Return the line number of the currently executing command. */
-int
-executing_line_number ()
-{
-  if (executing && showing_function_line == 0 &&
-      (variable_context == 0 || interactive_shell == 0) &&
-      currently_executing_command)
-    {
-#if defined (COND_COMMAND)
-      if (currently_executing_command->type == cm_cond)
-       return currently_executing_command->value.Cond->line;
-#endif
-#if defined (DPAREN_ARITHMETIC)
-      else if (currently_executing_command->type == cm_arith)
-       return currently_executing_command->value.Arith->line;
-#endif
-#if defined (ARITH_FOR_COMMAND)
-      else if (currently_executing_command->type == cm_arith_for)
-       return currently_executing_command->value.ArithFor->line;
-#endif
-
-       return line_number;
-    }
-  else
-    return line_number;
-}
-
-/* Execute the command passed in COMMAND.  COMMAND is exactly what
-   read_command () places into GLOBAL_COMMAND.  See "command.h" for the
-   details of the command structure.
-
-   EXECUTION_SUCCESS or EXECUTION_FAILURE are the only possible
-   return values.  Executing a command with nothing in it returns
-   EXECUTION_SUCCESS. */
-int
-execute_command (command)
-     COMMAND *command;
-{
-  struct fd_bitmap *bitmap;
-  int result;
-
-  current_fds_to_close = (struct fd_bitmap *)NULL;
-  bitmap = new_fd_bitmap (FD_BITMAP_DEFAULT_SIZE);
-  begin_unwind_frame ("execute-command");
-  add_unwind_protect (dispose_fd_bitmap, (char *)bitmap);
-
-  /* Just do the command, but not asynchronously. */
-  result = execute_command_internal (command, 0, NO_PIPE, NO_PIPE, bitmap);
-
-  dispose_fd_bitmap (bitmap);
-  discard_unwind_frame ("execute-command");
-
-#if defined (PROCESS_SUBSTITUTION)
-  /* don't unlink fifos if we're in a shell function; wait until the function
-     returns. */
-  if (variable_context == 0)
-    unlink_fifo_list ();
-#endif /* PROCESS_SUBSTITUTION */
-
-  QUIT;
-  return (result);
-}
-
-/* Return 1 if TYPE is a shell control structure type. */
-static int
-shell_control_structure (type)
-     enum command_type type;
-{
-  switch (type)
-    {
-#if defined (ARITH_FOR_COMMAND)
-    case cm_arith_for:
-#endif
-#if defined (SELECT_COMMAND)
-    case cm_select:
-#endif
-#if defined (DPAREN_ARITHMETIC)
-    case cm_arith:
-#endif
-#if defined (COND_COMMAND)
-    case cm_cond:
-#endif
-    case cm_case:
-    case cm_while:
-    case cm_until:
-    case cm_if:
-    case cm_for:
-    case cm_group:
-    case cm_function_def:
-      return (1);
-
-    default:
-      return (0);
-    }
-}
-
-/* A function to use to unwind_protect the redirection undo list
-   for loops. */
-static void
-cleanup_redirects (list)
-     REDIRECT *list;
-{
-  do_redirections (list, RX_ACTIVE);
-  dispose_redirects (list);
-}
-
-#if 0
-/* Function to unwind_protect the redirections for functions and builtins. */
-static void
-cleanup_func_redirects (list)
-     REDIRECT *list;
-{
-  do_redirections (list, RX_ACTIVE);
-}
-#endif
-
-void
-dispose_exec_redirects ()
-{
-  if (exec_redirection_undo_list)
-    {
-      dispose_redirects (exec_redirection_undo_list);
-      exec_redirection_undo_list = (REDIRECT *)NULL;
-    }
-}
-
-#if defined (JOB_CONTROL)
-/* A function to restore the signal mask to its proper value when the shell
-   is interrupted or errors occur while creating a pipeline. */
-static int
-restore_signal_mask (set)
-     sigset_t *set;
-{
-  return (sigprocmask (SIG_SETMASK, set, (sigset_t *)NULL));
-}
-#endif /* JOB_CONTROL */
-
-#ifdef DEBUG
-/* A debugging function that can be called from gdb, for instance. */
-void
-open_files ()
-{
-  register int i;
-  int f, fd_table_size;
-
-  fd_table_size = getdtablesize ();
-
-  fprintf (stderr, "pid %ld open files:", (long)getpid ());
-  for (i = 3; i < fd_table_size; i++)
-    {
-      if ((f = fcntl (i, F_GETFD, 0)) != -1)
-       fprintf (stderr, " %d (%s)", i, f ? "close" : "open");
-    }
-  fprintf (stderr, "\n");
-}
-#endif
-
-static void
-async_redirect_stdin ()
-{
-  int fd;
-
-  fd = open ("/dev/null", O_RDONLY);
-  if (fd > 0)
-    {
-      dup2 (fd, 0);
-      close (fd);
-    }
-  else if (fd < 0)
-    internal_error (_("cannot redirect standard input from /dev/null: %s"), strerror (errno));
-}
-
-#define DESCRIBE_PID(pid) do { if (interactive) describe_pid (pid); } while (0)
-
-/* Execute the command passed in COMMAND, perhaps doing it asynchrounously.
-   COMMAND is exactly what read_command () places into GLOBAL_COMMAND.
-   ASYNCHROUNOUS, if non-zero, says to do this command in the background.
-   PIPE_IN and PIPE_OUT are file descriptors saying where input comes
-   from and where it goes.  They can have the value of NO_PIPE, which means
-   I/O is stdin/stdout.
-   FDS_TO_CLOSE is a list of file descriptors to close once the child has
-   been forked.  This list often contains the unusable sides of pipes, etc.
-
-   EXECUTION_SUCCESS or EXECUTION_FAILURE are the only possible
-   return values.  Executing a command with nothing in it returns
-   EXECUTION_SUCCESS. */
-int
-execute_command_internal (command, asynchronous, pipe_in, pipe_out,
-                         fds_to_close)
-     COMMAND *command;
-     int asynchronous;
-     int pipe_in, pipe_out;
-     struct fd_bitmap *fds_to_close;
-{
-  int exec_result, user_subshell, invert, ignore_return, was_error_trap;
-  REDIRECT *my_undo_list, *exec_undo_list;
-  volatile int last_pid;
-  volatile int save_line_number;
-
-#if 0
-  if (command == 0 || breaking || continuing || read_but_dont_execute)
-    return (EXECUTION_SUCCESS);
-#else
-  if (breaking || continuing)
-    return (last_command_exit_value);
-  if (command == 0 || read_but_dont_execute)
-    return (EXECUTION_SUCCESS);
-#endif
-
-  QUIT;
-  run_pending_traps ();
-
-#if 0
-  if (running_trap == 0)
-#endif
-    currently_executing_command = command;
-
-  invert = (command->flags & CMD_INVERT_RETURN) != 0;
-
-  /* If we're inverting the return value and `set -e' has been executed,
-     we don't want a failing command to inadvertently cause the shell
-     to exit. */
-  if (exit_immediately_on_error && invert)     /* XXX */
-    command->flags |= CMD_IGNORE_RETURN;       /* XXX */
-
-  exec_result = EXECUTION_SUCCESS;
-
-  /* If a command was being explicitly run in a subshell, or if it is
-     a shell control-structure, and it has a pipe, then we do the command
-     in a subshell. */
-  if (command->type == cm_subshell && (command->flags & CMD_NO_FORK))
-    return (execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close));
-
-#if defined (COPROCESS_SUPPORT)
-  if (command->type == cm_coproc)
-    return (execute_coproc (command, pipe_in, pipe_out, fds_to_close));
-#endif
-
-  user_subshell = command->type == cm_subshell || ((command->flags & CMD_WANT_SUBSHELL) != 0);
-
-  if (command->type == cm_subshell ||
-      (command->flags & (CMD_WANT_SUBSHELL|CMD_FORCE_SUBSHELL)) ||
-      (shell_control_structure (command->type) &&
-       (pipe_out != NO_PIPE || pipe_in != NO_PIPE || asynchronous)))
-    {
-      pid_t paren_pid;
-
-      /* Fork a subshell, turn off the subshell bit, turn off job
-        control and call execute_command () on the command again. */
-      line_number_for_err_trap = line_number;
-      paren_pid = make_child (savestring (make_command_string (command)),
-                             asynchronous);
-      if (paren_pid == 0)
-       exit (execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close));
-       /* NOTREACHED */
-      else
-       {
-         close_pipes (pipe_in, pipe_out);
-
-#if defined (PROCESS_SUBSTITUTION) && defined (HAVE_DEV_FD)
-         unlink_fifo_list ();
-#endif
-         /* If we are part of a pipeline, and not the end of the pipeline,
-            then we should simply return and let the last command in the
-            pipe be waited for.  If we are not in a pipeline, or are the
-            last command in the pipeline, then we wait for the subshell
-            and return its exit status as usual. */
-         if (pipe_out != NO_PIPE)
-           return (EXECUTION_SUCCESS);
-
-         stop_pipeline (asynchronous, (COMMAND *)NULL);
-
-         if (asynchronous == 0)
-           {
-             was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0;
-             invert = (command->flags & CMD_INVERT_RETURN) != 0;
-             ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
-
-             last_command_exit_value = wait_for (paren_pid);
-
-             /* If we have to, invert the return value. */
-             if (invert)
-               exec_result = ((last_command_exit_value == EXECUTION_SUCCESS)
-                               ? EXECUTION_FAILURE
-                               : EXECUTION_SUCCESS);
-             else
-               exec_result = last_command_exit_value;
-
-             if (user_subshell && was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS)
-               {
-                 last_command_exit_value = exec_result;
-                 save_line_number = line_number;
-                 line_number = line_number_for_err_trap;
-                 run_error_trap ();
-                 line_number = save_line_number;
-               }
-
-             if (user_subshell && ignore_return == 0 && invert == 0 && exit_immediately_on_error && exec_result != EXECUTION_SUCCESS)
-               {
-                 last_command_exit_value = exec_result;
-                 run_pending_traps ();
-                 jump_to_top_level (ERREXIT);
-               }
-
-             return (last_command_exit_value = exec_result);
-           }
-         else
-           {
-             DESCRIBE_PID (paren_pid);
-
-             run_pending_traps ();
-
-             return (EXECUTION_SUCCESS);
-           }
-       }
-    }
-
-#if defined (COMMAND_TIMING)
-  if (command->flags & CMD_TIME_PIPELINE)
-    {
-      if (asynchronous)
-       {
-         command->flags |= CMD_FORCE_SUBSHELL;
-         exec_result = execute_command_internal (command, 1, pipe_in, pipe_out, fds_to_close);
-       }
-      else
-       {
-         exec_result = time_command (command, asynchronous, pipe_in, pipe_out, fds_to_close);
-#if 0
-         if (running_trap == 0)
-#endif
-           currently_executing_command = (COMMAND *)NULL;
-       }
-      return (exec_result);
-    }
-#endif /* COMMAND_TIMING */
-
-  if (shell_control_structure (command->type) && command->redirects)
-    stdin_redir = stdin_redirects (command->redirects);
-
-  /* Handle WHILE FOR CASE etc. with redirections.  (Also '&' input
-     redirection.)  */
-  if (do_redirections (command->redirects, RX_ACTIVE|RX_UNDOABLE) != 0)
-    {
-      cleanup_redirects (redirection_undo_list);
-      redirection_undo_list = (REDIRECT *)NULL;
-      dispose_exec_redirects ();
-      return (last_command_exit_value = EXECUTION_FAILURE);
-    }
-
-  if (redirection_undo_list)
-    {
-      my_undo_list = (REDIRECT *)copy_redirects (redirection_undo_list);
-      dispose_redirects (redirection_undo_list);
-      redirection_undo_list = (REDIRECT *)NULL;
-    }
-  else
-    my_undo_list = (REDIRECT *)NULL;
-
-  if (exec_redirection_undo_list)
-    {
-      exec_undo_list = (REDIRECT *)copy_redirects (exec_redirection_undo_list);
-      dispose_redirects (exec_redirection_undo_list);
-      exec_redirection_undo_list = (REDIRECT *)NULL;
-    }
-  else
-    exec_undo_list = (REDIRECT *)NULL;
-
-  if (my_undo_list || exec_undo_list)
-    begin_unwind_frame ("loop_redirections");
-
-  if (my_undo_list)
-    add_unwind_protect ((Function *)cleanup_redirects, my_undo_list);
-
-  if (exec_undo_list)
-    add_unwind_protect ((Function *)dispose_redirects, exec_undo_list);
-
-  ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
-
-  QUIT;
-
-  switch (command->type)
-    {
-    case cm_simple:
-      {
-       save_line_number = line_number;
-       /* We can't rely on variables retaining their values across a
-          call to execute_simple_command if a longjmp occurs as the
-          result of a `return' builtin.  This is true for sure with gcc. */
-#if defined (RECYCLES_PIDS)
-       last_made_pid = NO_PID;
-#endif
-       last_pid = last_made_pid;
-       was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0;
-
-       if (ignore_return && command->value.Simple)
-         command->value.Simple->flags |= CMD_IGNORE_RETURN;
-       if (command->flags & CMD_STDIN_REDIR)
-         command->value.Simple->flags |= CMD_STDIN_REDIR;
-
-       line_number_for_err_trap = line_number = command->value.Simple->line;
-       exec_result =
-         execute_simple_command (command->value.Simple, pipe_in, pipe_out,
-                                 asynchronous, fds_to_close);
-       line_number = save_line_number;
-
-       /* The temporary environment should be used for only the simple
-          command immediately following its definition. */
-       dispose_used_env_vars ();
-
-#if (defined (ultrix) && defined (mips)) || defined (C_ALLOCA)
-       /* Reclaim memory allocated with alloca () on machines which
-          may be using the alloca emulation code. */
-       (void) alloca (0);
-#endif /* (ultrix && mips) || C_ALLOCA */
-
-       /* If we forked to do the command, then we must wait_for ()
-          the child. */
-
-       /* XXX - this is something to watch out for if there are problems
-          when the shell is compiled without job control. */
-       if (already_making_children && pipe_out == NO_PIPE &&
-           last_made_pid != last_pid)
-         {
-           stop_pipeline (asynchronous, (COMMAND *)NULL);
-
-           if (asynchronous)
-             {
-               DESCRIBE_PID (last_made_pid);
-             }
-           else
-#if !defined (JOB_CONTROL)
-             /* Do not wait for asynchronous processes started from
-                startup files. */
-           if (last_made_pid != last_asynchronous_pid)
-#endif
-           /* When executing a shell function that executes other
-              commands, this causes the last simple command in
-              the function to be waited for twice.  This also causes
-              subshells forked to execute builtin commands (e.g., in
-              pipelines) to be waited for twice. */
-             exec_result = wait_for (last_made_pid);
-         }
-      }
-
-      /* 2009/02/13 -- pipeline failure is processed elsewhere.  This handles
-        only the failure of a simple command. */
-      if (was_error_trap && ignore_return == 0 && invert == 0 && pipe_in == NO_PIPE && pipe_out == NO_PIPE && exec_result != EXECUTION_SUCCESS)
-       {
-         last_command_exit_value = exec_result;
-         line_number = line_number_for_err_trap;
-         run_error_trap ();
-         line_number = save_line_number;
-       }
-
-      if (ignore_return == 0 && invert == 0 &&
-         ((posixly_correct && interactive == 0 && special_builtin_failed) ||
-          (exit_immediately_on_error && pipe_in == NO_PIPE && pipe_out == NO_PIPE && exec_result != EXECUTION_SUCCESS)))
-       {
-         last_command_exit_value = exec_result;
-         run_pending_traps ();
-         jump_to_top_level (ERREXIT);
-       }
-
-      break;
-
-    case cm_for:
-      if (ignore_return)
-       command->value.For->flags |= CMD_IGNORE_RETURN;
-      exec_result = execute_for_command (command->value.For);
-      break;
-
-#if defined (ARITH_FOR_COMMAND)
-    case cm_arith_for:
-      if (ignore_return)
-       command->value.ArithFor->flags |= CMD_IGNORE_RETURN;
-      exec_result = execute_arith_for_command (command->value.ArithFor);
-      break;
-#endif
-
-#if defined (SELECT_COMMAND)
-    case cm_select:
-      if (ignore_return)
-       command->value.Select->flags |= CMD_IGNORE_RETURN;
-      exec_result = execute_select_command (command->value.Select);
-      break;
-#endif
-
-    case cm_case:
-      if (ignore_return)
-       command->value.Case->flags |= CMD_IGNORE_RETURN;
-      exec_result = execute_case_command (command->value.Case);
-      break;
-
-    case cm_while:
-      if (ignore_return)
-       command->value.While->flags |= CMD_IGNORE_RETURN;
-      exec_result = execute_while_command (command->value.While);
-      break;
-
-    case cm_until:
-      if (ignore_return)
-       command->value.While->flags |= CMD_IGNORE_RETURN;
-      exec_result = execute_until_command (command->value.While);
-      break;
-
-    case cm_if:
-      if (ignore_return)
-       command->value.If->flags |= CMD_IGNORE_RETURN;
-      exec_result = execute_if_command (command->value.If);
-      break;
-
-    case cm_group:
-
-      /* This code can be executed from either of two paths: an explicit
-        '{}' command, or via a function call.  If we are executed via a
-        function call, we have already taken care of the function being
-        executed in the background (down there in execute_simple_command ()),
-        and this command should *not* be marked as asynchronous.  If we
-        are executing a regular '{}' group command, and asynchronous == 1,
-        we must want to execute the whole command in the background, so we
-        need a subshell, and we want the stuff executed in that subshell
-        (this group command) to be executed in the foreground of that
-        subshell (i.e. there will not be *another* subshell forked).
-
-        What we do is to force a subshell if asynchronous, and then call
-        execute_command_internal again with asynchronous still set to 1,
-        but with the original group command, so the printed command will
-        look right.
-
-        The code above that handles forking off subshells will note that
-        both subshell and async are on, and turn off async in the child
-        after forking the subshell (but leave async set in the parent, so
-        the normal call to describe_pid is made).  This turning off
-        async is *crucial*; if it is not done, this will fall into an
-        infinite loop of executions through this spot in subshell after
-        subshell until the process limit is exhausted. */
-
-      if (asynchronous)
-       {
-         command->flags |= CMD_FORCE_SUBSHELL;
-         exec_result =
-           execute_command_internal (command, 1, pipe_in, pipe_out,
-                                     fds_to_close);
-       }
-      else
-       {
-         if (ignore_return && command->value.Group->command)
-           command->value.Group->command->flags |= CMD_IGNORE_RETURN;
-         exec_result =
-           execute_command_internal (command->value.Group->command,
-                                     asynchronous, pipe_in, pipe_out,
-                                     fds_to_close);
-       }
-      break;
-
-    case cm_connection:
-      exec_result = execute_connection (command, asynchronous,
-                                       pipe_in, pipe_out, fds_to_close);
-      break;
-
-#if defined (DPAREN_ARITHMETIC)
-    case cm_arith:
-      was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0;
-      if (ignore_return)
-       command->value.Arith->flags |= CMD_IGNORE_RETURN;
-      line_number_for_err_trap = save_line_number = line_number;
-      exec_result = execute_arith_command (command->value.Arith);
-      line_number = save_line_number;
-
-      if (was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS)
-       {
-         last_command_exit_value = exec_result;
-         save_line_number = line_number;
-         line_number = line_number_for_err_trap;
-         run_error_trap ();
-         line_number = save_line_number;
-       }
-
-      if (ignore_return == 0 && invert == 0 && exit_immediately_on_error && exec_result != EXECUTION_SUCCESS)
-       {
-         last_command_exit_value = exec_result;
-         run_pending_traps ();
-         jump_to_top_level (ERREXIT);
-       }
-
-      break;
-#endif
-
-#if defined (COND_COMMAND)
-    case cm_cond:
-      was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0;
-      if (ignore_return)
-       command->value.Cond->flags |= CMD_IGNORE_RETURN;
-
-      line_number_for_err_trap = save_line_number = line_number;
-      exec_result = execute_cond_command (command->value.Cond);
-      line_number = save_line_number;
-
-      if (was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS)
-       {
-         last_command_exit_value = exec_result;
-         save_line_number = line_number;
-         line_number = line_number_for_err_trap;
-         run_error_trap ();
-         line_number = save_line_number;
-       }
-
-      if (ignore_return == 0 && invert == 0 && exit_immediately_on_error && exec_result != EXECUTION_SUCCESS)
-       {
-         last_command_exit_value = exec_result;
-         run_pending_traps ();
-         jump_to_top_level (ERREXIT);
-       }
-
-      break;
-#endif
-    
-    case cm_function_def:
-      exec_result = execute_intern_function (command->value.Function_def->name,
-                                            command->value.Function_def->command);
-      break;
-
-    default:
-      command_error ("execute_command", CMDERR_BADTYPE, command->type, 0);
-    }
-
-  if (my_undo_list)
-    {
-      do_redirections (my_undo_list, RX_ACTIVE);
-      dispose_redirects (my_undo_list);
-    }
-
-  if (exec_undo_list)
-    dispose_redirects (exec_undo_list);
-
-  if (my_undo_list || exec_undo_list)
-    discard_unwind_frame ("loop_redirections");
-
-  /* Invert the return value if we have to */
-  if (invert)
-    exec_result = (exec_result == EXECUTION_SUCCESS)
-                   ? EXECUTION_FAILURE
-                   : EXECUTION_SUCCESS;
-
-#if defined (DPAREN_ARITHMETIC) || defined (COND_COMMAND)
-  /* This is where we set PIPESTATUS from the exit status of the appropriate
-     compound commands (the ones that look enough like simple commands to
-     cause confusion).  We might be able to optimize by not doing this if
-     subshell_environment != 0. */
-  switch (command->type)
-    {
-#  if defined (DPAREN_ARITHMETIC)
-    case cm_arith:
-#  endif
-#  if defined (COND_COMMAND)
-    case cm_cond:
-#  endif
-      set_pipestatus_from_exit (exec_result);
-      break;
-    }
-#endif
-
-  last_command_exit_value = exec_result;
-  run_pending_traps ();
-#if 0
-  if (running_trap == 0)
-#endif
-    currently_executing_command = (COMMAND *)NULL;
-  return (last_command_exit_value);
-}
-
-#if defined (COMMAND_TIMING)
-
-#if defined (HAVE_GETRUSAGE) && defined (HAVE_GETTIMEOFDAY)
-extern struct timeval *difftimeval __P((struct timeval *, struct timeval *, struct timeval *));
-extern struct timeval *addtimeval __P((struct timeval *, struct timeval *, struct timeval *));
-extern int timeval_to_cpu __P((struct timeval *, struct timeval *, struct timeval *));
-#endif
-
-#define POSIX_TIMEFORMAT "real %2R\nuser %2U\nsys %2S"
-#define BASH_TIMEFORMAT  "\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS"
-
-static const int precs[] = { 0, 100, 10, 1 };
-
-/* Expand one `%'-prefixed escape sequence from a time format string. */
-static int
-mkfmt (buf, prec, lng, sec, sec_fraction)
-     char *buf;
-     int prec, lng;
-     time_t sec;
-     int sec_fraction;
-{
-  time_t min;
-  char abuf[INT_STRLEN_BOUND(time_t) + 1];
-  int ind, aind;
-
-  ind = 0;
-  abuf[sizeof(abuf) - 1] = '\0';
-
-  /* If LNG is non-zero, we want to decompose SEC into minutes and seconds. */
-  if (lng)
-    {
-      min = sec / 60;
-      sec %= 60;
-      aind = sizeof(abuf) - 2;
-      do
-       abuf[aind--] = (min % 10) + '0';
-      while (min /= 10);
-      aind++;
-      while (abuf[aind])
-       buf[ind++] = abuf[aind++];
-      buf[ind++] = 'm';
-    }
-
-  /* Now add the seconds. */
-  aind = sizeof (abuf) - 2;
-  do
-    abuf[aind--] = (sec % 10) + '0';
-  while (sec /= 10);
-  aind++;
-  while (abuf[aind])
-    buf[ind++] = abuf[aind++];
-
-  /* We want to add a decimal point and PREC places after it if PREC is
-     nonzero.  PREC is not greater than 3.  SEC_FRACTION is between 0
-     and 999. */
-  if (prec != 0)
-    {
-      buf[ind++] = '.';
-      for (aind = 1; aind <= prec; aind++)
-       {
-         buf[ind++] = (sec_fraction / precs[aind]) + '0';
-         sec_fraction %= precs[aind];
-       }
-    }
-
-  if (lng)
-    buf[ind++] = 's';
-  buf[ind] = '\0';
-
-  return (ind);
-}
-
-/* Interpret the format string FORMAT, interpolating the following escape
-   sequences:
-               %[prec][l][RUS]
-
-   where the optional `prec' is a precision, meaning the number of
-   characters after the decimal point, the optional `l' means to format
-   using minutes and seconds (MMmNN[.FF]s), like the `times' builtin',
-   and the last character is one of
-   
-               R       number of seconds of `real' time
-               U       number of seconds of `user' time
-               S       number of seconds of `system' time
-
-   An occurrence of `%%' in the format string is translated to a `%'.  The
-   result is printed to FP, a pointer to a FILE.  The other variables are
-   the seconds and thousandths of a second of real, user, and system time,
-   resectively. */
-static void
-print_formatted_time (fp, format, rs, rsf, us, usf, ss, ssf, cpu)
-     FILE *fp;
-     char *format;
-     time_t rs;
-     int rsf;
-     time_t us;
-     int usf;
-     time_t ss;
-     int ssf, cpu;
-{
-  int prec, lng, len;
-  char *str, *s, ts[INT_STRLEN_BOUND (time_t) + sizeof ("mSS.FFFF")];
-  time_t sum;
-  int sum_frac;
-  int sindex, ssize;
-
-  len = strlen (format);
-  ssize = (len + 64) - (len % 64);
-  str = (char *)xmalloc (ssize);
-  sindex = 0;
-
-  for (s = format; *s; s++)
-    {
-      if (*s != '%' || s[1] == '\0')
-       {
-         RESIZE_MALLOCED_BUFFER (str, sindex, 1, ssize, 64);
-         str[sindex++] = *s;
-       }
-      else if (s[1] == '%')
-       {
-         s++;
-         RESIZE_MALLOCED_BUFFER (str, sindex, 1, ssize, 64);
-         str[sindex++] = *s;
-       }
-      else if (s[1] == 'P')
-       {
-         s++;
-#if 0
-         /* clamp CPU usage at 100% */
-         if (cpu > 10000)
-           cpu = 10000;
-#endif
-         sum = cpu / 100;
-         sum_frac = (cpu % 100) * 10;
-         len = mkfmt (ts, 2, 0, sum, sum_frac);
-         RESIZE_MALLOCED_BUFFER (str, sindex, len, ssize, 64);
-         strcpy (str + sindex, ts);
-         sindex += len;
-       }
-      else
-       {
-         prec = 3;     /* default is three places past the decimal point. */
-         lng = 0;      /* default is to not use minutes or append `s' */
-         s++;
-         if (DIGIT (*s))               /* `precision' */
-           {
-             prec = *s++ - '0';
-             if (prec > 3) prec = 3;
-           }
-         if (*s == 'l')                /* `length extender' */
-           {
-             lng = 1;
-             s++;
-           }
-         if (*s == 'R' || *s == 'E')
-           len = mkfmt (ts, prec, lng, rs, rsf);
-         else if (*s == 'U')
-           len = mkfmt (ts, prec, lng, us, usf);
-         else if (*s == 'S')
-           len = mkfmt (ts, prec, lng, ss, ssf);
-         else
-           {
-             internal_error (_("TIMEFORMAT: `%c': invalid format character"), *s);
-             free (str);
-             return;
-           }
-         RESIZE_MALLOCED_BUFFER (str, sindex, len, ssize, 64);
-         strcpy (str + sindex, ts);
-         sindex += len;
-       }
-    }
-
-  str[sindex] = '\0';
-  fprintf (fp, "%s\n", str);
-  fflush (fp);
-
-  free (str);
-}
-
-static int
-time_command (command, asynchronous, pipe_in, pipe_out, fds_to_close)
-     COMMAND *command;
-     int asynchronous, pipe_in, pipe_out;
-     struct fd_bitmap *fds_to_close;
-{
-  int rv, posix_time, old_flags;
-  time_t rs, us, ss;
-  int rsf, usf, ssf;
-  int cpu;
-  char *time_format;
-
-#if defined (HAVE_GETRUSAGE) && defined (HAVE_GETTIMEOFDAY)
-  struct timeval real, user, sys;
-  struct timeval before, after;
-#  if defined (HAVE_STRUCT_TIMEZONE)
-  struct timezone dtz;                         /* posix doesn't define this */
-#  endif
-  struct rusage selfb, selfa, kidsb, kidsa;    /* a = after, b = before */
-#else
-#  if defined (HAVE_TIMES)
-  clock_t tbefore, tafter, real, user, sys;
-  struct tms before, after;
-#  endif
-#endif
-
-#if defined (HAVE_GETRUSAGE) && defined (HAVE_GETTIMEOFDAY)
-#  if defined (HAVE_STRUCT_TIMEZONE)
-  gettimeofday (&before, &dtz);
-#  else
-  gettimeofday (&before, (void *)NULL);
-#  endif /* !HAVE_STRUCT_TIMEZONE */
-  getrusage (RUSAGE_SELF, &selfb);
-  getrusage (RUSAGE_CHILDREN, &kidsb);
-#else
-#  if defined (HAVE_TIMES)
-  tbefore = times (&before);
-#  endif
-#endif
-
-  posix_time = (command->flags & CMD_TIME_POSIX);
-
-  old_flags = command->flags;
-  command->flags &= ~(CMD_TIME_PIPELINE|CMD_TIME_POSIX);
-  rv = execute_command_internal (command, asynchronous, pipe_in, pipe_out, fds_to_close);
-  command->flags = old_flags;
-
-  rs = us = ss = 0;
-  rsf = usf = ssf = cpu = 0;
-
-#if defined (HAVE_GETRUSAGE) && defined (HAVE_GETTIMEOFDAY)
-#  if defined (HAVE_STRUCT_TIMEZONE)
-  gettimeofday (&after, &dtz);
-#  else
-  gettimeofday (&after, (void *)NULL);
-#  endif /* !HAVE_STRUCT_TIMEZONE */
-  getrusage (RUSAGE_SELF, &selfa);
-  getrusage (RUSAGE_CHILDREN, &kidsa);
-
-  difftimeval (&real, &before, &after);
-  timeval_to_secs (&real, &rs, &rsf);
-
-  addtimeval (&user, difftimeval(&after, &selfb.ru_utime, &selfa.ru_utime),
-                    difftimeval(&before, &kidsb.ru_utime, &kidsa.ru_utime));
-  timeval_to_secs (&user, &us, &usf);
-
-  addtimeval (&sys, difftimeval(&after, &selfb.ru_stime, &selfa.ru_stime),
-                   difftimeval(&before, &kidsb.ru_stime, &kidsa.ru_stime));
-  timeval_to_secs (&sys, &ss, &ssf);
-
-  cpu = timeval_to_cpu (&real, &user, &sys);
-#else
-#  if defined (HAVE_TIMES)
-  tafter = times (&after);
-
-  real = tafter - tbefore;
-  clock_t_to_secs (real, &rs, &rsf);
-
-  user = (after.tms_utime - before.tms_utime) + (after.tms_cutime - before.tms_cutime);
-  clock_t_to_secs (user, &us, &usf);
-
-  sys = (after.tms_stime - before.tms_stime) + (after.tms_cstime - before.tms_cstime);
-  clock_t_to_secs (sys, &ss, &ssf);
-
-  cpu = (real == 0) ? 0 : ((user + sys) * 10000) / real;
-
-#  else
-  rs = us = ss = 0;
-  rsf = usf = ssf = cpu = 0;
-#  endif
-#endif
-
-  if (posix_time)
-    time_format = POSIX_TIMEFORMAT;
-  else if ((time_format = get_string_value ("TIMEFORMAT")) == 0)
-    time_format = BASH_TIMEFORMAT;
-
-  if (time_format && *time_format)
-    print_formatted_time (stderr, time_format, rs, rsf, us, usf, ss, ssf, cpu);
-
-  return rv;
-}
-#endif /* COMMAND_TIMING */
-
-/* Execute a command that's supposed to be in a subshell.  This must be
-   called after make_child and we must be running in the child process.
-   The caller will return or exit() immediately with the value this returns. */
-static int
-execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close)
-     COMMAND *command;
-     int asynchronous;
-     int pipe_in, pipe_out;
-     struct fd_bitmap *fds_to_close;
-{
-  int user_subshell, return_code, function_value, should_redir_stdin, invert;
-  int ois, user_coproc;
-  int result;
-  COMMAND *tcom;
-
-  USE_VAR(user_subshell);
-  USE_VAR(user_coproc);
-  USE_VAR(invert);
-  USE_VAR(tcom);
-  USE_VAR(asynchronous);
-
-  subshell_level++;
-  should_redir_stdin = (asynchronous && (command->flags & CMD_STDIN_REDIR) &&
-                         pipe_in == NO_PIPE &&
-                         stdin_redirects (command->redirects) == 0);
-
-  invert = (command->flags & CMD_INVERT_RETURN) != 0;
-  user_subshell = command->type == cm_subshell || ((command->flags & CMD_WANT_SUBSHELL) != 0);
-  user_coproc = command->type == cm_coproc;
-
-  command->flags &= ~(CMD_FORCE_SUBSHELL | CMD_WANT_SUBSHELL | CMD_INVERT_RETURN);
-
-  /* If a command is asynchronous in a subshell (like ( foo ) & or
-     the special case of an asynchronous GROUP command where the
-     the subshell bit is turned on down in case cm_group: below),
-     turn off `asynchronous', so that two subshells aren't spawned.
-     XXX - asynchronous used to be set to 0 in this block, but that
-     means that setup_async_signals was never run.  Now it's set to
-     0 after subshell_environment is set appropriately and setup_async_signals
-     is run.
-
-     This seems semantically correct to me.  For example,
-     ( foo ) & seems to say ``do the command `foo' in a subshell
-     environment, but don't wait for that subshell to finish'',
-     and "{ foo ; bar ; } &" seems to me to be like functions or
-     builtins in the background, which executed in a subshell
-     environment.  I just don't see the need to fork two subshells. */
-
-  /* Don't fork again, we are already in a subshell.  A `doubly
-     async' shell is not interactive, however. */
-  if (asynchronous)
-    {
-#if defined (JOB_CONTROL)
-      /* If a construct like ( exec xxx yyy ) & is given while job
-        control is active, we want to prevent exec from putting the
-        subshell back into the original process group, carefully
-        undoing all the work we just did in make_child. */
-      original_pgrp = -1;
-#endif /* JOB_CONTROL */
-      ois = interactive_shell;
-      interactive_shell = 0;
-      /* This test is to prevent alias expansion by interactive shells that
-        run `(command) &' but to allow scripts that have enabled alias
-        expansion with `shopt -s expand_alias' to continue to expand
-        aliases. */
-      if (ois != interactive_shell)
-       expand_aliases = 0;
-    }
-
-  /* Subshells are neither login nor interactive. */
-  login_shell = interactive = 0;
-
-  if (user_subshell)
-    subshell_environment = SUBSHELL_PAREN;
-  else
-    {
-      subshell_environment = 0;                        /* XXX */
-      if (asynchronous)
-       subshell_environment |= SUBSHELL_ASYNC;
-      if (pipe_in != NO_PIPE || pipe_out != NO_PIPE)
-       subshell_environment |= SUBSHELL_PIPE;
-      if (user_coproc)
-       subshell_environment |= SUBSHELL_COPROC;
-    }
-
-  reset_terminating_signals ();                /* in sig.c */
-  /* Cancel traps, in trap.c. */
-  restore_original_signals ();
-
-  /* Make sure restore_original_signals doesn't undo the work done by
-     make_child to ensure that asynchronous children are immune to SIGINT
-     and SIGQUIT.  Turn off asynchronous to make sure more subshells are
-     not spawned. */
-  if (asynchronous)
-    {
-      setup_async_signals ();
-      asynchronous = 0;
-    }
-
-#if defined (JOB_CONTROL)
-  set_sigchld_handler ();
-#endif /* JOB_CONTROL */
-
-  set_sigint_handler ();
-
-#if defined (JOB_CONTROL)
-  /* Delete all traces that there were any jobs running.  This is
-     only for subshells. */
-  without_job_control ();
-#endif /* JOB_CONTROL */
-
-  if (fds_to_close)
-    close_fd_bitmap (fds_to_close);
-
-  do_piping (pipe_in, pipe_out);
-
-#if defined (COPROCESS_SUPPORT)
-  coproc_closeall ();
-#endif
-
-  /* If this is a user subshell, set a flag if stdin was redirected.
-     This is used later to decide whether to redirect fd 0 to
-     /dev/null for async commands in the subshell.  This adds more
-     sh compatibility, but I'm not sure it's the right thing to do. */
-  if (user_subshell)
-    {
-      stdin_redir = stdin_redirects (command->redirects);
-      restore_default_signal (0);
-    }
-
-  /* If this is an asynchronous command (command &), we want to
-     redirect the standard input from /dev/null in the absence of
-     any specific redirection involving stdin. */
-  if (should_redir_stdin && stdin_redir == 0)
-    async_redirect_stdin ();
-
-  /* Do redirections, then dispose of them before recursive call. */
-  if (command->redirects)
-    {
-      if (do_redirections (command->redirects, RX_ACTIVE) != 0)
-       exit (invert ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
-
-      dispose_redirects (command->redirects);
-      command->redirects = (REDIRECT *)NULL;
-    }
-
-  if (command->type == cm_subshell)
-    tcom = command->value.Subshell->command;
-  else if (user_coproc)
-    tcom = command->value.Coproc->command;
-  else
-    tcom = command;
-
-  if (command->flags & CMD_TIME_PIPELINE)
-    tcom->flags |= CMD_TIME_PIPELINE;
-  if (command->flags & CMD_TIME_POSIX)
-    tcom->flags |= CMD_TIME_POSIX;
-  
-  /* Make sure the subshell inherits any CMD_IGNORE_RETURN flag. */
-  if ((command->flags & CMD_IGNORE_RETURN) && tcom != command)
-    tcom->flags |= CMD_IGNORE_RETURN;
-
-  /* If this is a simple command, tell execute_disk_command that it
-     might be able to get away without forking and simply exec.
-     This means things like ( sleep 10 ) will only cause one fork.
-     If we're timing the command or inverting its return value, however,
-     we cannot do this optimization. */
-  if ((user_subshell || user_coproc) && (tcom->type == cm_simple || tcom->type == cm_subshell) &&
-      ((tcom->flags & CMD_TIME_PIPELINE) == 0) &&
-      ((tcom->flags & CMD_INVERT_RETURN) == 0))
-    {
-      tcom->flags |= CMD_NO_FORK;
-      if (tcom->type == cm_simple)
-       tcom->value.Simple->flags |= CMD_NO_FORK;
-    }
-
-  invert = (tcom->flags & CMD_INVERT_RETURN) != 0;
-  tcom->flags &= ~CMD_INVERT_RETURN;
-
-  result = setjmp (top_level);
-
-  /* If we're inside a function while executing this subshell, we
-     need to handle a possible `return'. */
-  function_value = 0;
-  if (return_catch_flag)
-    function_value = setjmp (return_catch);
-
-  /* If we're going to exit the shell, we don't want to invert the return
-     status. */
-  if (result == EXITPROG)
-    invert = 0, return_code = last_command_exit_value;
-  else if (result)
-    return_code = EXECUTION_FAILURE;
-  else if (function_value)
-    return_code = return_catch_value;
-  else
-    return_code = execute_command_internal (tcom, asynchronous, NO_PIPE, NO_PIPE, fds_to_close);
-
-  /* If we are asked to, invert the return value. */
-  if (invert)
-    return_code = (return_code == EXECUTION_SUCCESS) ? EXECUTION_FAILURE
-                                                    : EXECUTION_SUCCESS;
-
-  /* If we were explicitly placed in a subshell with (), we need
-     to do the `shell cleanup' things, such as running traps[0]. */
-  if (user_subshell && signal_is_trapped (0))
-    {
-      last_command_exit_value = return_code;
-      return_code = run_exit_trap ();
-    }
-
-  subshell_level--;
-  return (return_code);
-  /* NOTREACHED */
-}
-
-#if defined (COPROCESS_SUPPORT)
-#define COPROC_MAX     16
-
-typedef struct cpelement
-  {
-    struct cpelement *next;
-    struct coproc *coproc;
-  }
-cpelement_t;
-    
-typedef struct cplist
-  {
-    struct cpelement *head;
-    struct cpelement *tail;
-    int ncoproc;
-  }
-cplist_t;
-
-static struct cpelement *cpe_alloc __P((struct coproc *));
-static void cpe_dispose __P((struct cpelement *));
-static struct cpelement *cpl_add __P((struct coproc *));
-static struct cpelement *cpl_delete __P((pid_t));
-static void cpl_reap __P((void));
-static void cpl_flush __P((void));
-static struct cpelement *cpl_search __P((pid_t));
-static struct cpelement *cpl_searchbyname __P((char *));
-static void cpl_prune __P((void));
-
-Coproc sh_coproc = { 0, NO_PID, -1, -1, 0, 0 };
-
-cplist_t coproc_list = {0, 0, 0};
-
-/* Functions to manage the list of coprocs */
-
-static struct cpelement *
-cpe_alloc (cp)
-     Coproc *cp;
-{
-  struct cpelement *cpe;
-
-  cpe = (struct cpelement *)xmalloc (sizeof (struct cpelement));
-  cpe->coproc = cp;
-  cpe->next = (struct cpelement *)0;
-  return cpe;
-}
-
-static void
-cpe_dispose (cpe)
-      struct cpelement *cpe;
-{
-  free (cpe);
-}
-
-static struct cpelement *
-cpl_add (cp)
-     Coproc *cp;
-{
-  struct cpelement *cpe;
-
-  cpe = cpe_alloc (cp);
-
-  if (coproc_list.head == 0)
-    {
-      coproc_list.head = coproc_list.tail = cpe;
-      coproc_list.ncoproc = 0;                 /* just to make sure */
-    }
-  else
-    {
-      coproc_list.tail->next = cpe;
-      coproc_list.tail = cpe;
-    }
-  coproc_list.ncoproc++;
-
-  return cpe;
-}
-
-static struct cpelement *
-cpl_delete (pid)
-     pid_t pid;
-{
-  struct cpelement *prev, *p;
-
-  for (prev = p = coproc_list.head; p; prev = p, p = p->next)
-    if (p->coproc->c_pid == pid)
-      {
-        prev->next = p->next;  /* remove from list */
-        break;
-      }
-
-  if (p == 0)
-    return 0;          /* not found */
-
-#if defined (DEBUG)
-  itrace("cpl_delete: deleting %d", pid);
-#endif
-
-  /* Housekeeping in the border cases. */
-  if (p == coproc_list.head)
-    coproc_list.head = coproc_list.head->next;
-  else if (p == coproc_list.tail)
-    coproc_list.tail = prev;
-
-  coproc_list.ncoproc--;
-  if (coproc_list.ncoproc == 0)
-    coproc_list.head = coproc_list.tail = 0;
-  else if (coproc_list.ncoproc == 1)
-    coproc_list.tail = coproc_list.head;               /* just to make sure */
-
-  return (p);
-}
-
-static void
-cpl_reap ()
-{
-  struct cpelement *prev, *p;
-
-  for (prev = p = coproc_list.head; p; prev = p, p = p->next)
-    if (p->coproc->c_flags & COPROC_DEAD)
-      {
-        prev->next = p->next;  /* remove from list */
-
-       /* Housekeeping in the border cases. */
-       if (p == coproc_list.head)
-         coproc_list.head = coproc_list.head->next;
-       else if (p == coproc_list.tail)
-         coproc_list.tail = prev;
-
-       coproc_list.ncoproc--;
-       if (coproc_list.ncoproc == 0)
-         coproc_list.head = coproc_list.tail = 0;
-       else if (coproc_list.ncoproc == 1)
-         coproc_list.tail = coproc_list.head;          /* just to make sure */
-
-#if defined (DEBUG)
-       itrace("cpl_reap: deleting %d", p->coproc->c_pid);
-#endif
-
-       coproc_dispose (p->coproc);
-       cpe_dispose (p);
-      }
-}
-
-/* Clear out the list of saved statuses */
-static void
-cpl_flush ()
-{
-  struct cpelement *cpe, *p;
-
-  for (cpe = coproc_list.head; cpe; )
-    {
-      p = cpe;
-      cpe = cpe->next;
-
-      coproc_dispose (p->coproc);
-      cpe_dispose (p);
-    }
-
-  coproc_list.head = coproc_list.tail = 0;
-  coproc_list.ncoproc = 0;
-}
-
-/* Search for PID in the list of coprocs; return the cpelement struct if
-   found.  If not found, return NULL. */
-static struct cpelement *
-cpl_search (pid)
-     pid_t pid;
-{
-  struct cpelement *cp;
-
-  for (cp = coproc_list.head ; cp; cp = cp->next)
-    if (cp->coproc->c_pid == pid)
-      return cp;
-  return (struct cpelement *)NULL;
-}
-
-/* Search for the coproc named NAME in the list of coprocs; return the
-   cpelement struct if found.  If not found, return NULL. */
-static struct cpelement *
-cpl_searchbyname (name)
-     char *name;
-{
-  struct cpelement *cp;
-
-  for (cp = coproc_list.head ; cp; cp = cp->next)
-    if (STREQ (cp->coproc->c_name, name))
-      return cp;
-  return (struct cpelement *)NULL;
-}
-
-#if 0
-static void
-cpl_prune ()
-{
-  struct cpelement *cp;
-
-  while (coproc_list.head && coproc_list.ncoproc > COPROC_MAX)
-    {
-      cp = coproc_list.head;
-      coproc_list.head = coproc_list.head->next;
-      coproc_dispose (cp->coproc);
-      cpe_dispose (cp);
-      coproc_list.ncoproc--;
-    }
-}
-#endif
-
-/* These currently use a single global "shell coproc" but are written in a
-   way to not preclude additional coprocs later (using the list management
-   package above). */
-
-struct coproc *
-getcoprocbypid (pid)
-     pid_t pid;
-{
-  return (pid == sh_coproc.c_pid ? &sh_coproc : 0);
-}
-
-struct coproc *
-getcoprocbyname (name)
-     const char *name;
-{
-  return ((sh_coproc.c_name && STREQ (sh_coproc.c_name, name)) ? &sh_coproc : 0);
-}
-
-void
-coproc_init (cp)
-     struct coproc *cp;
-{
-  cp->c_name = 0;
-  cp->c_pid = NO_PID;
-  cp->c_rfd = cp->c_wfd = -1;
-  cp->c_rsave = cp->c_wsave = -1;
-  cp->c_flags = cp->c_status = 0;  
-}
-
-struct coproc *
-coproc_alloc (name, pid)
-     char *name;
-     pid_t pid;
-{
-  struct coproc *cp;
-
-  cp = &sh_coproc;             /* XXX */
-  coproc_init (cp);
-
-  cp->c_name = savestring (name);
-  cp->c_pid = pid;
-
-  return (cp);
-}
-
-void
-coproc_dispose (cp)
-     struct coproc *cp;
-{
-  if (cp == 0)
-    return;
-
-  coproc_unsetvars (cp);
-  FREE (cp->c_name);
-  coproc_close (cp);
-  coproc_init (cp);
-}
-
-/* Placeholder for now. */
-void
-coproc_flush ()
-{
-  coproc_dispose (&sh_coproc);
-}
-
-void
-coproc_close (cp)
-     struct coproc *cp;
-{
-  if (cp->c_rfd >= 0)
-    {
-      close (cp->c_rfd);
-      cp->c_rfd = -1;
-    }
-  if (cp->c_wfd >= 0)
-    {
-      close (cp->c_wfd);
-      cp->c_wfd = -1;
-    }
-  cp->c_rsave = cp->c_wsave = -1;
-}
-
-void
-coproc_closeall ()
-{
-  coproc_close (&sh_coproc);
-}
-
-void
-coproc_reap ()
-{
-  struct coproc *cp;
-
-  cp = &sh_coproc;
-  if (cp && (cp->c_flags & COPROC_DEAD))
-    coproc_dispose (cp);
-}
-
-void
-coproc_rclose (cp, fd)
-     struct coproc *cp;
-     int fd;
-{
-  if (cp->c_rfd >= 0 && cp->c_rfd == fd)
-    {
-      close (cp->c_rfd);
-      cp->c_rfd = -1;
-    }
-}
-
-void
-coproc_wclose (cp, fd)
-     struct coproc *cp;
-     int fd;
-{
-  if (cp->c_wfd >= 0 && cp->c_wfd == fd)
-    {
-      close (cp->c_wfd);
-      cp->c_wfd = -1;
-    }
-}
-
-void
-coproc_checkfd (cp, fd)
-     struct coproc *cp;
-     int fd;
-{
-  int update;
-
-  update = 0;
-  if (cp->c_rfd >= 0 && cp->c_rfd == fd)
-    update = cp->c_rfd = -1;
-  if (cp->c_wfd >= 0 && cp->c_wfd == fd)
-    update = cp->c_wfd = -1;
-  if (update)
-    coproc_setvars (cp);
-}
-
-void
-coproc_fdchk (fd)
-     int fd;
-{
-  coproc_checkfd (&sh_coproc, fd);
-}
-
-void
-coproc_fdclose (cp, fd)
-     struct coproc *cp;
-     int fd;
-{
-  coproc_rclose (cp, fd);
-  coproc_wclose (cp, fd);
-  coproc_setvars (cp);
-}
-
-void
-coproc_fdsave (cp)
-     struct coproc *cp;
-{
-  cp->c_rsave = cp->c_rfd;
-  cp->c_wsave = cp->c_wfd;
-}
-
-void
-coproc_fdrestore (cp)
-     struct coproc *cp;
-{
-  cp->c_rfd = cp->c_rsave;
-  cp->c_wfd = cp->c_wsave;
-}
-
-void
-coproc_pidchk (pid, status)
-     pid_t pid;
-{
-  struct coproc *cp;
-
-  cp = getcoprocbypid (pid);
-#if 0
-  if (cp)
-    itrace("coproc_pidchk: pid %d has died", pid);
-#endif
-  if (cp)
-    {
-      cp->c_status = status;
-      cp->c_flags |= COPROC_DEAD;
-      cp->c_flags &= ~COPROC_RUNNING;
-#if 0
-      coproc_dispose (cp);
-#endif
-    }
-}
-
-void
-coproc_setvars (cp)
-     struct coproc *cp;
-{
-  SHELL_VAR *v;
-  char *namevar, *t;
-  int l;
-#if defined (ARRAY_VARS)
-  arrayind_t ind;
-#endif
-
-  if (cp->c_name == 0)
-    return;
-
-  l = strlen (cp->c_name);
-  namevar = xmalloc (l + 16);
-
-#if defined (ARRAY_VARS)
-  v = find_variable (cp->c_name);
-  if (v == 0)
-    v = make_new_array_variable (cp->c_name);
-  if (array_p (v) == 0)
-    v = convert_var_to_array (v);
-
-  t = itos (cp->c_rfd);
-  ind = 0;
-  v = bind_array_variable (cp->c_name, ind, t, 0);
-  free (t);
-
-  t = itos (cp->c_wfd);
-  ind = 1;
-  bind_array_variable (cp->c_name, ind, t, 0);
-  free (t);
-#else
-  sprintf (namevar, "%s_READ", cp->c_name);
-  t = itos (cp->c_rfd);
-  bind_variable (namevar, t, 0);
-  free (t);
-  sprintf (namevar, "%s_WRITE", cp->c_name);
-  t = itos (cp->c_wfd);
-  bind_variable (namevar, t, 0);
-  free (t);
-#endif
-
-  sprintf (namevar, "%s_PID", cp->c_name);
-  t = itos (cp->c_pid);
-  bind_variable (namevar, t, 0);
-  free (t);
-
-  free (namevar);
-}
-
-void
-coproc_unsetvars (cp)
-     struct coproc *cp;
-{
-  int l;
-  char *namevar;
-
-  if (cp->c_name == 0)
-    return;
-
-  l = strlen (cp->c_name);
-  namevar = xmalloc (l + 16);
-
-  sprintf (namevar, "%s_PID", cp->c_name);
-  unbind_variable (namevar);  
-
-#if defined (ARRAY_VARS)
-  unbind_variable (cp->c_name);
-#else
-  sprintf (namevar, "%s_READ", cp->c_name);
-  unbind_variable (namevar);
-  sprintf (namevar, "%s_WRITE", cp->c_name);
-  unbind_variable (namevar);
-#endif  
-
-  free (namevar);
-}
-
-static int
-execute_coproc (command, pipe_in, pipe_out, fds_to_close)
-     COMMAND *command;
-     int pipe_in, pipe_out;
-     struct fd_bitmap *fds_to_close;
-{
-  int rpipe[2], wpipe[2], estat;
-  pid_t coproc_pid;
-  Coproc *cp;
-  char *tcmd;
-
-  /* XXX -- will require changes to handle multiple coprocs */
-  if (sh_coproc.c_pid != NO_PID)
-    {
-#if 0
-      internal_error ("execute_coproc: coproc [%d:%s] already exists", sh_coproc.c_pid, sh_coproc.c_name);
-      return (last_command_exit_value = EXECUTION_FAILURE);
-#else
-      internal_warning ("execute_coproc: coproc [%d:%s] still exists", sh_coproc.c_pid, sh_coproc.c_name);
-#endif
-    }
-  coproc_init (&sh_coproc);
-
-  command_string_index = 0;
-  tcmd = make_command_string (command);
-
-  sh_openpipe ((int *)&rpipe); /* 0 = parent read, 1 = child write */
-  sh_openpipe ((int *)&wpipe); /* 0 = child read, 1 = parent write */
-
-  coproc_pid = make_child (savestring (tcmd), 1);
-  if (coproc_pid == 0)
-    {
-      close (rpipe[0]);
-      close (wpipe[1]);
-
-      estat = execute_in_subshell (command, 1, wpipe[0], rpipe[1], fds_to_close);
-
-      fflush (stdout);
-      fflush (stderr);
-
-      exit (estat);
-    }
-
-  close (rpipe[1]);
-  close (wpipe[0]);
-
-  cp = coproc_alloc (command->value.Coproc->name, coproc_pid);
-  cp->c_rfd = rpipe[0];
-  cp->c_wfd = wpipe[1];
-
-  SET_CLOSE_ON_EXEC (cp->c_rfd);
-  SET_CLOSE_ON_EXEC (cp->c_wfd);
-
-  coproc_setvars (cp);
-
-#if 0
-  itrace ("execute_coproc: [%d] %s", coproc_pid, the_printed_command);
-#endif
-
-  close_pipes (pipe_in, pipe_out);
-#if defined (PROCESS_SUBSTITUTION) && defined (HAVE_DEV_FD)
-  unlink_fifo_list ();
-#endif
-  stop_pipeline (1, (COMMAND *)NULL);
-  DESCRIBE_PID (coproc_pid);
-  run_pending_traps ();
-
-  return (EXECUTION_SUCCESS);
-}
-#endif
-
-static int
-execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close)
-     COMMAND *command;
-     int asynchronous, pipe_in, pipe_out;
-     struct fd_bitmap *fds_to_close;
-{
-  int prev, fildes[2], new_bitmap_size, dummyfd, ignore_return, exec_result;
-  COMMAND *cmd;
-  struct fd_bitmap *fd_bitmap;
-
-#if defined (JOB_CONTROL)
-  sigset_t set, oset;
-  BLOCK_CHILD (set, oset);
-#endif /* JOB_CONTROL */
-
-  ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
-
-  prev = pipe_in;
-  cmd = command;
-
-  while (cmd && cmd->type == cm_connection &&
-        cmd->value.Connection && cmd->value.Connection->connector == '|')
-    {
-      /* Make a pipeline between the two commands. */
-      if (pipe (fildes) < 0)
-       {
-         sys_error (_("pipe error"));
-#if defined (JOB_CONTROL)
-         terminate_current_pipeline ();
-         kill_current_pipeline ();
-         UNBLOCK_CHILD (oset);
-#endif /* JOB_CONTROL */
-         last_command_exit_value = EXECUTION_FAILURE;
-         /* The unwind-protects installed below will take care
-            of closing all of the open file descriptors. */
-         throw_to_top_level ();
-         return (EXECUTION_FAILURE);   /* XXX */
-       }
-
-      /* Here is a problem: with the new file close-on-exec
-        code, the read end of the pipe (fildes[0]) stays open
-        in the first process, so that process will never get a
-        SIGPIPE.  There is no way to signal the first process
-        that it should close fildes[0] after forking, so it
-        remains open.  No SIGPIPE is ever sent because there
-        is still a file descriptor open for reading connected
-        to the pipe.  We take care of that here.  This passes
-        around a bitmap of file descriptors that must be
-        closed after making a child process in execute_simple_command. */
-
-      /* We need fd_bitmap to be at least as big as fildes[0].
-        If fildes[0] is less than fds_to_close->size, then
-        use fds_to_close->size. */
-      new_bitmap_size = (fildes[0] < fds_to_close->size)
-                               ? fds_to_close->size
-                               : fildes[0] + 8;
-
-      fd_bitmap = new_fd_bitmap (new_bitmap_size);
-
-      /* Now copy the old information into the new bitmap. */
-      xbcopy ((char *)fds_to_close->bitmap, (char *)fd_bitmap->bitmap, fds_to_close->size);
-
-      /* And mark the pipe file descriptors to be closed. */
-      fd_bitmap->bitmap[fildes[0]] = 1;
-
-      /* In case there are pipe or out-of-processes errors, we
-        want all these file descriptors to be closed when
-        unwind-protects are run, and the storage used for the
-        bitmaps freed up. */
-      begin_unwind_frame ("pipe-file-descriptors");
-      add_unwind_protect (dispose_fd_bitmap, fd_bitmap);
-      add_unwind_protect (close_fd_bitmap, fd_bitmap);
-      if (prev >= 0)
-       add_unwind_protect (close, prev);
-      dummyfd = fildes[1];
-      add_unwind_protect (close, dummyfd);
-
-#if defined (JOB_CONTROL)
-      add_unwind_protect (restore_signal_mask, &oset);
-#endif /* JOB_CONTROL */
-
-      if (ignore_return && cmd->value.Connection->first)
-       cmd->value.Connection->first->flags |= CMD_IGNORE_RETURN;
-      execute_command_internal (cmd->value.Connection->first, asynchronous,
-                               prev, fildes[1], fd_bitmap);
-
-      if (prev >= 0)
-       close (prev);
-
-      prev = fildes[0];
-      close (fildes[1]);
-
-      dispose_fd_bitmap (fd_bitmap);
-      discard_unwind_frame ("pipe-file-descriptors");
-
-      cmd = cmd->value.Connection->second;
-    }
-
-  /* Now execute the rightmost command in the pipeline.  */
-  if (ignore_return && cmd)
-    cmd->flags |= CMD_IGNORE_RETURN;
-  exec_result = execute_command_internal (cmd, asynchronous, prev, pipe_out, fds_to_close);
-
-  if (prev >= 0)
-    close (prev);
-
-#if defined (JOB_CONTROL)
-  UNBLOCK_CHILD (oset);
-#endif
-
-  QUIT;
-  return (exec_result);
-}
-
-static int
-execute_connection (command, asynchronous, pipe_in, pipe_out, fds_to_close)
-     COMMAND *command;
-     int asynchronous, pipe_in, pipe_out;
-     struct fd_bitmap *fds_to_close;
-{
-  REDIRECT *rp;
-  COMMAND *tc, *second;
-  int ignore_return, exec_result, was_error_trap, invert;
-  volatile int save_line_number;
-
-  ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
-
-  switch (command->value.Connection->connector)
-    {
-    /* Do the first command asynchronously. */
-    case '&':
-      tc = command->value.Connection->first;
-      if (tc == 0)
-       return (EXECUTION_SUCCESS);
-
-      rp = tc->redirects;
-
-      if (ignore_return)
-       tc->flags |= CMD_IGNORE_RETURN;
-      tc->flags |= CMD_AMPERSAND;
-
-      /* If this shell was compiled without job control support,
-        if we are currently in a subshell via `( xxx )', or if job
-        control is not active then the standard input for an
-        asynchronous command is forced to /dev/null. */
-#if defined (JOB_CONTROL)
-      if ((subshell_environment || !job_control) && !stdin_redir)
-#else
-      if (!stdin_redir)
-#endif /* JOB_CONTROL */
-       tc->flags |= CMD_STDIN_REDIR;
-
-      exec_result = execute_command_internal (tc, 1, pipe_in, pipe_out, fds_to_close);
-      QUIT;
-
-      if (tc->flags & CMD_STDIN_REDIR)
-       tc->flags &= ~CMD_STDIN_REDIR;
-
-      second = command->value.Connection->second;
-      if (second)
-       {
-         if (ignore_return)
-           second->flags |= CMD_IGNORE_RETURN;
-
-         exec_result = execute_command_internal (second, asynchronous, pipe_in, pipe_out, fds_to_close);
-       }
-
-      break;
-
-    /* Just call execute command on both sides. */
-    case ';':
-      if (ignore_return)
-       {
-         if (command->value.Connection->first)
-           command->value.Connection->first->flags |= CMD_IGNORE_RETURN;
-         if (command->value.Connection->second)
-           command->value.Connection->second->flags |= CMD_IGNORE_RETURN;
-       }
-      executing_list++;
-      QUIT;
-      execute_command (command->value.Connection->first);
-      QUIT;
-      exec_result = execute_command_internal (command->value.Connection->second,
-                                     asynchronous, pipe_in, pipe_out,
-                                     fds_to_close);
-      executing_list--;
-      break;
-
-    case '|':
-      was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0;
-      invert = (command->flags & CMD_INVERT_RETURN) != 0;
-      ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
-
-      line_number_for_err_trap = line_number;
-      exec_result = execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close);
-
-      if (was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS)
-       {
-         last_command_exit_value = exec_result;
-         save_line_number = line_number;
-         line_number = line_number_for_err_trap;
-         run_error_trap ();
-         line_number = save_line_number;
-       }
-
-      if (ignore_return == 0 && invert == 0 && exit_immediately_on_error && exec_result != EXECUTION_SUCCESS)
-       {
-         last_command_exit_value = exec_result;
-         run_pending_traps ();
-         jump_to_top_level (ERREXIT);
-       }
-
-      break;
-
-    case AND_AND:
-    case OR_OR:
-      if (asynchronous)
-       {
-         /* If we have something like `a && b &' or `a || b &', run the
-            && or || stuff in a subshell.  Force a subshell and just call
-            execute_command_internal again.  Leave asynchronous on
-            so that we get a report from the parent shell about the
-            background job. */
-         command->flags |= CMD_FORCE_SUBSHELL;
-         exec_result = execute_command_internal (command, 1, pipe_in, pipe_out, fds_to_close);
-         break;
-       }
-
-      /* Execute the first command.  If the result of that is successful
-        and the connector is AND_AND, or the result is not successful
-        and the connector is OR_OR, then execute the second command,
-        otherwise return. */
-
-      executing_list++;
-      if (command->value.Connection->first)
-       command->value.Connection->first->flags |= CMD_IGNORE_RETURN;
-
-      exec_result = execute_command (command->value.Connection->first);
-      QUIT;
-      if (((command->value.Connection->connector == AND_AND) &&
-          (exec_result == EXECUTION_SUCCESS)) ||
-         ((command->value.Connection->connector == OR_OR) &&
-          (exec_result != EXECUTION_SUCCESS)))
-       {
-         if (ignore_return && command->value.Connection->second)
-           command->value.Connection->second->flags |= CMD_IGNORE_RETURN;
-
-         exec_result = execute_command (command->value.Connection->second);
-       }
-      executing_list--;
-      break;
-
-    default:
-      command_error ("execute_connection", CMDERR_BADCONN, command->value.Connection->connector, 0);
-      jump_to_top_level (DISCARD);
-      exec_result = EXECUTION_FAILURE;
-    }
-
-  return exec_result;
-}
-
-#define REAP() \
-  do \
-    { \
-      if (!interactive_shell) \
-       reap_dead_jobs (); \
-    } \
-  while (0)
-
-/* Execute a FOR command.  The syntax is: FOR word_desc IN word_list;
-   DO command; DONE */
-static int
-execute_for_command (for_command)
-     FOR_COM *for_command;
-{
-  register WORD_LIST *releaser, *list;
-  SHELL_VAR *v;
-  char *identifier;
-  int retval, save_line_number;
-#if 0
-  SHELL_VAR *old_value = (SHELL_VAR *)NULL; /* Remember the old value of x. */
-#endif
-
-  save_line_number = line_number;
-  if (check_identifier (for_command->name, 1) == 0)
-    {
-      if (posixly_correct && interactive_shell == 0)
-       {
-         last_command_exit_value = EX_BADUSAGE;
-         jump_to_top_level (ERREXIT);
-       }
-      return (EXECUTION_FAILURE);
-    }
-
-  loop_level++;
-  identifier = for_command->name->word;
-
-  list = releaser = expand_words_no_vars (for_command->map_list);
-
-  begin_unwind_frame ("for");
-  add_unwind_protect (dispose_words, releaser);
-
-#if 0
-  if (lexical_scoping)
-    {
-      old_value = copy_variable (find_variable (identifier));
-      if (old_value)
-       add_unwind_protect (dispose_variable, old_value);
-    }
-#endif
-
-  if (for_command->flags & CMD_IGNORE_RETURN)
-    for_command->action->flags |= CMD_IGNORE_RETURN;
-
-  for (retval = EXECUTION_SUCCESS; list; list = list->next)
-    {
-      QUIT;
-
-      line_number = for_command->line;
-
-      /* Remember what this command looks like, for debugger. */
-      command_string_index = 0;
-      print_for_command_head (for_command);
-
-      if (echo_command_at_execute)
-       xtrace_print_for_command_head (for_command);
-
-      /* Save this command unless it's a trap command and we're not running
-        a debug trap. */
-#if 0
-      if (signal_in_progress (DEBUG_TRAP) == 0 && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0)))
-#else
-      if (signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0)
-#endif
-       {
-         FREE (the_printed_command_except_trap);
-         the_printed_command_except_trap = savestring (the_printed_command);
-       }
-
-      retval = run_debug_trap ();
-#if defined (DEBUGGER)
-      /* In debugging mode, if the DEBUG trap returns a non-zero status, we
-        skip the command. */
-      if (debugging_mode && retval != EXECUTION_SUCCESS)
-        continue;
-#endif
-
-      this_command_name = (char *)NULL;
-      v = bind_variable (identifier, list->word->word, 0);
-      if (readonly_p (v) || noassign_p (v))
-       {
-         line_number = save_line_number;
-         if (readonly_p (v) && interactive_shell == 0 && posixly_correct)
-           {
-             last_command_exit_value = EXECUTION_FAILURE;
-             jump_to_top_level (FORCE_EOF);
-           }
-         else
-           {
-             dispose_words (releaser);
-             discard_unwind_frame ("for");
-             loop_level--;
-             return (EXECUTION_FAILURE);
-           }
-       }
-      retval = execute_command (for_command->action);
-      REAP ();
-      QUIT;
-
-      if (breaking)
-       {
-         breaking--;
-         break;
-       }
-
-      if (continuing)
-       {
-         continuing--;
-         if (continuing)
-           break;
-       }
-    }
-
-  loop_level--;
-  line_number = save_line_number;
-
-#if 0
-  if (lexical_scoping)
-    {
-      if (!old_value)
-        unbind_variable (identifier);
-      else
-       {
-         SHELL_VAR *new_value;
-
-         new_value = bind_variable (identifier, value_cell(old_value), 0);
-         new_value->attributes = old_value->attributes;
-         dispose_variable (old_value);
-       }
-    }
-#endif
-
-  dispose_words (releaser);
-  discard_unwind_frame ("for");
-  return (retval);
-}
-
-#if defined (ARITH_FOR_COMMAND)
-/* Execute an arithmetic for command.  The syntax is
-
-       for (( init ; step ; test ))
-       do
-               body
-       done
-
-   The execution should be exactly equivalent to
-
-       eval \(\( init \)\)
-       while eval \(\( test \)\) ; do
-               body;
-               eval \(\( step \)\)
-       done
-*/
-static intmax_t
-eval_arith_for_expr (l, okp)
-     WORD_LIST *l;
-     int *okp;
-{
-  WORD_LIST *new;
-  intmax_t expresult;
-  int r;
-
-  new = expand_words_no_vars (l);
-  if (new)
-    {
-      if (echo_command_at_execute)
-       xtrace_print_arith_cmd (new);
-      this_command_name = "((";                /* )) for expression error messages */
-
-      command_string_index = 0;
-      print_arith_command (new);
-      if (signal_in_progress (DEBUG_TRAP) == 0)
-       {
-         FREE (the_printed_command_except_trap);
-         the_printed_command_except_trap = savestring (the_printed_command);
-       }
-
-      r = run_debug_trap ();
-      /* In debugging mode, if the DEBUG trap returns a non-zero status, we
-        skip the command. */
-#if defined (DEBUGGER)
-      if (debugging_mode == 0 || r == EXECUTION_SUCCESS)
-       expresult = evalexp (new->word->word, okp);
-      else
-       {
-         expresult = 0;
-         if (okp)
-           *okp = 1;
-       }
-#else
-      expresult = evalexp (new->word->word, okp);
-#endif
-      dispose_words (new);
-    }
-  else
-    {
-      expresult = 0;
-      if (okp)
-       *okp = 1;
-    }
-  return (expresult);
-}
-
-static int
-execute_arith_for_command (arith_for_command)
-     ARITH_FOR_COM *arith_for_command;
-{
-  intmax_t expresult;
-  int expok, body_status, arith_lineno, save_lineno;
-
-  body_status = EXECUTION_SUCCESS;
-  loop_level++;
-  save_lineno = line_number;
-
-  if (arith_for_command->flags & CMD_IGNORE_RETURN)
-    arith_for_command->action->flags |= CMD_IGNORE_RETURN;
-
-  this_command_name = "((";    /* )) for expression error messages */
-
-  /* save the starting line number of the command so we can reset
-     line_number before executing each expression -- for $LINENO
-     and the DEBUG trap. */
-  line_number = arith_lineno = arith_for_command->line;
-  if (variable_context && interactive_shell)
-    line_number -= function_line_number;
-
-  /* Evaluate the initialization expression. */
-  expresult = eval_arith_for_expr (arith_for_command->init, &expok);
-  if (expok == 0)
-    {
-      line_number = save_lineno;
-      return (EXECUTION_FAILURE);
-    }
-
-  while (1)
-    {
-      /* Evaluate the test expression. */
-      line_number = arith_lineno;
-      expresult = eval_arith_for_expr (arith_for_command->test, &expok);
-      line_number = save_lineno;
-
-      if (expok == 0)
-       {
-         body_status = EXECUTION_FAILURE;
-         break;
-       }
-      REAP ();
-      if (expresult == 0)
-       break;
-
-      /* Execute the body of the arithmetic for command. */
-      QUIT;
-      body_status = execute_command (arith_for_command->action);
-      QUIT;
-
-      /* Handle any `break' or `continue' commands executed by the body. */
-      if (breaking)
-       {
-         breaking--;
-         break;
-       }
-
-      if (continuing)
-       {
-         continuing--;
-         if (continuing)
-           break;
-       }
-
-      /* Evaluate the step expression. */
-      line_number = arith_lineno;
-      expresult = eval_arith_for_expr (arith_for_command->step, &expok);
-      line_number = save_lineno;
-
-      if (expok == 0)
-       {
-         body_status = EXECUTION_FAILURE;
-         break;
-       }
-    }
-
-  loop_level--;
-  line_number = save_lineno;
-
-  return (body_status);
-}
-#endif
-
-#if defined (SELECT_COMMAND)
-static int LINES, COLS, tabsize;
-
-#define RP_SPACE ") "
-#define RP_SPACE_LEN 2
-
-/* XXX - does not handle numbers > 1000000 at all. */
-#define NUMBER_LEN(s) \
-((s < 10) ? 1 \
-         : ((s < 100) ? 2 \
-                     : ((s < 1000) ? 3 \
-                                  : ((s < 10000) ? 4 \
-                                                : ((s < 100000) ? 5 \
-                                                               : 6)))))
-
-static int
-print_index_and_element (len, ind, list)
-      int len, ind;
-      WORD_LIST *list;
-{
-  register WORD_LIST *l;
-  register int i;
-
-  if (list == 0)
-    return (0);
-  for (i = ind, l = list; l && --i; l = l->next)
-    ;
-  fprintf (stderr, "%*d%s%s", len, ind, RP_SPACE, l->word->word);
-  return (STRLEN (l->word->word));
-}
-
-static void
-indent (from, to)
-     int from, to;
-{
-  while (from < to)
-    {
-      if ((to / tabsize) > (from / tabsize))
-       {
-         putc ('\t', stderr);
-         from += tabsize - from % tabsize;
-       }
-      else
-       {
-         putc (' ', stderr);
-         from++;
-       }
-    }
-}
-
-static void
-print_select_list (list, list_len, max_elem_len, indices_len)
-     WORD_LIST *list;
-     int list_len, max_elem_len, indices_len;
-{
-  int ind, row, elem_len, pos, cols, rows;
-  int first_column_indices_len, other_indices_len;
-
-  if (list == 0)
-    {
-      putc ('\n', stderr);
-      return;
-    }
-
-  cols = max_elem_len ? COLS / max_elem_len : 1;
-  if (cols == 0)
-    cols = 1;
-  rows = list_len ? list_len / cols + (list_len % cols != 0) : 1;
-  cols = list_len ? list_len / rows + (list_len % rows != 0) : 1;
-
-  if (rows == 1)
-    {
-      rows = cols;
-      cols = 1;
-    }
-
-  first_column_indices_len = NUMBER_LEN (rows);
-  other_indices_len = indices_len;
-
-  for (row = 0; row < rows; row++)
-    {
-      ind = row;
-      pos = 0;
-      while (1)
-       {
-         indices_len = (pos == 0) ? first_column_indices_len : other_indices_len;
-         elem_len = print_index_and_element (indices_len, ind + 1, list);
-         elem_len += indices_len + RP_SPACE_LEN;
-         ind += rows;
-         if (ind >= list_len)
-           break;
-         indent (pos + elem_len, pos + max_elem_len);
-         pos += max_elem_len;
-       }
-      putc ('\n', stderr);
-    }
-}
-
-/* Print the elements of LIST, one per line, preceded by an index from 1 to
-   LIST_LEN.  Then display PROMPT and wait for the user to enter a number.
-   If the number is between 1 and LIST_LEN, return that selection.  If EOF
-   is read, return a null string.  If a blank line is entered, or an invalid
-   number is entered, the loop is executed again. */
-static char *
-select_query (list, list_len, prompt, print_menu)
-     WORD_LIST *list;
-     int list_len;
-     char *prompt;
-     int print_menu;
-{
-  int max_elem_len, indices_len, len;
-  intmax_t reply;
-  WORD_LIST *l;
-  char *repl_string, *t;
-
-  t = get_string_value ("LINES");
-  LINES = (t && *t) ? atoi (t) : 24;
-  t = get_string_value ("COLUMNS");
-  COLS =  (t && *t) ? atoi (t) : 80;
-
-#if 0
-  t = get_string_value ("TABSIZE");
-  tabsize = (t && *t) ? atoi (t) : 8;
-  if (tabsize <= 0)
-    tabsize = 8;
-#else
-  tabsize = 8;
-#endif
-
-  max_elem_len = 0;
-  for (l = list; l; l = l->next)
-    {
-      len = STRLEN (l->word->word);
-      if (len > max_elem_len)
-       max_elem_len = len;
-    }
-  indices_len = NUMBER_LEN (list_len);
-  max_elem_len += indices_len + RP_SPACE_LEN + 2;
-
-  while (1)
-    {
-      if (print_menu)
-       print_select_list (list, list_len, max_elem_len, indices_len);
-      fprintf (stderr, "%s", prompt);
-      fflush (stderr);
-      QUIT;
-
-      if (read_builtin ((WORD_LIST *)NULL) == EXECUTION_FAILURE)
-       {
-         putchar ('\n');
-         return ((char *)NULL);
-       }
-      repl_string = get_string_value ("REPLY");
-      if (*repl_string == 0)
-       {
-         print_menu = 1;
-         continue;
-       }
-      if (legal_number (repl_string, &reply) == 0)
-       return "";
-      if (reply < 1 || reply > list_len)
-       return "";
-
-      for (l = list; l && --reply; l = l->next)
-       ;
-      return (l->word->word);
-    }
-}
-
-/* Execute a SELECT command.  The syntax is:
-   SELECT word IN list DO command_list DONE
-   Only `break' or `return' in command_list will terminate
-   the command. */
-static int
-execute_select_command (select_command)
-     SELECT_COM *select_command;
-{
-  WORD_LIST *releaser, *list;
-  SHELL_VAR *v;
-  char *identifier, *ps3_prompt, *selection;
-  int retval, list_len, show_menu, save_line_number;
-
-  if (check_identifier (select_command->name, 1) == 0)
-    return (EXECUTION_FAILURE);
-
-  save_line_number = line_number;
-  line_number = select_command->line;
-
-  command_string_index = 0;
-  print_select_command_head (select_command);
-
-  if (echo_command_at_execute)
-    xtrace_print_select_command_head (select_command);
-
-#if 0
-  if (signal_in_progress (DEBUG_TRAP) == 0 && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0)))
-#else
-  if (signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0)
-#endif
-    {
-      FREE (the_printed_command_except_trap);
-      the_printed_command_except_trap = savestring (the_printed_command);
-    }
-
-  retval = run_debug_trap ();
-#if defined (DEBUGGER)
-  /* In debugging mode, if the DEBUG trap returns a non-zero status, we
-     skip the command. */
-  if (debugging_mode && retval != EXECUTION_SUCCESS)
-    return (EXECUTION_SUCCESS);
-#endif
-
-  loop_level++;
-  identifier = select_command->name->word;
-
-  /* command and arithmetic substitution, parameter and variable expansion,
-     word splitting, pathname expansion, and quote removal. */
-  list = releaser = expand_words_no_vars (select_command->map_list);
-  list_len = list_length (list);
-  if (list == 0 || list_len == 0)
-    {
-      if (list)
-       dispose_words (list);
-      line_number = save_line_number;
-      return (EXECUTION_SUCCESS);
-    }
-
-  begin_unwind_frame ("select");
-  add_unwind_protect (dispose_words, releaser);
-
-  if (select_command->flags & CMD_IGNORE_RETURN)
-    select_command->action->flags |= CMD_IGNORE_RETURN;
-
-  retval = EXECUTION_SUCCESS;
-  show_menu = 1;
-
-  while (1)
-    {
-      line_number = select_command->line;
-      ps3_prompt = get_string_value ("PS3");
-      if (ps3_prompt == 0)
-       ps3_prompt = "#? ";
-
-      QUIT;
-      selection = select_query (list, list_len, ps3_prompt, show_menu);
-      QUIT;
-      if (selection == 0)
-       {
-         /* select_query returns EXECUTION_FAILURE if the read builtin
-            fails, so we want to return failure in this case. */
-         retval = EXECUTION_FAILURE;
-         break;
-       }
-
-      v = bind_variable (identifier, selection, 0);
-      if (readonly_p (v) || noassign_p (v))
-       {
-         if (readonly_p (v) && interactive_shell == 0 && posixly_correct)
-           {
-             last_command_exit_value = EXECUTION_FAILURE;
-             jump_to_top_level (FORCE_EOF);
-           }
-         else
-           {
-             dispose_words (releaser);
-             discard_unwind_frame ("select");
-             loop_level--;
-             line_number = save_line_number;
-             return (EXECUTION_FAILURE);
-           }
-       }
-
-      retval = execute_command (select_command->action);
-
-      REAP ();
-      QUIT;
-
-      if (breaking)
-       {
-         breaking--;
-         break;
-       }
-
-      if (continuing)
-       {
-         continuing--;
-         if (continuing)
-           break;
-       }
-
-#if defined (KSH_COMPATIBLE_SELECT)
-      show_menu = 0;
-      selection = get_string_value ("REPLY");
-      if (selection && *selection == '\0')
-        show_menu = 1;
-#endif
-    }
-
-  loop_level--;
-  line_number = save_line_number;
-
-  dispose_words (releaser);
-  discard_unwind_frame ("select");
-  return (retval);
-}
-#endif /* SELECT_COMMAND */
-
-/* Execute a CASE command.  The syntax is: CASE word_desc IN pattern_list ESAC.
-   The pattern_list is a linked list of pattern clauses; each clause contains
-   some patterns to compare word_desc against, and an associated command to
-   execute. */
-static int
-execute_case_command (case_command)
-     CASE_COM *case_command;
-{
-  register WORD_LIST *list;
-  WORD_LIST *wlist, *es;
-  PATTERN_LIST *clauses;
-  char *word, *pattern;
-  int retval, match, ignore_return, save_line_number;
-
-  save_line_number = line_number;
-  line_number = case_command->line;
-
-  command_string_index = 0;
-  print_case_command_head (case_command);
-
-  if (echo_command_at_execute)
-    xtrace_print_case_command_head (case_command);
-
-#if 0
-  if (signal_in_progress (DEBUG_TRAP) == 0 && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0)))
-#else
-  if (signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0)
-#endif
-    {
-      FREE (the_printed_command_except_trap);
-      the_printed_command_except_trap = savestring (the_printed_command);
-    }
-
-  retval = run_debug_trap();
-#if defined (DEBUGGER)
-  /* In debugging mode, if the DEBUG trap returns a non-zero status, we
-     skip the command. */
-  if (debugging_mode && retval != EXECUTION_SUCCESS)
-    {
-      line_number = save_line_number;
-      return (EXECUTION_SUCCESS);
-    }
-#endif
-
-  wlist = expand_word_unsplit (case_command->word, 0);
-  word = wlist ? string_list (wlist) : savestring ("");
-  dispose_words (wlist);
-
-  retval = EXECUTION_SUCCESS;
-  ignore_return = case_command->flags & CMD_IGNORE_RETURN;
-
-  begin_unwind_frame ("case");
-  add_unwind_protect ((Function *)xfree, word);
-
-#define EXIT_CASE()  goto exit_case_command
-
-  for (clauses = case_command->clauses; clauses; clauses = clauses->next)
-    {
-      QUIT;
-      for (list = clauses->patterns; list; list = list->next)
-       {
-         es = expand_word_leave_quoted (list->word, 0);
-
-         if (es && es->word && es->word->word && *(es->word->word))
-           pattern = quote_string_for_globbing (es->word->word, QGLOB_CVTNULL);
-         else
-           {
-             pattern = (char *)xmalloc (1);
-             pattern[0] = '\0';
-           }
-
-         /* Since the pattern does not undergo quote removal (as per
-            Posix.2, section 3.9.4.3), the strmatch () call must be able
-            to recognize backslashes as escape characters. */
-         match = strmatch (pattern, word, FNMATCH_EXTFLAG|FNMATCH_IGNCASE) != FNM_NOMATCH;
-         free (pattern);
-
-         dispose_words (es);
-
-         if (match)
-           {
-             do
-               {
-                 if (clauses->action && ignore_return)
-                   clauses->action->flags |= CMD_IGNORE_RETURN;
-                 retval = execute_command (clauses->action);
-               }
-             while ((clauses->flags & CASEPAT_FALLTHROUGH) && (clauses = clauses->next));
-             if (clauses == 0 || (clauses->flags & CASEPAT_TESTNEXT) == 0)
-               EXIT_CASE ();
-             else
-               break;
-           }
-
-         QUIT;
-       }
-    }
-
-exit_case_command:
-  free (word);
-  discard_unwind_frame ("case");
-  line_number = save_line_number;
-  return (retval);
-}
-
-#define CMD_WHILE 0
-#define CMD_UNTIL 1
-
-/* The WHILE command.  Syntax: WHILE test DO action; DONE.
-   Repeatedly execute action while executing test produces
-   EXECUTION_SUCCESS. */
-static int
-execute_while_command (while_command)
-     WHILE_COM *while_command;
-{
-  return (execute_while_or_until (while_command, CMD_WHILE));
-}
-
-/* UNTIL is just like WHILE except that the test result is negated. */
-static int
-execute_until_command (while_command)
-     WHILE_COM *while_command;
-{
-  return (execute_while_or_until (while_command, CMD_UNTIL));
-}
-
-/* The body for both while and until.  The only difference between the
-   two is that the test value is treated differently.  TYPE is
-   CMD_WHILE or CMD_UNTIL.  The return value for both commands should
-   be EXECUTION_SUCCESS if no commands in the body are executed, and
-   the status of the last command executed in the body otherwise. */
-static int
-execute_while_or_until (while_command, type)
-     WHILE_COM *while_command;
-     int type;
-{
-  int return_value, body_status;
-
-  body_status = EXECUTION_SUCCESS;
-  loop_level++;
-
-  while_command->test->flags |= CMD_IGNORE_RETURN;
-  if (while_command->flags & CMD_IGNORE_RETURN)
-    while_command->action->flags |= CMD_IGNORE_RETURN;
-
-  while (1)
-    {
-      return_value = execute_command (while_command->test);
-      REAP ();
-
-      /* Need to handle `break' in the test when we would break out of the
-         loop.  The job control code will set `breaking' to loop_level
-         when a job in a loop is stopped with SIGTSTP.  If the stopped job
-         is in the loop test, `breaking' will not be reset unless we do
-         this, and the shell will cease to execute commands. */
-      if (type == CMD_WHILE && return_value != EXECUTION_SUCCESS)
-       {
-         if (breaking)
-           breaking--;
-         break;
-       }
-      if (type == CMD_UNTIL && return_value == EXECUTION_SUCCESS)
-       {
-         if (breaking)
-           breaking--;
-         break;
-       }
-
-      QUIT;
-      body_status = execute_command (while_command->action);
-      QUIT;
-
-      if (breaking)
-       {
-         breaking--;
-         break;
-       }
-
-      if (continuing)
-       {
-         continuing--;
-         if (continuing)
-           break;
-       }
-    }
-  loop_level--;
-
-  return (body_status);
-}
-
-/* IF test THEN command [ELSE command].
-   IF also allows ELIF in the place of ELSE IF, but
-   the parser makes *that* stupidity transparent. */
-static int
-execute_if_command (if_command)
-     IF_COM *if_command;
-{
-  int return_value, save_line_number;
-
-  save_line_number = line_number;
-  if_command->test->flags |= CMD_IGNORE_RETURN;
-  return_value = execute_command (if_command->test);
-  line_number = save_line_number;
-
-  if (return_value == EXECUTION_SUCCESS)
-    {
-      QUIT;
-
-      if (if_command->true_case && (if_command->flags & CMD_IGNORE_RETURN))
-       if_command->true_case->flags |= CMD_IGNORE_RETURN;
-
-      return (execute_command (if_command->true_case));
-    }
-  else
-    {
-      QUIT;
-
-      if (if_command->false_case && (if_command->flags & CMD_IGNORE_RETURN))
-       if_command->false_case->flags |= CMD_IGNORE_RETURN;
-
-      return (execute_command (if_command->false_case));
-    }
-}
-
-#if defined (DPAREN_ARITHMETIC)
-static int
-execute_arith_command (arith_command)
-     ARITH_COM *arith_command;
-{
-  int expok, save_line_number, retval;
-  intmax_t expresult;
-  WORD_LIST *new;
-  char *exp;
-
-  expresult = 0;
-
-  save_line_number = line_number;
-  this_command_name = "((";    /* )) */
-  line_number = arith_command->line;
-  /* If we're in a function, update the line number information. */
-  if (variable_context && interactive_shell)
-    line_number -= function_line_number;
-
-  command_string_index = 0;
-  print_arith_command (arith_command->exp);
-
-  if (signal_in_progress (DEBUG_TRAP) == 0)
-    {
-      FREE (the_printed_command_except_trap);
-      the_printed_command_except_trap = savestring (the_printed_command);
-    }
-
-  /* Run the debug trap before each arithmetic command, but do it after we
-     update the line number information and before we expand the various
-     words in the expression. */
-  retval = run_debug_trap ();
-#if defined (DEBUGGER)
-  /* In debugging mode, if the DEBUG trap returns a non-zero status, we
-     skip the command. */
-  if (debugging_mode && retval != EXECUTION_SUCCESS)
-    {
-      line_number = save_line_number;
-      return (EXECUTION_SUCCESS);
-    }
-#endif
-
-  new = expand_words_no_vars (arith_command->exp);
-
-  /* If we're tracing, make a new word list with `((' at the front and `))'
-     at the back and print it. */
-  if (echo_command_at_execute)
-    xtrace_print_arith_cmd (new);
-
-  if (new)
-    {
-      exp = new->next ? string_list (new) : new->word->word;
-      expresult = evalexp (exp, &expok);
-      line_number = save_line_number;
-      if (exp != new->word->word)
-       free (exp);
-      dispose_words (new);
-    }
-  else
-    {
-      expresult = 0;
-      expok = 1;
-    }
-
-  if (expok == 0)
-    return (EXECUTION_FAILURE);
-
-  return (expresult == 0 ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
-}
-#endif /* DPAREN_ARITHMETIC */
-
-#if defined (COND_COMMAND)
-
-static char * const nullstr = "";
-
-static int
-execute_cond_node (cond)
-     COND_COM *cond;
-{
-  int result, invert, patmatch, rmatch, mflags, ignore;
-  char *arg1, *arg2;
-
-  invert = (cond->flags & CMD_INVERT_RETURN);
-  ignore = (cond->flags & CMD_IGNORE_RETURN);
-  if (ignore)
-    {
-      if (cond->left)
-       cond->left->flags |= CMD_IGNORE_RETURN;
-      if (cond->right)
-       cond->right->flags |= CMD_IGNORE_RETURN;
-    }
-      
-  if (cond->type == COND_EXPR)
-    result = execute_cond_node (cond->left);
-  else if (cond->type == COND_OR)
-    {
-      result = execute_cond_node (cond->left);
-      if (result != EXECUTION_SUCCESS)
-       result = execute_cond_node (cond->right);
-    }
-  else if (cond->type == COND_AND)
-    {
-      result = execute_cond_node (cond->left);
-      if (result == EXECUTION_SUCCESS)
-       result = execute_cond_node (cond->right);
-    }
-  else if (cond->type == COND_UNARY)
-    {
-      if (ignore)
-       comsub_ignore_return++;
-      arg1 = cond_expand_word (cond->left->op, 0);
-      if (ignore)
-       comsub_ignore_return--;
-      if (arg1 == 0)
-       arg1 = nullstr;
-      if (echo_command_at_execute)
-       xtrace_print_cond_term (cond->type, invert, cond->op, arg1, (char *)NULL);
-      result = unary_test (cond->op->word, arg1) ? EXECUTION_SUCCESS : EXECUTION_FAILURE;
-      if (arg1 != nullstr)
-       free (arg1);
-    }
-  else if (cond->type == COND_BINARY)
-    {
-      rmatch = 0;
-      patmatch = ((cond->op->word[1] == '=') && (cond->op->word[2] == '\0') &&
-                 (cond->op->word[0] == '!' || cond->op->word[0] == '=') ||
-                 (cond->op->word[0] == '=' && cond->op->word[1] == '\0'));
-#if defined (COND_REGEXP)
-      rmatch = (cond->op->word[0] == '=' && cond->op->word[1] == '~' &&
-               cond->op->word[2] == '\0');
-#endif
-
-      if (ignore)
-       comsub_ignore_return++;
-      arg1 = cond_expand_word (cond->left->op, 0);
-      if (ignore)
-       comsub_ignore_return--;
-      if (arg1 == 0)
-       arg1 = nullstr;
-      if (ignore)
-       comsub_ignore_return++;
-      arg2 = cond_expand_word (cond->right->op,
-                              (rmatch && shell_compatibility_level > 31) ? 2 : (patmatch ? 1 : 0));
-      if (ignore)
-       comsub_ignore_return--;
-      if (arg2 == 0)
-       arg2 = nullstr;
-
-      if (echo_command_at_execute)
-       xtrace_print_cond_term (cond->type, invert, cond->op, arg1, arg2);
-
-#if defined (COND_REGEXP)
-      if (rmatch)
-       {
-         mflags = SHMAT_PWARN;
-#if defined (ARRAY_VARS)
-         mflags |= SHMAT_SUBEXP;
-#endif
-
-         result = sh_regmatch (arg1, arg2, mflags);
-       }
-      else
-#endif /* COND_REGEXP */
-       {
-         int oe;
-         oe = extended_glob;
-         extended_glob = 1;
-         result = binary_test (cond->op->word, arg1, arg2, TEST_PATMATCH|TEST_ARITHEXP|TEST_LOCALE)
-                                 ? EXECUTION_SUCCESS
-                                 : EXECUTION_FAILURE;
-         extended_glob = oe;
-       }
-      if (arg1 != nullstr)
-       free (arg1);
-      if (arg2 != nullstr)
-       free (arg2);
-    }
-  else
-    {
-      command_error ("execute_cond_node", CMDERR_BADTYPE, cond->type, 0);
-      jump_to_top_level (DISCARD);
-      result = EXECUTION_FAILURE;
-    }
-
-  if (invert)
-    result = (result == EXECUTION_SUCCESS) ? EXECUTION_FAILURE : EXECUTION_SUCCESS;
-
-  return result;
-}
-
-static int
-execute_cond_command (cond_command)
-     COND_COM *cond_command;
-{
-  int retval, save_line_number;
-
-  retval = EXECUTION_SUCCESS;
-  save_line_number = line_number;
-
-  this_command_name = "[[";
-  line_number = cond_command->line;
-  /* If we're in a function, update the line number information. */
-  if (variable_context && interactive_shell)
-    line_number -= function_line_number;
-  command_string_index = 0;
-  print_cond_command (cond_command);
-
-  if (signal_in_progress (DEBUG_TRAP) == 0)
-    {
-      FREE (the_printed_command_except_trap);
-      the_printed_command_except_trap = savestring (the_printed_command);
-    }
-
-  /* Run the debug trap before each conditional command, but do it after we
-     update the line number information. */
-  retval = run_debug_trap ();
-#if defined (DEBUGGER)
-  /* In debugging mode, if the DEBUG trap returns a non-zero status, we
-     skip the command. */
-  if (debugging_mode && retval != EXECUTION_SUCCESS)
-    {
-      line_number = save_line_number;
-      return (EXECUTION_SUCCESS);
-    }
-#endif
-
-#if 0
-  debug_print_cond_command (cond_command);
-#endif
-
-  last_command_exit_value = retval = execute_cond_node (cond_command);
-  line_number = save_line_number;
-  return (retval);
-}
-#endif /* COND_COMMAND */
-
-static void
-bind_lastarg (arg)
-     char *arg;
-{
-  SHELL_VAR *var;
-
-  if (arg == 0)
-    arg = "";
-  var = bind_variable ("_", arg, 0);
-  VUNSETATTR (var, att_exported);
-}
-
-/* Execute a null command.  Fork a subshell if the command uses pipes or is
-   to be run asynchronously.  This handles all the side effects that are
-   supposed to take place. */
-static int
-execute_null_command (redirects, pipe_in, pipe_out, async)
-     REDIRECT *redirects;
-     int pipe_in, pipe_out, async;
-{
-  int r;
-  int forcefork;
-  REDIRECT *rd;
-
-  for (forcefork = 0, rd = redirects; rd; rd = rd->next)
-    forcefork += rd->rflags & REDIR_VARASSIGN;
-
-  if (forcefork || pipe_in != NO_PIPE || pipe_out != NO_PIPE || async)
-    {
-      /* We have a null command, but we really want a subshell to take
-        care of it.  Just fork, do piping and redirections, and exit. */
-      if (make_child ((char *)NULL, async) == 0)
-       {
-         /* Cancel traps, in trap.c. */
-         restore_original_signals ();          /* XXX */
-
-         do_piping (pipe_in, pipe_out);
-
-#if defined (COPROCESS_SUPPORT)
-         coproc_closeall ();
-#endif
-
-         subshell_environment = 0;
-         if (async)
-           subshell_environment |= SUBSHELL_ASYNC;
-         if (pipe_in != NO_PIPE || pipe_out != NO_PIPE)
-           subshell_environment |= SUBSHELL_PIPE;
-
-         if (do_redirections (redirects, RX_ACTIVE) == 0)
-           exit (EXECUTION_SUCCESS);
-         else
-           exit (EXECUTION_FAILURE);
-       }
-      else
-       {
-         close_pipes (pipe_in, pipe_out);
-#if defined (PROCESS_SUBSTITUTION) && defined (HAVE_DEV_FD)
-         unlink_fifo_list ();
-#endif
-         return (EXECUTION_SUCCESS);
-       }
-    }
-  else
-    {
-      /* Even if there aren't any command names, pretend to do the
-        redirections that are specified.  The user expects the side
-        effects to take place.  If the redirections fail, then return
-        failure.  Otherwise, if a command substitution took place while
-        expanding the command or a redirection, return the value of that
-        substitution.  Otherwise, return EXECUTION_SUCCESS. */
-
-      r = do_redirections (redirects, RX_ACTIVE|RX_UNDOABLE);
-      cleanup_redirects (redirection_undo_list);
-      redirection_undo_list = (REDIRECT *)NULL;
-
-      if (r != 0)
-       return (EXECUTION_FAILURE);
-      else if (last_command_subst_pid != NO_PID)
-       return (last_command_exit_value);
-      else
-       return (EXECUTION_SUCCESS);
-    }
-}
-
-/* This is a hack to suppress word splitting for assignment statements
-   given as arguments to builtins with the ASSIGNMENT_BUILTIN flag set. */
-static void
-fix_assignment_words (words)
-     WORD_LIST *words;
-{
-  WORD_LIST *w;
-  struct builtin *b;
-  int assoc;
-
-  if (words == 0)
-    return;
-
-  b = 0;
-  assoc = 0;
-
-  for (w = words; w; w = w->next)
-    if (w->word->flags & W_ASSIGNMENT)
-      {
-       if (b == 0)
-         {
-           b = builtin_address_internal (words->word->word, 0);
-           if (b == 0 || (b->flags & ASSIGNMENT_BUILTIN) == 0)
-             return;
-           else if (b && (b->flags & ASSIGNMENT_BUILTIN))
-             words->word->flags |= W_ASSNBLTIN;
-         }
-       w->word->flags |= (W_NOSPLIT|W_NOGLOB|W_TILDEEXP|W_ASSIGNARG);
-#if defined (ARRAY_VARS)
-       if (assoc)
-         w->word->flags |= W_ASSIGNASSOC;
-#endif
-      }
-#if defined (ARRAY_VARS)
-    /* Note that we saw an associative array option to a builtin that takes
-       assignment statements.  This is a bit of a kludge. */
-    else if (w->word->word[0] == '-' && strchr (w->word->word, 'A'))
-      {
-       if (b == 0)
-         {
-           b = builtin_address_internal (words->word->word, 0);
-           if (b == 0 || (b->flags & ASSIGNMENT_BUILTIN) == 0)
-             return;
-           else if (b && (b->flags & ASSIGNMENT_BUILTIN))
-             words->word->flags |= W_ASSNBLTIN;
-         }
-       if (words->word->flags & W_ASSNBLTIN)
-         assoc = 1;
-      }
-#endif
-}
-
-/* Return 1 if the file found by searching $PATH for PATHNAME, defaulting
-   to PATHNAME, is a directory.  Used by the autocd code below. */
-static int
-is_dirname (pathname)
-     char *pathname;
-{
-  char *temp;
-  temp = search_for_command (pathname);
-  return (temp ? file_isdir (temp) : file_isdir (pathname));
-}
-
-/* The meaty part of all the executions.  We have to start hacking the
-   real execution of commands here.  Fork a process, set things up,
-   execute the command. */
-static int
-execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close)
-     SIMPLE_COM *simple_command;
-     int pipe_in, pipe_out, async;
-     struct fd_bitmap *fds_to_close;
-{
-  WORD_LIST *words, *lastword;
-  char *command_line, *lastarg, *temp;
-  int first_word_quoted, result, builtin_is_special, already_forked, dofork;
-  pid_t old_last_async_pid;
-  sh_builtin_func_t *builtin;
-  SHELL_VAR *func;
-
-  result = EXECUTION_SUCCESS;
-  special_builtin_failed = builtin_is_special = 0;
-  command_line = (char *)0;
-
-  /* If we're in a function, update the line number information. */
-  if (variable_context && interactive_shell && sourcelevel == 0)
-    line_number -= function_line_number;
-
-  /* Remember what this command line looks like at invocation. */
-  command_string_index = 0;
-  print_simple_command (simple_command);
-
-#if 0
-  if (signal_in_progress (DEBUG_TRAP) == 0 && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0)))
-#else
-  if (signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0)
-#endif
-    {
-      FREE (the_printed_command_except_trap);
-      the_printed_command_except_trap = the_printed_command ? savestring (the_printed_command) : (char *)0;
-    }
-
-  /* Run the debug trap before each simple command, but do it after we
-     update the line number information. */
-  result = run_debug_trap ();
-#if defined (DEBUGGER)
-  /* In debugging mode, if the DEBUG trap returns a non-zero status, we
-     skip the command. */
-  if (debugging_mode && result != EXECUTION_SUCCESS)
-    return (EXECUTION_SUCCESS);
-#endif
-
-  first_word_quoted =
-    simple_command->words ? (simple_command->words->word->flags & W_QUOTED) : 0;
-
-  last_command_subst_pid = NO_PID;
-  old_last_async_pid = last_asynchronous_pid;
-
-  already_forked = dofork = 0;
-
-  /* If we're in a pipeline or run in the background, set DOFORK so we
-     make the child early, before word expansion.  This keeps assignment
-     statements from affecting the parent shell's environment when they
-     should not. */
-  dofork = pipe_in != NO_PIPE || pipe_out != NO_PIPE || async;
-
-  /* Something like `%2 &' should restart job 2 in the background, not cause
-     the shell to fork here. */
-  if (dofork && pipe_in == NO_PIPE && pipe_out == NO_PIPE &&
-       simple_command->words && simple_command->words->word &&
-       simple_command->words->word->word &&
-       (simple_command->words->word->word[0] == '%'))
-    dofork = 0;
-
-  if (dofork)
-    {
-      /* Do this now, because execute_disk_command will do it anyway in the
-        vast majority of cases. */
-      maybe_make_export_env ();
-
-      /* Don't let a DEBUG trap overwrite the command string to be saved with
-        the process/job associated with this child. */
-      if (make_child (savestring (the_printed_command_except_trap), async) == 0)
-       {
-         already_forked = 1;
-         simple_command->flags |= CMD_NO_FORK;
-
-         subshell_environment = SUBSHELL_FORK;
-         if (pipe_in != NO_PIPE || pipe_out != NO_PIPE)
-           subshell_environment |= SUBSHELL_PIPE;
-         if (async)
-           subshell_environment |= SUBSHELL_ASYNC;
-
-         /* We need to do this before piping to handle some really
-            pathological cases where one of the pipe file descriptors
-            is < 2. */
-         if (fds_to_close)
-           close_fd_bitmap (fds_to_close);
-
-         do_piping (pipe_in, pipe_out);
-         pipe_in = pipe_out = NO_PIPE;
-#if defined (COPROCESS_SUPPORT)
-         coproc_closeall ();
-#endif
-
-         last_asynchronous_pid = old_last_async_pid;
-       }
-      else
-       {
-         close_pipes (pipe_in, pipe_out);
-#if defined (PROCESS_SUBSTITUTION) && defined (HAVE_DEV_FD)
-         unlink_fifo_list ();
-#endif
-         command_line = (char *)NULL;      /* don't free this. */
-         bind_lastarg ((char *)NULL);
-         return (result);
-       }
-    }
-
-  /* If we are re-running this as the result of executing the `command'
-     builtin, do not expand the command words a second time. */
-  if ((simple_command->flags & CMD_INHIBIT_EXPANSION) == 0)
-    {
-      current_fds_to_close = fds_to_close;
-      fix_assignment_words (simple_command->words);
-      /* Pass the ignore return flag down to command substitutions */
-      if (simple_command->flags & CMD_IGNORE_RETURN)   /* XXX */
-       comsub_ignore_return++;
-      words = expand_words (simple_command->words);
-      if (simple_command->flags & CMD_IGNORE_RETURN)
-       comsub_ignore_return--;
-      current_fds_to_close = (struct fd_bitmap *)NULL;
-    }
-  else
-    words = copy_word_list (simple_command->words);
-
-  /* It is possible for WORDS not to have anything left in it.
-     Perhaps all the words consisted of `$foo', and there was
-     no variable `$foo'. */
-  if (words == 0)
-    {
-      this_command_name = 0;
-      result = execute_null_command (simple_command->redirects,
-                                    pipe_in, pipe_out,
-                                    already_forked ? 0 : async);
-      if (already_forked)
-       exit (result);
-      else
-       {
-         bind_lastarg ((char *)NULL);
-         set_pipestatus_from_exit (result);
-         return (result);
-       }
-    }
-
-  lastarg = (char *)NULL;
-
-  begin_unwind_frame ("simple-command");
-
-  if (echo_command_at_execute)
-    xtrace_print_word_list (words, 1);
-
-  builtin = (sh_builtin_func_t *)NULL;
-  func = (SHELL_VAR *)NULL;
-  if ((simple_command->flags & CMD_NO_FUNCTIONS) == 0)
-    {
-      /* Posix.2 says special builtins are found before functions.  We
-        don't set builtin_is_special anywhere other than here, because
-        this path is followed only when the `command' builtin is *not*
-        being used, and we don't want to exit the shell if a special
-        builtin executed with `command builtin' fails.  `command' is not
-        a special builtin. */
-      if (posixly_correct)
-       {
-         builtin = find_special_builtin (words->word->word);
-         if (builtin)
-           builtin_is_special = 1;
-       }
-      if (builtin == 0)
-       func = find_function (words->word->word);
-    }
-
-  /* In POSIX mode, assignment errors in the temporary environment cause a
-     non-interactive shell to exit. */
-  if (builtin_is_special && interactive_shell == 0 && tempenv_assign_error)
-    {
-      last_command_exit_value = EXECUTION_FAILURE;
-      jump_to_top_level (ERREXIT);
-    }
-
-  add_unwind_protect (dispose_words, words);
-  QUIT;
-
-  /* Bind the last word in this command to "$_" after execution. */
-  for (lastword = words; lastword->next; lastword = lastword->next)
-    ;
-  lastarg = lastword->word->word;
-
-#if defined (JOB_CONTROL)
-  /* Is this command a job control related thing? */
-  if (words->word->word[0] == '%' && already_forked == 0)
-    {
-      this_command_name = async ? "bg" : "fg";
-      last_shell_builtin = this_shell_builtin;
-      this_shell_builtin = builtin_address (this_command_name);
-      result = (*this_shell_builtin) (words);
-      goto return_result;
-    }
-
-  /* One other possiblilty.  The user may want to resume an existing job.
-     If they do, find out whether this word is a candidate for a running
-     job. */
-  if (job_control && already_forked == 0 && async == 0 &&
-       !first_word_quoted &&
-       !words->next &&
-       words->word->word[0] &&
-       !simple_command->redirects &&
-       pipe_in == NO_PIPE &&
-       pipe_out == NO_PIPE &&
-       (temp = get_string_value ("auto_resume")))
-    {
-      int job, jflags, started_status;
-
-      jflags = JM_STOPPED|JM_FIRSTMATCH;
-      if (STREQ (temp, "exact"))
-       jflags |= JM_EXACT;
-      else if (STREQ (temp, "substring"))
-       jflags |= JM_SUBSTRING;
-      else
-       jflags |= JM_PREFIX;
-      job = get_job_by_name (words->word->word, jflags);
-      if (job != NO_JOB)
-       {
-         run_unwind_frame ("simple-command");
-         this_command_name = "fg";
-         last_shell_builtin = this_shell_builtin;
-         this_shell_builtin = builtin_address ("fg");
-
-         started_status = start_job (job, 1);
-         return ((started_status < 0) ? EXECUTION_FAILURE : started_status);
-       }
-    }
-#endif /* JOB_CONTROL */
-
-run_builtin:
-  /* Remember the name of this command globally. */
-  this_command_name = words->word->word;
-
-  QUIT;
-
-  /* This command could be a shell builtin or a user-defined function.
-     We have already found special builtins by this time, so we do not
-     set builtin_is_special.  If this is a function or builtin, and we
-     have pipes, then fork a subshell in here.  Otherwise, just execute
-     the command directly. */
-  if (func == 0 && builtin == 0)
-    builtin = find_shell_builtin (this_command_name);
-
-  last_shell_builtin = this_shell_builtin;
-  this_shell_builtin = builtin;
-
-  if (builtin || func)
-    {
-      if (builtin)
-       unwind_protect_int (executing_builtin); /* modified in execute_builtin */
-      if (already_forked)
-       {
-         /* reset_terminating_signals (); */   /* XXX */
-         /* Cancel traps, in trap.c. */
-         restore_original_signals ();
-
-         if (async)
-           {
-             if ((simple_command->flags & CMD_STDIN_REDIR) &&
-                   pipe_in == NO_PIPE &&
-                   (stdin_redirects (simple_command->redirects) == 0))
-               async_redirect_stdin ();
-             setup_async_signals ();
-           }
-
-         subshell_level++;
-         execute_subshell_builtin_or_function
-           (words, simple_command->redirects, builtin, func,
-            pipe_in, pipe_out, async, fds_to_close,
-            simple_command->flags);
-         subshell_level--;
-       }
-      else
-       {
-         result = execute_builtin_or_function
-           (words, builtin, func, simple_command->redirects, fds_to_close,
-            simple_command->flags);
-         if (builtin)
-           {
-             if (result > EX_SHERRBASE)
-               {
-                 result = builtin_status (result);
-                 if (builtin_is_special)
-                   special_builtin_failed = 1;
-               }
-             /* In POSIX mode, if there are assignment statements preceding
-                a special builtin, they persist after the builtin
-                completes. */
-             if (posixly_correct && builtin_is_special && temporary_env)
-               merge_temporary_env ();
-           }
-         else          /* function */
-           {
-             if (result == EX_USAGE)
-               result = EX_BADUSAGE;
-             else if (result > EX_SHERRBASE)
-               result = EXECUTION_FAILURE;
-           }
-
-         set_pipestatus_from_exit (result);
-
-         goto return_result;
-       }
-    }
-
-  if (autocd && interactive && words->word && is_dirname (words->word->word))
-    {
-      words = make_word_list (make_word ("cd"), words);
-      xtrace_print_word_list (words, 0);
-      goto run_builtin;
-    }
-
-  if (command_line == 0)
-    command_line = savestring (the_printed_command_except_trap);
-
-#if defined (PROCESS_SUBSTITUTION)
-  if ((subshell_environment & SUBSHELL_COMSUB) && (simple_command->flags & CMD_NO_FORK) && fifos_pending() > 0)
-    simple_command->flags &= ~CMD_NO_FORK;
-#endif
-
-  execute_disk_command (words, simple_command->redirects, command_line,
-                       pipe_in, pipe_out, async, fds_to_close,
-                       simple_command->flags);
-
- return_result:
-  bind_lastarg (lastarg);
-  FREE (command_line);
-  dispose_words (words);
-  discard_unwind_frame ("simple-command");
-  this_command_name = (char *)NULL;    /* points to freed memory now */
-  return (result);
-}
-
-/* Translate the special builtin exit statuses.  We don't really need a
-   function for this; it's a placeholder for future work. */
-static int
-builtin_status (result)
-     int result;
-{
-  int r;
-
-  switch (result)
-    {
-    case EX_USAGE:
-      r = EX_BADUSAGE;
-      break;
-    case EX_REDIRFAIL:
-    case EX_BADSYNTAX:
-    case EX_BADASSIGN:
-    case EX_EXPFAIL:
-      r = EXECUTION_FAILURE;
-      break;
-    default:
-      r = EXECUTION_SUCCESS;
-      break;
-    }
-  return (r);
-}
-
-static int
-execute_builtin (builtin, words, flags, subshell)
-     sh_builtin_func_t *builtin;
-     WORD_LIST *words;
-     int flags, subshell;
-{
-  int old_e_flag, result, eval_unwind;
-  int isbltinenv;
-  char *error_trap;
-
-#if 0
-  /* XXX -- added 12/11 */
-  terminate_immediately++;
-#endif
-
-  error_trap = 0;
-  old_e_flag = exit_immediately_on_error;
-  /* The eval builtin calls parse_and_execute, which does not know about
-     the setting of flags, and always calls the execution functions with
-     flags that will exit the shell on an error if -e is set.  If the
-     eval builtin is being called, and we're supposed to ignore the exit
-     value of the command, we turn the -e flag off ourselves and disable
-     the ERR trap, then restore them when the command completes.  This is
-     also a problem (as below) for the command and source/. builtins. */
-  if (subshell == 0 && (flags & CMD_IGNORE_RETURN) &&
-       (builtin == eval_builtin || builtin == command_builtin || builtin == source_builtin))
-    {
-      begin_unwind_frame ("eval_builtin");
-      unwind_protect_int (exit_immediately_on_error);
-      error_trap = TRAP_STRING (ERROR_TRAP);
-      if (error_trap)
-       {
-         error_trap = savestring (error_trap);
-         add_unwind_protect (xfree, error_trap);
-         add_unwind_protect (set_error_trap, error_trap);
-         restore_default_signal (ERROR_TRAP);
-       }
-      exit_immediately_on_error = 0;
-      eval_unwind = 1;
-    }
-  else
-    eval_unwind = 0;
-
-  /* The temporary environment for a builtin is supposed to apply to
-     all commands executed by that builtin.  Currently, this is a
-     problem only with the `unset', `source' and `eval' builtins. */
-
-  isbltinenv = (builtin == source_builtin || builtin == eval_builtin || builtin == unset_builtin);
-
-  if (isbltinenv)
-    {
-      if (subshell == 0)
-       begin_unwind_frame ("builtin_env");
-
-      if (temporary_env)
-       {
-         push_scope (VC_BLTNENV, temporary_env);
-         if (subshell == 0)
-           add_unwind_protect (pop_scope, (flags & CMD_COMMAND_BUILTIN) ? 0 : "1");
-          temporary_env = (HASH_TABLE *)NULL;    
-       }
-    }
-
-  /* `return' does a longjmp() back to a saved environment in execute_function.
-     If a variable assignment list preceded the command, and the shell is
-     running in POSIX mode, we need to merge that into the shell_variables
-     table, since `return' is a POSIX special builtin. */
-  if (posixly_correct && subshell == 0 && builtin == return_builtin && temporary_env)
-    {
-      begin_unwind_frame ("return_temp_env");
-      add_unwind_protect (merge_temporary_env, (char *)NULL);
-    }
-
-  executing_builtin++;
-  result = ((*builtin) (words->next));
-
-  /* This shouldn't happen, but in case `return' comes back instead of
-     longjmp'ing, we need to unwind. */
-  if (posixly_correct && subshell == 0 && builtin == return_builtin && temporary_env)
-    discard_unwind_frame ("return_temp_env");
-
-  if (subshell == 0 && isbltinenv)
-    run_unwind_frame ("builtin_env");
-
-  if (eval_unwind)
-    {
-      exit_immediately_on_error += old_e_flag;
-      if (error_trap)
-       {
-         set_error_trap (error_trap);
-         xfree (error_trap);
-       }
-      discard_unwind_frame ("eval_builtin");
-    }
-
-#if 0
-  /* XXX -- added 12/11 */
-  terminate_immediately--;
-#endif
-
-  return (result);
-}
-
-static int
-execute_function (var, words, flags, fds_to_close, async, subshell)
-     SHELL_VAR *var;
-     WORD_LIST *words;
-     int flags;
-     struct fd_bitmap *fds_to_close;
-     int async, subshell;
-{
-  int return_val, result;
-  COMMAND *tc, *fc, *save_current;
-  char *debug_trap, *error_trap, *return_trap;
-#if defined (ARRAY_VARS)
-  SHELL_VAR *funcname_v, *nfv, *bash_source_v, *bash_lineno_v;
-  ARRAY *funcname_a, *bash_source_a, *bash_lineno_a;
-#endif
-  FUNCTION_DEF *shell_fn;
-  char *sfile, *t;
-
-  USE_VAR(fc);
-
-  if (funcnest_max > 0 && funcnest >= funcnest_max)
-    {
-      internal_error ("%s: maximum function nesting level exceeded (%d)", var->name, funcnest);
-      jump_to_top_level (DISCARD);
-    }
-
-#if defined (ARRAY_VARS)
-  GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a);
-  GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
-  GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a);
-#endif
-
-  tc = (COMMAND *)copy_command (function_cell (var));
-  if (tc && (flags & CMD_IGNORE_RETURN))
-    tc->flags |= CMD_IGNORE_RETURN;
-
-  if (subshell == 0)
-    {
-      begin_unwind_frame ("function_calling");
-      push_context (var->name, subshell, temporary_env);
-      add_unwind_protect (pop_context, (char *)NULL);
-      unwind_protect_int (line_number);
-      unwind_protect_int (return_catch_flag);
-      unwind_protect_jmp_buf (return_catch);
-      add_unwind_protect (dispose_command, (char *)tc);
-      unwind_protect_pointer (this_shell_function);
-      unwind_protect_int (loop_level);
-      unwind_protect_int (funcnest);
-    }
-  else
-    push_context (var->name, subshell, temporary_env); /* don't unwind-protect for subshells */
-
-  temporary_env = (HASH_TABLE *)NULL;
-
-  this_shell_function = var;
-  make_funcname_visible (1);
-
-  debug_trap = TRAP_STRING(DEBUG_TRAP);
-  error_trap = TRAP_STRING(ERROR_TRAP);
-  return_trap = TRAP_STRING(RETURN_TRAP);
-  
-  /* The order of the unwind protects for debug_trap, error_trap and
-     return_trap is important here!  unwind-protect commands are run
-     in reverse order of registration.  If this causes problems, take
-     out the xfree unwind-protect calls and live with the small memory leak. */
-
-  /* function_trace_mode != 0 means that all functions inherit the DEBUG trap.
-     if the function has the trace attribute set, it inherits the DEBUG trap */
-  if (debug_trap && ((trace_p (var) == 0) && function_trace_mode == 0))
-    {
-      if (subshell == 0)
-       {
-         debug_trap = savestring (debug_trap);
-         add_unwind_protect (xfree, debug_trap);
-         add_unwind_protect (set_debug_trap, debug_trap);
-       }
-      restore_default_signal (DEBUG_TRAP);
-    }
-
-  /* error_trace_mode != 0 means that functions inherit the ERR trap. */
-  if (error_trap && error_trace_mode == 0)
-    {
-      if (subshell == 0)
-       {
-         error_trap = savestring (error_trap);
-         add_unwind_protect (xfree, error_trap);
-         add_unwind_protect (set_error_trap, error_trap);
-       }
-      restore_default_signal (ERROR_TRAP);
-    }
-
-  /* Shell functions inherit the RETURN trap if function tracing is on
-     globally or on individually for this function. */
-#if 0
-  if (return_trap && ((trace_p (var) == 0) && function_trace_mode == 0))
-#else
-  if (return_trap && (signal_in_progress (DEBUG_TRAP) || ((trace_p (var) == 0) && function_trace_mode == 0)))
-#endif
-    {
-      if (subshell == 0)
-       {
-         return_trap = savestring (return_trap);
-         add_unwind_protect (xfree, return_trap);
-         add_unwind_protect (set_return_trap, return_trap);
-       }
-      restore_default_signal (RETURN_TRAP);
-    }
-  
-  funcnest++;
-#if defined (ARRAY_VARS)
-  /* This is quite similar to the code in shell.c and elsewhere. */
-  shell_fn = find_function_def (this_shell_function->name);
-  sfile = shell_fn ? shell_fn->source_file : "";
-  array_push (funcname_a, this_shell_function->name);
-
-  array_push (bash_source_a, sfile);
-  t = itos (executing_line_number ());
-  array_push (bash_lineno_a, t);
-  free (t);
-#endif
-
-  /* The temporary environment for a function is supposed to apply to
-     all commands executed within the function body. */
-
-  remember_args (words->next, 1);
-
-  /* Update BASH_ARGV and BASH_ARGC */
-  if (debugging_mode)
-    push_args (words->next);
-
-  /* Number of the line on which the function body starts. */
-  line_number = function_line_number = tc->line;
-
-#if defined (JOB_CONTROL)
-  if (subshell)
-    stop_pipeline (async, (COMMAND *)NULL);
-#endif
-
-  fc = tc;
-
-  return_catch_flag++;
-  return_val = setjmp (return_catch);
-
-  if (return_val)
-    {
-      result = return_catch_value;
-      /* Run the RETURN trap in the function's context. */
-      save_current = currently_executing_command;
-      run_return_trap ();
-      currently_executing_command = save_current;
-    }
-  else
-    {
-      /* Run the debug trap here so we can trap at the start of a function's
-        execution rather than the execution of the body's first command. */
-      showing_function_line = 1;
-      save_current = currently_executing_command;
-      result = run_debug_trap ();
-#if defined (DEBUGGER)
-      /* In debugging mode, if the DEBUG trap returns a non-zero status, we
-        skip the command. */
-      if (debugging_mode == 0 || result == EXECUTION_SUCCESS)
-       {
-         showing_function_line = 0;
-         currently_executing_command = save_current;
-         result = execute_command_internal (fc, 0, NO_PIPE, NO_PIPE, fds_to_close);
-
-         /* Run the RETURN trap in the function's context */
-         save_current = currently_executing_command;
-         run_return_trap ();
-         currently_executing_command = save_current;
-       }
-#else
-      result = execute_command_internal (fc, 0, NO_PIPE, NO_PIPE, fds_to_close);
-
-      save_current = currently_executing_command;
-      run_return_trap ();
-      currently_executing_command = save_current;
-#endif
-      showing_function_line = 0;
-    }
-
-  /* Restore BASH_ARGC and BASH_ARGV */
-  if (debugging_mode)
-    pop_args ();
-
-  if (subshell == 0)
-    run_unwind_frame ("function_calling");
-
-#if defined (ARRAY_VARS)
-  /* These two variables cannot be unset, and cannot be affected by the
-     function. */
-  array_pop (bash_source_a);
-  array_pop (bash_lineno_a);
-
-  /* FUNCNAME can be unset, and so can potentially be changed by the
-     function. */
-  GET_ARRAY_FROM_VAR ("FUNCNAME", nfv, funcname_a);
-  if (nfv == funcname_v)
-    array_pop (funcname_a);
-#endif
-  
-  if (variable_context == 0 || this_shell_function == 0)
-    {
-      make_funcname_visible (0);
-      unlink_fifo_list ();
-    }
-  
-  return (result);
-}
-
-/* A convenience routine for use by other parts of the shell to execute
-   a particular shell function. */
-int
-execute_shell_function (var, words)
-     SHELL_VAR *var;
-     WORD_LIST *words;
-{
-  int ret;
-  struct fd_bitmap *bitmap;
-
-  bitmap = new_fd_bitmap (FD_BITMAP_DEFAULT_SIZE);
-  begin_unwind_frame ("execute-shell-function");
-  add_unwind_protect (dispose_fd_bitmap, (char *)bitmap);
-      
-  ret = execute_function (var, words, 0, bitmap, 0, 0);
-
-  dispose_fd_bitmap (bitmap);
-  discard_unwind_frame ("execute-shell-function");
-
-  return ret;
-}
-
-/* Execute a shell builtin or function in a subshell environment.  This
-   routine does not return; it only calls exit().  If BUILTIN is non-null,
-   it points to a function to call to execute a shell builtin; otherwise
-   VAR points at the body of a function to execute.  WORDS is the arguments
-   to the command, REDIRECTS specifies redirections to perform before the
-   command is executed. */
-static void
-execute_subshell_builtin_or_function (words, redirects, builtin, var,
-                                     pipe_in, pipe_out, async, fds_to_close,
-                                     flags)
-     WORD_LIST *words;
-     REDIRECT *redirects;
-     sh_builtin_func_t *builtin;
-     SHELL_VAR *var;
-     int pipe_in, pipe_out, async;
-     struct fd_bitmap *fds_to_close;
-     int flags;
-{
-  int result, r, funcvalue;
-#if defined (JOB_CONTROL)
-  int jobs_hack;
-
-  jobs_hack = (builtin == jobs_builtin) &&
-               ((subshell_environment & SUBSHELL_ASYNC) == 0 || pipe_out != NO_PIPE);
-#endif
-
-  /* A subshell is neither a login shell nor interactive. */
-  login_shell = interactive = 0;
-
-  if (async)
-    subshell_environment |= SUBSHELL_ASYNC;
-  if (pipe_in != NO_PIPE || pipe_out != NO_PIPE)
-    subshell_environment |= SUBSHELL_PIPE;
-
-  maybe_make_export_env ();    /* XXX - is this needed? */
-
-#if defined (JOB_CONTROL)
-  /* Eradicate all traces of job control after we fork the subshell, so
-     all jobs begun by this subshell are in the same process group as
-     the shell itself. */
-
-  /* Allow the output of `jobs' to be piped. */
-  if (jobs_hack)
-    kill_current_pipeline ();
-  else
-    without_job_control ();
-
-  set_sigchld_handler ();
-#endif /* JOB_CONTROL */
-
-  set_sigint_handler ();
-
-  if (fds_to_close)
-    close_fd_bitmap (fds_to_close);
-
-  do_piping (pipe_in, pipe_out);
-
-  if (do_redirections (redirects, RX_ACTIVE) != 0)
-    exit (EXECUTION_FAILURE);
-
-  if (builtin)
-    {
-      /* Give builtins a place to jump back to on failure,
-        so we don't go back up to main(). */
-      result = setjmp (top_level);
-
-      /* Give the return builtin a place to jump to when executed in a subshell
-         or pipeline */
-      funcvalue = 0;
-      if (return_catch_flag && builtin == return_builtin)
-        funcvalue = setjmp (return_catch);
-
-      if (result == EXITPROG)
-       exit (last_command_exit_value);
-      else if (result)
-       exit (EXECUTION_FAILURE);
-      else if (funcvalue)
-       exit (return_catch_value);
-      else
-       {
-         r = execute_builtin (builtin, words, flags, 1);
-         fflush (stdout);
-         if (r == EX_USAGE)
-           r = EX_BADUSAGE;
-         exit (r);
-       }
-    }
-  else
-    {
-      r = execute_function (var, words, flags, fds_to_close, async, 1);
-      fflush (stdout);
-      exit (r);
-    }
-}
-
-/* Execute a builtin or function in the current shell context.  If BUILTIN
-   is non-null, it is the builtin command to execute, otherwise VAR points
-   to the body of a function.  WORDS are the command's arguments, REDIRECTS
-   are the redirections to perform.  FDS_TO_CLOSE is the usual bitmap of
-   file descriptors to close.
-
-   If BUILTIN is exec_builtin, the redirections specified in REDIRECTS are
-   not undone before this function returns. */
-static int
-execute_builtin_or_function (words, builtin, var, redirects,
-                            fds_to_close, flags)
-     WORD_LIST *words;
-     sh_builtin_func_t *builtin;
-     SHELL_VAR *var;
-     REDIRECT *redirects;
-     struct fd_bitmap *fds_to_close;
-     int flags;
-{
-  int result;
-  REDIRECT *saved_undo_list;
-  sh_builtin_func_t *saved_this_shell_builtin;
-
-  if (do_redirections (redirects, RX_ACTIVE|RX_UNDOABLE) != 0)
-    {
-      cleanup_redirects (redirection_undo_list);
-      redirection_undo_list = (REDIRECT *)NULL;
-      dispose_exec_redirects ();
-      return (EX_REDIRFAIL);   /* was EXECUTION_FAILURE */
-    }
-
-  saved_this_shell_builtin = this_shell_builtin;
-  saved_undo_list = redirection_undo_list;
-
-  /* Calling the "exec" builtin changes redirections forever. */
-  if (builtin == exec_builtin)
-    {
-      dispose_redirects (saved_undo_list);
-      saved_undo_list = exec_redirection_undo_list;
-      exec_redirection_undo_list = (REDIRECT *)NULL;
-    }
-  else
-    dispose_exec_redirects ();
-
-  if (saved_undo_list)
-    {
-      begin_unwind_frame ("saved redirects");
-      add_unwind_protect (cleanup_redirects, (char *)saved_undo_list);
-    }
-
-  redirection_undo_list = (REDIRECT *)NULL;
-
-  if (builtin)
-    result = execute_builtin (builtin, words, flags, 0);
-  else
-    result = execute_function (var, words, flags, fds_to_close, 0, 0);
-
-  /* We do this before undoing the effects of any redirections. */
-  fflush (stdout);
-  fpurge (stdout);
-  if (ferror (stdout))
-    clearerr (stdout);  
-
-  /* If we are executing the `command' builtin, but this_shell_builtin is
-     set to `exec_builtin', we know that we have something like
-     `command exec [redirection]', since otherwise `exec' would have
-     overwritten the shell and we wouldn't get here.  In this case, we
-     want to behave as if the `command' builtin had not been specified
-     and preserve the redirections. */
-  if (builtin == command_builtin && this_shell_builtin == exec_builtin)
-    {
-      if (saved_undo_list)
-       dispose_redirects (saved_undo_list);
-      redirection_undo_list = exec_redirection_undo_list;
-      saved_undo_list = exec_redirection_undo_list = (REDIRECT *)NULL;      
-      discard_unwind_frame ("saved_redirects");
-    }
-
-  if (saved_undo_list)
-    {
-      redirection_undo_list = saved_undo_list;
-      discard_unwind_frame ("saved redirects");
-    }
-
-  if (redirection_undo_list)
-    {
-      cleanup_redirects (redirection_undo_list);
-      redirection_undo_list = (REDIRECT *)NULL;
-    }
-
-  return (result);
-}
-
-void
-setup_async_signals ()
-{
-#if defined (__BEOS__)
-  set_signal_handler (SIGHUP, SIG_IGN);        /* they want csh-like behavior */
-#endif
-
-#if defined (JOB_CONTROL)
-  if (job_control == 0)
-#endif
-    {
-      set_signal_handler (SIGINT, SIG_IGN);
-      set_signal_ignored (SIGINT);
-      set_signal_handler (SIGQUIT, SIG_IGN);
-      set_signal_ignored (SIGQUIT);
-    }
-}
-
-/* Execute a simple command that is hopefully defined in a disk file
-   somewhere.
-
-   1) fork ()
-   2) connect pipes
-   3) look up the command
-   4) do redirections
-   5) execve ()
-   6) If the execve failed, see if the file has executable mode set.
-   If so, and it isn't a directory, then execute its contents as
-   a shell script.
-
-   Note that the filename hashing stuff has to take place up here,
-   in the parent.  This is probably why the Bourne style shells
-   don't handle it, since that would require them to go through
-   this gnarly hair, for no good reason.
-
-   NOTE: callers expect this to fork or exit(). */
-
-/* Name of a shell function to call when a command name is not found. */
-#ifndef NOTFOUND_HOOK
-#  define NOTFOUND_HOOK "command_not_found_handle"
-#endif
-
-static void
-execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
-                     async, fds_to_close, cmdflags)
-     WORD_LIST *words;
-     REDIRECT *redirects;
-     char *command_line;
-     int pipe_in, pipe_out, async;
-     struct fd_bitmap *fds_to_close;
-     int cmdflags;
-{
-  char *pathname, *command, **args;
-  int nofork;
-  pid_t pid;
-  SHELL_VAR *hookf;
-  WORD_LIST *wl;
-
-  nofork = (cmdflags & CMD_NO_FORK);  /* Don't fork, just exec, if no pipes */
-  pathname = words->word->word;
-
-#if defined (RESTRICTED_SHELL)
-  command = (char *)NULL;
-  if (restricted && mbschr (pathname, '/'))
-    {
-      internal_error (_("%s: restricted: cannot specify `/' in command names"),
-                   pathname);
-      last_command_exit_value = EXECUTION_FAILURE;
-
-      /* If we're not going to fork below, we must already be in a child
-         process or a context in which it's safe to call exit(2).  */
-      if (nofork && pipe_in == NO_PIPE && pipe_out == NO_PIPE)
-       exit (last_command_exit_value);
-      else
-       goto parent_return;
-    }
-#endif /* RESTRICTED_SHELL */
-
-  command = search_for_command (pathname);
-
-  if (command)
-    {
-      maybe_make_export_env ();
-      put_command_name_into_env (command);
-    }
-
-  /* We have to make the child before we check for the non-existence
-     of COMMAND, since we want the error messages to be redirected. */
-  /* If we can get away without forking and there are no pipes to deal with,
-     don't bother to fork, just directly exec the command. */
-  if (nofork && pipe_in == NO_PIPE && pipe_out == NO_PIPE)
-    pid = 0;
-  else
-    pid = make_child (savestring (command_line), async);
-
-  if (pid == 0)
-    {
-      int old_interactive;
-
-#if 0
-      /* This has been disabled for the time being. */
-#if !defined (ARG_MAX) || ARG_MAX >= 10240
-      if (posixly_correct == 0)
-       put_gnu_argv_flags_into_env ((long)getpid (), glob_argv_flags);
-#endif
-#endif
-
-      /* Cancel traps, in trap.c. */
-      restore_original_signals ();
-
-      /* restore_original_signals may have undone the work done
-        by make_child to ensure that SIGINT and SIGQUIT are ignored
-        in asynchronous children. */
-      if (async)
-       {
-         if ((cmdflags & CMD_STDIN_REDIR) &&
-               pipe_in == NO_PIPE &&
-               (stdin_redirects (redirects) == 0))
-           async_redirect_stdin ();
-         setup_async_signals ();
-       }
-
-      /* This functionality is now provided by close-on-exec of the
-        file descriptors manipulated by redirection and piping.
-        Some file descriptors still need to be closed in all children
-        because of the way bash does pipes; fds_to_close is a
-        bitmap of all such file descriptors. */
-      if (fds_to_close)
-       close_fd_bitmap (fds_to_close);
-
-      do_piping (pipe_in, pipe_out);
-
-      old_interactive = interactive;
-      if (async)
-       interactive = 0;
-
-      subshell_environment = SUBSHELL_FORK;
-
-      if (redirects && (do_redirections (redirects, RX_ACTIVE) != 0))
-       {
-#if defined (PROCESS_SUBSTITUTION)
-         /* Try to remove named pipes that may have been created as the
-            result of redirections. */
-         unlink_fifo_list ();
-#endif /* PROCESS_SUBSTITUTION */
-         exit (EXECUTION_FAILURE);
-       }
-
-      if (async)
-       interactive = old_interactive;
-
-      if (command == 0)
-       {
-         hookf = find_function (NOTFOUND_HOOK);
-         if (hookf == 0)
-           {
-             internal_error (_("%s: command not found"), pathname);
-             exit (EX_NOTFOUND);       /* Posix.2 says the exit status is 127 */
-           }
-
-         wl = make_word_list (make_word (NOTFOUND_HOOK), words);
-         exit (execute_shell_function (hookf, wl));
-       }
-
-      /* Execve expects the command name to be in args[0].  So we
-        leave it there, in the same format that the user used to
-        type it in. */
-      args = strvec_from_word_list (words, 0, 0, (int *)NULL);
-      exit (shell_execve (command, args, export_env));
-    }
-  else
-    {
-parent_return:
-      /* Make sure that the pipes are closed in the parent. */
-      close_pipes (pipe_in, pipe_out);
-#if defined (PROCESS_SUBSTITUTION) && defined (HAVE_DEV_FD)
-      if (variable_context == 0)
-        unlink_fifo_list ();
-#endif
-      FREE (command);
-    }
-}
-
-/* CPP defines to decide whether a particular index into the #! line
-   corresponds to a valid interpreter name or argument character, or
-   whitespace.  The MSDOS define is to allow \r to be treated the same
-   as \n. */
-
-#if !defined (MSDOS)
-#  define STRINGCHAR(ind) \
-    (ind < sample_len && !whitespace (sample[ind]) && sample[ind] != '\n')
-#  define WHITECHAR(ind) \
-    (ind < sample_len && whitespace (sample[ind]))
-#else  /* MSDOS */
-#  define STRINGCHAR(ind) \
-    (ind < sample_len && !whitespace (sample[ind]) && sample[ind] != '\n' && sample[ind] != '\r')
-#  define WHITECHAR(ind) \
-    (ind < sample_len && whitespace (sample[ind]))
-#endif /* MSDOS */
-
-static char *
-getinterp (sample, sample_len, endp)
-     char *sample;
-     int sample_len, *endp;
-{
-  register int i;
-  char *execname;
-  int start;
-
-  /* Find the name of the interpreter to exec. */
-  for (i = 2; i < sample_len && whitespace (sample[i]); i++)
-    ;
-
-  for (start = i; STRINGCHAR(i); i++)
-    ;
-
-  execname = substring (sample, start, i);
-
-  if (endp)
-    *endp = i;
-  return execname;
-}
-
-#if !defined (HAVE_HASH_BANG_EXEC)
-/* If the operating system on which we're running does not handle
-   the #! executable format, then help out.  SAMPLE is the text read
-   from the file, SAMPLE_LEN characters.  COMMAND is the name of
-   the script; it and ARGS, the arguments given by the user, will
-   become arguments to the specified interpreter.  ENV is the environment
-   to pass to the interpreter.
-
-   The word immediately following the #! is the interpreter to execute.
-   A single argument to the interpreter is allowed. */
-
-static int
-execute_shell_script (sample, sample_len, command, args, env)
-     char *sample;
-     int sample_len;
-     char *command;
-     char **args, **env;
-{
-  char *execname, *firstarg;
-  int i, start, size_increment, larry;
-
-  /* Find the name of the interpreter to exec. */
-  execname = getinterp (sample, sample_len, &i);
-  size_increment = 1;
-
-  /* Now the argument, if any. */
-  for (firstarg = (char *)NULL, start = i; WHITECHAR(i); i++)
-    ;
-
-  /* If there is more text on the line, then it is an argument for the
-     interpreter. */
-
-  if (STRINGCHAR(i))  
-    {
-      for (start = i; STRINGCHAR(i); i++)
-       ;
-      firstarg = substring ((char *)sample, start, i);
-      size_increment = 2;
-    }
-
-  larry = strvec_len (args) + size_increment;
-  args = strvec_resize (args, larry + 1);
-
-  for (i = larry - 1; i; i--)
-    args[i] = args[i - size_increment];
-
-  args[0] = execname;
-  if (firstarg)
-    {
-      args[1] = firstarg;
-      args[2] = command;
-    }
-  else
-    args[1] = command;
-
-  args[larry] = (char *)NULL;
-
-  return (shell_execve (execname, args, env));
-}
-#undef STRINGCHAR
-#undef WHITECHAR
-
-#endif /* !HAVE_HASH_BANG_EXEC */
-
-static void
-initialize_subshell ()
-{
-#if defined (ALIAS)
-  /* Forget about any aliases that we knew of.  We are in a subshell. */
-  delete_all_aliases ();
-#endif /* ALIAS */
-
-#if defined (HISTORY)
-  /* Forget about the history lines we have read.  This is a non-interactive
-     subshell. */
-  history_lines_this_session = 0;
-#endif
-
-#if defined (JOB_CONTROL)
-  /* Forget about the way job control was working. We are in a subshell. */
-  without_job_control ();
-  set_sigchld_handler ();
-  init_job_stats ();
-#endif /* JOB_CONTROL */
-
-  /* Reset the values of the shell flags and options. */
-  reset_shell_flags ();
-  reset_shell_options ();
-  reset_shopt_options ();
-
-  /* Zero out builtin_env, since this could be a shell script run from a
-     sourced file with a temporary environment supplied to the `source/.'
-     builtin.  Such variables are not supposed to be exported (empirical
-     testing with sh and ksh).  Just throw it away; don't worry about a
-     memory leak. */
-  if (vc_isbltnenv (shell_variables))
-    shell_variables = shell_variables->down;
-
-  clear_unwind_protect_list (0);
-  /* XXX -- are there other things we should be resetting here? */
-  parse_and_execute_level = 0;         /* nothing left to restore it */
-
-  /* We're no longer inside a shell function. */
-  variable_context = return_catch_flag = funcnest = 0;
-
-  executing_list = 0;          /* XXX */
-
-  /* If we're not interactive, close the file descriptor from which we're
-     reading the current shell script. */
-  if (interactive_shell == 0)
-    unset_bash_input (0);
-}
-
-#if defined (HAVE_SETOSTYPE) && defined (_POSIX_SOURCE)
-#  define SETOSTYPE(x) __setostype(x)
-#else
-#  define SETOSTYPE(x)
-#endif
-
-#define READ_SAMPLE_BUF(file, buf, len) \
-  do \
-    { \
-      fd = open(file, O_RDONLY); \
-      if (fd >= 0) \
-       { \
-         len = read (fd, buf, 80); \
-         close (fd); \
-       } \
-      else \
-       len = -1; \
-    } \
-  while (0)
-      
-/* Call execve (), handling interpreting shell scripts, and handling
-   exec failures. */
-int
-shell_execve (command, args, env)
-     char *command;
-     char **args, **env;
-{
-  int larray, i, fd;
-  char sample[80];
-  int sample_len;
-
-  SETOSTYPE (0);               /* Some systems use for USG/POSIX semantics */
-  execve (command, args, env);
-  i = errno;                   /* error from execve() */
-  CHECK_TERMSIG;
-  SETOSTYPE (1);
-
-  /* If we get to this point, then start checking out the file.
-     Maybe it is something we can hack ourselves. */
-  if (i != ENOEXEC)
-    {
-      if (file_isdir (command))
-       internal_error (_("%s: is a directory"), command);
-      else if (executable_file (command) == 0)
-       {
-         errno = i;
-         file_error (command);
-       }
-      /* errors not involving the path argument to execve. */
-      else if (i == E2BIG || i == ENOMEM)
-       {
-         errno = i;
-         file_error (command);
-       }
-      else
-       {
-         /* The file has the execute bits set, but the kernel refuses to
-            run it for some reason.  See why. */
-#if defined (HAVE_HASH_BANG_EXEC)
-         READ_SAMPLE_BUF (command, sample, sample_len);
-         if (sample_len > 2 && sample[0] == '#' && sample[1] == '!')
-           {
-             char *interp;
-             int ilen;
-
-             interp = getinterp (sample, sample_len, (int *)NULL);
-             ilen = strlen (interp);
-             errno = i;
-             if (interp[ilen - 1] == '\r')
-               {
-                 interp = xrealloc (interp, ilen + 2);
-                 interp[ilen - 1] = '^';
-                 interp[ilen] = 'M';
-                 interp[ilen + 1] = '\0';
-               }
-             sys_error (_("%s: %s: bad interpreter"), command, interp ? interp : "");
-             FREE (interp);
-             return (EX_NOEXEC);
-           }
-#endif
-         errno = i;
-         file_error (command);
-       }
-      return ((i == ENOENT) ? EX_NOTFOUND : EX_NOEXEC);        /* XXX Posix.2 says that exit status is 126 */
-    }
-
-  /* This file is executable.
-     If it begins with #!, then help out people with losing operating
-     systems.  Otherwise, check to see if it is a binary file by seeing
-     if the contents of the first line (or up to 80 characters) are in the
-     ASCII set.  If it's a text file, execute the contents as shell commands,
-     otherwise return 126 (EX_BINARY_FILE). */
-  READ_SAMPLE_BUF (command, sample, sample_len);
-
-  if (sample_len == 0)
-    return (EXECUTION_SUCCESS);
-
-  /* Is this supposed to be an executable script?
-     If so, the format of the line is "#! interpreter [argument]".
-     A single argument is allowed.  The BSD kernel restricts
-     the length of the entire line to 32 characters (32 bytes
-     being the size of the BSD exec header), but we allow 80
-     characters. */
-  if (sample_len > 0)
-    {
-#if !defined (HAVE_HASH_BANG_EXEC)
-      if (sample_len > 2 && sample[0] == '#' && sample[1] == '!')
-       return (execute_shell_script (sample, sample_len, command, args, env));
-      else
-#endif
-      if (check_binary_file (sample, sample_len))
-       {
-         internal_error (_("%s: cannot execute binary file"), command);
-         return (EX_BINARY_FILE);
-       }
-    }
-
-  /* We have committed to attempting to execute the contents of this file
-     as shell commands. */
-
-  initialize_subshell ();
-
-  set_sigint_handler ();
-
-  /* Insert the name of this shell into the argument list. */
-  larray = strvec_len (args) + 1;
-  args = strvec_resize (args, larray + 1);
-
-  for (i = larray - 1; i; i--)
-    args[i] = args[i - 1];
-
-  args[0] = shell_name;
-  args[1] = command;
-  args[larray] = (char *)NULL;
-
-  if (args[0][0] == '-')
-    args[0]++;
-
-#if defined (RESTRICTED_SHELL)
-  if (restricted)
-    change_flag ('r', FLAG_OFF);
-#endif
-
-  if (subshell_argv)
-    {
-      /* Can't free subshell_argv[0]; that is shell_name. */
-      for (i = 1; i < subshell_argc; i++)
-       free (subshell_argv[i]);
-      free (subshell_argv);
-    }
-
-  dispose_command (currently_executing_command);       /* XXX */
-  currently_executing_command = (COMMAND *)NULL;
-
-  subshell_argc = larray;
-  subshell_argv = args;
-  subshell_envp = env;
-
-  unbind_args ();      /* remove the positional parameters */
-
-  longjmp (subshell_top_level, 1);
-  /*NOTREACHED*/
-}
-
-static int
-execute_intern_function (name, function)
-     WORD_DESC *name;
-     COMMAND *function;
-{
-  SHELL_VAR *var;
-
-  if (check_identifier (name, posixly_correct) == 0)
-    {
-      if (posixly_correct && interactive_shell == 0)
-       {
-         last_command_exit_value = EX_BADUSAGE;
-         jump_to_top_level (ERREXIT);
-       }
-      return (EXECUTION_FAILURE);
-    }
-
-  var = find_function (name->word);
-  if (var && (readonly_p (var) || noassign_p (var)))
-    {
-      if (readonly_p (var))
-       internal_error (_("%s: readonly function"), var->name);
-      return (EXECUTION_FAILURE);
-    }
-
-  bind_function (name->word, function);
-  return (EXECUTION_SUCCESS);
-}
-
-#if defined (INCLUDE_UNUSED)
-#if defined (PROCESS_SUBSTITUTION)
-void
-close_all_files ()
-{
-  register int i, fd_table_size;
-
-  fd_table_size = getdtablesize ();
-  if (fd_table_size > 256)     /* clamp to a reasonable value */
-    fd_table_size = 256;
-
-  for (i = 3; i < fd_table_size; i++)
-    close (i);
-}
-#endif /* PROCESS_SUBSTITUTION */
-#endif
-
-static void
-close_pipes (in, out)
-     int in, out;
-{
-  if (in >= 0)
-    close (in);
-  if (out >= 0)
-    close (out);
-}
-
-static void
-dup_error (oldd, newd)
-     int oldd, newd;
-{
-  sys_error (_("cannot duplicate fd %d to fd %d"), oldd, newd);
-}
-
-/* Redirect input and output to be from and to the specified pipes.
-   NO_PIPE and REDIRECT_BOTH are handled correctly. */
-static void
-do_piping (pipe_in, pipe_out)
-     int pipe_in, pipe_out;
-{
-  if (pipe_in != NO_PIPE)
-    {
-      if (dup2 (pipe_in, 0) < 0)
-       dup_error (pipe_in, 0);
-      if (pipe_in > 0)
-       close (pipe_in);
-    }
-  if (pipe_out != NO_PIPE)
-    {
-      if (pipe_out != REDIRECT_BOTH)
-       {
-         if (dup2 (pipe_out, 1) < 0)
-           dup_error (pipe_out, 1);
-         if (pipe_out == 0 || pipe_out > 1)
-           close (pipe_out);
-       }
-      else
-       {
-         if (dup2 (1, 2) < 0)
-           dup_error (1, 2);
-       }
-    }
-}
diff --git a/expr.c~ b/expr.c~
deleted file mode 100644 (file)
index d65513b..0000000
--- a/expr.c~
+++ /dev/null
@@ -1,1353 +0,0 @@
-/* expr.c -- arithmetic expression evaluation. */
-
-/* Copyright (C) 1990-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/>.
-*/
-
-/*
- All arithmetic is done as intmax_t integers with no checking for overflow
- (though division by 0 is caught and flagged as an error).
-
- The following operators are handled, grouped into a set of levels in
- order of decreasing precedence.
-
-       "id++", "id--"          [post-increment and post-decrement]
-       "++id", "--id"          [pre-increment and pre-decrement]
-       "-", "+"                [(unary operators)]
-       "!", "~"
-       "**"                    [(exponentiation)]
-       "*", "/", "%"
-       "+", "-"
-       "<<", ">>"
-       "<=", ">=", "<", ">"
-       "==", "!="
-       "&"
-       "^"
-       "|"
-       "&&"
-       "||"
-       "expr ? expr : expr"
-       "=", "*=", "/=", "%=", "+=", "-=", "<<=", ">>=", "&=", "^=", "|="
-       ,                       [comma]
-
- (Note that most of these operators have special meaning to bash, and an
- entire expression should be quoted, e.g. "a=$a+1" or "a=a+1" to ensure
- that it is passed intact to the evaluator when using `let'.  When using
- the $[] or $(( )) forms, the text between the `[' and `]' or `((' and `))'
- is treated as if in double quotes.)
-
- Sub-expressions within parentheses have a precedence level greater than
- all of the above levels and are evaluated first.  Within a single prece-
- dence group, evaluation is left-to-right, except for the arithmetic
- assignment operator (`='), which is evaluated right-to-left (as in C).
-
- The expression evaluator returns the value of the expression (assignment
- statements have as a value what is returned by the RHS).  The `let'
- builtin, on the other hand, returns 0 if the last expression evaluates to
- a non-zero, and 1 otherwise.
-
- Implementation is a recursive-descent parser.
-
- Chet Ramey
- chet@ins.CWRU.Edu
-*/
-
-#include "config.h"
-
-#include <stdio.h>
-#include "bashansi.h"
-
-#if defined (HAVE_UNISTD_H)
-#  ifdef _MINIX
-#    include <sys/types.h>
-#  endif
-#  include <unistd.h>
-#endif
-
-#include "chartypes.h"
-#include "bashintl.h"
-
-#include "shell.h"
-
-/* Because of the $((...)) construct, expressions may include newlines.
-   Here is a macro which accepts newlines, tabs and spaces as whitespace. */
-#define cr_whitespace(c) (whitespace(c) || ((c) == '\n'))
-
-/* Size be which the expression stack grows when neccessary. */
-#define EXPR_STACK_GROW_SIZE 10
-
-/* Maximum amount of recursion allowed.  This prevents a non-integer
-   variable such as "num=num+2" from infinitely adding to itself when
-   "let num=num+2" is given. */
-#define MAX_EXPR_RECURSION_LEVEL 1024
-
-/* The Tokens.  Singing "The Lion Sleeps Tonight". */
-
-#define EQEQ   1       /* "==" */
-#define NEQ    2       /* "!=" */
-#define LEQ    3       /* "<=" */
-#define GEQ    4       /* ">=" */
-#define STR    5       /* string */
-#define NUM    6       /* number */
-#define LAND   7       /* "&&" Logical AND */
-#define LOR    8       /* "||" Logical OR */
-#define LSH    9       /* "<<" Left SHift */
-#define RSH    10      /* ">>" Right SHift */
-#define OP_ASSIGN 11   /* op= expassign as in Posix.2 */
-#define COND   12      /* exp1 ? exp2 : exp3 */
-#define POWER  13      /* exp1**exp2 */
-#define PREINC 14      /* ++var */
-#define PREDEC 15      /* --var */
-#define POSTINC        16      /* var++ */
-#define POSTDEC        17      /* var-- */
-#define EQ     '='
-#define GT     '>'
-#define LT     '<'
-#define PLUS   '+'
-#define MINUS  '-'
-#define MUL    '*'
-#define DIV    '/'
-#define MOD    '%'
-#define NOT    '!'
-#define LPAR   '('
-#define RPAR   ')'
-#define BAND   '&'     /* Bitwise AND */
-#define BOR    '|'     /* Bitwise OR. */
-#define BXOR   '^'     /* Bitwise eXclusive OR. */
-#define BNOT   '~'     /* Bitwise NOT; Two's complement. */
-#define QUES   '?'
-#define COL    ':'
-#define COMMA  ','
-
-/* This should be the function corresponding to the operator with the
-   highest precedence. */
-#define EXP_HIGHEST    expcomma
-
-static char    *expression;    /* The current expression */
-static char    *tp;            /* token lexical position */
-static char    *lasttp;        /* pointer to last token position */
-static int     curtok;         /* the current token */
-static int     lasttok;        /* the previous token */
-static int     assigntok;      /* the OP in OP= */
-static char    *tokstr;        /* current token string */
-static intmax_t        tokval;         /* current token value */
-static int     noeval;         /* set to 1 if no assignment to be done */
-static procenv_t evalbuf;
-
-static int     _is_arithop __P((int));
-static void    readtok __P((void));    /* lexical analyzer */
-
-static intmax_t        expr_streval __P((char *, int));
-static intmax_t        strlong __P((char *));
-static void    evalerror __P((const char *));
-
-static void    pushexp __P((void));
-static void    popexp __P((void));
-static void    expr_unwind __P((void));
-static void    expr_bind_variable __P((char *, char *));
-
-static intmax_t subexpr __P((char *));
-
-static intmax_t        expcomma __P((void));
-static intmax_t expassign __P((void));
-static intmax_t        expcond __P((void));
-static intmax_t explor __P((void));
-static intmax_t expland __P((void));
-static intmax_t        expbor __P((void));
-static intmax_t        expbxor __P((void));
-static intmax_t        expband __P((void));
-static intmax_t exp5 __P((void));
-static intmax_t exp4 __P((void));
-static intmax_t expshift __P((void));
-static intmax_t exp3 __P((void));
-static intmax_t exp2 __P((void));
-static intmax_t        exppower __P((void));
-static intmax_t exp1 __P((void));
-static intmax_t exp0 __P((void));
-
-/* A structure defining a single expression context. */
-typedef struct {
-  int curtok, lasttok;
-  char *expression, *tp, *lasttp;
-  intmax_t tokval;
-  char *tokstr;
-  int noeval;
-} EXPR_CONTEXT;
-
-#ifdef INCLUDE_UNUSED
-/* Not used yet. */
-typedef struct {
-  char *tokstr;
-  intmax_t tokval;
-} LVALUE;
-#endif
-
-/* Global var which contains the stack of expression contexts. */
-static EXPR_CONTEXT **expr_stack;
-static int expr_depth;            /* Location in the stack. */
-static int expr_stack_size;       /* Number of slots already allocated. */
-
-extern char *this_command_name;
-extern int unbound_vars_is_error;
-
-#if defined (ARRAY_VARS)
-extern const char * const bash_badsub_errmsg;
-#endif
-
-#define SAVETOK(X) \
-  do { \
-    (X)->curtok = curtok; \
-    (X)->lasttok = lasttok; \
-    (X)->tp = tp; \
-    (X)->lasttp = lasttp; \
-    (X)->tokval = tokval; \
-    (X)->tokstr = tokstr; \
-    (X)->noeval = noeval; \
-  } while (0)
-
-#define RESTORETOK(X) \
-  do { \
-    curtok = (X)->curtok; \
-    lasttok = (X)->lasttok; \
-    tp = (X)->tp; \
-    lasttp = (X)->lasttp; \
-    tokval = (X)->tokval; \
-    tokstr = (X)->tokstr; \
-    noeval = (X)->noeval; \
-  } while (0)
-
-/* Push and save away the contents of the globals describing the
-   current expression context. */
-static void
-pushexp ()
-{
-  EXPR_CONTEXT *context;
-
-  if (expr_depth >= MAX_EXPR_RECURSION_LEVEL)
-    evalerror (_("expression recursion level exceeded"));
-
-  if (expr_depth >= expr_stack_size)
-    {
-      expr_stack_size += EXPR_STACK_GROW_SIZE;
-      expr_stack = (EXPR_CONTEXT **)xrealloc (expr_stack, expr_stack_size * sizeof (EXPR_CONTEXT *));
-    }
-
-  context = (EXPR_CONTEXT *)xmalloc (sizeof (EXPR_CONTEXT));
-
-  context->expression = expression;
-  SAVETOK(context);
-
-  expr_stack[expr_depth++] = context;
-}
-
-/* Pop the the contents of the expression context stack into the
-   globals describing the current expression context. */
-static void
-popexp ()
-{
-  EXPR_CONTEXT *context;
-
-  if (expr_depth == 0)
-    evalerror (_("recursion stack underflow"));
-
-  context = expr_stack[--expr_depth];
-
-  expression = context->expression;
-  RESTORETOK (context);
-
-  free (context);
-}
-
-static void
-expr_unwind ()
-{
-  while (--expr_depth > 0)
-    {
-      if (expr_stack[expr_depth]->tokstr)
-       free (expr_stack[expr_depth]->tokstr);
-
-      if (expr_stack[expr_depth]->expression)
-       free (expr_stack[expr_depth]->expression);
-
-      free (expr_stack[expr_depth]);
-    }
-  free (expr_stack[expr_depth]);       /* free the allocated EXPR_CONTEXT */
-
-  noeval = 0;  /* XXX */
-}
-
-static void
-expr_bind_variable (lhs, rhs)
-     char *lhs, *rhs;
-{
-  (void)bind_int_variable (lhs, rhs);
-  stupidly_hack_special_variables (lhs);
-}
-
-/* Evaluate EXPR, and return the arithmetic result.  If VALIDP is
-   non-null, a zero is stored into the location to which it points
-   if the expression is invalid, non-zero otherwise.  If a non-zero
-   value is returned in *VALIDP, the return value of evalexp() may
-   be used.
-
-   The `while' loop after the longjmp is caught relies on the above
-   implementation of pushexp and popexp leaving in expr_stack[0] the
-   values that the variables had when the program started.  That is,
-   the first things saved are the initial values of the variables that
-   were assigned at program startup or by the compiler.  Therefore, it is
-   safe to let the loop terminate when expr_depth == 0, without freeing up
-   any of the expr_depth[0] stuff. */
-intmax_t
-evalexp (expr, validp)
-     char *expr;
-     int *validp;
-{
-  intmax_t val;
-  int c;
-  procenv_t oevalbuf;
-
-  val = 0;
-  noeval = 0;
-
-  FASTCOPY (evalbuf, oevalbuf, sizeof (evalbuf));
-
-  c = setjmp (evalbuf);
-
-  if (c)
-    {
-      FREE (tokstr);
-      FREE (expression);
-      tokstr = expression = (char *)NULL;
-
-      expr_unwind ();
-
-      if (validp)
-       *validp = 0;
-      return (0);
-    }
-
-  val = subexpr (expr);
-
-  if (validp)
-    *validp = 1;
-
-  FASTCOPY (oevalbuf, evalbuf, sizeof (evalbuf));
-
-  return (val);
-}
-
-static intmax_t
-subexpr (expr)
-     char *expr;
-{
-  intmax_t val;
-  char *p;
-
-  for (p = expr; p && *p && cr_whitespace (*p); p++)
-    ;
-
-  if (p == NULL || *p == '\0')
-    return (0);
-
-  pushexp ();
-  curtok = lasttok = 0;
-  expression = savestring (expr);
-  tp = expression;
-
-  tokstr = (char *)NULL;
-  tokval = 0;
-
-  readtok ();
-
-  val = EXP_HIGHEST ();
-
-  if (curtok != 0)
-    evalerror (_("syntax error in expression"));
-
-  FREE (tokstr);
-  FREE (expression);
-
-  popexp ();
-
-  return val;
-}
-
-static intmax_t
-expcomma ()
-{
-  register intmax_t value;
-
-  value = expassign ();
-  while (curtok == COMMA)
-    {
-      readtok ();
-      value = expassign ();
-    }
-
-  return value;
-}
-  
-static intmax_t
-expassign ()
-{
-  register intmax_t value;
-  char *lhs, *rhs;
-
-  value = expcond ();
-  if (curtok == EQ || curtok == OP_ASSIGN)
-    {
-      int special, op;
-      intmax_t lvalue;
-
-      special = curtok == OP_ASSIGN;
-
-      if (lasttok != STR)
-       evalerror (_("attempted assignment to non-variable"));
-
-      if (special)
-       {
-         op = assigntok;               /* a OP= b */
-         lvalue = value;
-       }
-
-      lhs = savestring (tokstr);
-      readtok ();
-      value = expassign ();
-
-      if (special)
-       {
-         switch (op)
-           {
-           case MUL:
-             lvalue *= value;
-             break;
-           case DIV:
-             if (value == 0)
-               evalerror (_("division by 0"));
-             lvalue /= value;
-             break;
-           case MOD:
-             if (value == 0)
-               evalerror (_("division by 0"));
-             lvalue %= value;
-             break;
-           case PLUS:
-             lvalue += value;
-             break;
-           case MINUS:
-             lvalue -= value;
-             break;
-           case LSH:
-             lvalue <<= value;
-             break;
-           case RSH:
-             lvalue >>= value;
-             break;
-           case BAND:
-             lvalue &= value;
-             break;
-           case BOR:
-             lvalue |= value;
-             break;
-           case BXOR:
-             lvalue ^= value;
-             break;
-           default:
-             free (lhs);
-             evalerror (_("bug: bad expassign token"));
-             break;
-           }
-         value = lvalue;
-       }
-
-      rhs = itos (value);
-      if (noeval == 0)
-       expr_bind_variable (lhs, rhs);
-      free (rhs);
-      free (lhs);
-      FREE (tokstr);
-      tokstr = (char *)NULL;           /* For freeing on errors. */
-    }
-  return (value);
-}
-
-/* Conditional expression (expr?expr:expr) */
-static intmax_t
-expcond ()
-{
-  intmax_t cval, val1, val2, rval;
-  int set_noeval;
-
-  set_noeval = 0;
-  rval = cval = explor ();
-  if (curtok == QUES)          /* found conditional expr */
-    {
-      readtok ();
-      if (curtok == 0 || curtok == COL)
-       evalerror (_("expression expected"));
-      if (cval == 0)
-       {
-         set_noeval = 1;
-         noeval++;
-       }
-
-      val1 = EXP_HIGHEST ();
-
-      if (set_noeval)
-       noeval--;
-      if (curtok != COL)
-       evalerror (_("`:' expected for conditional expression"));
-      readtok ();
-      if (curtok == 0)
-       evalerror (_("expression expected"));
-      set_noeval = 0;
-      if (cval)
-       {
-         set_noeval = 1;
-         noeval++;
-       }
-
-      val2 = expcond ();
-      if (set_noeval)
-       noeval--;
-      rval = cval ? val1 : val2;
-      lasttok = COND;
-    }
-  return rval;
-}
-
-/* Logical OR. */
-static intmax_t
-explor ()
-{
-  register intmax_t val1, val2;
-  int set_noeval;
-
-  val1 = expland ();
-
-  while (curtok == LOR)
-    {
-      set_noeval = 0;
-      if (val1 != 0)
-       {
-         noeval++;
-         set_noeval = 1;
-       }
-      readtok ();
-      val2 = expland ();
-      if (set_noeval)
-       noeval--;
-      val1 = val1 || val2;
-      lasttok = LOR;
-    }
-
-  return (val1);
-}
-
-/* Logical AND. */
-static intmax_t
-expland ()
-{
-  register intmax_t val1, val2;
-  int set_noeval;
-
-  val1 = expbor ();
-
-  while (curtok == LAND)
-    {
-      set_noeval = 0;
-      if (val1 == 0)
-       {
-         set_noeval = 1;
-         noeval++;
-       }
-      readtok ();
-      val2 = expbor ();
-      if (set_noeval)
-       noeval--;
-      val1 = val1 && val2;
-      lasttok = LAND;
-    }
-
-  return (val1);
-}
-
-/* Bitwise OR. */
-static intmax_t
-expbor ()
-{
-  register intmax_t val1, val2;
-
-  val1 = expbxor ();
-
-  while (curtok == BOR)
-    {
-      readtok ();
-      val2 = expbxor ();
-      val1 = val1 | val2;
-    }
-
-  return (val1);
-}
-
-/* Bitwise XOR. */
-static intmax_t
-expbxor ()
-{
-  register intmax_t val1, val2;
-
-  val1 = expband ();
-
-  while (curtok == BXOR)
-    {
-      readtok ();
-      val2 = expband ();
-      val1 = val1 ^ val2;
-    }
-
-  return (val1);
-}
-
-/* Bitwise AND. */
-static intmax_t
-expband ()
-{
-  register intmax_t val1, val2;
-
-  val1 = exp5 ();
-
-  while (curtok == BAND)
-    {
-      readtok ();
-      val2 = exp5 ();
-      val1 = val1 & val2;
-    }
-
-  return (val1);
-}
-
-static intmax_t
-exp5 ()
-{
-  register intmax_t val1, val2;
-
-  val1 = exp4 ();
-
-  while ((curtok == EQEQ) || (curtok == NEQ))
-    {
-      int op = curtok;
-
-      readtok ();
-      val2 = exp4 ();
-      if (op == EQEQ)
-       val1 = (val1 == val2);
-      else if (op == NEQ)
-       val1 = (val1 != val2);
-    }
-  return (val1);
-}
-
-static intmax_t
-exp4 ()
-{
-  register intmax_t val1, val2;
-
-  val1 = expshift ();
-  while ((curtok == LEQ) ||
-        (curtok == GEQ) ||
-        (curtok == LT) ||
-        (curtok == GT))
-    {
-      int op = curtok;
-
-      readtok ();
-      val2 = expshift ();
-
-      if (op == LEQ)
-       val1 = val1 <= val2;
-      else if (op == GEQ)
-       val1 = val1 >= val2;
-      else if (op == LT)
-       val1 = val1 < val2;
-      else                     /* (op == GT) */
-       val1 = val1 > val2;
-    }
-  return (val1);
-}
-
-/* Left and right shifts. */
-static intmax_t
-expshift ()
-{
-  register intmax_t val1, val2;
-
-  val1 = exp3 ();
-
-  while ((curtok == LSH) || (curtok == RSH))
-    {
-      int op = curtok;
-
-      readtok ();
-      val2 = exp3 ();
-
-      if (op == LSH)
-       val1 = val1 << val2;
-      else
-       val1 = val1 >> val2;
-    }
-
-  return (val1);
-}
-
-static intmax_t
-exp3 ()
-{
-  register intmax_t val1, val2;
-
-  val1 = exp2 ();
-
-  while ((curtok == PLUS) || (curtok == MINUS))
-    {
-      int op = curtok;
-
-      readtok ();
-      val2 = exp2 ();
-
-      if (op == PLUS)
-       val1 += val2;
-      else if (op == MINUS)
-       val1 -= val2;
-    }
-  return (val1);
-}
-
-static intmax_t
-exp2 ()
-{
-  register intmax_t val1, val2;
-
-  val1 = exppower ();
-
-  while ((curtok == MUL) ||
-        (curtok == DIV) ||
-        (curtok == MOD))
-    {
-      int op = curtok;
-
-      readtok ();
-
-      val2 = exppower ();
-
-      if (((op == DIV) || (op == MOD)) && (val2 == 0))
-       evalerror (_("division by 0"));
-
-      if (op == MUL)
-       val1 *= val2;
-      else if (op == DIV)
-       val1 /= val2;
-      else if (op == MOD)
-       val1 %= val2;
-    }
-  return (val1);
-}
-
-static intmax_t
-exppower ()
-{
-  register intmax_t val1, val2, c;
-
-  val1 = exp1 ();
-  while (curtok == POWER)
-    {
-      readtok ();
-      val2 = exppower ();      /* exponentiation is right-associative */
-      if (val2 == 0)
-       return (1);
-      if (val2 < 0)
-       evalerror (_("exponent less than 0"));
-      for (c = 1; val2--; c *= val1)
-       ;
-      val1 = c;
-    }
-  return (val1);
-}
-
-static intmax_t
-exp1 ()
-{
-  register intmax_t val;
-
-  if (curtok == NOT)
-    {
-      readtok ();
-      val = !exp1 ();
-    }
-  else if (curtok == BNOT)
-    {
-      readtok ();
-      val = ~exp1 ();
-    }
-  else
-    val = exp0 ();
-
-  return (val);
-}
-
-static intmax_t
-exp0 ()
-{
-  register intmax_t val = 0, v2;
-  char *vincdec;
-  int stok;
-  EXPR_CONTEXT ec;
-
-  /* XXX - might need additional logic here to decide whether or not
-          pre-increment or pre-decrement is legal at this point. */
-  if (curtok == PREINC || curtok == PREDEC)
-    {
-      stok = lasttok = curtok;
-      readtok ();
-      if (curtok != STR)
-       /* readtok() catches this */
-       evalerror (_("identifier expected after pre-increment or pre-decrement"));
-
-      v2 = tokval + ((stok == PREINC) ? 1 : -1);
-      vincdec = itos (v2);
-      if (noeval == 0)
-       expr_bind_variable (tokstr, vincdec);
-      free (vincdec);
-      val = v2;
-
-      curtok = NUM;    /* make sure --x=7 is flagged as an error */
-      readtok ();
-    }
-  else if (curtok == MINUS)
-    {
-      readtok ();
-      val = - exp0 ();
-    }
-  else if (curtok == PLUS)
-    {
-      readtok ();
-      val = exp0 ();
-    }
-  else if (curtok == LPAR)
-    {
-      readtok ();
-      val = EXP_HIGHEST ();
-
-      if (curtok != RPAR) /* ( */
-       evalerror (_("missing `)'"));
-
-      /* Skip over closing paren. */
-      readtok ();
-    }
-  else if ((curtok == NUM) || (curtok == STR))
-    {
-      val = tokval;
-      if (curtok == STR)
-       {
-         SAVETOK (&ec);
-         tokstr = (char *)NULL;        /* keep it from being freed */
-          noeval = 1;
-          readtok ();
-          stok = curtok;
-
-         /* post-increment or post-decrement */
-         if (stok == POSTINC || stok == POSTDEC)
-           {
-             /* restore certain portions of EC */
-             tokstr = ec.tokstr;
-             noeval = ec.noeval;
-             lasttok = STR;    /* ec.curtok */
-
-             v2 = val + ((stok == POSTINC) ? 1 : -1);
-             vincdec = itos (v2);
-             if (noeval == 0)
-               expr_bind_variable (tokstr, vincdec);
-             free (vincdec);
-             curtok = NUM;     /* make sure x++=7 is flagged as an error */
-           }
-         else
-           {
-             if (stok == STR)  /* free new tokstr before old one is restored */
-               FREE (tokstr);
-             RESTORETOK (&ec);
-           }
-
-       }
-         
-      readtok ();
-    }
-  else
-    evalerror (_("syntax error: operand expected"));
-
-  return (val);
-}
-
-static intmax_t
-expr_streval (tok, e)
-     char *tok;
-     int e;
-{
-  SHELL_VAR *v;
-  char *value;
-  intmax_t tval;
-
-  /* [[[[[ */
-#if defined (ARRAY_VARS)
-  v = (e == ']') ? array_variable_part (tok, (char **)0, (int *)0) : find_variable (tok);
-#else
-  v = find_variable (tok);
-#endif
-
-  if ((v == 0 || invisible_p (v)) && unbound_vars_is_error)
-    {
-#if defined (ARRAY_VARS)
-      value = (e == ']') ? array_variable_name (tok, (char **)0, (int *)0) : tok;
-#else
-      value = tok;
-#endif
-
-      last_command_exit_value = EXECUTION_FAILURE;
-      err_unboundvar (value);
-
-#if defined (ARRAY_VARS)
-      if (e == ']')
-       FREE (value);   /* array_variable_name returns new memory */
-#endif
-
-      if (interactive_shell)
-       {
-         expr_unwind ();
-         top_level_cleanup ();
-         jump_to_top_level (DISCARD);
-       }
-      else
-       jump_to_top_level (FORCE_EOF);
-    }
-
-#if defined (ARRAY_VARS)
-  /* Second argument of 0 to get_array_value means that we don't allow
-     references like array[@].  In this case, get_array_value is just
-     like get_variable_value in that it does not return newly-allocated
-     memory or quote the results. */
-  value = (e == ']') ? get_array_value (tok, 0, (int *)NULL) : get_variable_value (v);
-#else
-  value = get_variable_value (v);
-#endif
-
-  tval = (value && *value) ? subexpr (value) : 0;
-
-  return (tval);
-}
-
-static int
-_is_multiop (c)
-     int c;
-{
-  switch (c)
-    {
-    case EQEQ:
-    case NEQ:
-    case LEQ:
-    case GEQ:
-    case LAND:
-    case LOR:
-    case LSH:
-    case RSH:
-    case OP_ASSIGN:
-    case COND:
-    case POWER:
-    case PREINC:
-    case PREDEC:
-    case POSTINC:
-    case POSTDEC:
-      return 1;
-    default:
-      return 0;
-    }
-}
-
-static int
-_is_arithop (c)
-     int c;
-{
-  switch (c)
-    {
-    case EQ:
-    case GT:
-    case LT:
-    case PLUS:
-    case MINUS:
-    case MUL:
-    case DIV:
-    case MOD:
-    case NOT:
-    case LPAR:
-    case RPAR:
-    case BAND:
-    case BOR:
-    case BXOR:
-    case BNOT:
-      return 1;                /* operator tokens */
-    case QUES:
-    case COL:
-    case COMMA:
-      return 1;                /* questionable */
-    default:
-      return 0;                /* anything else is invalid */
-    }
-}
-
-/* Lexical analyzer/token reader for the expression evaluator.  Reads the
-   next token and puts its value into curtok, while advancing past it.
-   Updates value of tp.  May also set tokval (for number) or tokstr (for
-   string). */
-static void
-readtok ()
-{
-  register char *cp, *xp;
-  register unsigned char c, c1;
-  register int e;
-
-  /* Skip leading whitespace. */
-  cp = tp;
-  c = e = 0;
-  while (cp && (c = *cp) && (cr_whitespace (c)))
-    cp++;
-
-  if (c)
-    cp++;
-
-  if (c == '\0')
-    {
-      lasttok = curtok;
-      curtok = 0;
-      tp = cp;
-      return;
-    }
-  lasttp = tp = cp - 1;
-
-  if (legal_variable_starter (c))
-    {
-      /* variable names not preceded with a dollar sign are shell variables. */
-      char *savecp;
-      EXPR_CONTEXT ec;
-      int peektok;
-
-      while (legal_variable_char (c))
-       c = *cp++;
-
-      c = *--cp;
-
-#if defined (ARRAY_VARS)
-      if (c == '[')
-       {
-         e = skipsubscript (cp, 0);
-         if (cp[e] == ']')
-           {
-             cp += e + 1;
-             c = *cp;
-             e = ']';
-           }
-         else
-           evalerror (bash_badsub_errmsg);
-       }
-#endif /* ARRAY_VARS */
-
-      *cp = '\0';
-      FREE (tokstr);
-      tokstr = savestring (tp);
-      *cp = c;
-
-      SAVETOK (&ec);
-      tokstr = (char *)NULL;   /* keep it from being freed */
-      tp = savecp = cp;
-      noeval = 1;
-      curtok = STR;
-      readtok ();
-      peektok = curtok;
-      if (peektok == STR)      /* free new tokstr before old one is restored */
-       FREE (tokstr);
-      RESTORETOK (&ec);
-      cp = savecp;
-
-      /* The tests for PREINC and PREDEC aren't strictly correct, but they
-        preserve old behavior if a construct like --x=9 is given. */
-      if (lasttok == PREINC || lasttok == PREDEC || peektok != EQ)
-       tokval = expr_streval (tokstr, e);
-      else
-       tokval = 0;
-
-      lasttok = curtok;
-      curtok = STR;
-    }
-  else if (DIGIT(c))
-    {
-      while (ISALNUM (c) || c == '#' || c == '@' || c == '_')
-       c = *cp++;
-
-      c = *--cp;
-      *cp = '\0';
-
-      tokval = strlong (tp);
-      *cp = c;
-      lasttok = curtok;
-      curtok = NUM;
-    }
-  else
-    {
-      c1 = *cp++;
-      if ((c == EQ) && (c1 == EQ))
-       c = EQEQ;
-      else if ((c == NOT) && (c1 == EQ))
-       c = NEQ;
-      else if ((c == GT) && (c1 == EQ))
-       c = GEQ;
-      else if ((c == LT) && (c1 == EQ))
-       c = LEQ;
-      else if ((c == LT) && (c1 == LT))
-       {
-         if (*cp == '=')       /* a <<= b */
-           {
-             assigntok = LSH;
-             c = OP_ASSIGN;
-             cp++;
-           }
-         else
-           c = LSH;
-       }
-      else if ((c == GT) && (c1 == GT))
-       {
-         if (*cp == '=')
-           {
-             assigntok = RSH;  /* a >>= b */
-             c = OP_ASSIGN;
-             cp++;
-           }
-         else
-           c = RSH;
-       }
-      else if ((c == BAND) && (c1 == BAND))
-       c = LAND;
-      else if ((c == BOR) && (c1 == BOR))
-       c = LOR;
-      else if ((c == '*') && (c1 == '*'))
-       c = POWER;
-      else if ((c == '-' || c == '+') && c1 == c && curtok == STR)
-       c = (c == '-') ? POSTDEC : POSTINC;
-      else if ((c == '-' || c == '+') && c1 == c)
-       {
-         /* Quickly scan forward to see if this is followed by optional
-            whitespace and an identifier. */
-         xp = cp;
-         while (xp && *xp && cr_whitespace (*xp))
-           xp++;
-         if (legal_variable_starter ((unsigned char)*xp))
-           c = (c == '-') ? PREDEC : PREINC;
-         else
-           cp--;       /* not preinc or predec, so unget the character */
-       }
-      else if (c1 == EQ && member (c, "*/%+-&^|"))
-       {
-         assigntok = c;        /* a OP= b */
-         c = OP_ASSIGN;
-       }
-      else if (_is_arithop (c) == 0)
-       {
-         cp--;
-         /* use curtok, since it hasn't been copied to lasttok yet */
-         if (curtok == 0 || _is_arithop (curtok) || _is_multiop (curtok))
-           evalerror (_("syntax error: operand expected"));
-         else
-           evalerror (_("syntax error: invalid arithmetic operator"));
-       }
-      else
-       cp--;                   /* `unget' the character */
-
-      /* Should check here to make sure that the current character is one
-        of the recognized operators and flag an error if not.  Could create
-        a character map the first time through and check it on subsequent
-        calls. */
-      lasttok = curtok;
-      curtok = c;
-    }
-  tp = cp;
-}
-
-static void
-evalerror (msg)
-     const char *msg;
-{
-  char *name, *t;
-
-  name = this_command_name;
-  for (t = expression; whitespace (*t); t++)
-    ;
-  internal_error (_("%s%s%s: %s (error token is \"%s\")"),
-                  name ? name : "", name ? ": " : "", t,
-                  msg, (lasttp && *lasttp) ? lasttp : "");
-  longjmp (evalbuf, 1);
-}
-
-/* Convert a string to an intmax_t integer, with an arbitrary base.
-   0nnn -> base 8
-   0[Xx]nn -> base 16
-   Anything else: [base#]number (this is implemented to match ksh93)
-
-   Base may be >=2 and <=64.  If base is <= 36, the numbers are drawn
-   from [0-9][a-zA-Z], and lowercase and uppercase letters may be used
-   interchangably.  If base is > 36 and <= 64, the numbers are drawn
-   from [0-9][a-z][A-Z]_@ (a = 10, z = 35, A = 36, Z = 61, @ = 62, _ = 63 --
-   you get the picture). */
-
-static intmax_t
-strlong (num)
-     char *num;
-{
-  register char *s;
-  register unsigned char c;
-  int base, foundbase;
-  intmax_t val;
-
-  s = num;
-
-  base = 10;
-  foundbase = 0;
-  if (*s == '0')
-    {
-      s++;
-
-      if (*s == '\0')
-       return 0;
-
-       /* Base 16? */
-      if (*s == 'x' || *s == 'X')
-       {
-         base = 16;
-         s++;
-       }
-      else
-       base = 8;
-      foundbase++;
-    }
-
-  val = 0;
-  for (c = *s++; c; c = *s++)
-    {
-      if (c == '#')
-       {
-         if (foundbase)
-           evalerror (_("invalid number"));
-
-         /* Illegal base specifications raise an evaluation error. */
-         if (val < 2 || val > 64)
-           evalerror (_("invalid arithmetic base"));
-
-         base = val;
-         val = 0;
-         foundbase++;
-       }
-      else if (ISALNUM(c) || (c == '_') || (c == '@'))
-       {
-         if (DIGIT(c))
-           c = TODIGIT(c);
-         else if (c >= 'a' && c <= 'z')
-           c -= 'a' - 10;
-         else if (c >= 'A' && c <= 'Z')
-           c -= 'A' - ((base <= 36) ? 10 : 36);
-         else if (c == '@')
-           c = 62;
-         else if (c == '_')
-           c = 63;
-
-         if (c >= base)
-           evalerror (_("value too great for base"));
-
-         val = (val * base) + c;
-       }
-      else
-       break;
-    }
-
-  return (val);
-}
-
-#if defined (EXPR_TEST)
-void *
-xmalloc (n)
-     int n;
-{
-  return (malloc (n));
-}
-
-void *
-xrealloc (s, n)
-     char *s;
-     int n;
-{
-  return (realloc (s, n));
-}
-
-SHELL_VAR *find_variable () { return 0;}
-SHELL_VAR *bind_variable () { return 0; }
-
-char *get_string_value () { return 0; }
-
-procenv_t top_level;
-
-main (argc, argv)
-     int argc;
-     char **argv;
-{
-  register int i;
-  intmax_t v;
-  int expok;
-
-  if (setjmp (top_level))
-    exit (0);
-
-  for (i = 1; i < argc; i++)
-    {
-      v = evalexp (argv[i], &expok);
-      if (expok == 0)
-       fprintf (stderr, _("%s: expression error\n"), argv[i]);
-      else
-       printf ("'%s' -> %ld\n", argv[i], v);
-    }
-  exit (0);
-}
-
-int
-builtin_error (format, arg1, arg2, arg3, arg4, arg5)
-     char *format;
-{
-  fprintf (stderr, "expr: ");
-  fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
-  fprintf (stderr, "\n");
-  return 0;
-}
-
-char *
-itos (n)
-     intmax_t n;
-{
-  return ("42");
-}
-
-#endif /* EXPR_TEST */
diff --git a/externs.h~ b/externs.h~
deleted file mode 100644 (file)
index dfc803d..0000000
+++ /dev/null
@@ -1,474 +0,0 @@
-/* externs.h -- extern function declarations which do not appear in their
-   own header file. */
-
-/* Copyright (C) 1993-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/>.
-*/
-
-/* Make sure that this is included *after* config.h! */
-
-#if !defined (_EXTERNS_H_)
-#  define _EXTERNS_H_
-
-#include "stdc.h"
-
-/* Functions from expr.c. */
-extern intmax_t evalexp __P((char *, int *));
-
-/* Functions from print_cmd.c. */
-#define FUNC_MULTILINE 0x01
-#define FUNC_EXTERNAL  0x02
-
-extern char *make_command_string __P((COMMAND *));
-extern char *named_function_string __P((char *, COMMAND *, int));
-
-extern void print_command __P((COMMAND *));
-extern void print_simple_command __P((SIMPLE_COM *));
-extern void print_word_list __P((WORD_LIST *, char *));
-
-/* debugger support */
-extern void print_for_command_head __P((FOR_COM *));
-#if defined (SELECT_COMMAND)
-extern void print_select_command_head __P((SELECT_COM *));
-#endif
-extern void print_case_command_head __P((CASE_COM *));
-#if defined (DPAREN_ARITHMETIC)
-extern void print_arith_command __P((WORD_LIST *));
-#endif
-#if defined (COND_COMMAND)
-extern void print_cond_command __P((COND_COM *));
-#endif
-
-/* set -x support */
-extern void xtrace_init __P((void));
-#ifdef NEED_XTRACE_SET_DECL
-extern void xtrace_set __P((int, FILE *));
-#endif
-extern void xtrace_reset __P((void));
-extern char *indirection_level_string __P((void));
-extern void xtrace_print_assignment __P((char *, char *, int, int));
-extern void xtrace_print_word_list __P((WORD_LIST *, int));
-extern void xtrace_print_for_command_head __P((FOR_COM *));
-#if defined (SELECT_COMMAND)
-extern void xtrace_print_select_command_head __P((SELECT_COM *));
-#endif
-extern void xtrace_print_case_command_head __P((CASE_COM *));
-#if defined (DPAREN_ARITHMETIC)
-extern void xtrace_print_arith_cmd __P((WORD_LIST *));
-#endif
-#if defined (COND_COMMAND)
-extern void xtrace_print_cond_term __P((int, int, WORD_DESC *, char *, char *));
-#endif
-
-/* Functions from shell.c. */
-extern void exit_shell __P((int)) __attribute__((__noreturn__));
-extern void sh_exit __P((int)) __attribute__((__noreturn__));
-extern void disable_priv_mode __P((void));
-extern void unbind_args __P((void));
-
-#if defined (RESTRICTED_SHELL)
-extern int shell_is_restricted __P((char *));
-extern int maybe_make_restricted __P((char *));
-#endif
-
-extern void unset_bash_input __P((int));
-extern void get_current_user_info __P((void));
-
-/* Functions from eval.c. */
-extern int reader_loop __P((void));
-extern int parse_command __P((void));
-extern int read_command __P((void));
-
-/* Functions from braces.c. */
-#if defined (BRACE_EXPANSION)
-extern char **brace_expand __P((char *));
-#endif
-
-/* Miscellaneous functions from parse.y */
-extern int yyparse __P((void));
-extern int return_EOF __P((void));
-extern char *xparse_dolparen __P((char *, char *, int *, int));
-extern void reset_parser __P((void));
-extern WORD_LIST *parse_string_to_word_list __P((char *, int, const char *));
-
-extern void free_pushed_string_input __P((void));
-
-extern char *decode_prompt_string __P((char *));
-
-extern int get_current_prompt_level __P((void));
-extern void set_current_prompt_level __P((int));
-
-#if defined (HISTORY)
-extern char *history_delimiting_chars __P((void));
-#endif
-
-/* Declarations for functions defined in locale.c */
-extern void set_default_locale __P((void));
-extern void set_default_locale_vars __P((void));
-extern int set_locale_var __P((char *, char *));
-extern int set_lang __P((char *, char *));
-extern void set_default_lang __P((void));
-extern char *get_locale_var __P((char *));
-extern char *localetrans __P((char *, int, int *));
-extern char *mk_msgstr __P((char *, int *));
-extern char *localeexpand __P((char *, int, int, int, int *));
-
-/* Declarations for functions defined in list.c. */
-extern void list_walk __P((GENERIC_LIST *, sh_glist_func_t *));
-extern void wlist_walk __P((WORD_LIST *, sh_icpfunc_t *));
-extern GENERIC_LIST *list_reverse ();
-extern int list_length ();
-extern GENERIC_LIST *list_append ();
-extern GENERIC_LIST *list_remove ();
-
-/* Declarations for functions defined in stringlib.c */
-extern int find_string_in_alist __P((char *, STRING_INT_ALIST *, int));
-extern char *find_token_in_alist __P((int, STRING_INT_ALIST *, int));
-extern int find_index_in_alist __P((char *, STRING_INT_ALIST *, int));
-
-extern char *substring __P((const char *, int, int));
-extern char *strsub __P((char *, char *, char *, int));
-extern char *strcreplace __P((char *, int, char *, int));
-extern void strip_leading __P((char *));
-extern void strip_trailing __P((char *, int, int));
-extern void xbcopy __P((char *, char *, int));
-
-/* Functions from version.c. */
-extern char *shell_version_string __P((void));
-extern void show_shell_version __P((int));
-
-/* Functions from the bash library, lib/sh/libsh.a.  These should really
-   go into a separate include file. */
-
-/* declarations for functions defined in lib/sh/casemod.c */
-extern char *sh_modcase __P((const char *, char *, int));
-
-/* Defines for flags argument to sh_modcase.  These need to agree with what's
-   in lib/sh/casemode.c */
-#define CASE_LOWER     0x0001
-#define CASE_UPPER     0x0002
-#define CASE_CAPITALIZE        0x0004
-#define CASE_UNCAP     0x0008
-#define CASE_TOGGLE    0x0010
-#define CASE_TOGGLEALL 0x0020
-#define CASE_UPFIRST   0x0040
-#define CASE_LOWFIRST  0x0080
-
-#define CASE_USEWORDS  0x1000
-
-/* declarations for functions defined in lib/sh/clktck.c */
-extern long get_clk_tck __P((void));
-
-/* declarations for functions defined in lib/sh/clock.c */
-extern void clock_t_to_secs ();
-extern void print_clock_t ();
-
-/* Declarations for functions defined in lib/sh/fdprintf.c */
-extern void fdprintf __P((int, const char *, ...))  __attribute__((__format__ (printf, 2, 3)));
-
-/* Declarations for functions defined in lib/sh/fmtulong.c */
-#define FL_PREFIX     0x01    /* add 0x, 0X, or 0 prefix as appropriate */
-#define FL_ADDBASE    0x02    /* add base# prefix to converted value */
-#define FL_HEXUPPER   0x04    /* use uppercase when converting to hex */
-#define FL_UNSIGNED   0x08    /* don't add any sign */
-
-extern char *fmtulong __P((unsigned long int, int, char *, size_t, int));
-
-/* Declarations for functions defined in lib/sh/fmtulong.c */
-#if defined (HAVE_LONG_LONG)
-extern char *fmtullong __P((unsigned long long int, int, char *, size_t, int));
-#endif
-
-/* Declarations for functions defined in lib/sh/fmtumax.c */
-extern char *fmtumax __P((uintmax_t, int, char *, size_t, int));
-
-/* Declarations for functions defined in lib/sh/fnxform.c */
-extern char *fnx_fromfs __P((ICONV_CONST char *, size_t));
-extern char *fnx_tofs __P((ICONV_CONST char *, size_t));
-
-/* Declarations for functions defined in lib/sh/fpurge.c */
-
-#if defined NEED_FPURGE_DECL
-#if !HAVE_DECL_FPURGE
-
-#if HAVE_FPURGE
-#  define fpurge _bash_fpurge
-#endif
-extern int fpurge __P((FILE *stream));
-
-#endif /* HAVE_DECL_FPURGE */
-#endif /* NEED_FPURGE_DECL */
-
-/* Declarations for functions defined in lib/sh/getcwd.c */
-#if !defined (HAVE_GETCWD)
-extern char *getcwd __P((char *, size_t));
-#endif
-
-/* Declarations for functions defined in lib/sh/input_avail.c */
-extern int input_avail __P((int));
-
-/* Declarations for functions defined in lib/sh/itos.c */
-extern char *inttostr __P((intmax_t, char *, size_t));
-extern char *itos __P((intmax_t));
-extern char *uinttostr __P((uintmax_t, char *, size_t));
-extern char *uitos __P((uintmax_t));
-
-/* declarations for functions defined in lib/sh/makepath.c */
-#define MP_DOTILDE     0x01
-#define MP_DOCWD       0x02
-#define MP_RMDOT       0x04
-#define MP_IGNDOT      0x08
-
-extern char *sh_makepath __P((const char *, const char *, int));
-
-/* declarations for functions defined in lib/sh/mbscasecmp.c */
-#if !defined (HAVE_MBSCASECMP)
-extern char *mbscasecmp __P((const char *, const char *));
-#endif
-
-/* declarations for functions defined in lib/sh/mbschr.c */
-#if !defined (HAVE_MBSCHR)
-extern char *mbschr __P((const char *, int));
-#endif
-
-/* declarations for functions defined in lib/sh/mbscmp.c */
-#if !defined (HAVE_MBSCMP)
-extern char *mbscmp __P((const char *, const char *));
-#endif
-
-/* declarations for functions defined in lib/sh/netconn.c */
-extern int isnetconn __P((int));
-
-/* declarations for functions defined in lib/sh/netopen.c */
-extern int netopen __P((char *));
-
-/* Declarations for  functions defined in lib/sh/oslib.c */
-
-#if !defined (HAVE_DUP2) || defined (DUP2_BROKEN)
-extern int dup2 __P((int, int));
-#endif
-
-#if !defined (HAVE_GETDTABLESIZE)
-extern int getdtablesize __P((void));
-#endif /* !HAVE_GETDTABLESIZE */
-
-#if !defined (HAVE_GETHOSTNAME)
-extern int gethostname __P((char *, int));
-#endif /* !HAVE_GETHOSTNAME */
-
-extern int getmaxgroups __P((void));
-extern long getmaxchild __P((void));
-
-/* declarations for functions defined in lib/sh/pathcanon.c */
-#define PATH_CHECKDOTDOT       0x0001
-#define PATH_CHECKEXISTS       0x0002
-#define PATH_HARDPATH          0x0004
-#define PATH_NOALLOC           0x0008
-
-extern char *sh_canonpath __P((char *, int));
-
-/* declarations for functions defined in lib/sh/pathphys.c */
-extern char *sh_physpath __P((char *, int));
-extern char *sh_realpath __P((const char *, char *));
-
-/* declarations for functions defined in lib/sh/setlinebuf.c */
-#ifdef NEED_SH_SETLINEBUF_DECL
-extern int sh_setlinebuf __P((FILE *));
-#endif
-
-/* declarations for functions defined in lib/sh/shaccess.c */
-extern int sh_eaccess __P((char *, int));
-
-/* declarations for functions defined in lib/sh/shmatch.c */
-extern int sh_regmatch __P((const char *, const char *, int));
-
-/* defines for flags argument to sh_regmatch. */
-#define SHMAT_SUBEXP           0x001   /* save subexpressions in SH_REMATCH */
-#define SHMAT_PWARN            0x002   /* print a warning message on invalid regexp */
-
-/* declarations for functions defined in lib/sh/shquote.c */
-extern char *sh_single_quote __P((char *));
-extern char *sh_double_quote __P((char *));
-extern char *sh_mkdoublequoted __P((const char *, int, int));
-extern char *sh_un_double_quote __P((char *));
-extern char *sh_backslash_quote __P((char *));
-extern char *sh_backslash_quote_for_double_quotes __P((char *));
-extern int sh_contains_shell_metas __P((char *));
-
-/* declarations for functions defined in lib/sh/spell.c */
-extern int spname __P((char *, char *));
-extern char *dirspell __P((char *));
-
-/* declarations for functions defined in lib/sh/strcasecmp.c */
-#if !defined (HAVE_STRCASECMP)
-extern int strncasecmp __P((const char *, const char *, int));
-extern int strcasecmp __P((const char *, const char *));
-#endif /* HAVE_STRCASECMP */
-
-/* declarations for functions defined in lib/sh/strcasestr.c */
-#if ! HAVE_STRCASESTR
-extern char *strcasestr __P((const char *, const char *));
-#endif
-
-/* declarations for functions defined in lib/sh/strerror.c */
-#if !defined (HAVE_STRERROR) && !defined (strerror)
-extern char *strerror __P((int));
-#endif
-
-/* declarations for functions defined in lib/sh/strftime.c */
-#if !defined (HAVE_STRFTIME) && defined (NEED_STRFTIME_DECL)
-extern size_t strftime __P((char *, size_t, const char *, const struct tm *));
-#endif
-
-/* declarations for functions and structures defined in lib/sh/stringlist.c */
-
-/* This is a general-purpose argv-style array struct. */
-typedef struct _list_of_strings {
-  char **list;
-  int list_size;
-  int list_len;
-} STRINGLIST;
-
-typedef int sh_strlist_map_func_t __P((char *));
-
-extern STRINGLIST *strlist_create __P((int));
-extern STRINGLIST *strlist_resize __P((STRINGLIST *, int));
-extern void strlist_flush __P((STRINGLIST *));
-extern void strlist_dispose __P((STRINGLIST *));
-extern int strlist_remove __P((STRINGLIST *, char *));
-extern STRINGLIST *strlist_copy __P((STRINGLIST *));
-extern STRINGLIST *strlist_merge __P((STRINGLIST *, STRINGLIST *));
-extern STRINGLIST *strlist_append __P((STRINGLIST *, STRINGLIST *));
-extern STRINGLIST *strlist_prefix_suffix __P((STRINGLIST *, char *, char *));
-extern void strlist_print __P((STRINGLIST *, char *));
-extern void strlist_walk __P((STRINGLIST *, sh_strlist_map_func_t *));
-extern void strlist_sort __P((STRINGLIST *));
-
-/* declarations for functions defined in lib/sh/stringvec.c */
-
-extern char **strvec_create __P((int));
-extern char **strvec_resize __P((char **, int));
-extern void strvec_flush __P((char **));
-extern void strvec_dispose __P((char **));
-extern int strvec_remove __P((char **, char *));
-extern int strvec_len __P((char **));
-extern int strvec_search __P((char **, char *));
-extern char **strvec_copy __P((char **));
-extern int strvec_strcmp __P((char **, char **));
-extern void strvec_sort __P((char **));
-
-extern char **strvec_from_word_list __P((WORD_LIST *, int, int, int *));
-extern WORD_LIST *strvec_to_word_list __P((char **, int, int));
-
-/* declarations for functions defined in lib/sh/strnlen.c */
-#if !defined (HAVE_STRNLEN)
-extern size_t strnlen __P((const char *, size_t));
-#endif
-
-/* declarations for functions defined in lib/sh/strpbrk.c */
-#if !defined (HAVE_STRPBRK)
-extern char *strpbrk __P((const char *, const char *));
-#endif
-
-/* declarations for functions defined in lib/sh/strtod.c */
-#if !defined (HAVE_STRTOD)
-extern double strtod __P((const char *, char **));
-#endif
-
-/* declarations for functions defined in lib/sh/strtol.c */
-#if !HAVE_DECL_STRTOL
-extern long strtol __P((const char *, char **, int));
-#endif
-
-/* declarations for functions defined in lib/sh/strtoll.c */
-#if defined (HAVE_LONG_LONG) && !HAVE_DECL_STRTOLL
-extern long long strtoll __P((const char *, char **, int));
-#endif
-
-/* declarations for functions defined in lib/sh/strtoul.c */
-#if !HAVE_DECL_STRTOUL
-extern unsigned long strtoul __P((const char *, char **, int));
-#endif
-
-/* declarations for functions defined in lib/sh/strtoull.c */
-#if defined (HAVE_LONG_LONG) && !HAVE_DECL_STRTOULL
-extern unsigned long long strtoull __P((const char *, char **, int));
-#endif
-
-/* declarations for functions defined in lib/sh/strimax.c */
-#if !HAVE_DECL_STRTOIMAX
-extern intmax_t strtoimax __P((const char *, char **, int));
-#endif
-
-/* declarations for functions defined in lib/sh/strumax.c */
-#if !HAVE_DECL_STRTOUMAX
-extern uintmax_t strtoumax __P((const char *, char **, int));
-#endif
-
-/* declarations for functions defined in lib/sh/strtrans.c */
-extern char *ansicstr __P((char *, int, int, int *, int *));
-extern char *ansic_quote __P((char *, int, int *));
-extern int ansic_shouldquote __P((const char *));
-extern char *ansiexpand __P((char *, int, int, int *));
-
-/* declarations for functions defined in lib/sh/timeval.c.  No prototypes
-   so we don't have to count on having a definition of struct timeval in
-   scope when this file is included. */
-extern void timeval_to_secs ();
-extern void print_timeval ();
-
-/* declarations for functions defined in lib/sh/tmpfile.c */
-#define MT_USETMPDIR           0x0001
-#define MT_READWRITE           0x0002
-#define MT_USERANDOM           0x0004
-
-extern char *sh_mktmpname __P((char *, int));
-extern int sh_mktmpfd __P((char *, int, char **));
-/* extern FILE *sh_mktmpfp __P((char *, int, char **)); */
-
-/* declarations for functions defined in lib/sh/uconvert.c */
-extern int uconvert __P((char *, long *, long *));
-
-/* declarations for functions defined in lib/sh/ufuncs.c */
-extern unsigned int falarm __P((unsigned int, unsigned int));
-extern unsigned int fsleep __P((unsigned int, unsigned int));
-
-/* declarations for functions defined in lib/sh/winsize.c */
-extern void get_new_window_size __P((int, int *, int *));
-
-/* declarations for functions defined in lib/sh/zcatfd.c */
-extern int zcatfd __P((int, int, char *));
-
-/* declarations for functions defined in lib/sh/zgetline.c */
-extern ssize_t zgetline __P((int, char **, size_t *, int));
-
-/* declarations for functions defined in lib/sh/zmapfd.c */
-extern int zmapfd __P((int, char **, char *));
-
-/* declarations for functions defined in lib/sh/zread.c */
-extern ssize_t zread __P((int, char *, size_t));
-extern ssize_t zreadretry __P((int, char *, size_t));
-extern ssize_t zreadintr __P((int, char *, size_t));
-extern ssize_t zreadc __P((int, char *));
-extern ssize_t zreadcintr __P((int, char *));
-extern void zreset __P((void));
-extern void zsyncfd __P((int));
-
-/* declarations for functions defined in lib/sh/zwrite.c */
-extern int zwrite __P((int, char *, size_t));
-
-#endif /* _EXTERNS_H_ */
diff --git a/findcmd.c~ b/findcmd.c~
deleted file mode 100644 (file)
index 07c6a13..0000000
+++ /dev/null
@@ -1,607 +0,0 @@
-/* findcmd.c -- Functions to search for commands by name. */
-
-/* Copyright (C) 1997-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/>.
-*/
-
-#include "config.h"
-
-#include <stdio.h>
-#include "chartypes.h"
-#include "bashtypes.h"
-#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H)
-#  include <sys/file.h>
-#endif
-#include "filecntl.h"
-#include "posixstat.h"
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include "bashansi.h"
-
-#include "memalloc.h"
-#include "shell.h"
-#include "flags.h"
-#include "hashlib.h"
-#include "pathexp.h"
-#include "hashcmd.h"
-#include "findcmd.h"   /* matching prototypes and declarations */
-
-extern int posixly_correct;
-
-/* Static functions defined and used in this file. */
-static char *_find_user_command_internal __P((const char *, int));
-static char *find_user_command_internal __P((const char *, int));
-static char *find_user_command_in_path __P((const char *, char *, int));
-static char *find_in_path_element __P((const char *, char *, int, int, struct stat *));
-static char *find_absolute_program __P((const char *, int));
-
-static char *get_next_path_element __P((char *, int *));
-
-/* The file name which we would try to execute, except that it isn't
-   possible to execute it.  This is the first file that matches the
-   name that we are looking for while we are searching $PATH for a
-   suitable one to execute.  If we cannot find a suitable executable
-   file, then we use this one. */
-static char *file_to_lose_on;
-
-/* Non-zero if we should stat every command found in the hash table to
-   make sure it still exists. */
-int check_hashed_filenames;
-
-/* DOT_FOUND_IN_SEARCH becomes non-zero when find_user_command ()
-   encounters a `.' as the directory pathname while scanning the
-   list of possible pathnames; i.e., if `.' comes before the directory
-   containing the file of interest. */
-int dot_found_in_search = 0;
-
-/* Return some flags based on information about this file.
-   The EXISTS bit is non-zero if the file is found.
-   The EXECABLE bit is non-zero the file is executble.
-   Zero is returned if the file is not found. */
-int
-file_status (name)
-     const char *name;
-{
-  struct stat finfo;
-  int r;
-
-  /* Determine whether this file exists or not. */
-  if (stat (name, &finfo) < 0)
-    return (0);
-
-  /* If the file is a directory, then it is not "executable" in the
-     sense of the shell. */
-  if (S_ISDIR (finfo.st_mode))
-    return (FS_EXISTS|FS_DIRECTORY);
-
-  r = FS_EXISTS;
-
-#if defined (HAVE_EACCESS)
-  /* Use eaccess(2) if we have it to take things like ACLs and other
-     file access mechanisms into account.  eaccess uses the effective
-     user and group IDs, not the real ones. */
-  if (eaccess (name, X_OK) == 0)
-    r |= FS_EXECABLE;
-  if (eaccess (name, R_OK) == 0)
-    r |= FS_READABLE;
-
-  return r;
-#elif defined (AFS)
-  /* We have to use access(2) to determine access because AFS does not
-     support Unix file system semantics.  This may produce wrong
-     answers for non-AFS files when ruid != euid.  I hate AFS. */
-  if (access (name, X_OK) == 0)
-    r |= FS_EXECABLE;
-  if (access (name, R_OK) == 0)
-    r |= FS_READABLE;
-
-  return r;
-#else /* !HAVE_EACCESS && !AFS */
-
-  /* Find out if the file is actually executable.  By definition, the
-     only other criteria is that the file has an execute bit set that
-     we can use.  The same with whether or not a file is readable. */
-
-  /* Root only requires execute permission for any of owner, group or
-     others to be able to exec a file, and can read any file. */
-  if (current_user.euid == (uid_t)0)
-    {
-      r |= FS_READABLE;
-      if (finfo.st_mode & S_IXUGO)
-       r |= FS_EXECABLE;
-      return r;
-    }
-
-  /* If we are the owner of the file, the owner bits apply. */
-  if (current_user.euid == finfo.st_uid)
-    {
-      if (finfo.st_mode & S_IXUSR)
-       r |= FS_EXECABLE;
-      if (finfo.st_mode & S_IRUSR)
-       r |= FS_READABLE;
-    }
-
-  /* If we are in the owning group, the group permissions apply. */
-  else if (group_member (finfo.st_gid))
-    {
-      if (finfo.st_mode & S_IXGRP)
-       r |= FS_EXECABLE;
-      if (finfo.st_mode & S_IRGRP)
-       r |= FS_READABLE;
-    }
-
-  /* Else we check whether `others' have permission to execute the file */
-  else
-    {
-      if (finfo.st_mode & S_IXOTH)
-       r |= FS_EXECABLE;
-      if (finfo.st_mode & S_IROTH)
-       r |= FS_READABLE;
-    }
-
-  return r;
-#endif /* !AFS */
-}
-
-/* Return non-zero if FILE exists and is executable.
-   Note that this function is the definition of what an
-   executable file is; do not change this unless YOU know
-   what an executable file is. */
-int
-executable_file (file)
-     const char *file;
-{
-  int s;
-
-  s = file_status (file);
-  return ((s & FS_EXECABLE) && ((s & FS_DIRECTORY) == 0));
-}
-
-int
-is_directory (file)
-     const char *file;
-{
-  return (file_status (file) & FS_DIRECTORY);
-}
-
-int
-executable_or_directory (file)
-     const char *file;
-{
-  int s;
-
-  s = file_status (file);
-  return ((s & FS_EXECABLE) || (s & FS_DIRECTORY));
-}
-
-/* Locate the executable file referenced by NAME, searching along
-   the contents of the shell PATH variable.  Return a new string
-   which is the full pathname to the file, or NULL if the file
-   couldn't be found.  If a file is found that isn't executable,
-   and that is the only match, then return that. */
-char *
-find_user_command (name)
-     const char *name;
-{
-  return (find_user_command_internal (name, FS_EXEC_PREFERRED|FS_NODIRS));
-}
-
-/* Locate the file referenced by NAME, searching along the contents
-   of the shell PATH variable.  Return a new string which is the full
-   pathname to the file, or NULL if the file couldn't be found.  This
-   returns the first readable file found; designed to be used to look
-   for shell scripts or files to source. */
-char *
-find_path_file (name)
-     const char *name;
-{
-  return (find_user_command_internal (name, FS_READABLE));
-}
-
-static char *
-_find_user_command_internal (name, flags)
-     const char *name;
-     int flags;
-{
-  char *path_list, *cmd;
-  SHELL_VAR *var;
-
-  /* Search for the value of PATH in both the temporary environments and
-     in the regular list of variables. */
-  if (var = find_variable_internal ("PATH", 1))        /* XXX could be array? */
-    path_list = value_cell (var);
-  else
-    path_list = (char *)NULL;
-
-  if (path_list == 0 || *path_list == '\0')
-    return (savestring (name));
-
-  cmd = find_user_command_in_path (name, path_list, flags);
-
-  return (cmd);
-}
-
-static char *
-find_user_command_internal (name, flags)
-     const char *name;
-     int flags;
-{
-#ifdef __WIN32__
-  char *res, *dotexe;
-
-  dotexe = (char *)xmalloc (strlen (name) + 5);
-  strcpy (dotexe, name);
-  strcat (dotexe, ".exe");
-  res = _find_user_command_internal (dotexe, flags);
-  free (dotexe);
-  if (res == 0)
-    res = _find_user_command_internal (name, flags);
-  return res;
-#else
-  return (_find_user_command_internal (name, flags));
-#endif
-}
-
-/* Return the next element from PATH_LIST, a colon separated list of
-   paths.  PATH_INDEX_POINTER is the address of an index into PATH_LIST;
-   the index is modified by this function.
-   Return the next element of PATH_LIST or NULL if there are no more. */
-static char *
-get_next_path_element (path_list, path_index_pointer)
-     char *path_list;
-     int *path_index_pointer;
-{
-  char *path;
-
-  path = extract_colon_unit (path_list, path_index_pointer);
-
-  if (path == 0)
-    return (path);
-
-  if (*path == '\0')
-    {
-      free (path);
-      path = savestring (".");
-    }
-
-  return (path);
-}
-
-/* Look for PATHNAME in $PATH.  Returns either the hashed command
-   corresponding to PATHNAME or the first instance of PATHNAME found
-   in $PATH.  Returns a newly-allocated string. */
-char *
-search_for_command (pathname)
-     const char *pathname;
-{
-  char *hashed_file, *command;
-  int temp_path, st;
-  SHELL_VAR *path;
-
-  hashed_file = command = (char *)NULL;
-
-  /* If PATH is in the temporary environment for this command, don't use the
-     hash table to search for the full pathname. */
-  path = find_variable_internal ("PATH", 1);
-  temp_path = path && tempvar_p (path);
-  if (temp_path == 0 && path)
-    path = (SHELL_VAR *)NULL;
-
-  /* Don't waste time trying to find hashed data for a pathname
-     that is already completely specified or if we're using a command-
-     specific value for PATH. */
-  if (path == 0 && absolute_program (pathname) == 0)
-    hashed_file = phash_search (pathname);
-
-  /* If a command found in the hash table no longer exists, we need to
-     look for it in $PATH.  Thank you Posix.2.  This forces us to stat
-     every command found in the hash table. */
-
-  if (hashed_file && (posixly_correct || check_hashed_filenames))
-    {
-      st = file_status (hashed_file);
-      if ((st & (FS_EXISTS|FS_EXECABLE)) != (FS_EXISTS|FS_EXECABLE))
-       {
-         phash_remove (pathname);
-         free (hashed_file);
-         hashed_file = (char *)NULL;
-       }
-    }
-
-  if (hashed_file)
-    command = hashed_file;
-  else if (absolute_program (pathname))
-    /* A command containing a slash is not looked up in PATH or saved in
-       the hash table. */
-    command = savestring (pathname);
-  else
-    {
-      /* If $PATH is in the temporary environment, we've already retrieved
-        it, so don't bother trying again. */
-      if (temp_path)
-       {
-         command = find_user_command_in_path (pathname, value_cell (path),
-                                              FS_EXEC_PREFERRED|FS_NODIRS);
-       }
-      else
-       command = find_user_command (pathname);
-      if (command && hashing_enabled && temp_path == 0)
-       phash_insert ((char *)pathname, command, dot_found_in_search, 1);       /* XXX fix const later */
-    }
-  return (command);
-}
-
-char *
-user_command_matches (name, flags, state)
-     const char *name;
-     int flags, state;
-{
-  register int i;
-  int  path_index, name_len;
-  char *path_list, *path_element, *match;
-  struct stat dotinfo;
-  static char **match_list = NULL;
-  static int match_list_size = 0;
-  static int match_index = 0;
-
-  if (state == 0)
-    {
-      /* Create the list of matches. */
-      if (match_list == 0)
-       {
-         match_list_size = 5;
-         match_list = strvec_create (match_list_size);
-       }
-
-      /* Clear out the old match list. */
-      for (i = 0; i < match_list_size; i++)
-       match_list[i] = 0;
-
-      /* We haven't found any files yet. */
-      match_index = 0;
-
-      if (absolute_program (name))
-       {
-         match_list[0] = find_absolute_program (name, flags);
-         match_list[1] = (char *)NULL;
-         path_list = (char *)NULL;
-       }
-      else
-       {
-         name_len = strlen (name);
-         file_to_lose_on = (char *)NULL;
-         dot_found_in_search = 0;
-         stat (".", &dotinfo);
-         path_list = get_string_value ("PATH");
-         path_index = 0;
-       }
-
-      while (path_list && path_list[path_index])
-       {
-         path_element = get_next_path_element (path_list, &path_index);
-
-         if (path_element == 0)
-           break;
-
-         match = find_in_path_element (name, path_element, flags, name_len, &dotinfo);
-
-         free (path_element);
-
-         if (match == 0)
-           continue;
-
-         if (match_index + 1 == match_list_size)
-           {
-             match_list_size += 10;
-             match_list = strvec_resize (match_list, (match_list_size + 1));
-           }
-
-         match_list[match_index++] = match;
-         match_list[match_index] = (char *)NULL;
-         FREE (file_to_lose_on);
-         file_to_lose_on = (char *)NULL;
-       }
-
-      /* We haven't returned any strings yet. */
-      match_index = 0;
-    }
-
-  match = match_list[match_index];
-
-  if (match)
-    match_index++;
-
-  return (match);
-}
-
-static char *
-find_absolute_program (name, flags)
-     const char *name;
-     int flags;
-{
-  int st;
-
-  st = file_status (name);
-
-  /* If the file doesn't exist, quit now. */
-  if ((st & FS_EXISTS) == 0)
-    return ((char *)NULL);
-
-  /* If we only care about whether the file exists or not, return
-     this filename.  Otherwise, maybe we care about whether this
-     file is executable.  If it is, and that is what we want, return it. */
-  if ((flags & FS_EXISTS) || ((flags & FS_EXEC_ONLY) && (st & FS_EXECABLE)))
-    return (savestring (name));
-
-  return (NULL);
-}
-
-static char *
-find_in_path_element (name, path, flags, name_len, dotinfop)
-     const char *name;
-     char *path;
-     int flags, name_len;
-     struct stat *dotinfop;
-{
-  int status;
-  char *full_path, *xpath;
-
-  xpath = (*path == '~') ? bash_tilde_expand (path, 0) : path;
-
-  /* Remember the location of "." in the path, in all its forms
-     (as long as they begin with a `.', e.g. `./.') */
-  if (dot_found_in_search == 0 && *xpath == '.')
-    dot_found_in_search = same_file (".", xpath, dotinfop, (struct stat *)NULL);
-
-  full_path = sh_makepath (xpath, name, 0);
-
-  status = file_status (full_path);
-
-  if (xpath != path)
-    free (xpath);
-
-  if ((status & FS_EXISTS) == 0)
-    {
-      free (full_path);
-      return ((char *)NULL);
-    }
-
-  /* The file exists.  If the caller simply wants the first file, here it is. */
-  if (flags & FS_EXISTS)
-    return (full_path);
-
-  /* If we have a readable file, and the caller wants a readable file, this
-     is it. */
-  if ((flags & FS_READABLE) && (status & FS_READABLE))
-    return (full_path);
-
-  /* If the file is executable, then it satisfies the cases of
-      EXEC_ONLY and EXEC_PREFERRED.  Return this file unconditionally. */
-  if ((status & FS_EXECABLE) && (flags & (FS_EXEC_ONLY|FS_EXEC_PREFERRED)) &&
-      (((flags & FS_NODIRS) == 0) || ((status & FS_DIRECTORY) == 0)))
-    {
-      FREE (file_to_lose_on);
-      file_to_lose_on = (char *)NULL;
-      return (full_path);
-    }
-
-  /* The file is not executable, but it does exist.  If we prefer
-     an executable, then remember this one if it is the first one
-     we have found. */
-  if ((flags & FS_EXEC_PREFERRED) && file_to_lose_on == 0)
-    file_to_lose_on = savestring (full_path);
-
-  /* If we want only executable files, or we don't want directories and
-     this file is a directory, or we want a readable file and this file
-     isn't readable, fail. */
-  if ((flags & (FS_EXEC_ONLY|FS_EXEC_PREFERRED)) ||
-      ((flags & FS_NODIRS) && (status & FS_DIRECTORY)) ||
-      ((flags & FS_READABLE) && (status & FS_READABLE) == 0))
-    {
-      free (full_path);
-      return ((char *)NULL);
-    }
-  else
-    return (full_path);
-}
-
-/* This does the dirty work for find_user_command_internal () and
-   user_command_matches ().
-   NAME is the name of the file to search for.
-   PATH_LIST is a colon separated list of directories to search.
-   FLAGS contains bit fields which control the files which are eligible.
-   Some values are:
-      FS_EXEC_ONLY:            The file must be an executable to be found.
-      FS_EXEC_PREFERRED:       If we can't find an executable, then the
-                               the first file matching NAME will do.
-      FS_EXISTS:               The first file found will do.
-      FS_NODIRS:               Don't find any directories.
-*/
-static char *
-find_user_command_in_path (name, path_list, flags)
-     const char *name;
-     char *path_list;
-     int flags;
-{
-  char *full_path, *path;
-  int path_index, name_len;
-  struct stat dotinfo;
-
-  /* We haven't started looking, so we certainly haven't seen
-     a `.' as the directory path yet. */
-  dot_found_in_search = 0;
-
-  if (absolute_program (name))
-    {
-      full_path = find_absolute_program (name, flags);
-      return (full_path);
-    }
-
-  if (path_list == 0 || *path_list == '\0')
-    return (savestring (name));                /* XXX */
-
-  file_to_lose_on = (char *)NULL;
-  name_len = strlen (name);
-  stat (".", &dotinfo);
-  path_index = 0;
-
-  while (path_list[path_index])
-    {
-      /* Allow the user to interrupt out of a lengthy path search. */
-      QUIT;
-
-      path = get_next_path_element (path_list, &path_index);
-      if (path == 0)
-       break;
-
-      /* Side effects: sets dot_found_in_search, possibly sets
-        file_to_lose_on. */
-      full_path = find_in_path_element (name, path, flags, name_len, &dotinfo);
-      free (path);
-
-      /* This should really be in find_in_path_element, but there isn't the
-        right combination of flags. */
-      if (full_path && is_directory (full_path))
-       {
-         free (full_path);
-         continue;
-       }
-
-      if (full_path)
-       {
-         FREE (file_to_lose_on);
-         return (full_path);
-       }
-    }
-
-  /* We didn't find exactly what the user was looking for.  Return
-     the contents of FILE_TO_LOSE_ON which is NULL when the search
-     required an executable, or non-NULL if a file was found and the
-     search would accept a non-executable as a last resort.  If the
-     caller specified FS_NODIRS, and file_to_lose_on is a directory,
-     return NULL. */
-  if (file_to_lose_on && (flags & FS_NODIRS) && is_directory (file_to_lose_on))
-    {
-      free (file_to_lose_on);
-      file_to_lose_on = (char *)NULL;
-    }
-
-  return (file_to_lose_on);
-}
diff --git a/general.c~ b/general.c~
deleted file mode 100644 (file)
index 36b2f5b..0000000
+++ /dev/null
@@ -1,1136 +0,0 @@
-/* general.c -- Stuff that is used by all files. */
-
-/* Copyright (C) 1987-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/>.
-*/
-
-#include "config.h"
-
-#include "bashtypes.h"
-#ifndef _MINIX
-#  include <sys/param.h>
-#endif
-#include "posixstat.h"
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include "filecntl.h"
-#include "bashansi.h"
-#include <stdio.h>
-#include "chartypes.h"
-#include <errno.h>
-
-#include "bashintl.h"
-
-#include "shell.h"
-#include "test.h"
-
-#include <tilde/tilde.h>
-
-#if !defined (errno)
-extern int errno;
-#endif /* !errno */
-
-extern int expand_aliases;
-extern int interactive_comments;
-extern int check_hashed_filenames;
-extern int source_uses_path;
-extern int source_searches_cwd;
-
-static char *bash_special_tilde_expansions __P((char *));
-static int unquoted_tilde_word __P((const char *));
-static void initialize_group_array __P((void));
-
-/* A standard error message to use when getcwd() returns NULL. */
-const char * const bash_getcwd_errstr = N_("getcwd: cannot access parent directories");
-
-/* Do whatever is necessary to initialize `Posix mode'. */
-void
-posix_initialize (on)
-     int on;
-{
-  /* Things that should be turned on when posix mode is enabled. */
-  if (on != 0)
-    {
-      interactive_comments = source_uses_path = expand_aliases = 1;
-      source_searches_cwd = 0;
-    }
-
-  /* Things that should be turned on when posix mode is disabled. */
-  if (on == 0)
-    {
-      source_searches_cwd = 1;
-      expand_aliases = interactive_shell;
-    }
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*  Functions to convert to and from and display non-standard types */
-/*                                                                 */
-/* **************************************************************** */
-
-#if defined (RLIMTYPE)
-RLIMTYPE
-string_to_rlimtype (s)
-     char *s;
-{
-  RLIMTYPE ret;
-  int neg;
-
-  ret = 0;
-  neg = 0;
-  while (s && *s && whitespace (*s))
-    s++;
-  if (s && (*s == '-' || *s == '+'))
-    {
-      neg = *s == '-';
-      s++;
-    }
-  for ( ; s && *s && DIGIT (*s); s++)
-    ret = (ret * 10) + TODIGIT (*s);
-  return (neg ? -ret : ret);
-}
-
-void
-print_rlimtype (n, addnl)
-     RLIMTYPE n;
-     int addnl;
-{
-  char s[INT_STRLEN_BOUND (RLIMTYPE) + 1], *p;
-
-  p = s + sizeof(s);
-  *--p = '\0';
-
-  if (n < 0)
-    {
-      do
-       *--p = '0' - n % 10;
-      while ((n /= 10) != 0);
-
-      *--p = '-';
-    }
-  else
-    {
-      do
-       *--p = '0' + n % 10;
-      while ((n /= 10) != 0);
-    }
-
-  printf ("%s%s", p, addnl ? "\n" : "");
-}
-#endif /* RLIMTYPE */
-
-/* **************************************************************** */
-/*                                                                 */
-/*                    Input Validation Functions                   */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Return non-zero if all of the characters in STRING are digits. */
-int
-all_digits (string)
-     char *string;
-{
-  register char *s;
-
-  for (s = string; *s; s++)
-    if (DIGIT (*s) == 0)
-      return (0);
-
-  return (1);
-}
-
-/* Return non-zero if the characters pointed to by STRING constitute a
-   valid number.  Stuff the converted number into RESULT if RESULT is
-   not null. */
-int
-legal_number (string, result)
-     const char *string;
-     intmax_t *result;
-{
-  intmax_t value;
-  char *ep;
-
-  if (result)
-    *result = 0;
-
-  errno = 0;
-  value = strtoimax (string, &ep, 10);
-  if (errno || ep == string)
-    return 0;  /* errno is set on overflow or underflow */
-
-  /* Skip any trailing whitespace, since strtoimax does not. */
-  while (whitespace (*ep))
-    ep++;
-
-  /* If *string is not '\0' but *ep is '\0' on return, the entire string
-     is valid. */
-  if (string && *string && *ep == '\0')
-    {
-      if (result)
-       *result = value;
-      /* The SunOS4 implementation of strtol() will happily ignore
-        overflow conditions, so this cannot do overflow correctly
-        on those systems. */
-      return 1;
-    }
-    
-  return (0);
-}
-
-/* Return 1 if this token is a legal shell `identifier'; that is, it consists
-   solely of letters, digits, and underscores, and does not begin with a
-   digit. */
-int
-legal_identifier (name)
-     char *name;
-{
-  register char *s;
-  unsigned char c;
-
-  if (!name || !(c = *name) || (legal_variable_starter (c) == 0))
-    return (0);
-
-  for (s = name + 1; (c = *s) != 0; s++)
-    {
-      if (legal_variable_char (c) == 0)
-       return (0);
-    }
-  return (1);
-}
-
-/* Make sure that WORD is a valid shell identifier, i.e.
-   does not contain a dollar sign, nor is quoted in any way.  Nor
-   does it consist of all digits.  If CHECK_WORD is non-zero,
-   the word is checked to ensure that it consists of only letters,
-   digits, and underscores. */
-int
-check_identifier (word, check_word)
-     WORD_DESC *word;
-     int check_word;
-{
-  if ((word->flags & (W_HASDOLLAR|W_QUOTED)) || all_digits (word->word))
-    {
-      internal_error (_("`%s': not a valid identifier"), word->word);
-      return (0);
-    }
-  else if (check_word && legal_identifier (word->word) == 0)
-    {
-      internal_error (_("`%s': not a valid identifier"), word->word);
-      return (0);
-    }
-  else
-    return (1);
-}
-
-/* Return 1 if STRING comprises a valid alias name.  The shell accepts
-   essentially all characters except those which must be quoted to the
-   parser (which disqualifies them from alias expansion anyway) and `/'. */
-int
-legal_alias_name (string, flags)
-     char *string;
-     int flags;
-{
-  register char *s;
-
-  for (s = string; *s; s++)
-    if (shellbreak (*s) || shellxquote (*s) || shellexp (*s) || (*s == '/'))
-      return 0;
-  return 1;
-}
-
-/* Returns non-zero if STRING is an assignment statement.  The returned value
-   is the index of the `=' sign. */
-int
-assignment (string, flags)
-     const char *string;
-     int flags;
-{
-  register unsigned char c;
-  register int newi, indx;
-
-  c = string[indx = 0];
-
-#if defined (ARRAY_VARS)
-  if ((legal_variable_starter (c) == 0) && (flags == 0 || c != '[')) /* ] */
-#else
-  if (legal_variable_starter (c) == 0)
-#endif
-    return (0);
-
-  while (c = string[indx])
-    {
-      /* The following is safe.  Note that '=' at the start of a word
-        is not an assignment statement. */
-      if (c == '=')
-       return (indx);
-
-#if defined (ARRAY_VARS)
-      if (c == '[')
-       {
-         newi = skipsubscript (string, indx, 0);
-         if (string[newi++] != ']')
-           return (0);
-         if (string[newi] == '+' && string[newi+1] == '=')
-           return (newi + 1);
-         return ((string[newi] == '=') ? newi : 0);
-       }
-#endif /* ARRAY_VARS */
-
-      /* Check for `+=' */
-      if (c == '+' && string[indx+1] == '=')
-       return (indx + 1);
-
-      /* Variable names in assignment statements may contain only letters,
-        digits, and `_'. */
-      if (legal_variable_char (c) == 0)
-       return (0);
-
-      indx++;
-    }
-  return (0);
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*          Functions to manage files and file descriptors         */
-/*                                                                 */
-/* **************************************************************** */
-
-/* A function to unset no-delay mode on a file descriptor.  Used in shell.c
-   to unset it on the fd passed as stdin.  Should be called on stdin if
-   readline gets an EAGAIN or EWOULDBLOCK when trying to read input. */
-
-#if !defined (O_NDELAY)
-#  if defined (FNDELAY)
-#    define O_NDELAY FNDELAY
-#  endif
-#endif /* O_NDELAY */
-
-/* Make sure no-delay mode is not set on file descriptor FD. */
-int
-sh_unset_nodelay_mode (fd)
-     int fd;
-{
-  int flags, bflags;
-
-  if ((flags = fcntl (fd, F_GETFL, 0)) < 0)
-    return -1;
-
-  bflags = 0;
-
-  /* This is defined to O_NDELAY in filecntl.h if O_NONBLOCK is not present
-     and O_NDELAY is defined. */
-#ifdef O_NONBLOCK
-  bflags |= O_NONBLOCK;
-#endif
-
-#ifdef O_NDELAY
-  bflags |= O_NDELAY;
-#endif
-
-  if (flags & bflags)
-    {
-      flags &= ~bflags;
-      return (fcntl (fd, F_SETFL, flags));
-    }
-
-  return 0;
-}
-
-/* Return 1 if file descriptor FD is valid; 0 otherwise. */
-int
-sh_validfd (fd)
-     int fd;
-{
-  return (fcntl (fd, F_GETFD, 0) >= 0);
-}
-
-/* There is a bug in the NeXT 2.1 rlogind that causes opens
-   of /dev/tty to fail. */
-
-#if defined (__BEOS__)
-/* On BeOS, opening in non-blocking mode exposes a bug in BeOS, so turn it
-   into a no-op.  This should probably go away in the future. */
-#  undef O_NONBLOCK
-#  define O_NONBLOCK 0
-#endif /* __BEOS__ */
-
-void
-check_dev_tty ()
-{
-  int tty_fd;
-  char *tty;
-
-  tty_fd = open ("/dev/tty", O_RDWR|O_NONBLOCK);
-
-  if (tty_fd < 0)
-    {
-      tty = (char *)ttyname (fileno (stdin));
-      if (tty == 0)
-       return;
-      tty_fd = open (tty, O_RDWR|O_NONBLOCK);
-    }
-  close (tty_fd);
-}
-
-/* Return 1 if PATH1 and PATH2 are the same file.  This is kind of
-   expensive.  If non-NULL STP1 and STP2 point to stat structures
-   corresponding to PATH1 and PATH2, respectively. */
-int
-same_file (path1, path2, stp1, stp2)
-     char *path1, *path2;
-     struct stat *stp1, *stp2;
-{
-  struct stat st1, st2;
-
-  if (stp1 == NULL)
-    {
-      if (stat (path1, &st1) != 0)
-       return (0);
-      stp1 = &st1;
-    }
-
-  if (stp2 == NULL)
-    {
-      if (stat (path2, &st2) != 0)
-       return (0);
-      stp2 = &st2;
-    }
-
-  return ((stp1->st_dev == stp2->st_dev) && (stp1->st_ino == stp2->st_ino));
-}
-
-/* Move FD to a number close to the maximum number of file descriptors
-   allowed in the shell process, to avoid the user stepping on it with
-   redirection and causing us extra work.  If CHECK_NEW is non-zero,
-   we check whether or not the file descriptors are in use before
-   duplicating FD onto them.  MAXFD says where to start checking the
-   file descriptors.  If it's less than 20, we get the maximum value
-   available from getdtablesize(2). */
-int
-move_to_high_fd (fd, check_new, maxfd)
-     int fd, check_new, maxfd;
-{
-  int script_fd, nfds, ignore;
-
-  if (maxfd < 20)
-    {
-      nfds = getdtablesize ();
-      if (nfds <= 0)
-       nfds = 20;
-      if (nfds > HIGH_FD_MAX)
-       nfds = HIGH_FD_MAX;             /* reasonable maximum */
-    }
-  else
-    nfds = maxfd;
-
-  for (nfds--; check_new && nfds > 3; nfds--)
-    if (fcntl (nfds, F_GETFD, &ignore) == -1)
-      break;
-
-  if (nfds > 3 && fd != nfds && (script_fd = dup2 (fd, nfds)) != -1)
-    {
-      if (check_new == 0 || fd != fileno (stderr))     /* don't close stderr */
-       close (fd);
-      return (script_fd);
-    }
-
-  /* OK, we didn't find one less than our artificial maximum; return the
-     original file descriptor. */
-  return (fd);
-}
-/* Return non-zero if the characters from SAMPLE are not all valid
-   characters to be found in the first line of a shell script.  We
-   check up to the first newline, or SAMPLE_LEN, whichever comes first.
-   All of the characters must be printable or whitespace. */
-
-int
-check_binary_file (sample, sample_len)
-     char *sample;
-     int sample_len;
-{
-  register int i;
-  unsigned char c;
-
-  for (i = 0; i < sample_len; i++)
-    {
-      c = sample[i];
-      if (c == '\n')
-       return (0);
-      if (c == '\0')
-       return (1);
-    }
-
-  return (0);
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*                 Functions to manipulate pipes                   */
-/*                                                                 */
-/* **************************************************************** */
-
-int
-sh_openpipe (pv)
-     int *pv;
-{
-  int r;
-
-  if ((r = pipe (pv)) < 0)
-    return r;
-
-  pv[0] = move_to_high_fd (pv[0], 1, 64);
-  pv[1] = move_to_high_fd (pv[1], 1, 64);
-
-  return 0;  
-}
-
-int
-sh_closepipe (pv)
-     int *pv;
-{
-  if (pv[0] >= 0)
-    close (pv[0]);
-
-  if (pv[1] >= 0)
-    close (pv[1]);
-
-  pv[0] = pv[1] = -1;
-  return 0;
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*                 Functions to inspect pathnames                  */
-/*                                                                 */
-/* **************************************************************** */
-
-int
-file_exists (fn)
-     char *fn;
-{
-  struct stat sb;
-
-  return (stat (fn, &sb) == 0);
-}
-
-int
-file_isdir (fn)
-     char *fn;
-{
-  struct stat sb;
-
-  return ((stat (fn, &sb) == 0) && S_ISDIR (sb.st_mode));
-}
-
-int
-file_iswdir (fn)
-     char *fn;
-{
-  return (file_isdir (fn) && sh_eaccess (fn, W_OK) == 0);
-}
-
-/* Return 1 if STRING contains an absolute pathname, else 0.  Used by `cd'
-   to decide whether or not to look up a directory name in $CDPATH. */
-int
-absolute_pathname (string)
-     const char *string;
-{
-  if (string == 0 || *string == '\0')
-    return (0);
-
-  if (ABSPATH(string))
-    return (1);
-
-  if (string[0] == '.' && PATHSEP(string[1]))  /* . and ./ */
-    return (1);
-
-  if (string[0] == '.' && string[1] == '.' && PATHSEP(string[2]))      /* .. and ../ */
-    return (1);
-
-  return (0);
-}
-
-/* Return 1 if STRING is an absolute program name; it is absolute if it
-   contains any slashes.  This is used to decide whether or not to look
-   up through $PATH. */
-int
-absolute_program (string)
-     const char *string;
-{
-  return ((char *)mbschr (string, '/') != (char *)NULL);
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*                 Functions to manipulate pathnames               */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Turn STRING (a pathname) into an absolute pathname, assuming that
-   DOT_PATH contains the symbolic location of `.'.  This always
-   returns a new string, even if STRING was an absolute pathname to
-   begin with. */
-char *
-make_absolute (string, dot_path)
-     char *string, *dot_path;
-{
-  char *result;
-
-  if (dot_path == 0 || ABSPATH(string))
-#ifdef __CYGWIN__
-    {
-      char pathbuf[PATH_MAX + 1];
-
-      cygwin_conv_to_full_posix_path (string, pathbuf);
-      result = savestring (pathbuf);
-    }
-#else
-    result = savestring (string);
-#endif
-  else
-    result = sh_makepath (dot_path, string, 0);
-
-  return (result);
-}
-
-/* Return the `basename' of the pathname in STRING (the stuff after the
-   last '/').  If STRING is `/', just return it. */
-char *
-base_pathname (string)
-     char *string;
-{
-  char *p;
-
-#if 0
-  if (absolute_pathname (string) == 0)
-    return (string);
-#endif
-
-  if (string[0] == '/' && string[1] == 0)
-    return (string);
-
-  p = (char *)strrchr (string, '/');
-  return (p ? ++p : string);
-}
-
-/* Return the full pathname of FILE.  Easy.  Filenames that begin
-   with a '/' are returned as themselves.  Other filenames have
-   the current working directory prepended.  A new string is
-   returned in either case. */
-char *
-full_pathname (file)
-     char *file;
-{
-  char *ret;
-
-  file = (*file == '~') ? bash_tilde_expand (file, 0) : savestring (file);
-
-  if (ABSPATH(file))
-    return (file);
-
-  ret = sh_makepath ((char *)NULL, file, (MP_DOCWD|MP_RMDOT));
-  free (file);
-
-  return (ret);
-}
-
-/* A slightly related function.  Get the prettiest name of this
-   directory possible. */
-static char tdir[PATH_MAX];
-
-/* Return a pretty pathname.  If the first part of the pathname is
-   the same as $HOME, then replace that with `~'.  */
-char *
-polite_directory_format (name)
-     char *name;
-{
-  char *home;
-  int l;
-
-  home = get_string_value ("HOME");
-  l = home ? strlen (home) : 0;
-  if (l > 1 && strncmp (home, name, l) == 0 && (!name[l] || name[l] == '/'))
-    {
-      strncpy (tdir + 1, name + l, sizeof(tdir) - 2);
-      tdir[0] = '~';
-      tdir[sizeof(tdir) - 1] = '\0';
-      return (tdir);
-    }
-  else
-    return (name);
-}
-
-/* Trim NAME.  If NAME begins with `~/', skip over tilde prefix.  Trim to
-   keep any tilde prefix and PROMPT_DIRTRIM trailing directory components
-   and replace the intervening characters with `...' */
-char *
-trim_pathname (name, maxlen)
-     char *name;
-     int maxlen;
-{
-  int nlen, ndirs;
-  intmax_t nskip;
-  char *nbeg, *nend, *ntail, *v;
-
-  if (name == 0 || (nlen = strlen (name)) == 0)
-    return name;
-  nend = name + nlen;
-
-  v = get_string_value ("PROMPT_DIRTRIM");
-  if (v == 0 || *v == 0)
-    return name;
-  if (legal_number (v, &nskip) == 0 || nskip <= 0)
-    return name;
-
-  /* Skip over tilde prefix */
-  nbeg = name;
-  if (name[0] == '~')
-    for (nbeg = name; *nbeg; nbeg++)
-      if (*nbeg == '/')
-       {
-         nbeg++;
-         break;
-       }
-  if (*nbeg == 0)
-    return name;
-
-  for (ndirs = 0, ntail = nbeg; *ntail; ntail++)
-    if (*ntail == '/')
-      ndirs++;
-  if (ndirs <= nskip)
-    return name;
-
-  for (ntail = (*nend == '/') ? nend : nend - 1; ntail > nbeg; ntail--)
-    {
-      if (*ntail == '/')
-       nskip--;
-      if (nskip == 0)
-       break;
-    }
-  if (ntail == nbeg)
-    return name;
-
-  /* Now we want to return name[0..nbeg]+"..."+ntail, modifying name in place */
-  nlen = ntail - nbeg;
-  if (nlen <= 3)
-    return name;
-
-  *nbeg++ = '.';
-  *nbeg++ = '.';
-  *nbeg++ = '.';
-
-  nlen = nend - ntail;
-  memcpy (nbeg, ntail, nlen);
-  nbeg[nlen] = '\0';
-
-  return name;
-}
-
-/* Given a string containing units of information separated by colons,
-   return the next one pointed to by (P_INDEX), or NULL if there are no more.
-   Advance (P_INDEX) to the character after the colon. */
-char *
-extract_colon_unit (string, p_index)
-     char *string;
-     int *p_index;
-{
-  int i, start, len;
-  char *value;
-
-  if (string == 0)
-    return (string);
-
-  len = strlen (string);
-  if (*p_index >= len)
-    return ((char *)NULL);
-
-  i = *p_index;
-
-  /* Each call to this routine leaves the index pointing at a colon if
-     there is more to the path.  If I is > 0, then increment past the
-     `:'.  If I is 0, then the path has a leading colon.  Trailing colons
-     are handled OK by the `else' part of the if statement; an empty
-     string is returned in that case. */
-  if (i && string[i] == ':')
-    i++;
-
-  for (start = i; string[i] && string[i] != ':'; i++)
-    ;
-
-  *p_index = i;
-
-  if (i == start)
-    {
-      if (string[i])
-       (*p_index)++;
-      /* Return "" in the case of a trailing `:'. */
-      value = (char *)xmalloc (1);
-      value[0] = '\0';
-    }
-  else
-    value = substring (string, start, i);
-
-  return (value);
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*                 Tilde Initialization and Expansion              */
-/*                                                                 */
-/* **************************************************************** */
-
-#if defined (PUSHD_AND_POPD)
-extern char *get_dirstack_from_string __P((char *));
-#endif
-
-static char **bash_tilde_prefixes;
-static char **bash_tilde_prefixes2;
-static char **bash_tilde_suffixes;
-static char **bash_tilde_suffixes2;
-
-/* If tilde_expand hasn't been able to expand the text, perhaps it
-   is a special shell expansion.  This function is installed as the
-   tilde_expansion_preexpansion_hook.  It knows how to expand ~- and ~+.
-   If PUSHD_AND_POPD is defined, ~[+-]N expands to directories from the
-   directory stack. */
-static char *
-bash_special_tilde_expansions (text)
-     char *text;
-{
-  char *result;
-
-  result = (char *)NULL;
-
-  if (text[0] == '+' && text[1] == '\0')
-    result = get_string_value ("PWD");
-  else if (text[0] == '-' && text[1] == '\0')
-    result = get_string_value ("OLDPWD");
-#if defined (PUSHD_AND_POPD)
-  else if (DIGIT (*text) || ((*text == '+' || *text == '-') && DIGIT (text[1])))
-    result = get_dirstack_from_string (text);
-#endif
-
-  return (result ? savestring (result) : (char *)NULL);
-}
-
-/* Initialize the tilde expander.  In Bash, we handle `~-' and `~+', as
-   well as handling special tilde prefixes; `:~" and `=~' are indications
-   that we should do tilde expansion. */
-void
-tilde_initialize ()
-{
-  static int times_called = 0;
-
-  /* Tell the tilde expander that we want a crack first. */
-  tilde_expansion_preexpansion_hook = bash_special_tilde_expansions;
-
-  /* Tell the tilde expander about special strings which start a tilde
-     expansion, and the special strings that end one.  Only do this once.
-     tilde_initialize () is called from within bashline_reinitialize (). */
-  if (times_called++ == 0)
-    {
-      bash_tilde_prefixes = strvec_create (3);
-      bash_tilde_prefixes[0] = "=~";
-      bash_tilde_prefixes[1] = ":~";
-      bash_tilde_prefixes[2] = (char *)NULL;
-
-      bash_tilde_prefixes2 = strvec_create (2);
-      bash_tilde_prefixes2[0] = ":~";
-      bash_tilde_prefixes2[1] = (char *)NULL;
-
-      tilde_additional_prefixes = bash_tilde_prefixes;
-
-      bash_tilde_suffixes = strvec_create (3);
-      bash_tilde_suffixes[0] = ":";
-      bash_tilde_suffixes[1] = "=~";   /* XXX - ?? */
-      bash_tilde_suffixes[2] = (char *)NULL;
-
-      tilde_additional_suffixes = bash_tilde_suffixes;
-
-      bash_tilde_suffixes2 = strvec_create (2);
-      bash_tilde_suffixes2[0] = ":";
-      bash_tilde_suffixes2[1] = (char *)NULL;
-    }
-}
-
-/* POSIX.2, 3.6.1:  A tilde-prefix consists of an unquoted tilde character
-   at the beginning of the word, followed by all of the characters preceding
-   the first unquoted slash in the word, or all the characters in the word
-   if there is no slash...If none of the characters in the tilde-prefix are
-   quoted, the characters in the tilde-prefix following the tilde shell be
-   treated as a possible login name. */
-
-#define TILDE_END(c)   ((c) == '\0' || (c) == '/' || (c) == ':')
-
-static int
-unquoted_tilde_word (s)
-     const char *s;
-{
-  const char *r;
-
-  for (r = s; TILDE_END(*r) == 0; r++)
-    {
-      switch (*r)
-       {
-       case '\\':
-       case '\'':
-       case '"':
-         return 0;
-       }
-    }
-  return 1;
-}
-
-/* Find the end of the tilde-prefix starting at S, and return the tilde
-   prefix in newly-allocated memory.  Return the length of the string in
-   *LENP.  FLAGS tells whether or not we're in an assignment context --
-   if so, `:' delimits the end of the tilde prefix as well. */
-char *
-bash_tilde_find_word (s, flags, lenp)
-     const char *s;
-     int flags, *lenp;
-{
-  const char *r;
-  char *ret;
-  int l;
-
-  for (r = s; *r && *r != '/'; r++)
-    {
-      /* Short-circuit immediately if we see a quote character.  Even though
-        POSIX says that `the first unquoted slash' (or `:') terminates the
-        tilde-prefix, in practice, any quoted portion of the tilde prefix
-        will cause it to not be expanded. */
-      if (*r == '\\' || *r == '\'' || *r == '"')  
-       {
-         ret = savestring (s);
-         if (lenp)
-           *lenp = 0;
-         return ret;
-       }
-      else if (flags && *r == ':')
-       break;
-    }
-  l = r - s;
-  ret = xmalloc (l + 1);
-  strncpy (ret, s, l);
-  ret[l] = '\0';
-  if (lenp)
-    *lenp = l;
-  return ret;
-}
-    
-/* Tilde-expand S by running it through the tilde expansion library.
-   ASSIGN_P is 1 if this is a variable assignment, so the alternate
-   tilde prefixes should be enabled (`=~' and `:~', see above).  If
-   ASSIGN_P is 2, we are expanding the rhs of an assignment statement,
-   so `=~' is not valid. */
-char *
-bash_tilde_expand (s, assign_p)
-     const char *s;
-     int assign_p;
-{
-  int old_immed, old_term, r;
-  char *ret;
-
-  old_immed = interrupt_immediately;
-  old_term = terminate_immediately;
-  interrupt_immediately = terminate_immediately = 1;
-
-  tilde_additional_prefixes = assign_p == 0 ? (char **)0
-                                           : (assign_p == 2 ? bash_tilde_prefixes2 : bash_tilde_prefixes);
-  if (assign_p == 2)
-    tilde_additional_suffixes = bash_tilde_suffixes2;
-
-  r = (*s == '~') ? unquoted_tilde_word (s) : 1;
-  ret = r ? tilde_expand (s) : savestring (s);
-  interrupt_immediately = old_immed;
-  terminate_immediately = old_term;
-  return (ret);
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*       Functions to manipulate and search the group list         */
-/*                                                                 */
-/* **************************************************************** */
-
-static int ngroups, maxgroups;
-
-/* The set of groups that this user is a member of. */
-static GETGROUPS_T *group_array = (GETGROUPS_T *)NULL;
-
-#if !defined (NOGROUP)
-#  define NOGROUP (gid_t) -1
-#endif
-
-static void
-initialize_group_array ()
-{
-  register int i;
-
-  if (maxgroups == 0)
-    maxgroups = getmaxgroups ();
-
-  ngroups = 0;
-  group_array = (GETGROUPS_T *)xrealloc (group_array, maxgroups * sizeof (GETGROUPS_T));
-
-#if defined (HAVE_GETGROUPS)
-  ngroups = getgroups (maxgroups, group_array);
-#endif
-
-  /* If getgroups returns nothing, or the OS does not support getgroups(),
-     make sure the groups array includes at least the current gid. */
-  if (ngroups == 0)
-    {
-      group_array[0] = current_user.gid;
-      ngroups = 1;
-    }
-
-  /* If the primary group is not in the groups array, add it as group_array[0]
-     and shuffle everything else up 1, if there's room. */
-  for (i = 0; i < ngroups; i++)
-    if (current_user.gid == (gid_t)group_array[i])
-      break;
-  if (i == ngroups && ngroups < maxgroups)
-    {
-      for (i = ngroups; i > 0; i--)
-       group_array[i] = group_array[i - 1];
-      group_array[0] = current_user.gid;
-      ngroups++;
-    }
-
-  /* If the primary group is not group_array[0], swap group_array[0] and
-     whatever the current group is.  The vast majority of systems should
-     not need this; a notable exception is Linux. */
-  if (group_array[0] != current_user.gid)
-    {
-      for (i = 0; i < ngroups; i++)
-       if (group_array[i] == current_user.gid)
-         break;
-      if (i < ngroups)
-       {
-         group_array[i] = group_array[0];
-         group_array[0] = current_user.gid;
-       }
-    }
-}
-
-/* Return non-zero if GID is one that we have in our groups list. */
-int
-#if defined (__STDC__) || defined ( _MINIX)
-group_member (gid_t gid)
-#else
-group_member (gid)
-     gid_t gid;
-#endif /* !__STDC__ && !_MINIX */
-{
-#if defined (HAVE_GETGROUPS)
-  register int i;
-#endif
-
-  /* Short-circuit if possible, maybe saving a call to getgroups(). */
-  if (gid == current_user.gid || gid == current_user.egid)
-    return (1);
-
-#if defined (HAVE_GETGROUPS)
-  if (ngroups == 0)
-    initialize_group_array ();
-
-  /* In case of error, the user loses. */
-  if (ngroups <= 0)
-    return (0);
-
-  /* Search through the list looking for GID. */
-  for (i = 0; i < ngroups; i++)
-    if (gid == (gid_t)group_array[i])
-      return (1);
-#endif
-
-  return (0);
-}
-
-char **
-get_group_list (ngp)
-     int *ngp;
-{
-  static char **group_vector = (char **)NULL;
-  register int i;
-
-  if (group_vector)
-    {
-      if (ngp)
-       *ngp = ngroups;
-      return group_vector;
-    }
-
-  if (ngroups == 0)
-    initialize_group_array ();
-
-  if (ngroups <= 0)
-    {
-      if (ngp)
-       *ngp = 0;
-      return (char **)NULL;
-    }
-
-  group_vector = strvec_create (ngroups);
-  for (i = 0; i < ngroups; i++)
-    group_vector[i] = itos (group_array[i]);
-
-  if (ngp)
-    *ngp = ngroups;
-  return group_vector;
-}
-
-int *
-get_group_array (ngp)
-     int *ngp;
-{
-  int i;
-  static int *group_iarray = (int *)NULL;
-
-  if (group_iarray)
-    {
-      if (ngp)
-       *ngp = ngroups;
-      return (group_iarray);
-    }
-
-  if (ngroups == 0)
-    initialize_group_array ();    
-
-  if (ngroups <= 0)
-    {
-      if (ngp)
-       *ngp = 0;
-      return (int *)NULL;
-    }
-
-  group_iarray = (int *)xmalloc (ngroups * sizeof (int));
-  for (i = 0; i < ngroups; i++)
-    group_iarray[i] = (int)group_array[i];
-
-  if (ngp)
-    *ngp = ngroups;
-  return group_iarray;
-}
diff --git a/general.h~ b/general.h~
deleted file mode 100644 (file)
index 5ea0d45..0000000
+++ /dev/null
@@ -1,325 +0,0 @@
-/* general.h -- defines that everybody likes to use. */
-
-/* Copyright (C) 1993-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 (_GENERAL_H_)
-#define _GENERAL_H_
-
-#include "stdc.h"
-
-#include "bashtypes.h"
-#include "chartypes.h"
-
-#if defined (HAVE_SYS_RESOURCE_H) && defined (RLIMTYPE)
-#  if defined (HAVE_SYS_TIME_H)
-#    include <sys/time.h>
-#  endif
-#  include <sys/resource.h>
-#endif
-
-#if defined (HAVE_STRING_H)
-#  include <string.h>
-#else
-#  include <strings.h>
-#endif /* !HAVE_STRING_H */
-
-#if defined (HAVE_LIMITS_H)
-#  include <limits.h>
-#endif
-
-#include "xmalloc.h"
-
-/* NULL pointer type. */
-#if !defined (NULL)
-#  if defined (__STDC__)
-#    define NULL ((void *) 0)
-#  else
-#    define NULL 0x0
-#  endif /* !__STDC__ */
-#endif /* !NULL */
-
-/* Hardly used anymore */
-#define pointer_to_int(x)      (int)((char *)x - (char *)0)
-
-#if defined (alpha) && defined (__GNUC__) && !defined (strchr) && !defined (__STDC__)
-extern char *strchr (), *strrchr ();
-#endif
-
-#if !defined (strcpy) && (defined (HAVE_DECL_STRCPY) && !HAVE_DECL_STRCPY)
-extern char *strcpy __P((char *, const char *));
-#endif
-
-#if !defined (savestring)
-#  define savestring(x) (char *)strcpy (xmalloc (1 + strlen (x)), (x))
-#endif
-
-#ifndef member
-#  define member(c, s) ((c) ? ((char *)xstrchr ((s), (c)) != (char *)NULL) : 0)
-#endif
-
-#ifndef whitespace
-#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
-#endif
-
-#ifndef CHAR_MAX
-#  ifdef __CHAR_UNSIGNED__
-#    define CHAR_MAX   0xff
-#  else
-#    define CHAR_MAX   0x7f
-#  endif
-#endif
-
-#ifndef CHAR_BIT
-#  define CHAR_BIT 8
-#endif
-
-/* Nonzero if the integer type T is signed.  */
-#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
-
-/* Bound on length of the string representing an integer value of type T.
-   Subtract one for the sign bit if T is signed;
-   302 / 1000 is log10 (2) rounded up;
-   add one for integer division truncation;
-   add one more for a minus sign if t is signed.  */
-#define INT_STRLEN_BOUND(t) \
-  ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 \
-   + 1 + TYPE_SIGNED (t))
-
-
-/* Define exactly what a legal shell identifier consists of. */
-#define legal_variable_starter(c) (ISALPHA(c) || (c == '_'))
-#define legal_variable_char(c) (ISALNUM(c) || c == '_')
-
-/* Definitions used in subst.c and by the `read' builtin for field
-   splitting. */
-#define spctabnl(c)    ((c) == ' ' || (c) == '\t' || (c) == '\n')
-
-/* All structs which contain a `next' field should have that field
-   as the first field in the struct.  This means that functions
-   can be written to handle the general case for linked lists. */
-typedef struct g_list {
-  struct g_list *next;
-} GENERIC_LIST;
-
-/* Here is a generic structure for associating character strings
-   with integers.  It is used in the parser for shell tokenization. */
-typedef struct {
-  char *word;
-  int token;
-} STRING_INT_ALIST;
-
-/* A macro to avoid making an uneccessary function call. */
-#define REVERSE_LIST(list, type) \
-  ((list && list->next) ? (type)list_reverse ((GENERIC_LIST *)list) \
-                       : (type)(list))
-
-#if __GNUC__ > 1
-#  define FASTCOPY(s, d, n)  __builtin_memcpy ((d), (s), (n))
-#else /* !__GNUC__ */
-#  if !defined (HAVE_BCOPY)
-#    if !defined (HAVE_MEMMOVE)
-#      define FASTCOPY(s, d, n)  memcpy ((d), (s), (n))
-#    else
-#      define FASTCOPY(s, d, n)  memmove ((d), (s), (n))
-#    endif /* !HAVE_MEMMOVE */
-#  else /* HAVE_BCOPY */
-#    define FASTCOPY(s, d, n)  bcopy ((s), (d), (n))
-#  endif /* HAVE_BCOPY */
-#endif /* !__GNUC__ */
-
-/* String comparisons that possibly save a function call each. */
-#define STREQ(a, b) ((a)[0] == (b)[0] && strcmp(a, b) == 0)
-#define STREQN(a, b, n) ((n == 0) ? (1) \
-                                 : ((a)[0] == (b)[0] && strncmp(a, b, n) == 0))
-
-/* More convenience definitions that possibly save system or libc calls. */
-#define STRLEN(s) (((s) && (s)[0]) ? ((s)[1] ? ((s)[2] ? strlen(s) : 2) : 1) : 0)
-#define FREE(s)  do { if (s) free (s); } while (0)
-#define MEMBER(c, s) (((c) && c == (s)[0] && !(s)[1]) || (member(c, s)))
-
-/* A fairly hairy macro to check whether an allocated string has more room,
-   and to resize it using xrealloc if it does not.
-   STR is the string (char *)
-   CIND is the current index into the string (int)
-   ROOM is the amount of additional room we need in the string (int)
-   CSIZE is the currently-allocated size of STR (int)
-   SINCR is how much to increment CSIZE before calling xrealloc (int) */
-
-#define RESIZE_MALLOCED_BUFFER(str, cind, room, csize, sincr) \
-  do { \
-    if ((cind) + (room) >= csize) \
-      { \
-       while ((cind) + (room) >= csize) \
-         csize += (sincr); \
-       str = xrealloc (str, csize); \
-      } \
-  } while (0)
-
-/* Function pointers can be declared as (Function *)foo. */
-#if !defined (_FUNCTION_DEF)
-#  define _FUNCTION_DEF
-typedef int Function ();
-typedef void VFunction ();
-typedef char *CPFunction ();           /* no longer used */
-typedef char **CPPFunction ();         /* no longer used */
-#endif /* _FUNCTION_DEF */
-
-#ifndef SH_FUNCTION_TYPEDEF
-#  define SH_FUNCTION_TYPEDEF
-
-/* Shell function typedefs with prototypes */
-/* `Generic' function pointer typedefs */
-
-typedef int sh_intfunc_t __P((int));
-typedef int sh_ivoidfunc_t __P((void));
-typedef int sh_icpfunc_t __P((char *));
-typedef int sh_icppfunc_t __P((char **));
-typedef int sh_iptrfunc_t __P((PTR_T));
-
-typedef void sh_voidfunc_t __P((void));
-typedef void sh_vintfunc_t __P((int));
-typedef void sh_vcpfunc_t __P((char *));
-typedef void sh_vcppfunc_t __P((char **));
-typedef void sh_vptrfunc_t __P((PTR_T));
-
-typedef int sh_wdesc_func_t __P((WORD_DESC *));
-typedef int sh_wlist_func_t __P((WORD_LIST *));
-
-typedef int sh_glist_func_t __P((GENERIC_LIST *));
-
-typedef char *sh_string_func_t __P((char *));  /* like savestring, et al. */
-
-typedef int sh_msg_func_t __P((const char *, ...));    /* printf(3)-like */
-typedef void sh_vmsg_func_t __P((const char *, ...));  /* printf(3)-like */
-
-/* Specific function pointer typedefs.  Most of these could be done
-   with #defines. */
-typedef void sh_sv_func_t __P((char *));       /* sh_vcpfunc_t */
-typedef void sh_free_func_t __P((PTR_T));      /* sh_vptrfunc_t */
-typedef void sh_resetsig_func_t __P((int));    /* sh_vintfunc_t */
-
-typedef int sh_ignore_func_t __P((const char *));      /* sh_icpfunc_t */
-
-typedef int sh_assign_func_t __P((const char *));      /* sh_icpfunc_t */
-typedef int sh_wassign_func_t __P((WORD_DESC *));
-
-typedef int sh_builtin_func_t __P((WORD_LIST *)); /* sh_wlist_func_t */
-
-#endif /* SH_FUNCTION_TYPEDEF */
-
-#define NOW    ((time_t) time ((time_t *) 0))
-
-/* Some defines for calling file status functions. */
-#define FS_EXISTS        0x1
-#define FS_EXECABLE      0x2
-#define FS_EXEC_PREFERRED 0x4
-#define FS_EXEC_ONLY     0x8
-#define FS_DIRECTORY     0x10
-#define FS_NODIRS        0x20
-#define FS_READABLE      0x40
-
-/* Default maximum for move_to_high_fd */
-#define HIGH_FD_MAX    256
-
-/* The type of function passed as the fourth argument to qsort(3). */
-#ifdef __STDC__
-typedef int QSFUNC (const void *, const void *);
-#else
-typedef int QSFUNC ();
-#endif 
-
-/* Some useful definitions for Unix pathnames.  Argument convention:
-   x == string, c == character */
-
-#if !defined (__CYGWIN__)
-#  define ABSPATH(x)   ((x)[0] == '/')
-#  define RELPATH(x)   ((x)[0] != '/')
-#else /* __CYGWIN__ */
-#  define ABSPATH(x)   (((x)[0] && ISALPHA((unsigned char)(x)[0]) && (x)[1] == ':') || ISDIRSEP((x)[0]))
-#  define RELPATH(x)   (ABSPATH(x) == 0)
-#endif /* __CYGWIN__ */
-
-#define ROOTEDPATH(x)  (ABSPATH(x))
-
-#define DIRSEP '/'
-#if !defined (__CYGWIN__)
-#  define ISDIRSEP(c)  ((c) == '/')
-#else
-#  define ISDIRSEP(c)  ((c) == '/' || (c) == '\\')
-#endif /* __CYGWIN__ */
-#define PATHSEP(c)     (ISDIRSEP(c) || (c) == 0)
-
-#if 0
-/* Declarations for functions defined in xmalloc.c */
-extern PTR_T xmalloc __P((size_t));
-extern PTR_T xrealloc __P((void *, size_t));
-extern void xfree __P((void *));
-#endif
-
-/* Declarations for functions defined in general.c */
-extern void posix_initialize __P((int));
-
-#if defined (RLIMTYPE)
-extern RLIMTYPE string_to_rlimtype __P((char *));
-extern void print_rlimtype __P((RLIMTYPE, int));
-#endif
-
-extern int all_digits __P((char *));
-extern int legal_number __P((const char *, intmax_t *));
-extern int legal_identifier __P((char *));
-extern int check_identifier __P((WORD_DESC *, int));
-extern int legal_alias_name __P((char *, int));
-extern int assignment __P((const char *, int));
-
-extern int sh_unset_nodelay_mode __P((int));
-extern int sh_validfd __P((int));
-extern void check_dev_tty __P((void));
-extern int move_to_high_fd __P((int, int, int));
-extern int check_binary_file __P((char *, int));
-
-#ifdef _POSIXSTAT_H_
-extern int same_file __P((char *, char *, struct stat *, struct stat *));
-#endif
-
-extern int sh_openpipe __P((int *));
-extern int sh_closepipe __P((int *));
-
-extern int file_exists __P((char *));
-extern int file_isdir __P((char  *));
-extern int file_iswdir __P((char  *));
-extern int absolute_pathname __P((const char *));
-extern int absolute_program __P((const char *));
-
-extern char *make_absolute __P((char *, char *));
-extern char *base_pathname __P((char *));
-extern char *full_pathname __P((char *));
-extern char *polite_directory_format __P((char *));
-extern char *trim_pathname __P((char *, int));
-
-extern char *extract_colon_unit __P((char *, int *));
-
-extern void tilde_initialize __P((void));
-extern char *bash_tilde_find_word __P((const char *, int, int *));
-extern char *bash_tilde_expand __P((const char *, int));
-
-extern int group_member __P((gid_t));
-extern char **get_group_list __P((int *));
-extern int *get_group_array __P((int *));
-
-#endif /* _GENERAL_H_ */
diff --git a/include/memalloc.h.save b/include/memalloc.h.save
deleted file mode 100644 (file)
index a1a2706..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/* memalloc.h -- consolidate code for including alloca.h or malloc.h and
-   defining alloca. */
-
-/* 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, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#if !defined (_MEMALLOC_H_)
-#  define _MEMALLOC_H_
-
-#if defined (sparc) && defined (sun) && !defined (HAVE_ALLOCA_H)
-#  define HAVE_ALLOCA_H
-#endif
-
-#if defined (__GNUC__) && !defined (HAVE_ALLOCA)
-#  define HAVE_ALLOCA
-#endif
-
-#if defined (HAVE_ALLOCA_H) && !defined (HAVE_ALLOCA)
-#  define HAVE_ALLOCA
-#endif /* HAVE_ALLOCA_H && !HAVE_ALLOCA */
-
-#if defined (__GNUC__) && !defined (C_ALLOCA)
-#  undef alloca
-#  define alloca __builtin_alloca
-#else /* !__GNUC__ || C_ALLOCA */
-#  if defined (HAVE_ALLOCA_H) && !defined (C_ALLOCA)
-#    if defined (IBMESA)
-#      include <malloc.h>
-#    else /* !IBMESA */
-#      include <alloca.h>
-#    endif /* !IBMESA */
-#  else  /* !HAVE_ALLOCA_H || C_ALLOCA */
-#    if defined (__hpux) && defined (__STDC__) && !defined (alloca)
-extern void *alloca ();
-#    else
-#      if !defined (alloca)
-extern char *alloca ();
-#      endif /* !alloca */
-#    endif /* !__hpux || !__STDC__ && !alloca */
-#  endif /* !HAVE_ALLOCA_H || C_ALLOCA */
-#endif /* !__GNUC__ || C_ALLOCA */
-
-#endif /* _MEMALLOC_H_ */
diff --git a/include/posixselect.h~ b/include/posixselect.h~
deleted file mode 100644 (file)
index 471c6d7..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* posixselect.h -- wrapper for select(2) includes and definitions */
-
-/* Copyright (C) 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/>.
-*/
-
-#ifndef _POSIXSELECT_H_
-#define _POSIXSELECT_H_
-
-#endif /* _POSIXSELECT_H_ */
diff --git a/jobs.c~ b/jobs.c~
deleted file mode 100644 (file)
index 3321113..0000000
--- a/jobs.c~
+++ /dev/null
@@ -1,4240 +0,0 @@
-/* jobs.c - functions that make children, remember them, and handle their termination. */
-
-/* This file works with both POSIX and BSD systems.  It implements job
-   control. */
-
-/* Copyright (C) 1989-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/>.
-*/
-
-#include "config.h"
-
-#include "bashtypes.h"
-#include "trap.h"
-#include <stdio.h>
-#include <signal.h>
-#include <errno.h>
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include "posixtime.h"
-
-#if defined (HAVE_SYS_RESOURCE_H) && defined (HAVE_WAIT3) && !defined (_POSIX_VERSION) && !defined (RLIMTYPE)
-#  include <sys/resource.h>
-#endif /* !_POSIX_VERSION && HAVE_SYS_RESOURCE_H && HAVE_WAIT3 && !RLIMTYPE */
-
-#if defined (HAVE_SYS_FILE_H)
-#  include <sys/file.h>
-#endif
-
-#include "filecntl.h"
-#include <sys/ioctl.h>
-#include <sys/param.h>
-
-#if defined (BUFFERED_INPUT)
-#  include "input.h"
-#endif
-
-/* Need to include this up here for *_TTY_DRIVER definitions. */
-#include "shtty.h"
-
-/* Define this if your output is getting swallowed.  It's a no-op on
-   machines with the termio or termios tty drivers. */
-/* #define DRAIN_OUTPUT */
-
-/* For the TIOCGPGRP and TIOCSPGRP ioctl parameters on HP-UX */
-#if defined (hpux) && !defined (TERMIOS_TTY_DRIVER)
-#  include <bsdtty.h>
-#endif /* hpux && !TERMIOS_TTY_DRIVER */
-
-#include "bashansi.h"
-#include "bashintl.h"
-#include "shell.h"
-#include "jobs.h"
-#include "execute_cmd.h"
-#include "flags.h"
-
-#include "builtins/builtext.h"
-#include "builtins/common.h"
-
-#if !defined (errno)
-extern int errno;
-#endif /* !errno */
-
-#define DEFAULT_CHILD_MAX 32
-#if !defined (DEBUG)
-#define MAX_JOBS_IN_ARRAY 4096         /* production */
-#else
-#define MAX_JOBS_IN_ARRAY 128          /* testing */
-#endif
-
-/* Flag values for second argument to delete_job */
-#define DEL_WARNSTOPPED                1       /* warn about deleting stopped jobs */
-#define DEL_NOBGPID            2       /* don't add pgrp leader to bgpids */
-
-/* Take care of system dependencies that must be handled when waiting for
-   children.  The arguments to the WAITPID macro match those to the Posix.1
-   waitpid() function. */
-
-#if defined (ultrix) && defined (mips) && defined (_POSIX_VERSION)
-#  define WAITPID(pid, statusp, options) \
-       wait3 ((union wait *)statusp, options, (struct rusage *)0)
-#else
-#  if defined (_POSIX_VERSION) || defined (HAVE_WAITPID)
-#    define WAITPID(pid, statusp, options) \
-       waitpid ((pid_t)pid, statusp, options)
-#  else
-#    if defined (HAVE_WAIT3)
-#      define WAITPID(pid, statusp, options) \
-       wait3 (statusp, options, (struct rusage *)0)
-#    else
-#      define WAITPID(pid, statusp, options) \
-       wait3 (statusp, options, (int *)0)
-#    endif /* HAVE_WAIT3 */
-#  endif /* !_POSIX_VERSION && !HAVE_WAITPID*/
-#endif /* !(Ultrix && mips && _POSIX_VERSION) */
-
-/* getpgrp () varies between systems.  Even systems that claim to be
-   Posix.1 compatible lie sometimes (Ultrix, SunOS4, apollo). */
-#if defined (GETPGRP_VOID)
-#  define getpgid(p) getpgrp ()
-#else
-#  define getpgid(p) getpgrp (p)
-#endif /* !GETPGRP_VOID */
-
-/* If the system needs it, REINSTALL_SIGCHLD_HANDLER will reinstall the
-   handler for SIGCHLD. */
-#if defined (MUST_REINSTALL_SIGHANDLERS)
-#  define REINSTALL_SIGCHLD_HANDLER signal (SIGCHLD, sigchld_handler)
-#else
-#  define REINSTALL_SIGCHLD_HANDLER
-#endif /* !MUST_REINSTALL_SIGHANDLERS */
-
-/* Some systems let waitpid(2) tell callers about stopped children. */
-#if !defined (WCONTINUED) || defined (WCONTINUED_BROKEN)
-#  undef WCONTINUED
-#  define WCONTINUED 0
-#endif
-#if !defined (WIFCONTINUED)
-#  define WIFCONTINUED(s)      (0)
-#endif
-
-/* The number of additional slots to allocate when we run out. */
-#define JOB_SLOTS 8
-
-typedef int sh_job_map_func_t __P((JOB *, int, int, int));
-
-/* Variables used here but defined in other files. */
-extern int subshell_environment, line_number;
-extern int posixly_correct, shell_level;
-extern int last_command_exit_value, last_command_exit_signal;
-extern int loop_level, breaking;
-extern int executing_list;
-extern int sourcelevel;
-extern int running_trap;
-extern sh_builtin_func_t *this_shell_builtin;
-extern char *shell_name, *this_command_name;
-extern sigset_t top_level_mask;
-extern procenv_t wait_intr_buf;
-extern int wait_signal_received;
-extern WORD_LIST *subst_assign_varlist;
-
-static struct jobstats zerojs = { -1L, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NO_JOB, NO_JOB, 0, 0 };
-struct jobstats js = { -1L, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NO_JOB, NO_JOB, 0, 0 };
-
-struct bgpids bgpids = { 0, 0, 0 };
-
-/* The array of known jobs. */
-JOB **jobs = (JOB **)NULL;
-
-#if 0
-/* The number of slots currently allocated to JOBS. */
-int job_slots = 0;
-#endif
-
-/* The controlling tty for this shell. */
-int shell_tty = -1;
-
-/* The shell's process group. */
-pid_t shell_pgrp = NO_PID;
-
-/* The terminal's process group. */
-pid_t terminal_pgrp = NO_PID;
-
-/* The process group of the shell's parent. */
-pid_t original_pgrp = NO_PID;
-
-/* The process group of the pipeline currently being made. */
-pid_t pipeline_pgrp = (pid_t)0;
-
-#if defined (PGRP_PIPE)
-/* Pipes which each shell uses to communicate with the process group leader
-   until all of the processes in a pipeline have been started.  Then the
-   process leader is allowed to continue. */
-int pgrp_pipe[2] = { -1, -1 };
-#endif
-
-#if 0
-/* The job which is current; i.e. the one that `%+' stands for. */
-int current_job = NO_JOB;
-
-/* The previous job; i.e. the one that `%-' stands for. */
-int previous_job = NO_JOB;
-#endif
-
-/* Last child made by the shell.  */
-pid_t last_made_pid = NO_PID;
-
-/* Pid of the last asynchronous child. */
-pid_t last_asynchronous_pid = NO_PID;
-
-/* The pipeline currently being built. */
-PROCESS *the_pipeline = (PROCESS *)NULL;
-
-/* If this is non-zero, do job control. */
-int job_control = 1;
-
-/* Call this when you start making children. */
-int already_making_children = 0;
-
-/* If this is non-zero, $LINES and $COLUMNS are reset after every process
-   exits from get_tty_state(). */
-int check_window_size;
-
-/* Functions local to this file. */
-
-static sighandler wait_sigint_handler __P((int));
-static sighandler sigchld_handler __P((int));
-static sighandler sigcont_sighandler __P((int));
-static sighandler sigstop_sighandler __P((int));
-
-static int waitchld __P((pid_t, int));
-
-static PROCESS *find_pipeline __P((pid_t, int, int *));
-static PROCESS *find_process __P((pid_t, int, int *));
-
-static char *current_working_directory __P((void));
-static char *job_working_directory __P((void));
-static char *j_strsignal __P((int));
-static char *printable_job_status __P((int, PROCESS *, int));
-
-static PROCESS *find_last_proc __P((int, int));
-static pid_t find_last_pid __P((int, int));
-
-static int set_new_line_discipline __P((int));
-static int map_over_jobs __P((sh_job_map_func_t *, int, int));
-static int job_last_stopped __P((int));
-static int job_last_running __P((int));
-static int most_recent_job_in_state __P((int, JOB_STATE));
-static int find_job __P((pid_t, int, PROCESS **));
-static int print_job __P((JOB *, int, int, int));
-static int process_exit_status __P((WAIT));
-static int process_exit_signal __P((WAIT));
-static int job_exit_status __P((int));
-static int job_exit_signal __P((int));
-static int set_job_status_and_cleanup __P((int));
-
-static WAIT job_signal_status __P((int));
-static WAIT raw_job_exit_status __P((int));
-
-static void notify_of_job_status __P((void));
-static void reset_job_indices __P((void));
-static void cleanup_dead_jobs __P((void));
-static int processes_in_job __P((int));
-static void realloc_jobs_list __P((void));
-static int compact_jobs_list __P((int));
-static int discard_pipeline __P((PROCESS *));
-static void add_process __P((char *, pid_t));
-static void print_pipeline __P((PROCESS *, int, int, FILE *));
-static void pretty_print_job __P((int, int, FILE *));
-static void set_current_job __P((int));
-static void reset_current __P((void));
-static void set_job_running __P((int));
-static void setjstatus __P((int));
-static int maybe_give_terminal_to __P((pid_t, pid_t, int));
-static void mark_all_jobs_as_dead __P((void));
-static void mark_dead_jobs_as_notified __P((int));
-static void restore_sigint_handler __P((void));
-#if defined (PGRP_PIPE)
-static void pipe_read __P((int *));
-#endif
-
-static struct pidstat *bgp_alloc __P((pid_t, int));
-static struct pidstat *bgp_add __P((pid_t, int));
-static int bgp_delete __P((pid_t));
-static void bgp_clear __P((void));
-static int bgp_search __P((pid_t));
-static void bgp_prune __P((void));
-
-#if defined (ARRAY_VARS)
-static int *pstatuses;         /* list of pipeline statuses */
-static int statsize;
-#endif
-
-/* Used to synchronize between wait_for and other functions and the SIGCHLD
-   signal handler. */
-static int sigchld;
-static int queue_sigchld;
-
-#define QUEUE_SIGCHLD(os)      (os) = sigchld, queue_sigchld++
-
-#define UNQUEUE_SIGCHLD(os) \
-       do { \
-         queue_sigchld--; \
-         if (queue_sigchld == 0 && os != sigchld) \
-           waitchld (-1, 0); \
-       } while (0)
-
-static SigHandler *old_tstp, *old_ttou, *old_ttin;
-static SigHandler *old_cont = (SigHandler *)SIG_DFL;
-
-/* A place to temporarily save the current pipeline. */
-static PROCESS *saved_pipeline;
-static int saved_already_making_children;
-
-/* Set this to non-zero whenever you don't want the jobs list to change at
-   all: no jobs deleted and no status change notifications.  This is used,
-   for example, when executing SIGCHLD traps, which may run arbitrary
-   commands. */
-static int jobs_list_frozen;
-
-static char retcode_name_buffer[64];
-
-/* flags to detect pid wraparound */
-static pid_t first_pid = NO_PID;
-static int pid_wrap = -1;
-
-#if !defined (_POSIX_VERSION)
-
-/* These are definitions to map POSIX 1003.1 functions onto existing BSD
-   library functions and system calls. */
-#define setpgid(pid, pgrp)     setpgrp (pid, pgrp)
-#define tcsetpgrp(fd, pgrp)    ioctl ((fd), TIOCSPGRP, &(pgrp))
-
-pid_t
-tcgetpgrp (fd)
-     int fd;
-{
-  pid_t pgrp;
-
-  /* ioctl will handle setting errno correctly. */
-  if (ioctl (fd, TIOCGPGRP, &pgrp) < 0)
-    return (-1);
-  return (pgrp);
-}
-
-#endif /* !_POSIX_VERSION */
-
-/* Initialize the global job stats structure and other bookkeeping variables */
-void
-init_job_stats ()
-{
-  js = zerojs;
-  first_pid = NO_PID;
-  pid_wrap = -1;
-}
-
-/* Return the working directory for the current process.  Unlike
-   job_working_directory, this does not call malloc (), nor do any
-   of the functions it calls.  This is so that it can safely be called
-   from a signal handler. */
-static char *
-current_working_directory ()
-{
-  char *dir;
-  static char d[PATH_MAX];
-
-  dir = get_string_value ("PWD");
-
-  if (dir == 0 && the_current_working_directory && no_symbolic_links)
-    dir = the_current_working_directory;
-
-  if (dir == 0)
-    {
-      dir = getcwd (d, sizeof(d));
-      if (dir)
-       dir = d;
-    }
-
-  return (dir == 0) ? "<unknown>" : dir;
-}
-
-/* Return the working directory for the current process. */
-static char *
-job_working_directory ()
-{
-  char *dir;
-
-  dir = get_string_value ("PWD");
-  if (dir)
-    return (savestring (dir));
-
-  dir = get_working_directory ("job-working-directory");
-  if (dir)
-    return (dir);
-
-  return (savestring ("<unknown>"));
-}
-
-void
-making_children ()
-{
-  if (already_making_children)
-    return;
-
-  already_making_children = 1;
-  start_pipeline ();
-}
-
-void
-stop_making_children ()
-{
-  already_making_children = 0;
-}
-
-void
-cleanup_the_pipeline ()
-{
-  PROCESS *disposer;
-  sigset_t set, oset;
-
-  BLOCK_CHILD (set, oset);
-  disposer = the_pipeline;
-  the_pipeline = (PROCESS *)NULL;
-  UNBLOCK_CHILD (oset);
-
-  if (disposer)
-    discard_pipeline (disposer);
-}
-
-void
-save_pipeline (clear)
-     int clear;
-{
-  saved_pipeline = the_pipeline;
-  if (clear)
-    the_pipeline = (PROCESS *)NULL;
-  saved_already_making_children = already_making_children;
-}
-
-void
-restore_pipeline (discard)
-     int discard;
-{
-  PROCESS *old_pipeline;
-
-  old_pipeline = the_pipeline;
-  the_pipeline = saved_pipeline;
-  already_making_children = saved_already_making_children;
-  if (discard && old_pipeline)
-    discard_pipeline (old_pipeline);
-}
-
-/* Start building a pipeline.  */
-void
-start_pipeline ()
-{
-  if (the_pipeline)
-    {
-      cleanup_the_pipeline ();
-      pipeline_pgrp = 0;
-#if defined (PGRP_PIPE)
-      sh_closepipe (pgrp_pipe);
-#endif
-    }
-
-#if defined (PGRP_PIPE)
-  if (job_control)
-    {
-      if (pipe (pgrp_pipe) == -1)
-       sys_error (_("start_pipeline: pgrp pipe"));
-    }
-#endif
-}
-
-/* Stop building a pipeline.  Install the process list in the job array.
-   This returns the index of the newly installed job.
-   DEFERRED is a command structure to be executed upon satisfactory
-   execution exit of this pipeline. */
-int
-stop_pipeline (async, deferred)
-     int async;
-     COMMAND *deferred;
-{
-  register int i, j;
-  JOB *newjob;
-  sigset_t set, oset;
-
-  BLOCK_CHILD (set, oset);
-
-#if defined (PGRP_PIPE)
-  /* The parent closes the process group synchronization pipe. */
-  sh_closepipe (pgrp_pipe);
-#endif
-
-  cleanup_dead_jobs ();
-
-  if (js.j_jobslots == 0)
-    {
-      js.j_jobslots = JOB_SLOTS;
-      jobs = (JOB **)xmalloc (js.j_jobslots * sizeof (JOB *));
-
-      /* Now blank out these new entries. */
-      for (i = 0; i < js.j_jobslots; i++)
-       jobs[i] = (JOB *)NULL;
-
-      js.j_firstj = js.j_lastj = js.j_njobs = 0;
-    }
-
-  /* Scan from the last slot backward, looking for the next free one. */
-  /* XXX - revisit this interactive assumption */
-  /* XXX - this way for now */
-  if (interactive)
-    {
-      for (i = js.j_jobslots; i; i--)
-       if (jobs[i - 1])
-         break;
-    }
-  else
-    {
-#if 0
-      /* This wraps around, but makes it inconvenient to extend the array */
-      for (i = js.j_lastj+1; i != js.j_lastj; i++)
-       {
-         if (i >= js.j_jobslots)
-           i = 0;
-         if (jobs[i] == 0)
-           break;
-       }       
-      if (i == js.j_lastj)
-        i = js.j_jobslots;
-#else
-      /* This doesn't wrap around yet. */
-      for (i = js.j_lastj ? js.j_lastj + 1 : js.j_lastj; i < js.j_jobslots; i++)
-       if (jobs[i] == 0)
-         break;
-#endif
-    }
-
-  /* Do we need more room? */
-
-  /* First try compaction */
-  if ((interactive_shell == 0 || subshell_environment) && i == js.j_jobslots && js.j_jobslots >= MAX_JOBS_IN_ARRAY)
-    i = compact_jobs_list (0);
-
-  /* If we can't compact, reallocate */
-  if (i == js.j_jobslots)
-    {
-      js.j_jobslots += JOB_SLOTS;
-      jobs = (JOB **)xrealloc (jobs, (js.j_jobslots * sizeof (JOB *)));
-
-      for (j = i; j < js.j_jobslots; j++)
-       jobs[j] = (JOB *)NULL;
-    }
-
-  /* Add the current pipeline to the job list. */
-  if (the_pipeline)
-    {
-      register PROCESS *p;
-      int any_running, any_stopped, n;
-
-      newjob = (JOB *)xmalloc (sizeof (JOB));
-
-      for (n = 1, p = the_pipeline; p->next != the_pipeline; n++, p = p->next)
-       ;
-      p->next = (PROCESS *)NULL;
-      newjob->pipe = REVERSE_LIST (the_pipeline, PROCESS *);
-      for (p = newjob->pipe; p->next; p = p->next)
-       ;
-      p->next = newjob->pipe;
-
-      the_pipeline = (PROCESS *)NULL;
-      newjob->pgrp = pipeline_pgrp;
-      pipeline_pgrp = 0;
-
-      newjob->flags = 0;
-
-      /* Flag to see if in another pgrp. */
-      if (job_control)
-       newjob->flags |= J_JOBCONTROL;
-
-      /* Set the state of this pipeline. */
-      p = newjob->pipe;
-      any_running = any_stopped = 0;
-      do
-       {
-         any_running |= PRUNNING (p);
-         any_stopped |= PSTOPPED (p);
-         p = p->next;
-       }
-      while (p != newjob->pipe);
-
-      newjob->state = any_running ? JRUNNING : (any_stopped ? JSTOPPED : JDEAD);
-      newjob->wd = job_working_directory ();
-      newjob->deferred = deferred;
-
-      newjob->j_cleanup = (sh_vptrfunc_t *)NULL;
-      newjob->cleanarg = (PTR_T) NULL;
-
-      jobs[i] = newjob;
-      if (newjob->state == JDEAD && (newjob->flags & J_FOREGROUND))
-       setjstatus (i);
-      if (newjob->state == JDEAD)
-       {
-         js.c_reaped += n;     /* wouldn't have been done since this was not part of a job */
-         js.j_ndead++;
-       }
-      js.c_injobs += n;
-
-      js.j_lastj = i;
-      js.j_njobs++;
-    }
-  else
-    newjob = (JOB *)NULL;
-
-  if (newjob)
-    js.j_lastmade = newjob;
-
-  if (async)
-    {
-      if (newjob)
-       {
-         newjob->flags &= ~J_FOREGROUND;
-         newjob->flags |= J_ASYNC;
-         js.j_lastasync = newjob;
-       }
-      reset_current ();
-    }
-  else
-    {
-      if (newjob)
-       {
-         newjob->flags |= J_FOREGROUND;
-         /*
-          *            !!!!! NOTE !!!!!  (chet@ins.cwru.edu)
-          *
-          * The currently-accepted job control wisdom says to set the
-          * terminal's process group n+1 times in an n-step pipeline:
-          * once in the parent and once in each child.  This is where
-          * the parent gives it away.
-          *
-          * Don't give the terminal away if this shell is an asynchronous
-          * subshell.
-          *
-          */
-         if (job_control && newjob->pgrp && (subshell_environment&SUBSHELL_ASYNC) == 0)
-           maybe_give_terminal_to (shell_pgrp, newjob->pgrp, 0);
-       }
-    }
-
-  stop_making_children ();
-  UNBLOCK_CHILD (oset);
-  return (js.j_current);
-}
-
-/* Functions to manage the list of exited background pids whose status has
-   been saved. */
-
-static struct pidstat *
-bgp_alloc (pid, status)
-     pid_t pid;
-     int status;
-{
-  struct pidstat *ps;
-
-  ps = (struct pidstat *)xmalloc (sizeof (struct pidstat));
-  ps->pid = pid;
-  ps->status = status;
-  ps->next = (struct pidstat *)0;
-  return ps;
-}
-
-static struct pidstat *
-bgp_add (pid, status)
-     pid_t pid;
-     int status;
-{
-  struct pidstat *ps;
-
-  ps = bgp_alloc (pid, status);
-
-  if (bgpids.list == 0)
-    {
-      bgpids.list = bgpids.end = ps;
-      bgpids.npid = 0;                 /* just to make sure */
-    }
-  else
-    {
-      bgpids.end->next = ps;
-      bgpids.end = ps;
-    }
-  bgpids.npid++;
-
-  if (bgpids.npid > js.c_childmax)
-    bgp_prune ();
-
-  return ps;
-}
-
-static int
-bgp_delete (pid)
-     pid_t pid;
-{
-  struct pidstat *prev, *p;
-
-  for (prev = p = bgpids.list; p; prev = p, p = p->next)
-    if (p->pid == pid)
-      {
-       prev->next = p->next;   /* remove from list */
-       break;
-      }
-
-  if (p == 0)
-    return 0;          /* not found */
-
-#if defined (DEBUG)
-  itrace("bgp_delete: deleting %d", pid);
-#endif
-
-  /* Housekeeping in the border cases. */
-  if (p == bgpids.list)
-    bgpids.list = bgpids.list->next;
-  else if (p == bgpids.end)
-    bgpids.end = prev;
-
-  bgpids.npid--;
-  if (bgpids.npid == 0)
-    bgpids.list = bgpids.end = 0;
-  else if (bgpids.npid == 1)
-    bgpids.end = bgpids.list;          /* just to make sure */
-
-  free (p);
-  return 1;
-}
-
-/* Clear out the list of saved statuses */
-static void
-bgp_clear ()
-{
-  struct pidstat *ps, *p;
-
-  for (ps = bgpids.list; ps; )
-    {
-      p = ps;
-      ps = ps->next;
-      free (p);
-    }
-  bgpids.list = bgpids.end = 0;
-  bgpids.npid = 0;
-}
-
-/* Search for PID in the list of saved background pids; return its status if
-   found.  If not found, return -1. */
-static int
-bgp_search (pid)
-     pid_t pid;
-{
-  struct pidstat *ps;
-
-  for (ps = bgpids.list ; ps; ps = ps->next)
-    if (ps->pid == pid)
-      return ps->status;
-  return -1;
-}
-
-static void
-bgp_prune ()
-{
-  struct pidstat *ps;
-
-  while (bgpids.npid > js.c_childmax)
-    {
-      ps = bgpids.list;
-      bgpids.list = bgpids.list->next;
-      free (ps);
-      bgpids.npid--;
-    }
-}
-
-/* Reset the values of js.j_lastj and js.j_firstj after one or both have
-   been deleted.  The caller should check whether js.j_njobs is 0 before
-   calling this.  This wraps around, but the rest of the code does not.  At
-   this point, it should not matter. */
-static void
-reset_job_indices ()
-{
-  int old;
-
-  if (jobs[js.j_firstj] == 0)
-    {
-      old = js.j_firstj++;
-      if (old >= js.j_jobslots)
-       old = js.j_jobslots - 1;
-      while (js.j_firstj != old)
-       {
-         if (js.j_firstj >= js.j_jobslots)
-           js.j_firstj = 0;
-         if (jobs[js.j_firstj] || js.j_firstj == old)  /* needed if old == 0 */
-           break;
-         js.j_firstj++;
-       }
-      if (js.j_firstj == old)
-        js.j_firstj = js.j_lastj = js.j_njobs = 0;
-    }
-  if (jobs[js.j_lastj] == 0)
-    {
-      old = js.j_lastj--;
-      if (old < 0)
-       old = 0;
-      while (js.j_lastj != old)
-       {
-         if (js.j_lastj < 0)
-           js.j_lastj = js.j_jobslots - 1;
-         if (jobs[js.j_lastj] || js.j_lastj == old)    /* needed if old == js.j_jobslots */
-           break;
-         js.j_lastj--;
-       }
-      if (js.j_lastj == old)
-        js.j_firstj = js.j_lastj = js.j_njobs = 0;
-    }
-}
-      
-/* Delete all DEAD jobs that the user had received notification about. */
-static void
-cleanup_dead_jobs ()
-{
-  register int i;
-  int os;
-
-  if (js.j_jobslots == 0 || jobs_list_frozen)
-    return;
-
-  QUEUE_SIGCHLD(os);
-
-  /* XXX could use js.j_firstj and js.j_lastj here */
-  for (i = 0; i < js.j_jobslots; i++)
-    {
-#if defined (DEBUG)
-      if (i < js.j_firstj && jobs[i])
-       itrace("cleanup_dead_jobs: job %d non-null before js.j_firstj (%d)", i, js.j_firstj);
-      if (i > js.j_lastj && jobs[i])
-       itrace("cleanup_dead_jobs: job %d non-null after js.j_lastj (%d)", i, js.j_lastj);
-#endif
-
-      if (jobs[i] && DEADJOB (i) && IS_NOTIFIED (i))
-       delete_job (i, 0);
-    }
-
-#if defined (COPROCESS_SUPPORT)
-  coproc_reap ();
-#endif
-
-  UNQUEUE_SIGCHLD(os);
-}
-
-static int
-processes_in_job (job)
-     int job;
-{
-  int nproc;
-  register PROCESS *p;
-
-  nproc = 0;
-  p = jobs[job]->pipe;
-  do
-    {
-      p = p->next;
-      nproc++;
-    }
-  while (p != jobs[job]->pipe);
-
-  return nproc;
-}
-
-static void
-delete_old_job (pid)
-     pid_t pid;
-{
-  PROCESS *p;
-  int job;
-
-  job = find_job (pid, 0, &p);
-  if (job != NO_JOB)
-    {
-#ifdef DEBUG
-      itrace ("delete_old_job: found pid %d in job %d with state %d", pid, job, jobs[job]->state);
-#endif
-      if (JOBSTATE (job) == JDEAD)
-       delete_job (job, DEL_NOBGPID);
-      else
-       {
-         internal_warning (_("forked pid %d appears in running job %d"), pid, job);
-         if (p)
-           p->pid = 0;
-       }
-    }
-}
-
-/* Reallocate and compress the jobs list.  This returns with a jobs array
-   whose size is a multiple of JOB_SLOTS and can hold the current number of
-   jobs.  Heuristics are used to minimize the number of new reallocs. */
-static void
-realloc_jobs_list ()
-{
-  sigset_t set, oset;
-  int nsize, i, j, ncur, nprev;
-  JOB **nlist;
-
-  ncur = nprev = NO_JOB;
-  nsize = ((js.j_njobs + JOB_SLOTS - 1) / JOB_SLOTS);
-  nsize *= JOB_SLOTS;
-  i = js.j_njobs % JOB_SLOTS;
-  if (i == 0 || i > (JOB_SLOTS >> 1))
-    nsize += JOB_SLOTS;
-
-  BLOCK_CHILD (set, oset);
-  nlist = (js.j_jobslots == nsize) ? jobs : (JOB **) xmalloc (nsize * sizeof (JOB *));
-
-  js.c_reaped = js.j_ndead = 0;
-  for (i = j = 0; i < js.j_jobslots; i++)
-    if (jobs[i])
-      {
-       if (i == js.j_current)
-         ncur = j;
-       if (i == js.j_previous)
-         nprev = j;
-       nlist[j++] = jobs[i];
-       if (jobs[i]->state == JDEAD)
-         {
-           js.j_ndead++;
-           js.c_reaped += processes_in_job (i);
-         }
-      }
-
-#if defined (DEBUG)
-  itrace ("realloc_jobs_list: resize jobs list from %d to %d", js.j_jobslots, nsize);
-  itrace ("realloc_jobs_list: j_lastj changed from %d to %d", js.j_lastj, (j > 0) ? j - 1 : 0);
-  itrace ("realloc_jobs_list: j_njobs changed from %d to %d", js.j_njobs, j);
-  itrace ("realloc_jobs_list: js.j_ndead %d js.c_reaped %d", js.j_ndead, js.c_reaped);
-#endif
-
-  js.j_firstj = 0;
-  js.j_lastj = (j > 0) ? j - 1 : 0;
-  js.j_njobs = j;
-  js.j_jobslots = nsize;
-
-  /* Zero out remaining slots in new jobs list */
-  for ( ; j < nsize; j++)
-    nlist[j] = (JOB *)NULL;
-
-  if (jobs != nlist)
-    {
-      free (jobs);
-      jobs = nlist;
-    }
-
-  if (ncur != NO_JOB)
-    js.j_current = ncur;
-  if (nprev != NO_JOB)
-    js.j_previous = nprev;
-
-  /* Need to reset these */
-  if (js.j_current == NO_JOB || js.j_previous == NO_JOB || js.j_current > js.j_lastj || js.j_previous > js.j_lastj)
-    reset_current ();
-
-#ifdef DEBUG
-  itrace ("realloc_jobs_list: reset js.j_current (%d) and js.j_previous (%d)", js.j_current, js.j_previous);
-#endif
-
-  UNBLOCK_CHILD (oset);
-}
-
-/* Compact the jobs list by removing dead jobs.  Assumed that we have filled
-   the jobs array to some predefined maximum.  Called when the shell is not
-   the foreground process (subshell_environment != 0).  Returns the first
-   available slot in the compacted list.  If that value is js.j_jobslots, then
-   the list needs to be reallocated.  The jobs array may be in new memory if
-   this returns > 0 and < js.j_jobslots.  FLAGS is reserved for future use. */
-static int
-compact_jobs_list (flags)
-     int flags;
-{
-  if (js.j_jobslots == 0 || jobs_list_frozen)
-    return js.j_jobslots;
-
-  reap_dead_jobs ();
-  realloc_jobs_list ();
-
-#ifdef DEBUG
-  itrace("compact_jobs_list: returning %d", (js.j_lastj || jobs[js.j_lastj]) ? js.j_lastj + 1 : 0);
-#endif
-
-  return ((js.j_lastj || jobs[js.j_lastj]) ? js.j_lastj + 1 : 0);
-}
-
-/* Delete the job at INDEX from the job list.  Must be called
-   with SIGCHLD blocked. */
-void
-delete_job (job_index, dflags)
-     int job_index, dflags;
-{
-  register JOB *temp;
-  PROCESS *proc;
-  int ndel;
-
-  if (js.j_jobslots == 0 || jobs_list_frozen)
-    return;
-
-  if ((dflags & DEL_WARNSTOPPED) && subshell_environment == 0 && STOPPED (job_index))
-    internal_warning (_("deleting stopped job %d with process group %ld"), job_index+1, (long)jobs[job_index]->pgrp);
-  temp = jobs[job_index];
-  if (temp == 0)
-    return;
-
-  if ((dflags & DEL_NOBGPID) == 0)
-    {
-      proc = find_last_proc (job_index, 0);
-      /* Could do this just for J_ASYNC jobs, but we save all. */
-      if (proc)
-       bgp_add (proc->pid, process_exit_status (proc->status));
-    }
-
-  jobs[job_index] = (JOB *)NULL;
-  if (temp == js.j_lastmade)
-    js.j_lastmade = 0;
-  else if (temp == js.j_lastasync)
-    js.j_lastasync = 0;
-
-  free (temp->wd);
-  ndel = discard_pipeline (temp->pipe);
-
-  js.c_injobs -= ndel;
-  if (temp->state == JDEAD)
-    {
-      js.c_reaped -= ndel;
-      js.j_ndead--;
-      if (js.c_reaped < 0)
-       {
-#ifdef DEBUG
-         itrace("delete_job (%d pgrp %d): js.c_reaped (%d) < 0 ndel = %d js.j_ndead = %d", job_index, temp->pgrp, js.c_reaped, ndel, js.j_ndead);
-#endif
-         js.c_reaped = 0;
-       }
-    }
-
-  if (temp->deferred)
-    dispose_command (temp->deferred);
-
-  free (temp);
-
-  js.j_njobs--;
-  if (js.j_njobs == 0)
-    js.j_firstj = js.j_lastj = 0;
-  else if (jobs[js.j_firstj] == 0 || jobs[js.j_lastj] == 0)
-    reset_job_indices ();
-
-  if (job_index == js.j_current || job_index == js.j_previous)
-    reset_current ();
-}
-
-/* Must be called with SIGCHLD blocked. */
-void
-nohup_job (job_index)
-     int job_index;
-{
-  register JOB *temp;
-
-  if (js.j_jobslots == 0)
-    return;
-
-  if (temp = jobs[job_index])
-    temp->flags |= J_NOHUP;
-}
-
-/* Get rid of the data structure associated with a process chain. */
-static int
-discard_pipeline (chain)
-     register PROCESS *chain;
-{
-  register PROCESS *this, *next;
-  int n;
-
-  this = chain;
-  n = 0;
-  do
-    {
-      next = this->next;
-      FREE (this->command);
-      free (this);
-      n++;
-      this = next;
-    }
-  while (this != chain);
-
-  return n;
-}
-
-/* Add this process to the chain being built in the_pipeline.
-   NAME is the command string that will be exec'ed later.
-   PID is the process id of the child. */
-static void
-add_process (name, pid)
-     char *name;
-     pid_t pid;
-{
-  PROCESS *t, *p;
-
-#if defined (RECYCLES_PIDS)
-  int j;
-  p = find_process (pid, 0, &j);
-  if (p)
-    {
-#  ifdef DEBUG
-      if (j == NO_JOB)
-       internal_warning (_("add_process: process %5ld (%s) in the_pipeline"), (long)p->pid, p->command);
-#  endif
-      if (PALIVE (p))
-        internal_warning (_("add_process: pid %5ld (%s) marked as still alive"), (long)p->pid, p->command);
-      p->running = PS_RECYCLED;                /* mark as recycled */
-    }
-#endif
-
-  t = (PROCESS *)xmalloc (sizeof (PROCESS));
-  t->next = the_pipeline;
-  t->pid = pid;
-  WSTATUS (t->status) = 0;
-  t->running = PS_RUNNING;
-  t->command = name;
-  the_pipeline = t;
-
-  if (t->next == 0)
-    t->next = t;
-  else
-    {
-      p = t->next;
-      while (p->next != t->next)
-       p = p->next;
-      p->next = t;
-    }
-}
-
-#if 0
-/* Take the last job and make it the first job.  Must be called with
-   SIGCHLD blocked. */
-int
-rotate_the_pipeline ()
-{
-  PROCESS *p;
-
-  if (the_pipeline->next == the_pipeline)
-    return;
-  for (p = the_pipeline; p->next != the_pipeline; p = p->next)
-    ;
-  the_pipeline = p;
-}
-
-/* Reverse the order of the processes in the_pipeline.  Must be called with
-   SIGCHLD blocked. */
-int
-reverse_the_pipeline ()
-{
-  PROCESS *p, *n;
-
-  if (the_pipeline->next == the_pipeline)
-    return;
-
-  for (p = the_pipeline; p->next != the_pipeline; p = p->next)
-    ;
-  p->next = (PROCESS *)NULL;
-
-  n = REVERSE_LIST (the_pipeline, PROCESS *);
-
-  the_pipeline = n;
-  for (p = the_pipeline; p->next; p = p->next)
-    ;
-  p->next = the_pipeline;
-}
-#endif
-
-/* Map FUNC over the list of jobs.  If FUNC returns non-zero,
-   then it is time to stop mapping, and that is the return value
-   for map_over_jobs.  FUNC is called with a JOB, arg1, arg2,
-   and INDEX. */
-static int
-map_over_jobs (func, arg1, arg2)
-     sh_job_map_func_t *func;
-     int arg1, arg2;
-{
-  register int i;
-  int result;
-  sigset_t set, oset;
-
-  if (js.j_jobslots == 0)
-    return 0;
-
-  BLOCK_CHILD (set, oset);
-
-  /* XXX could use js.j_firstj here */
-  for (i = result = 0; i < js.j_jobslots; i++)
-    {
-#if defined (DEBUG)
-      if (i < js.j_firstj && jobs[i])
-       itrace("map_over_jobs: job %d non-null before js.j_firstj (%d)", i, js.j_firstj);
-      if (i > js.j_lastj && jobs[i])
-       itrace("map_over_jobs: job %d non-null after js.j_lastj (%d)", i, js.j_lastj);
-#endif
-      if (jobs[i])
-       {
-         result = (*func)(jobs[i], arg1, arg2, i);
-         if (result)
-           break;
-       }
-    }
-
-  UNBLOCK_CHILD (oset);
-
-  return (result);
-}
-
-/* Cause all the jobs in the current pipeline to exit. */
-void
-terminate_current_pipeline ()
-{
-  if (pipeline_pgrp && pipeline_pgrp != shell_pgrp)
-    {
-      killpg (pipeline_pgrp, SIGTERM);
-      killpg (pipeline_pgrp, SIGCONT);
-    }
-}
-
-/* Cause all stopped jobs to exit. */
-void
-terminate_stopped_jobs ()
-{
-  register int i;
-
-  /* XXX could use js.j_firstj here */
-  for (i = 0; i < js.j_jobslots; i++)
-    {
-      if (jobs[i] && STOPPED (i))
-       {
-         killpg (jobs[i]->pgrp, SIGTERM);
-         killpg (jobs[i]->pgrp, SIGCONT);
-       }
-    }
-}
-
-/* Cause all jobs, running or stopped, to receive a hangup signal.  If
-   a job is marked J_NOHUP, don't send the SIGHUP. */
-void
-hangup_all_jobs ()
-{
-  register int i;
-
-  /* XXX could use js.j_firstj here */
-  for (i = 0; i < js.j_jobslots; i++)
-    {
-      if (jobs[i])
-       {
-         if  (jobs[i]->flags & J_NOHUP)
-           continue;
-         killpg (jobs[i]->pgrp, SIGHUP);
-         if (STOPPED (i))
-           killpg (jobs[i]->pgrp, SIGCONT);
-       }
-    }
-}
-
-void
-kill_current_pipeline ()
-{
-  stop_making_children ();
-  start_pipeline ();
-}
-
-/* Return the pipeline that PID belongs to.  Note that the pipeline
-   doesn't have to belong to a job.  Must be called with SIGCHLD blocked.
-   If JOBP is non-null, return the index of the job containing PID.  */
-static PROCESS *
-find_pipeline (pid, alive_only, jobp)
-     pid_t pid;
-     int alive_only;
-     int *jobp;                /* index into jobs list or NO_JOB */
-{
-  int job;
-  PROCESS *p;
-
-  /* See if this process is in the pipeline that we are building. */
-  if (jobp)
-    *jobp = NO_JOB;
-  if (the_pipeline)
-    {
-      p = the_pipeline;
-      do
-       {
-         /* Return it if we found it.  Don't ever return a recycled pid. */
-         if (p->pid == pid && ((alive_only == 0 && PRECYCLED(p) == 0) || PALIVE(p)))
-           return (p);
-
-         p = p->next;
-       }
-      while (p != the_pipeline);
-    }
-
-  job = find_job (pid, alive_only, &p);
-  if (jobp)
-    *jobp = job;
-  return (job == NO_JOB) ? (PROCESS *)NULL : jobs[job]->pipe;
-}
-
-/* Return the PROCESS * describing PID.  If JOBP is non-null return the index
-   into the jobs array of the job containing PID.  Must be called with
-   SIGCHLD blocked. */
-static PROCESS *
-find_process (pid, alive_only, jobp)
-     pid_t pid;
-     int alive_only;
-     int *jobp;                /* index into jobs list or NO_JOB */
-{
-  PROCESS *p;
-
-  p = find_pipeline (pid, alive_only, jobp);
-  while (p && p->pid != pid)
-    p = p->next;
-  return p;
-}
-
-/* Return the job index that PID belongs to, or NO_JOB if it doesn't
-   belong to any job.  Must be called with SIGCHLD blocked. */
-static int
-find_job (pid, alive_only, procp)
-     pid_t pid;
-     int alive_only;
-     PROCESS **procp;
-{
-  register int i;
-  PROCESS *p;
-
-  /* XXX could use js.j_firstj here, and should check js.j_lastj */
-  for (i = 0; i < js.j_jobslots; i++)
-    {
-#if defined (DEBUG)
-      if (i < js.j_firstj && jobs[i])
-       itrace("find_job: job %d non-null before js.j_firstj (%d)", i, js.j_firstj);
-      if (i > js.j_lastj && jobs[i])
-       itrace("find_job: job %d non-null after js.j_lastj (%d)", i, js.j_lastj);
-#endif
-      if (jobs[i])
-       {
-         p = jobs[i]->pipe;
-
-         do
-           {
-             if (p->pid == pid && ((alive_only == 0 && PRECYCLED(p) == 0) || PALIVE(p)))
-               {
-                 if (procp)
-                   *procp = p;
-                 return (i);
-               }
-
-             p = p->next;
-           }
-         while (p != jobs[i]->pipe);
-       }
-    }
-
-  return (NO_JOB);
-}
-
-/* Find a job given a PID.  If BLOCK is non-zero, block SIGCHLD as
-   required by find_job. */
-int
-get_job_by_pid (pid, block)
-     pid_t pid;
-     int block;
-{
-  int job;
-  sigset_t set, oset;
-
-  if (block)
-    BLOCK_CHILD (set, oset);
-
-  job = find_job (pid, 0, NULL);
-
-  if (block)
-    UNBLOCK_CHILD (oset);
-
-  return job;
-}
-
-/* Print descriptive information about the job with leader pid PID. */
-void
-describe_pid (pid)
-     pid_t pid;
-{
-  int job;
-  sigset_t set, oset;
-
-  BLOCK_CHILD (set, oset);
-
-  job = find_job (pid, 0, NULL);
-
-  if (job != NO_JOB)
-    fprintf (stderr, "[%d] %ld\n", job + 1, (long)pid);
-  else
-    programming_error (_("describe_pid: %ld: no such pid"), (long)pid);
-
-  UNBLOCK_CHILD (oset);
-}
-
-static char *
-j_strsignal (s)
-     int s;
-{
-  char *x;
-
-  x = strsignal (s);
-  if (x == 0)
-    {
-      x = retcode_name_buffer;
-      sprintf (x, _("Signal %d"), s);
-    }
-  return x;
-}
-
-static char *
-printable_job_status (j, p, format)
-     int j;
-     PROCESS *p;
-     int format;
-{
-  static char *temp;
-  int es;
-
-  temp = _("Done");
-
-  if (STOPPED (j) && format == 0)
-    {
-      if (posixly_correct == 0 || p == 0 || (WIFSTOPPED (p->status) == 0))
-       temp = _("Stopped");
-      else
-       {
-         temp = retcode_name_buffer;
-         sprintf (temp, _("Stopped(%s)"), signal_name (WSTOPSIG (p->status)));
-       }
-    }
-  else if (RUNNING (j))
-    temp = _("Running");
-  else
-    {
-      if (WIFSTOPPED (p->status))
-       temp = j_strsignal (WSTOPSIG (p->status));
-      else if (WIFSIGNALED (p->status))
-       temp = j_strsignal (WTERMSIG (p->status));
-      else if (WIFEXITED (p->status))
-       {
-         temp = retcode_name_buffer;
-         es = WEXITSTATUS (p->status);
-         if (es == 0)
-           strcpy (temp, _("Done"));
-         else if (posixly_correct)
-           sprintf (temp, _("Done(%d)"), es);
-         else
-           sprintf (temp, _("Exit %d"), es);
-       }
-      else
-       temp = _("Unknown status");
-    }
-
-  return temp;
-}
-
-/* This is the way to print out information on a job if you
-   know the index.  FORMAT is:
-
-    JLIST_NORMAL)   [1]+ Running          emacs
-    JLIST_LONG  )   [1]+ 2378 Running      emacs
-    -1   )   [1]+ 2378       emacs
-
-    JLIST_NORMAL)   [1]+ Stopped          ls | more
-    JLIST_LONG  )   [1]+ 2369 Stopped      ls
-                        2367       | more
-    JLIST_PID_ONLY)
-       Just list the pid of the process group leader (really
-       the process group).
-    JLIST_CHANGED_ONLY)
-       Use format JLIST_NORMAL, but list only jobs about which
-       the user has not been notified. */
-
-/* Print status for pipeline P.  If JOB_INDEX is >= 0, it is the index into
-   the JOBS array corresponding to this pipeline.  FORMAT is as described
-   above.  Must be called with SIGCHLD blocked.
-
-   If you're printing a pipeline that's not in the jobs array, like the
-   current pipeline as it's being created, pass -1 for JOB_INDEX */
-static void
-print_pipeline (p, job_index, format, stream)
-     PROCESS *p;
-     int job_index, format;
-     FILE *stream;
-{
-  PROCESS *first, *last, *show;
-  int es, name_padding;
-  char *temp;
-
-  if (p == 0)
-    return;
-
-  first = last = p;
-  while (last->next != first)
-    last = last->next;
-
-  for (;;)
-    {
-      if (p != first)
-       fprintf (stream, format ? "     " : " |");
-
-      if (format != JLIST_STANDARD)
-       fprintf (stream, "%5ld", (long)p->pid);
-
-      fprintf (stream, " ");
-
-      if (format > -1 && job_index >= 0)
-       {
-         show = format ? p : last;
-         temp = printable_job_status (job_index, show, format);
-
-         if (p != first)
-           {
-             if (format)
-               {
-                 if (show->running == first->running &&
-                     WSTATUS (show->status) == WSTATUS (first->status))
-                   temp = "";
-               }
-             else
-               temp = (char *)NULL;
-           }
-
-         if (temp)
-           {
-             fprintf (stream, "%s", temp);
-
-             es = STRLEN (temp);
-             if (es == 0)
-               es = 2; /* strlen ("| ") */
-             name_padding = LONGEST_SIGNAL_DESC - es;
-
-             fprintf (stream, "%*s", name_padding, "");
-
-             if ((WIFSTOPPED (show->status) == 0) &&
-                 (WIFCONTINUED (show->status) == 0) &&
-                 WIFCORED (show->status))
-               fprintf (stream, _("(core dumped) "));
-           }
-       }
-
-      if (p != first && format)
-       fprintf (stream, "| ");
-
-      if (p->command)
-       fprintf (stream, "%s", p->command);
-
-      if (p == last && job_index >= 0)
-       {
-         temp = current_working_directory ();
-
-         if (RUNNING (job_index) && (IS_FOREGROUND (job_index) == 0))
-           fprintf (stream, " &");
-
-         if (strcmp (temp, jobs[job_index]->wd) != 0)
-           fprintf (stream,
-             _("  (wd: %s)"), polite_directory_format (jobs[job_index]->wd));
-       }
-
-      if (format || (p == last))
-       {
-         /* We need to add a CR only if this is an interactive shell, and
-            we're reporting the status of a completed job asynchronously.
-            We can't really check whether this particular job is being
-            reported asynchronously, so just add the CR if the shell is
-            currently interactive and asynchronous notification is enabled. */
-         if (asynchronous_notification && interactive)
-           fprintf (stream, "\r\n");
-         else
-           fprintf (stream, "\n");
-       }
-
-      if (p == last)
-       break;
-      p = p->next;
-    }
-  fflush (stream);
-}
-
-/* Print information to STREAM about jobs[JOB_INDEX] according to FORMAT.
-   Must be called with SIGCHLD blocked or queued with queue_sigchld */
-static void
-pretty_print_job (job_index, format, stream)
-     int job_index, format;
-     FILE *stream;
-{
-  register PROCESS *p;
-
-  /* Format only pid information about the process group leader? */
-  if (format == JLIST_PID_ONLY)
-    {
-      fprintf (stream, "%ld\n", (long)jobs[job_index]->pipe->pid);
-      return;
-    }
-
-  if (format == JLIST_CHANGED_ONLY)
-    {
-      if (IS_NOTIFIED (job_index))
-       return;
-      format = JLIST_STANDARD;
-    }
-
-  if (format != JLIST_NONINTERACTIVE)
-    fprintf (stream, "[%d]%c ", job_index + 1,
-             (job_index == js.j_current) ? '+':
-               (job_index == js.j_previous) ? '-' : ' ');
-
-  if (format == JLIST_NONINTERACTIVE)
-    format = JLIST_LONG;
-
-  p = jobs[job_index]->pipe;
-
-  print_pipeline (p, job_index, format, stream);
-
-  /* We have printed information about this job.  When the job's
-     status changes, waitchld () sets the notification flag to 0. */
-  jobs[job_index]->flags |= J_NOTIFIED;
-}
-
-static int
-print_job (job, format, state, job_index)
-     JOB *job;
-     int format, state, job_index;
-{
-  if (state == -1 || (JOB_STATE)state == job->state)
-    pretty_print_job (job_index, format, stdout);
-  return (0);
-}
-
-void
-list_one_job (job, format, ignore, job_index)
-     JOB *job;
-     int format, ignore, job_index;
-{
-  pretty_print_job (job_index, format, stdout);
-}
-
-void
-list_stopped_jobs (format)
-     int format;
-{
-  cleanup_dead_jobs ();
-  map_over_jobs (print_job, format, (int)JSTOPPED);
-}
-
-void
-list_running_jobs (format)
-     int format;
-{
-  cleanup_dead_jobs ();
-  map_over_jobs (print_job, format, (int)JRUNNING);
-}
-
-/* List jobs.  If FORMAT is non-zero, then the long form of the information
-   is printed, else just a short version. */
-void
-list_all_jobs (format)
-     int format;
-{
-  cleanup_dead_jobs ();
-  map_over_jobs (print_job, format, -1);
-}
-
-/* Fork, handling errors.  Returns the pid of the newly made child, or 0.
-   COMMAND is just for remembering the name of the command; we don't do
-   anything else with it.  ASYNC_P says what to do with the tty.  If
-   non-zero, then don't give it away. */
-pid_t
-make_child (command, async_p)
-     char *command;
-     int async_p;
-{
-  int forksleep;
-  sigset_t set, oset;
-  pid_t pid;
-
-  sigemptyset (&set);
-  sigaddset (&set, SIGCHLD);
-  sigaddset (&set, SIGINT);
-  sigemptyset (&oset);
-  sigprocmask (SIG_BLOCK, &set, &oset);
-
-  making_children ();
-
-  forksleep = 1;
-
-#if defined (BUFFERED_INPUT)
-  /* If default_buffered_input is active, we are reading a script.  If
-     the command is asynchronous, we have already duplicated /dev/null
-     as fd 0, but have not changed the buffered stream corresponding to
-     the old fd 0.  We don't want to sync the stream in this case. */
-  if (default_buffered_input != -1 &&
-      (!async_p || default_buffered_input > 0))
-    sync_buffered_stream (default_buffered_input);
-#endif /* BUFFERED_INPUT */
-
-  /* Create the child, handle severe errors.  Retry on EAGAIN. */
-  while ((pid = fork ()) < 0 && errno == EAGAIN && forksleep < FORKSLEEP_MAX)
-    {
-#if 0          /* for bash-4.2 */
-      /* If we can't create any children, try to wait for some dead ones. */
-      waitchld (-1, 0);
-#endif
-      sys_error ("fork: retry");
-      if (sleep (forksleep) != 0)
-       break;
-      forksleep <<= 1;
-    }
-
-  if (pid < 0)
-    {
-      sys_error ("fork");
-
-      /* Kill all of the processes in the current pipeline. */
-      terminate_current_pipeline ();
-
-      /* Discard the current pipeline, if any. */
-      if (the_pipeline)
-       kill_current_pipeline ();
-
-      last_command_exit_value = EX_NOEXEC;
-      throw_to_top_level ();   /* Reset signals, etc. */
-    }
-
-  if (pid == 0)
-    {
-      /* In the child.  Give this child the right process group, set the
-        signals to the default state for a new process. */
-      pid_t mypid;
-
-      mypid = getpid ();
-#if defined (BUFFERED_INPUT)
-      /* Close default_buffered_input if it's > 0.  We don't close it if it's
-        0 because that's the file descriptor used when redirecting input,
-        and it's wrong to close the file in that case. */
-      unset_bash_input (0);
-#endif /* BUFFERED_INPUT */
-
-      /* Restore top-level signal mask. */
-      sigprocmask (SIG_SETMASK, &top_level_mask, (sigset_t *)NULL);
-
-      if (job_control)
-       {
-         /* All processes in this pipeline belong in the same
-            process group. */
-
-         if (pipeline_pgrp == 0)       /* This is the first child. */
-           pipeline_pgrp = mypid;
-
-         /* Check for running command in backquotes. */
-         if (pipeline_pgrp == shell_pgrp)
-           ignore_tty_job_signals ();
-         else
-           default_tty_job_signals ();
-
-         /* Set the process group before trying to mess with the terminal's
-            process group.  This is mandated by POSIX. */
-         /* This is in accordance with the Posix 1003.1 standard,
-            section B.7.2.4, which says that trying to set the terminal
-            process group with tcsetpgrp() to an unused pgrp value (like
-            this would have for the first child) is an error.  Section
-            B.4.3.3, p. 237 also covers this, in the context of job control
-            shells. */
-         if (setpgid (mypid, pipeline_pgrp) < 0)
-           sys_error (_("child setpgid (%ld to %ld)"), (long)mypid, (long)pipeline_pgrp);
-
-         /* By convention (and assumption above), if
-            pipeline_pgrp == shell_pgrp, we are making a child for
-            command substitution.
-            In this case, we don't want to give the terminal to the
-            shell's process group (we could be in the middle of a
-            pipeline, for example). */
-         if (async_p == 0 && pipeline_pgrp != shell_pgrp && ((subshell_environment&SUBSHELL_ASYNC) == 0))
-           give_terminal_to (pipeline_pgrp, 0);
-
-#if defined (PGRP_PIPE)
-         if (pipeline_pgrp == mypid)
-           pipe_read (pgrp_pipe);
-#endif
-       }
-      else                     /* Without job control... */
-       {
-         if (pipeline_pgrp == 0)
-           pipeline_pgrp = shell_pgrp;
-
-         /* If these signals are set to SIG_DFL, we encounter the curious
-            situation of an interactive ^Z to a running process *working*
-            and stopping the process, but being unable to do anything with
-            that process to change its state.  On the other hand, if they
-            are set to SIG_IGN, jobs started from scripts do not stop when
-            the shell running the script gets a SIGTSTP and stops. */
-
-         default_tty_job_signals ();
-       }
-
-#if defined (PGRP_PIPE)
-      /* Release the process group pipe, since our call to setpgid ()
-        is done.  The last call to sh_closepipe is done in stop_pipeline. */
-      sh_closepipe (pgrp_pipe);
-#endif /* PGRP_PIPE */
-
-#if 0
-      /* Don't set last_asynchronous_pid in the child */
-      if (async_p)
-       last_asynchronous_pid = mypid;          /* XXX */
-      else
-#endif
-#if defined (RECYCLES_PIDS)
-      if (last_asynchronous_pid == mypid)
-        /* Avoid pid aliasing.  1 seems like a safe, unusual pid value. */
-       last_asynchronous_pid = 1;
-#endif
-    }
-  else
-    {
-      /* In the parent.  Remember the pid of the child just created
-        as the proper pgrp if this is the first child. */
-
-      if (first_pid == NO_PID)
-       first_pid = pid;
-      else if (pid_wrap == -1 && pid < first_pid)
-       pid_wrap = 0;
-      else if (pid_wrap == 0 && pid >= first_pid)
-       pid_wrap = 1;
-
-      if (job_control)
-       {
-         if (pipeline_pgrp == 0)
-           {
-             pipeline_pgrp = pid;
-             /* Don't twiddle terminal pgrps in the parent!  This is the bug,
-                not the good thing of twiddling them in the child! */
-             /* give_terminal_to (pipeline_pgrp, 0); */
-           }
-         /* This is done on the recommendation of the Rationale section of
-            the POSIX 1003.1 standard, where it discusses job control and
-            shells.  It is done to avoid possible race conditions. (Ref.
-            1003.1 Rationale, section B.4.3.3, page 236). */
-         setpgid (pid, pipeline_pgrp);
-       }
-      else
-       {
-         if (pipeline_pgrp == 0)
-           pipeline_pgrp = shell_pgrp;
-       }
-
-      /* Place all processes into the jobs array regardless of the
-        state of job_control. */
-      add_process (command, pid);
-
-      if (async_p)
-       last_asynchronous_pid = pid;
-#if defined (RECYCLES_PIDS)
-      else if (last_asynchronous_pid == pid)
-        /* Avoid pid aliasing.  1 seems like a safe, unusual pid value. */
-       last_asynchronous_pid = 1;
-#endif
-
-      if (pid_wrap > 0)
-       delete_old_job (pid);
-
-#if !defined (RECYCLES_PIDS)
-      /* Only check for saved status if we've saved more than CHILD_MAX
-        statuses, unless the system recycles pids. */
-      if ((js.c_reaped + bgpids.npid) >= js.c_childmax)
-#endif
-       bgp_delete (pid);               /* new process, discard any saved status */
-
-      last_made_pid = pid;
-
-      /* keep stats */
-      js.c_totforked++;
-      js.c_living++;
-
-      /* Unblock SIGINT and SIGCHLD unless creating a pipeline, in which case
-        SIGCHLD remains blocked until all commands in the pipeline have been
-        created. */
-      sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
-    }
-
-  return (pid);
-}
-
-/* These two functions are called only in child processes. */
-void
-ignore_tty_job_signals ()
-{
-  set_signal_handler (SIGTSTP, SIG_IGN);
-  set_signal_handler (SIGTTIN, SIG_IGN);
-  set_signal_handler (SIGTTOU, SIG_IGN);
-}
-
-void
-default_tty_job_signals ()
-{
-  set_signal_handler (SIGTSTP, SIG_DFL);
-  set_signal_handler (SIGTTIN, SIG_DFL);
-  set_signal_handler (SIGTTOU, SIG_DFL);
-}
-
-/* When we end a job abnormally, or if we stop a job, we set the tty to the
-   state kept in here.  When a job ends normally, we set the state in here
-   to the state of the tty. */
-
-static TTYSTRUCT shell_tty_info;
-
-#if defined (NEW_TTY_DRIVER)
-static struct tchars shell_tchars;
-static struct ltchars shell_ltchars;
-#endif /* NEW_TTY_DRIVER */
-
-#if defined (NEW_TTY_DRIVER) && defined (DRAIN_OUTPUT)
-/* Since the BSD tty driver does not allow us to change the tty modes
-   while simultaneously waiting for output to drain and preserving
-   typeahead, we have to drain the output ourselves before calling
-   ioctl.  We cheat by finding the length of the output queue, and
-   using select to wait for an appropriate length of time.  This is
-   a hack, and should be labeled as such (it's a hastily-adapted
-   mutation of a `usleep' implementation).  It's only reason for
-   existing is the flaw in the BSD tty driver. */
-
-static int ttspeeds[] =
-{
-  0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
-  1800, 2400, 4800, 9600, 19200, 38400
-};
-
-static void
-draino (fd, ospeed)
-     int fd, ospeed;
-{
-  register int delay = ttspeeds[ospeed];
-  int n;
-
-  if (!delay)
-    return;
-
-  while ((ioctl (fd, TIOCOUTQ, &n) == 0) && n)
-    {
-      if (n > (delay / 100))
-       {
-         struct timeval tv;
-
-         n *= 10;              /* 2 bits more for conservativeness. */
-         tv.tv_sec = n / delay;
-         tv.tv_usec = ((n % delay) * 1000000) / delay;
-         select (fd, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv);
-       }
-      else
-       break;
-    }
-}
-#endif /* NEW_TTY_DRIVER && DRAIN_OUTPUT */
-
-/* Return the fd from which we are actually getting input. */
-#define input_tty() (shell_tty != -1) ? shell_tty : fileno (stderr)
-
-/* Fill the contents of shell_tty_info with the current tty info. */
-int
-get_tty_state ()
-{
-  int tty;
-
-  tty = input_tty ();
-  if (tty != -1)
-    {
-#if defined (NEW_TTY_DRIVER)
-      ioctl (tty, TIOCGETP, &shell_tty_info);
-      ioctl (tty, TIOCGETC, &shell_tchars);
-      ioctl (tty, TIOCGLTC, &shell_ltchars);
-#endif /* NEW_TTY_DRIVER */
-
-#if defined (TERMIO_TTY_DRIVER)
-      ioctl (tty, TCGETA, &shell_tty_info);
-#endif /* TERMIO_TTY_DRIVER */
-
-#if defined (TERMIOS_TTY_DRIVER)
-      if (tcgetattr (tty, &shell_tty_info) < 0)
-       {
-#if 0
-         /* Only print an error message if we're really interactive at
-            this time. */
-         if (interactive)
-           sys_error ("[%ld: %d (%d)] tcgetattr", (long)getpid (), shell_level, tty);
-#endif
-         return -1;
-       }
-#endif /* TERMIOS_TTY_DRIVER */
-      if (check_window_size)
-       get_new_window_size (0, (int *)0, (int *)0);
-    }
-  return 0;
-}
-
-/* Make the current tty use the state in shell_tty_info. */
-int
-set_tty_state ()
-{
-  int tty;
-
-  tty = input_tty ();
-  if (tty != -1)
-    {
-#if defined (NEW_TTY_DRIVER)
-#  if defined (DRAIN_OUTPUT)
-      draino (tty, shell_tty_info.sg_ospeed);
-#  endif /* DRAIN_OUTPUT */
-      ioctl (tty, TIOCSETN, &shell_tty_info);
-      ioctl (tty, TIOCSETC, &shell_tchars);
-      ioctl (tty, TIOCSLTC, &shell_ltchars);
-#endif /* NEW_TTY_DRIVER */
-
-#if defined (TERMIO_TTY_DRIVER)
-      ioctl (tty, TCSETAW, &shell_tty_info);
-#endif /* TERMIO_TTY_DRIVER */
-
-#if defined (TERMIOS_TTY_DRIVER)
-      if (tcsetattr (tty, TCSADRAIN, &shell_tty_info) < 0)
-       {
-         /* Only print an error message if we're really interactive at
-            this time. */
-         if (interactive)
-           sys_error ("[%ld: %d (%d)] tcsetattr", (long)getpid (), shell_level, tty);
-         return -1;
-       }
-#endif /* TERMIOS_TTY_DRIVER */
-    }
-  return 0;
-}
-
-/* Given an index into the jobs array JOB, return the PROCESS struct of the last
-   process in that job's pipeline.  This is the one whose exit status
-   counts.  Must be called with SIGCHLD blocked or queued. */
-static PROCESS *
-find_last_proc (job, block)
-     int job;
-     int block;
-{
-  register PROCESS *p;
-  sigset_t set, oset;
-
-  if (block)
-    BLOCK_CHILD (set, oset);
-
-  p = jobs[job]->pipe;
-  while (p && p->next != jobs[job]->pipe)
-    p = p->next;
-
-  if (block)
-    UNBLOCK_CHILD (oset);
-
-  return (p);
-}
-
-static pid_t
-find_last_pid (job, block)
-     int job;
-     int block;
-{
-  PROCESS *p;
-
-  p = find_last_proc (job, block);
-  /* Possible race condition here. */
-  return p->pid;
-}     
-
-/* Wait for a particular child of the shell to finish executing.
-   This low-level function prints an error message if PID is not
-   a child of this shell.  It returns -1 if it fails, or whatever
-   wait_for returns otherwise.  If the child is not found in the
-   jobs table, it returns 127. */
-int
-wait_for_single_pid (pid)
-     pid_t pid;
-{
-  register PROCESS *child;
-  sigset_t set, oset;
-  int r, job;
-
-  BLOCK_CHILD (set, oset);
-  child = find_pipeline (pid, 0, (int *)NULL);
-  UNBLOCK_CHILD (oset);
-
-  if (child == 0)
-    {
-      r = bgp_search (pid);
-      if (r >= 0)
-       return r;
-    }
-
-  if (child == 0)
-    {
-      internal_error (_("wait: pid %ld is not a child of this shell"), (long)pid);
-      return (127);
-    }
-
-  r = wait_for (pid);
-
-  /* POSIX.2: if we just waited for a job, we can remove it from the jobs
-     table. */
-  BLOCK_CHILD (set, oset);
-  job = find_job (pid, 0, NULL);
-  if (job != NO_JOB && jobs[job] && DEADJOB (job))
-    jobs[job]->flags |= J_NOTIFIED;
-  UNBLOCK_CHILD (oset);
-
-  /* If running in posix mode, remove the job from the jobs table immediately */
-  if (posixly_correct)
-    {
-      cleanup_dead_jobs ();
-      bgp_delete (pid);
-    }
-
-  return r;
-}
-
-/* Wait for all of the backgrounds of this shell to finish. */
-void
-wait_for_background_pids ()
-{
-  register int i, r, waited_for;
-  sigset_t set, oset;
-  pid_t pid;
-
-  for (waited_for = 0;;)
-    {
-      BLOCK_CHILD (set, oset);
-
-      /* find first running job; if none running in foreground, break */
-      /* XXX could use js.j_firstj and js.j_lastj here */
-      for (i = 0; i < js.j_jobslots; i++)
-       {
-#if defined (DEBUG)
-         if (i < js.j_firstj && jobs[i])
-           itrace("wait_for_background_pids: job %d non-null before js.j_firstj (%d)", i, js.j_firstj);
-         if (i > js.j_lastj && jobs[i])
-           itrace("wait_for_background_pids: job %d non-null after js.j_lastj (%d)", i, js.j_lastj);
-#endif
-         if (jobs[i] && RUNNING (i) && IS_FOREGROUND (i) == 0)
-           break;
-       }
-      if (i == js.j_jobslots)
-       {
-         UNBLOCK_CHILD (oset);
-         break;
-       }
-
-      /* now wait for the last pid in that job. */
-      pid = find_last_pid (i, 0);
-      UNBLOCK_CHILD (oset);
-      QUIT;
-      errno = 0;               /* XXX */
-      r = wait_for_single_pid (pid);
-      if (r == -1)
-       {
-         /* If we're mistaken about job state, compensate. */
-         if (errno == ECHILD)
-           mark_all_jobs_as_dead ();
-       }
-      else
-       waited_for++;
-    }
-
-  /* POSIX.2 says the shell can discard the statuses of all completed jobs if
-     `wait' is called with no arguments. */
-  mark_dead_jobs_as_notified (1);
-  cleanup_dead_jobs ();
-  bgp_clear ();
-}
-
-/* Make OLD_SIGINT_HANDLER the SIGINT signal handler. */
-#define INVALID_SIGNAL_HANDLER (SigHandler *)wait_for_background_pids
-static SigHandler *old_sigint_handler = INVALID_SIGNAL_HANDLER;
-
-static void
-restore_sigint_handler ()
-{
-  if (old_sigint_handler != INVALID_SIGNAL_HANDLER)
-    {
-      set_signal_handler (SIGINT, old_sigint_handler);
-      old_sigint_handler = INVALID_SIGNAL_HANDLER;
-    }
-}
-
-static int wait_sigint_received;
-
-/* Handle SIGINT while we are waiting for children in a script to exit.
-   The `wait' builtin should be interruptible, but all others should be
-   effectively ignored (i.e. not cause the shell to exit). */
-static sighandler
-wait_sigint_handler (sig)
-     int sig;
-{
-  SigHandler *sigint_handler;
-
-  if (interrupt_immediately ||
-      (this_shell_builtin && this_shell_builtin == wait_builtin))
-    {
-      last_command_exit_value = EXECUTION_FAILURE;
-      restore_sigint_handler ();
-      /* If we got a SIGINT while in `wait', and SIGINT is trapped, do
-        what POSIX.2 says (see builtins/wait.def for more info). */
-      if (this_shell_builtin && this_shell_builtin == wait_builtin &&
-         signal_is_trapped (SIGINT) &&
-         ((sigint_handler = trap_to_sighandler (SIGINT)) == trap_handler))
-       {
-         interrupt_immediately = 0;
-         trap_handler (SIGINT);        /* set pending_traps[SIGINT] */
-         wait_signal_received = SIGINT;
-         longjmp (wait_intr_buf, 1);
-       }
-      
-      ADDINTERRUPT;
-      QUIT;
-    }
-
-  /* XXX - should this be interrupt_state?  If it is, the shell will act
-     as if it got the SIGINT interrupt. */
-  wait_sigint_received = 1;
-
-  /* Otherwise effectively ignore the SIGINT and allow the running job to
-     be killed. */
-  SIGRETURN (0);
-}
-
-static int
-process_exit_signal (status)
-     WAIT status;
-{
-  return (WIFSIGNALED (status) ? WTERMSIG (status) : 0);
-}
-
-static int
-process_exit_status (status)
-     WAIT status;
-{
-  if (WIFSIGNALED (status))
-    return (128 + WTERMSIG (status));
-  else if (WIFSTOPPED (status) == 0)
-    return (WEXITSTATUS (status));
-  else
-    return (EXECUTION_SUCCESS);
-}
-
-static WAIT
-job_signal_status (job)
-     int job;
-{
-  register PROCESS *p;
-  WAIT s;
-
-  p = jobs[job]->pipe;
-  do
-    {
-      s = p->status;
-      if (WIFSIGNALED(s) || WIFSTOPPED(s))
-       break;
-      p = p->next;
-    }
-  while (p != jobs[job]->pipe);
-
-  return s;
-}
-  
-/* Return the exit status of the last process in the pipeline for job JOB.
-   This is the exit status of the entire job. */
-static WAIT
-raw_job_exit_status (job)
-     int job;
-{
-  register PROCESS *p;
-  int fail;
-  WAIT ret;
-
-  if (pipefail_opt)
-    {
-      fail = 0;
-      p = jobs[job]->pipe;
-      do
-       {
-         if (WSTATUS (p->status) != EXECUTION_SUCCESS)
-           fail = WSTATUS(p->status);
-         p = p->next;
-       }
-      while (p != jobs[job]->pipe);
-      WSTATUS (ret) = fail;
-      return ret;
-    }
-
-  for (p = jobs[job]->pipe; p->next != jobs[job]->pipe; p = p->next)
-    ;
-  return (p->status);
-}
-
-/* Return the exit status of job JOB.  This is the exit status of the last
-   (rightmost) process in the job's pipeline, modified if the job was killed
-   by a signal or stopped. */
-static int
-job_exit_status (job)
-     int job;
-{
-  return (process_exit_status (raw_job_exit_status (job)));
-}
-
-static int
-job_exit_signal (job)
-     int job;
-{
-  return (process_exit_signal (raw_job_exit_status (job)));
-}
-
-#define FIND_CHILD(pid, child) \
-  do \
-    { \
-      child = find_pipeline (pid, 0, (int *)NULL); \
-      if (child == 0) \
-       { \
-         give_terminal_to (shell_pgrp, 0); \
-         UNBLOCK_CHILD (oset); \
-         internal_error (_("wait_for: No record of process %ld"), (long)pid); \
-         restore_sigint_handler (); \
-         return (termination_state = 127); \
-       } \
-    } \
-  while (0)
-
-/* Wait for pid (one of our children) to terminate, then
-   return the termination state.  Returns 127 if PID is not found in
-   the jobs table.  Returns -1 if waitchld() returns -1, indicating
-   that there are no unwaited-for child processes. */
-int
-wait_for (pid)
-     pid_t pid;
-{
-  int job, termination_state, r;
-  WAIT s;
-  register PROCESS *child;
-  sigset_t set, oset;
-  register PROCESS *p;
-
-  /* In the case that this code is interrupted, and we longjmp () out of it,
-     we are relying on the code in throw_to_top_level () to restore the
-     top-level signal mask. */
-  BLOCK_CHILD (set, oset);
-
-  /* Ignore interrupts while waiting for a job run without job control
-     to finish.  We don't want the shell to exit if an interrupt is
-     received, only if one of the jobs run is killed via SIGINT.  If
-     job control is not set, the job will be run in the same pgrp as
-     the shell, and the shell will see any signals the job gets.  In
-     fact, we want this set every time the waiting shell and the waited-
-     for process are in the same process group, including command
-     substitution. */
-
-  /* This is possibly a race condition -- should it go in stop_pipeline? */
-  wait_sigint_received = 0;
-  if (job_control == 0 || (subshell_environment&SUBSHELL_COMSUB))
-    {
-      old_sigint_handler = set_signal_handler (SIGINT, wait_sigint_handler);
-      if (old_sigint_handler == SIG_IGN)
-       set_signal_handler (SIGINT, old_sigint_handler);
-    }
-
-  termination_state = last_command_exit_value;
-
-  if (interactive && job_control == 0)
-    QUIT;
-  /* Check for terminating signals and exit the shell if we receive one */
-  CHECK_TERMSIG;
-
-  /* If we say wait_for (), then we have a record of this child somewhere.
-     If it and none of its peers are running, don't call waitchld(). */
-
-  job = NO_JOB;
-  do
-    {
-      FIND_CHILD (pid, child);
-
-      /* If this child is part of a job, then we are really waiting for the
-        job to finish.  Otherwise, we are waiting for the child to finish.
-        We check for JDEAD in case the job state has been set by waitchld
-        after receipt of a SIGCHLD. */
-      if (job == NO_JOB)
-       job = find_job (pid, 0, NULL);
-
-      /* waitchld() takes care of setting the state of the job.  If the job
-        has already exited before this is called, sigchld_handler will have
-        called waitchld and the state will be set to JDEAD. */
-
-      if (PRUNNING(child) || (job != NO_JOB && RUNNING (job)))
-       {
-#if defined (WAITPID_BROKEN)    /* SCOv4 */
-         sigset_t suspend_set;
-         sigemptyset (&suspend_set);
-         sigsuspend (&suspend_set);
-#else /* !WAITPID_BROKEN */
-#  if defined (MUST_UNBLOCK_CHLD)
-         struct sigaction act, oact;
-         sigset_t nullset, chldset;
-
-         sigemptyset (&nullset);
-         sigemptyset (&chldset);
-         sigprocmask (SIG_SETMASK, &nullset, &chldset);
-         act.sa_handler = SIG_DFL;
-         sigemptyset (&act.sa_mask);
-         sigemptyset (&oact.sa_mask);
-         act.sa_flags = 0;
-         sigaction (SIGCHLD, &act, &oact);
-#  endif
-         queue_sigchld = 1;
-         r = waitchld (pid, 1);
-#  if defined (MUST_UNBLOCK_CHLD)
-         sigaction (SIGCHLD, &oact, (struct sigaction *)NULL);
-         sigprocmask (SIG_SETMASK, &chldset, (sigset_t *)NULL);
-#  endif
-         queue_sigchld = 0;
-         if (r == -1 && errno == ECHILD && this_shell_builtin == wait_builtin)
-           {
-             termination_state = -1;
-             goto wait_for_return;
-           }
-
-         /* If child is marked as running, but waitpid() returns -1/ECHILD,
-            there is something wrong.  Somewhere, wait should have returned
-            that child's pid.  Mark the child as not running and the job,
-            if it exists, as JDEAD. */
-         if (r == -1 && errno == ECHILD)
-           {
-             child->running = PS_DONE;
-             WSTATUS (child->status) = 0;      /* XXX -- can't find true status */
-             js.c_living = 0;          /* no living child processes */
-             if (job != NO_JOB)
-               {
-                 jobs[job]->state = JDEAD;
-                 js.c_reaped++;
-                 js.j_ndead++;
-               }
-           }
-#endif /* WAITPID_BROKEN */
-       }
-
-      /* If the shell is interactive, and job control is disabled, see
-        if the foreground process has died due to SIGINT and jump out
-        of the wait loop if it has.  waitchld has already restored the
-        old SIGINT signal handler. */
-      if (interactive && job_control == 0)
-       QUIT;
-      /* Check for terminating signals and exit the shell if we receive one */
-      CHECK_TERMSIG;
-    }
-  while (PRUNNING (child) || (job != NO_JOB && RUNNING (job)));
-
-  /* The exit state of the command is either the termination state of the
-     child, or the termination state of the job.  If a job, the status
-     of the last child in the pipeline is the significant one.  If the command
-     or job was terminated by a signal, note that value also. */
-  termination_state = (job != NO_JOB) ? job_exit_status (job)
-                                     : process_exit_status (child->status);
-  last_command_exit_signal = (job != NO_JOB) ? job_exit_signal (job)
-                                            : process_exit_signal (child->status);
-
-  /* XXX */
-  if ((job != NO_JOB && JOBSTATE (job) == JSTOPPED) || WIFSTOPPED (child->status))
-    termination_state = 128 + WSTOPSIG (child->status);
-
-  if (job == NO_JOB || IS_JOBCONTROL (job))
-    {
-      /* XXX - under what circumstances is a job not present in the jobs
-        table (job == NO_JOB)?
-               1.  command substitution
-
-        In the case of command substitution, at least, it's probably not
-        the right thing to give the terminal to the shell's process group,
-        even though there is code in subst.c:command_substitute to work
-        around it.
-
-        Things that don't:
-               $PROMPT_COMMAND execution
-               process substitution
-       */
-#if 0
-if (job == NO_JOB)
-  itrace("wait_for: job == NO_JOB, giving the terminal to shell_pgrp (%ld)", (long)shell_pgrp);
-#endif
-      give_terminal_to (shell_pgrp, 0);
-    }
-
-  /* If the command did not exit cleanly, or the job is just
-     being stopped, then reset the tty state back to what it
-     was before this command.  Reset the tty state and notify
-     the user of the job termination only if the shell is
-     interactive.  Clean up any dead jobs in either case. */
-  if (job != NO_JOB)
-    {
-      if (interactive_shell && subshell_environment == 0)
-       {
-         /* This used to use `child->status'.  That's wrong, however, for
-            pipelines.  `child' is the first process in the pipeline.  It's
-            likely that the process we want to check for abnormal termination
-            or stopping is the last process in the pipeline, especially if
-            it's long-lived and the first process is short-lived.  Since we
-            know we have a job here, we can check all the processes in this
-            job's pipeline and see if one of them stopped or terminated due
-            to a signal.  We might want to change this later to just check
-            the last process in the pipeline.  If no process exits due to a
-            signal, S is left as the status of the last job in the pipeline. */
-         s = job_signal_status (job);
-
-         if (WIFSIGNALED (s) || WIFSTOPPED (s))
-           {
-             set_tty_state ();
-
-             /* If the current job was stopped or killed by a signal, and
-                the user has requested it, get a possibly new window size */
-             if (check_window_size && (job == js.j_current || IS_FOREGROUND (job)))
-               get_new_window_size (0, (int *)0, (int *)0);
-           }
-         else
-           get_tty_state ();
-
-         /* If job control is enabled, the job was started with job
-            control, the job was the foreground job, and it was killed
-            by SIGINT, then print a newline to compensate for the kernel
-            printing the ^C without a trailing newline. */
-         if (job_control && IS_JOBCONTROL (job) && IS_FOREGROUND (job) &&
-               WIFSIGNALED (s) && WTERMSIG (s) == SIGINT)
-           {
-             /* If SIGINT is not trapped and the shell is in a for, while,
-                or until loop, act as if the shell received SIGINT as
-                well, so the loop can be broken.  This doesn't call the
-                SIGINT signal handler; maybe it should. */
-             if (signal_is_trapped (SIGINT) == 0 && (loop_level || (shell_compatibility_level > 32 && executing_list)))
-               ADDINTERRUPT;
-             else
-               {
-                 putchar ('\n');
-                 fflush (stdout);
-               }
-           }
-       }
-      else if ((subshell_environment & SUBSHELL_COMSUB) && wait_sigint_received)
-       {
-         /* If waiting for a job in a subshell started to do command
-            substitution, simulate getting and being killed by the SIGINT to
-            pass the status back to our parent. */
-         s = job_signal_status (job);
-       
-         if (WIFSIGNALED (s) && WTERMSIG (s) == SIGINT && signal_is_trapped (SIGINT) == 0)
-           {
-             UNBLOCK_CHILD (oset);
-             restore_sigint_handler ();
-             old_sigint_handler = set_signal_handler (SIGINT, SIG_DFL);
-             if (old_sigint_handler == SIG_IGN)
-               restore_sigint_handler ();
-             else
-               kill (getpid (), SIGINT);
-           }
-       }
-
-      /* Moved here from set_job_status_and_cleanup, which is in the SIGCHLD
-         signal handler path */
-      if (DEADJOB (job) && IS_FOREGROUND (job) /*&& subshell_environment == 0*/)
-       setjstatus (job);
-
-      /* If this job is dead, notify the user of the status.  If the shell
-        is interactive, this will display a message on the terminal.  If
-        the shell is not interactive, make sure we turn on the notify bit
-        so we don't get an unwanted message about the job's termination,
-        and so delete_job really clears the slot in the jobs table. */
-      notify_and_cleanup ();
-    }
-
-wait_for_return:
-
-  UNBLOCK_CHILD (oset);
-
-  /* Restore the original SIGINT signal handler before we return. */
-  restore_sigint_handler ();
-
-  return (termination_state);
-}
-
-/* Wait for the last process in the pipeline for JOB.  Returns whatever
-   wait_for returns: the last process's termination state or -1 if there
-   are no unwaited-for child processes or an error occurs. */
-int
-wait_for_job (job)
-     int job;
-{
-  pid_t pid;
-  int r;
-  sigset_t set, oset;
-
-  BLOCK_CHILD(set, oset);
-  if (JOBSTATE (job) == JSTOPPED)
-    internal_warning (_("wait_for_job: job %d is stopped"), job+1);
-
-  pid = find_last_pid (job, 0);
-  UNBLOCK_CHILD(oset);
-  r = wait_for (pid);
-
-  /* POSIX.2: we can remove the job from the jobs table if we just waited
-     for it. */
-  BLOCK_CHILD (set, oset);
-  if (job != NO_JOB && jobs[job] && DEADJOB (job))
-    jobs[job]->flags |= J_NOTIFIED;
-  UNBLOCK_CHILD (oset);
-
-  return r;
-}
-
-/* Print info about dead jobs, and then delete them from the list
-   of known jobs.  This does not actually delete jobs when the
-   shell is not interactive, because the dead jobs are not marked
-   as notified. */
-void
-notify_and_cleanup ()
-{
-  if (jobs_list_frozen)
-    return;
-
-  if (interactive || interactive_shell == 0 || sourcelevel)
-    notify_of_job_status ();
-
-  cleanup_dead_jobs ();
-}
-
-/* Make dead jobs disappear from the jobs array without notification.
-   This is used when the shell is not interactive. */
-void
-reap_dead_jobs ()
-{
-  mark_dead_jobs_as_notified (0);
-  cleanup_dead_jobs ();
-}
-
-/* Return the next closest (chronologically) job to JOB which is in
-   STATE.  STATE can be JSTOPPED, JRUNNING.  NO_JOB is returned if
-   there is no next recent job. */
-static int
-most_recent_job_in_state (job, state)
-     int job;
-     JOB_STATE state;
-{
-  register int i, result;
-  sigset_t set, oset;
-
-  BLOCK_CHILD (set, oset);
-
-  for (result = NO_JOB, i = job - 1; i >= 0; i--)
-    {
-      if (jobs[i] && (JOBSTATE (i) == state))
-       {
-         result = i;
-         break;
-       }
-    }
-
-  UNBLOCK_CHILD (oset);
-
-  return (result);
-}
-
-/* Return the newest *stopped* job older than JOB, or NO_JOB if not
-   found. */
-static int
-job_last_stopped (job)
-     int job;
-{
-  return (most_recent_job_in_state (job, JSTOPPED));
-}
-
-/* Return the newest *running* job older than JOB, or NO_JOB if not
-   found. */
-static int
-job_last_running (job)
-     int job;
-{
-  return (most_recent_job_in_state (job, JRUNNING));
-}
-
-/* Make JOB be the current job, and make previous be useful.  Must be
-   called with SIGCHLD blocked. */
-static void
-set_current_job (job)
-     int job;
-{
-  int candidate;
-
-  if (js.j_current != job)
-    {
-      js.j_previous = js.j_current;
-      js.j_current = job;
-    }
-
-  /* First choice for previous job is the old current job. */
-  if (js.j_previous != js.j_current &&
-      js.j_previous != NO_JOB &&
-      jobs[js.j_previous] &&
-      STOPPED (js.j_previous))
-    return;
-
-  /* Second choice:  Newest stopped job that is older than
-     the current job. */
-  candidate = NO_JOB;
-  if (STOPPED (js.j_current))
-    {
-      candidate = job_last_stopped (js.j_current);
-
-      if (candidate != NO_JOB)
-       {
-         js.j_previous = candidate;
-         return;
-       }
-    }
-
-  /* If we get here, there is either only one stopped job, in which case it is
-     the current job and the previous job should be set to the newest running
-     job, or there are only running jobs and the previous job should be set to
-     the newest running job older than the current job.  We decide on which
-     alternative to use based on whether or not JOBSTATE(js.j_current) is
-     JSTOPPED. */
-
-  candidate = RUNNING (js.j_current) ? job_last_running (js.j_current)
-                                   : job_last_running (js.j_jobslots);
-
-  if (candidate != NO_JOB)
-    {
-      js.j_previous = candidate;
-      return;
-    }
-
-  /* There is only a single job, and it is both `+' and `-'. */
-  js.j_previous = js.j_current;
-}
-
-/* Make current_job be something useful, if it isn't already. */
-
-/* Here's the deal:  The newest non-running job should be `+', and the
-   next-newest non-running job should be `-'.  If there is only a single
-   stopped job, the js.j_previous is the newest non-running job.  If there
-   are only running jobs, the newest running job is `+' and the
-   next-newest running job is `-'.  Must be called with SIGCHLD blocked. */
-
-static void
-reset_current ()
-{
-  int candidate;
-
-  if (js.j_jobslots && js.j_current != NO_JOB && jobs[js.j_current] && STOPPED (js.j_current))
-    candidate = js.j_current;
-  else
-    {
-      candidate = NO_JOB;
-
-      /* First choice: the previous job. */
-      if (js.j_previous != NO_JOB && jobs[js.j_previous] && STOPPED (js.j_previous))
-       candidate = js.j_previous;
-
-      /* Second choice: the most recently stopped job. */
-      if (candidate == NO_JOB)
-       candidate = job_last_stopped (js.j_jobslots);
-
-      /* Third choice: the newest running job. */
-      if (candidate == NO_JOB)
-       candidate = job_last_running (js.j_jobslots);
-    }
-
-  /* If we found a job to use, then use it.  Otherwise, there
-     are no jobs period. */
-  if (candidate != NO_JOB)
-    set_current_job (candidate);
-  else
-    js.j_current = js.j_previous = NO_JOB;
-}
-
-/* Set up the job structures so we know the job and its processes are
-   all running. */
-static void
-set_job_running (job)
-     int job;
-{
-  register PROCESS *p;
-
-  /* Each member of the pipeline is now running. */
-  p = jobs[job]->pipe;
-
-  do
-    {
-      if (WIFSTOPPED (p->status))
-       p->running = PS_RUNNING;        /* XXX - could be PS_STOPPED */
-      p = p->next;
-    }
-  while (p != jobs[job]->pipe);
-
-  /* This means that the job is running. */
-  JOBSTATE (job) = JRUNNING;
-}
-
-/* Start a job.  FOREGROUND if non-zero says to do that.  Otherwise,
-   start the job in the background.  JOB is a zero-based index into
-   JOBS.  Returns -1 if it is unable to start a job, and the return
-   status of the job otherwise. */
-int
-start_job (job, foreground)
-     int job, foreground;
-{
-  register PROCESS *p;
-  int already_running;
-  sigset_t set, oset;
-  char *wd, *s;
-  static TTYSTRUCT save_stty;
-
-  BLOCK_CHILD (set, oset);
-
-  if (DEADJOB (job))
-    {
-      internal_error (_("%s: job has terminated"), this_command_name);
-      UNBLOCK_CHILD (oset);
-      return (-1);
-    }
-
-  already_running = RUNNING (job);
-
-  if (foreground == 0 && already_running)
-    {
-      internal_error (_("%s: job %d already in background"), this_command_name, job + 1);
-      UNBLOCK_CHILD (oset);
-      return (0);              /* XPG6/SUSv3 says this is not an error */
-    }
-
-  wd = current_working_directory ();
-
-  /* You don't know about the state of this job.  Do you? */
-  jobs[job]->flags &= ~J_NOTIFIED;
-
-  if (foreground)
-    {
-      set_current_job (job);
-      jobs[job]->flags |= J_FOREGROUND;
-    }
-
-  /* Tell the outside world what we're doing. */
-  p = jobs[job]->pipe;
-
-  if (foreground == 0)
-    {
-      /* POSIX.2 says `bg' doesn't give any indication about current or
-        previous job. */
-      if (posixly_correct == 0)
-       s = (job == js.j_current) ? "+ ": ((job == js.j_previous) ? "- " : " ");       
-      else
-       s = " ";
-      printf ("[%d]%s", job + 1, s);
-    }
-
-  do
-    {
-      printf ("%s%s",
-              p->command ? p->command : "",
-              p->next != jobs[job]->pipe? " | " : "");
-      p = p->next;
-    }
-  while (p != jobs[job]->pipe);
-
-  if (foreground == 0)
-    printf (" &");
-
-  if (strcmp (wd, jobs[job]->wd) != 0)
-    printf ("  (wd: %s)", polite_directory_format (jobs[job]->wd));
-
-  printf ("\n");
-
-  /* Run the job. */
-  if (already_running == 0)
-    set_job_running (job);
-
-  /* Save the tty settings before we start the job in the foreground. */
-  if (foreground)
-    {
-      get_tty_state ();
-      save_stty = shell_tty_info;
-      /* Give the terminal to this job. */
-      if (IS_JOBCONTROL (job))
-       give_terminal_to (jobs[job]->pgrp, 0);
-    }
-  else
-    jobs[job]->flags &= ~J_FOREGROUND;
-
-  /* If the job is already running, then don't bother jump-starting it. */
-  if (already_running == 0)
-    {
-      jobs[job]->flags |= J_NOTIFIED;
-      killpg (jobs[job]->pgrp, SIGCONT);
-    }
-
-  if (foreground)
-    {
-      pid_t pid;
-      int st;
-
-      pid = find_last_pid (job, 0);
-      UNBLOCK_CHILD (oset);
-      st = wait_for (pid);
-      shell_tty_info = save_stty;
-      set_tty_state ();
-      return (st);
-    }
-  else
-    {
-      reset_current ();
-      UNBLOCK_CHILD (oset);
-      return (0);
-    }
-}
-
-/* Give PID SIGNAL.  This determines what job the pid belongs to (if any).
-   If PID does belong to a job, and the job is stopped, then CONTinue the
-   job after giving it SIGNAL.  Returns -1 on failure.  If GROUP is non-null,
-   then kill the process group associated with PID. */
-int
-kill_pid (pid, sig, group)
-     pid_t pid;
-     int sig, group;
-{
-  register PROCESS *p;
-  int job, result, negative;
-  sigset_t set, oset;
-
-  if (pid < -1)
-    {
-      pid = -pid;
-      group = negative = 1;
-    }
-  else
-    negative = 0;
-
-  result = EXECUTION_SUCCESS;
-  if (group)
-    {
-      BLOCK_CHILD (set, oset);
-      p = find_pipeline (pid, 0, &job);
-
-      if (job != NO_JOB)
-       {
-         jobs[job]->flags &= ~J_NOTIFIED;
-
-         /* Kill process in backquotes or one started without job control? */
-
-         /* If we're passed a pid < -1, just call killpg and see what happens  */
-         if (negative && jobs[job]->pgrp == shell_pgrp)
-           result = killpg (pid, sig);
-         /* If we're killing using job control notification, for example,
-            without job control active, we have to do things ourselves. */
-         else if (jobs[job]->pgrp == shell_pgrp)
-           {
-             p = jobs[job]->pipe;
-             do
-               {
-                 if (PALIVE (p) == 0)
-                   continue;           /* avoid pid recycling problem */
-                 kill (p->pid, sig);
-                 if (PEXITED (p) && (sig == SIGTERM || sig == SIGHUP))
-                   kill (p->pid, SIGCONT);
-                 p = p->next;
-               }
-             while  (p != jobs[job]->pipe);
-           }
-         else
-           {
-             result = killpg (jobs[job]->pgrp, sig);
-             if (p && STOPPED (job) && (sig == SIGTERM || sig == SIGHUP))
-               killpg (jobs[job]->pgrp, SIGCONT);
-             /* If we're continuing a stopped job via kill rather than bg or
-                fg, emulate the `bg' behavior. */
-             if (p && STOPPED (job) && (sig == SIGCONT))
-               {
-                 set_job_running (job);
-                 jobs[job]->flags &= ~J_FOREGROUND;
-                 jobs[job]->flags |= J_NOTIFIED;
-               }
-           }
-       }
-      else
-       result = killpg (pid, sig);
-
-      UNBLOCK_CHILD (oset);
-    }
-  else
-    result = kill (pid, sig);
-
-  return (result);
-}
-
-/* sigchld_handler () flushes at least one of the children that we are
-   waiting for.  It gets run when we have gotten a SIGCHLD signal. */
-static sighandler
-sigchld_handler (sig)
-     int sig;
-{
-  int n, oerrno;
-
-  oerrno = errno;
-  REINSTALL_SIGCHLD_HANDLER;
-  sigchld++;
-  n = 0;
-  if (queue_sigchld == 0)
-    n = waitchld (-1, 0);
-  errno = oerrno;
-  SIGRETURN (n);
-}
-
-/* waitchld() reaps dead or stopped children.  It's called by wait_for and
-   sigchld_handler, and runs until there aren't any children terminating any
-   more.
-   If BLOCK is 1, this is to be a blocking wait for a single child, although
-   an arriving SIGCHLD could cause the wait to be non-blocking.  It returns
-   the number of children reaped, or -1 if there are no unwaited-for child
-   processes. */
-static int
-waitchld (wpid, block)
-     pid_t wpid;
-     int block;
-{
-  WAIT status;
-  PROCESS *child;
-  pid_t pid;
-  int call_set_current, last_stopped_job, job, children_exited, waitpid_flags;
-  static int wcontinued = WCONTINUED;  /* run-time fix for glibc problem */
-
-  call_set_current = children_exited = 0;
-  last_stopped_job = NO_JOB;
-
-  do
-    {
-      /* We don't want to be notified about jobs stopping if job control
-        is not active.  XXX - was interactive_shell instead of job_control */
-      waitpid_flags = (job_control && subshell_environment == 0)
-                       ? (WUNTRACED|wcontinued)
-                       : 0;
-      if (sigchld || block == 0)
-       waitpid_flags |= WNOHANG;
-      /* Check for terminating signals and exit the shell if we receive one */
-      CHECK_TERMSIG;
-
-      if (block == 1 && queue_sigchld == 0 && (waitpid_flags & WNOHANG) == 0)
-       {
-         internal_warning (_("waitchld: turning on WNOHANG to avoid indefinite block"));
-         waitpid_flags |= WNOHANG;
-       }
-
-      pid = WAITPID (-1, &status, waitpid_flags);
-
-      /* WCONTINUED may be rejected by waitpid as invalid even when defined */
-      if (wcontinued && pid < 0 && errno == EINVAL)
-       {
-         wcontinued = 0;
-         continue;     /* jump back to the test and retry without WCONTINUED */
-       }
-
-      /* The check for WNOHANG is to make sure we decrement sigchld only
-        if it was non-zero before we called waitpid. */
-      if (sigchld > 0 && (waitpid_flags & WNOHANG))
-       sigchld--;
-  
-      /* If waitpid returns -1 with errno == ECHILD, there are no more
-        unwaited-for child processes of this shell. */
-      if (pid < 0 && errno == ECHILD)
-       {
-         if (children_exited == 0)
-           return -1;
-         else
-           break;
-       }
-
-      /* If waitpid returns 0, there are running children.  If it returns -1,
-        the only other error POSIX says it can return is EINTR. */
-      CHECK_TERMSIG;
-      if (pid <= 0)
-       continue;       /* jumps right to the test */
-
-      /* children_exited is used to run traps on SIGCHLD.  We don't want to
-         run the trap if a process is just being continued. */
-      if (WIFCONTINUED(status) == 0)
-       {
-         children_exited++;
-         js.c_living--;
-       }
-
-      /* Locate our PROCESS for this pid. */
-      child = find_process (pid, 1, &job);     /* want living procs only */
-
-#if defined (COPROCESS_SUPPORT)
-      coproc_pidchk (pid, status);
-#endif
-
-      /* It is not an error to have a child terminate that we did
-        not have a record of.  This child could have been part of
-        a pipeline in backquote substitution.  Even so, I'm not
-        sure child is ever non-zero. */
-      if (child == 0)
-       {
-         if (WIFEXITED (status) || WIFSIGNALED (status))
-           js.c_reaped++;
-         continue;
-       }
-
-      /* Remember status, and whether or not the process is running. */
-      child->status = status;
-      child->running = WIFCONTINUED(status) ? PS_RUNNING : PS_DONE;
-
-      if (PEXITED (child))
-       {
-         js.c_totreaped++;
-         if (job != NO_JOB)
-           js.c_reaped++;
-       }
-        
-      if (job == NO_JOB)
-       continue;
-
-      call_set_current += set_job_status_and_cleanup (job);
-
-      if (STOPPED (job))
-       last_stopped_job = job;
-      else if (DEADJOB (job) && last_stopped_job == job)
-       last_stopped_job = NO_JOB;
-    }
-  while ((sigchld || block == 0) && pid > (pid_t)0);
-
-  /* If a job was running and became stopped, then set the current
-     job.  Otherwise, don't change a thing. */
-  if (call_set_current)
-    {
-      if (last_stopped_job != NO_JOB)
-       set_current_job (last_stopped_job);
-      else
-       reset_current ();
-    }
-
-  /* Call a SIGCHLD trap handler for each child that exits, if one is set. */
-  if (job_control && signal_is_trapped (SIGCHLD) && children_exited &&
-      trap_list[SIGCHLD] != (char *)IGNORE_SIG)
-    {
-      if (posixly_correct && this_shell_builtin && this_shell_builtin == wait_builtin)
-       {
-         interrupt_immediately = 0;
-         trap_handler (SIGCHLD);       /* set pending_traps[SIGCHLD] */
-         wait_signal_received = SIGCHLD;
-         longjmp (wait_intr_buf, 1);
-       }
-
-      run_sigchld_trap (children_exited);
-    }
-
-  /* We have successfully recorded the useful information about this process
-     that has just changed state.  If we notify asynchronously, and the job
-     that this process belongs to is no longer running, then notify the user
-     of that fact now. */
-  if (asynchronous_notification && interactive)
-    notify_of_job_status ();
-
-  return (children_exited);
-}
-
-/* Set the status of JOB and perform any necessary cleanup if the job is
-   marked as JDEAD.
-
-   Currently, the cleanup activity is restricted to handling any SIGINT
-   received while waiting for a foreground job to finish. */
-static int
-set_job_status_and_cleanup (job)
-     int job;
-{
-  PROCESS *child;
-  int tstatus, job_state, any_stopped, any_tstped, call_set_current;
-  SigHandler *temp_handler;
-
-  child = jobs[job]->pipe;
-  jobs[job]->flags &= ~J_NOTIFIED;
-
-  call_set_current = 0;
-
-  /*
-   * COMPUTE JOB STATUS
-   */
-
-  /* If all children are not running, but any of them is  stopped, then
-     the job is stopped, not dead. */
-  job_state = any_stopped = any_tstped = 0;
-  do
-    {
-      job_state |= PRUNNING (child);
-#if 0
-      if (PEXITED (child) && (WIFSTOPPED (child->status)))
-#else
-      /* Only checking for WIFSTOPPED now, not for PS_DONE */
-      if (PSTOPPED (child))
-#endif
-       {
-         any_stopped = 1;
-         any_tstped |= interactive && job_control &&
-                           (WSTOPSIG (child->status) == SIGTSTP);
-       }
-      child = child->next;
-    }
-  while (child != jobs[job]->pipe);
-
-  /* If job_state != 0, the job is still running, so don't bother with
-     setting the process exit status and job state unless we're
-     transitioning from stopped to running. */
-  if (job_state != 0 && JOBSTATE(job) != JSTOPPED)
-    return 0;
-
-  /*
-   * SET JOB STATUS
-   */
-
-  /* The job is either stopped or dead.  Set the state of the job accordingly. */
-  if (any_stopped)
-    {
-      jobs[job]->state = JSTOPPED;
-      jobs[job]->flags &= ~J_FOREGROUND;
-      call_set_current++;
-      /* Suspending a job with SIGTSTP breaks all active loops. */
-      if (any_tstped && loop_level)
-       breaking = loop_level;
-    }
-  else if (job_state != 0)     /* was stopped, now running */
-    {
-      jobs[job]->state = JRUNNING;
-      call_set_current++;
-    }
-  else
-    {
-      jobs[job]->state = JDEAD;
-      js.j_ndead++;
-
-#if 0
-      if (IS_FOREGROUND (job))
-       setjstatus (job);
-#endif
-
-      /* If this job has a cleanup function associated with it, call it
-        with `cleanarg' as the single argument, then set the function
-        pointer to NULL so it is not inadvertently called twice.  The
-        cleanup function is responsible for deallocating cleanarg. */
-      if (jobs[job]->j_cleanup)
-       {
-         (*jobs[job]->j_cleanup) (jobs[job]->cleanarg);
-         jobs[job]->j_cleanup = (sh_vptrfunc_t *)NULL;
-       }
-    }
-
-  /*
-   * CLEANUP
-   *
-   * Currently, we just do special things if we got a SIGINT while waiting
-   * for a foreground job to complete
-   */
-
-  if (JOBSTATE (job) == JDEAD)
-    {
-      /* If we're running a shell script and we get a SIGINT with a
-        SIGINT trap handler, but the foreground job handles it and
-        does not exit due to SIGINT, run the trap handler but do not
-        otherwise act as if we got the interrupt. */
-      if (wait_sigint_received && interactive_shell == 0 &&
-         WIFSIGNALED (child->status) == 0 && IS_FOREGROUND (job) &&
-         signal_is_trapped (SIGINT))
-       {
-         int old_frozen;
-         wait_sigint_received = 0;
-         last_command_exit_value = process_exit_status (child->status);
-
-         old_frozen = jobs_list_frozen;
-         jobs_list_frozen = 1;
-         tstatus = maybe_call_trap_handler (SIGINT);
-         jobs_list_frozen = old_frozen;
-       }
-
-      /* If the foreground job is killed by SIGINT when job control is not
-        active, we need to perform some special handling.
-
-        The check of wait_sigint_received is a way to determine if the
-        SIGINT came from the keyboard (in which case the shell has already
-        seen it, and wait_sigint_received is non-zero, because keyboard
-        signals are sent to process groups) or via kill(2) to the foreground
-        process by another process (or itself).  If the shell did receive the
-        SIGINT, it needs to perform normal SIGINT processing. */
-      else if (wait_sigint_received && (WTERMSIG (child->status) == SIGINT) &&
-             IS_FOREGROUND (job) && IS_JOBCONTROL (job) == 0)
-       {
-         int old_frozen;
-
-         wait_sigint_received = 0;
-
-         /* If SIGINT is trapped, set the exit status so that the trap
-            handler can see it. */
-         if (signal_is_trapped (SIGINT))
-           last_command_exit_value = process_exit_status (child->status);
-
-         /* If the signal is trapped, let the trap handler get it no matter
-            what and simply return if the trap handler returns.
-           maybe_call_trap_handler() may cause dead jobs to be removed from
-           the job table because of a call to execute_command.  We work
-           around this by setting JOBS_LIST_FROZEN. */
-         old_frozen = jobs_list_frozen;
-         jobs_list_frozen = 1;
-         tstatus = maybe_call_trap_handler (SIGINT);
-         jobs_list_frozen = old_frozen;
-         if (tstatus == 0 && old_sigint_handler != INVALID_SIGNAL_HANDLER)
-           {
-             /* wait_sigint_handler () has already seen SIGINT and
-                allowed the wait builtin to jump out.  We need to
-                call the original SIGINT handler, if necessary.  If
-                the original handler is SIG_DFL, we need to resend
-                the signal to ourselves. */
-
-             temp_handler = old_sigint_handler;
-
-             /* Bogus.  If we've reset the signal handler as the result
-                of a trap caught on SIGINT, then old_sigint_handler
-                will point to trap_handler, which now knows nothing about
-                SIGINT (if we reset the sighandler to the default).
-                In this case, we have to fix things up.  What a crock. */
-             if (temp_handler == trap_handler && signal_is_trapped (SIGINT) == 0)
-                 temp_handler = trap_to_sighandler (SIGINT);
-               restore_sigint_handler ();
-             if (temp_handler == SIG_DFL)
-               termsig_handler (SIGINT);
-             else if (temp_handler != SIG_IGN)
-               (*temp_handler) (SIGINT);
-           }
-       }
-    }
-
-  return call_set_current;
-}
-
-/* Build the array of values for the $PIPESTATUS variable from the set of
-   exit statuses of all processes in the job J. */
-static void
-setjstatus (j)
-     int j;
-{
-#if defined (ARRAY_VARS)
-  register int i;
-  register PROCESS *p;
-
-  for (i = 1, p = jobs[j]->pipe; p->next != jobs[j]->pipe; p = p->next, i++)
-    ;
-  i++;
-  if (statsize < i)
-    {
-      pstatuses = (int *)xrealloc (pstatuses, i * sizeof (int));
-      statsize = i;
-    }
-  i = 0;
-  p = jobs[j]->pipe;
-  do
-    {
-      pstatuses[i++] = process_exit_status (p->status);
-      p = p->next;
-    }
-  while (p != jobs[j]->pipe);
-
-  pstatuses[i] = -1;   /* sentinel */
-  set_pipestatus_array (pstatuses, i);
-#endif
-}
-
-void
-run_sigchld_trap (nchild)
-     int nchild;
-{
-  char *trap_command;
-  int i;
-
-  /* Turn off the trap list during the call to parse_and_execute ()
-     to avoid potentially infinite recursive calls.  Preserve the
-     values of last_command_exit_value, last_made_pid, and the_pipeline
-     around the execution of the trap commands. */
-  trap_command = savestring (trap_list[SIGCHLD]);
-
-  begin_unwind_frame ("SIGCHLD trap");
-  unwind_protect_int (last_command_exit_value);
-  unwind_protect_int (last_command_exit_signal);
-  unwind_protect_var (last_made_pid);
-  unwind_protect_int (interrupt_immediately);
-  unwind_protect_int (jobs_list_frozen);
-  unwind_protect_pointer (the_pipeline);
-  unwind_protect_pointer (subst_assign_varlist);
-
-  /* We have to add the commands this way because they will be run
-     in reverse order of adding.  We don't want maybe_set_sigchld_trap ()
-     to reference freed memory. */
-  add_unwind_protect (xfree, trap_command);
-  add_unwind_protect (maybe_set_sigchld_trap, trap_command);
-
-  subst_assign_varlist = (WORD_LIST *)NULL;
-  the_pipeline = (PROCESS *)NULL;
-
-  set_impossible_sigchld_trap ();
-  jobs_list_frozen = 1;
-  for (i = 0; i < nchild; i++)
-    {
-      interrupt_immediately = 1;
-      parse_and_execute (savestring (trap_command), "trap", SEVAL_NOHIST|SEVAL_RESETLINE);
-    }
-
-  run_unwind_frame ("SIGCHLD trap");
-}
-
-/* Function to call when you want to notify people of changes
-   in job status.  This prints out all jobs which are pending
-   notification to stderr, and marks those printed as already
-   notified, thus making them candidates for cleanup. */
-static void
-notify_of_job_status ()
-{
-  register int job, termsig;
-  char *dir;
-  sigset_t set, oset;
-  WAIT s;
-
-  if (jobs == 0 || js.j_jobslots == 0)
-    return;
-
-  if (old_ttou != 0)
-    {
-      sigemptyset (&set);
-      sigaddset (&set, SIGCHLD);
-      sigaddset (&set, SIGTTOU);
-      sigemptyset (&oset);
-      sigprocmask (SIG_BLOCK, &set, &oset);
-    }
-  else
-    queue_sigchld++;
-
-  /* XXX could use js.j_firstj here */
-  for (job = 0, dir = (char *)NULL; job < js.j_jobslots; job++)
-    {
-      if (jobs[job] && IS_NOTIFIED (job) == 0)
-       {
-         s = raw_job_exit_status (job);
-         termsig = WTERMSIG (s);
-
-         /* POSIX.2 says we have to hang onto the statuses of at most the
-            last CHILD_MAX background processes if the shell is running a
-            script.  If the shell is running a script, either from a file
-            or standard input, don't print anything unless the job was
-            killed by a signal. */
-         if (startup_state == 0 && WIFSIGNALED (s) == 0 &&
-               ((DEADJOB (job) && IS_FOREGROUND (job) == 0) || STOPPED (job)))
-           continue;
-         
-#if 0
-         /* If job control is disabled, don't print the status messages.
-            Mark dead jobs as notified so that they get cleaned up.  If
-            startup_state == 2, we were started to run `-c command', so
-            don't print anything. */
-         if ((job_control == 0 && interactive_shell) || startup_state == 2)
-#else
-         /* If job control is disabled, don't print the status messages.
-            Mark dead jobs as notified so that they get cleaned up.  If
-            startup_state == 2 and subshell_environment has the
-            SUBSHELL_COMSUB bit turned on, we were started to run a command
-            substitution, so don't print anything. */
-         if ((job_control == 0 && interactive_shell) ||
-             (startup_state == 2 && (subshell_environment & SUBSHELL_COMSUB)))
-#endif
-           {
-             /* POSIX.2 compatibility:  if the shell is not interactive,
-                hang onto the job corresponding to the last asynchronous
-                pid until the user has been notified of its status or does
-                a `wait'. */
-             if (DEADJOB (job) && (interactive_shell || (find_last_pid (job, 0) != last_asynchronous_pid)))
-               jobs[job]->flags |= J_NOTIFIED;
-             continue;
-           }
-
-         /* Print info on jobs that are running in the background,
-            and on foreground jobs that were killed by anything
-            except SIGINT (and possibly SIGPIPE). */
-         switch (JOBSTATE (job))
-           {
-           case JDEAD:
-             if (interactive_shell == 0 && termsig && WIFSIGNALED (s) &&
-                 termsig != SIGINT &&
-#if defined (DONT_REPORT_SIGPIPE)
-                 termsig != SIGPIPE &&
-#endif
-                 signal_is_trapped (termsig) == 0)
-               {
-                 /* Don't print `0' for a line number. */
-                 fprintf (stderr, _("%s: line %d: "), get_name_for_error (), (line_number == 0) ? 1 : line_number);
-                 pretty_print_job (job, JLIST_NONINTERACTIVE, stderr);
-               }
-             else if (IS_FOREGROUND (job))
-               {
-#if !defined (DONT_REPORT_SIGPIPE)
-                 if (termsig && WIFSIGNALED (s) && termsig != SIGINT)
-#else
-                 if (termsig && WIFSIGNALED (s) && termsig != SIGINT && termsig != SIGPIPE)
-#endif
-                   {
-                     fprintf (stderr, "%s", j_strsignal (termsig));
-
-                     if (WIFCORED (s))
-                       fprintf (stderr, _(" (core dumped)"));
-
-                     fprintf (stderr, "\n");
-                   }
-               }
-             else if (job_control)     /* XXX job control test added */
-               {
-                 if (dir == 0)
-                   dir = current_working_directory ();
-                 pretty_print_job (job, JLIST_STANDARD, stderr);
-                 if (dir && strcmp (dir, jobs[job]->wd) != 0)
-                   fprintf (stderr,
-                            _("(wd now: %s)\n"), polite_directory_format (dir));
-               }
-
-             jobs[job]->flags |= J_NOTIFIED;
-             break;
-
-           case JSTOPPED:
-             fprintf (stderr, "\n");
-             if (dir == 0)
-               dir = current_working_directory ();
-             pretty_print_job (job, JLIST_STANDARD, stderr);
-             if (dir && (strcmp (dir, jobs[job]->wd) != 0))
-               fprintf (stderr,
-                        _("(wd now: %s)\n"), polite_directory_format (dir));
-             jobs[job]->flags |= J_NOTIFIED;
-             break;
-
-           case JRUNNING:
-           case JMIXED:
-             break;
-
-           default:
-             programming_error ("notify_of_job_status");
-           }
-       }
-    }
-  if (old_ttou != 0)
-    sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
-  else
-    queue_sigchld--;
-}
-
-/* Initialize the job control mechanism, and set up the tty stuff. */
-int
-initialize_job_control (force)
-     int force;
-{
-  pid_t t;
-  int t_errno;
-
-  t_errno = -1;
-  shell_pgrp = getpgid (0);
-
-  if (shell_pgrp == -1)
-    {
-      sys_error (_("initialize_job_control: getpgrp failed"));
-      exit (1);
-    }
-
-  /* We can only have job control if we are interactive. */
-  if (interactive == 0)
-    {
-      job_control = 0;
-      original_pgrp = NO_PID;
-      shell_tty = fileno (stderr);
-    }
-  else
-    {
-      shell_tty = -1;
-
-      /* If forced_interactive is set, we skip the normal check that stderr
-        is attached to a tty, so we need to check here.  If it's not, we
-        need to see whether we have a controlling tty by opening /dev/tty,
-        since trying to use job control tty pgrp manipulations on a non-tty
-        is going to fail. */
-      if (forced_interactive && isatty (fileno (stderr)) == 0)
-       shell_tty = open ("/dev/tty", O_RDWR|O_NONBLOCK);
-
-      /* Get our controlling terminal.  If job_control is set, or
-        interactive is set, then this is an interactive shell no
-        matter where fd 2 is directed. */
-      if (shell_tty == -1)
-       shell_tty = dup (fileno (stderr));      /* fd 2 */
-
-      shell_tty = move_to_high_fd (shell_tty, 1, -1);
-
-      /* Compensate for a bug in systems that compiled the BSD
-        rlogind with DEBUG defined, like NeXT and Alliant. */
-      if (shell_pgrp == 0)
-       {
-         shell_pgrp = getpid ();
-         setpgid (0, shell_pgrp);
-         tcsetpgrp (shell_tty, shell_pgrp);
-       }
-
-      while ((terminal_pgrp = tcgetpgrp (shell_tty)) != -1)
-       {
-         if (shell_pgrp != terminal_pgrp)
-           {
-             SigHandler *ottin;
-
-             ottin = set_signal_handler(SIGTTIN, SIG_DFL);
-             kill (0, SIGTTIN);
-             set_signal_handler (SIGTTIN, ottin);
-             continue;
-           }
-         break;
-       }
-
-      if (terminal_pgrp == -1)
-       t_errno = errno;
-
-      /* Make sure that we are using the new line discipline. */
-      if (set_new_line_discipline (shell_tty) < 0)
-       {
-         sys_error (_("initialize_job_control: line discipline"));
-         job_control = 0;
-       }
-      else
-       {
-         original_pgrp = shell_pgrp;
-         shell_pgrp = getpid ();
-
-         if ((original_pgrp != shell_pgrp) && (setpgid (0, shell_pgrp) < 0))
-           {
-             sys_error (_("initialize_job_control: setpgid"));
-             shell_pgrp = original_pgrp;
-           }
-
-         job_control = 1;
-
-         /* If (and only if) we just set our process group to our pid,
-            thereby becoming a process group leader, and the terminal
-            is not in the same process group as our (new) process group,
-            then set the terminal's process group to our (new) process
-            group.  If that fails, set our process group back to what it
-            was originally (so we can still read from the terminal) and
-            turn off job control.  */
-         if (shell_pgrp != original_pgrp && shell_pgrp != terminal_pgrp)
-           {
-             if (give_terminal_to (shell_pgrp, 0) < 0)
-               {
-                 t_errno = errno;
-                 setpgid (0, original_pgrp);
-                 shell_pgrp = original_pgrp;
-                 job_control = 0;
-               }
-           }
-
-         if (job_control && ((t = tcgetpgrp (shell_tty)) == -1 || t != shell_pgrp))
-           {
-             if (t_errno != -1)
-               errno = t_errno;
-             sys_error (_("cannot set terminal process group (%d)"), t);
-             job_control = 0;
-           }
-       }
-      if (job_control == 0)
-       internal_error (_("no job control in this shell"));
-    }
-
-  if (shell_tty != fileno (stderr))
-    SET_CLOSE_ON_EXEC (shell_tty);
-
-  set_signal_handler (SIGCHLD, sigchld_handler);
-
-  change_flag ('m', job_control ? '-' : '+');
-
-  if (interactive)
-    get_tty_state ();
-
-  if (js.c_childmax < 0)
-    js.c_childmax = getmaxchild ();
-  if (js.c_childmax < 0)
-    js.c_childmax = DEFAULT_CHILD_MAX;
-
-  return job_control;
-}
-
-#ifdef DEBUG
-void
-debug_print_pgrps ()
-{
-  itrace("original_pgrp = %ld shell_pgrp = %ld terminal_pgrp = %ld",
-        (long)original_pgrp, (long)shell_pgrp, (long)terminal_pgrp);
-  itrace("tcgetpgrp(%d) -> %ld, getpgid(0) -> %ld",
-        shell_tty, (long)tcgetpgrp (shell_tty), (long)getpgid(0));
-}
-#endif
-
-/* Set the line discipline to the best this system has to offer.
-   Return -1 if this is not possible. */
-static int
-set_new_line_discipline (tty)
-     int tty;
-{
-#if defined (NEW_TTY_DRIVER)
-  int ldisc;
-
-  if (ioctl (tty, TIOCGETD, &ldisc) < 0)
-    return (-1);
-
-  if (ldisc != NTTYDISC)
-    {
-      ldisc = NTTYDISC;
-
-      if (ioctl (tty, TIOCSETD, &ldisc) < 0)
-       return (-1);
-    }
-  return (0);
-#endif /* NEW_TTY_DRIVER */
-
-#if defined (TERMIO_TTY_DRIVER)
-#  if defined (TERMIO_LDISC) && (NTTYDISC)
-  if (ioctl (tty, TCGETA, &shell_tty_info) < 0)
-    return (-1);
-
-  if (shell_tty_info.c_line != NTTYDISC)
-    {
-      shell_tty_info.c_line = NTTYDISC;
-      if (ioctl (tty, TCSETAW, &shell_tty_info) < 0)
-       return (-1);
-    }
-#  endif /* TERMIO_LDISC && NTTYDISC */
-  return (0);
-#endif /* TERMIO_TTY_DRIVER */
-
-#if defined (TERMIOS_TTY_DRIVER)
-#  if defined (TERMIOS_LDISC) && defined (NTTYDISC)
-  if (tcgetattr (tty, &shell_tty_info) < 0)
-    return (-1);
-
-  if (shell_tty_info.c_line != NTTYDISC)
-    {
-      shell_tty_info.c_line = NTTYDISC;
-      if (tcsetattr (tty, TCSADRAIN, &shell_tty_info) < 0)
-       return (-1);
-    }
-#  endif /* TERMIOS_LDISC && NTTYDISC */
-  return (0);
-#endif /* TERMIOS_TTY_DRIVER */
-
-#if !defined (NEW_TTY_DRIVER) && !defined (TERMIO_TTY_DRIVER) && !defined (TERMIOS_TTY_DRIVER)
-  return (-1);
-#endif
-}
-
-/* Setup this shell to handle C-C, etc. */
-void
-initialize_job_signals ()
-{
-  if (interactive)
-    {
-      set_signal_handler (SIGINT, sigint_sighandler);
-      set_signal_handler (SIGTSTP, SIG_IGN);
-      set_signal_handler (SIGTTOU, SIG_IGN);
-      set_signal_handler (SIGTTIN, SIG_IGN);
-    }
-  else if (job_control)
-    {
-      old_tstp = set_signal_handler (SIGTSTP, sigstop_sighandler);
-      old_ttin = set_signal_handler (SIGTTIN, sigstop_sighandler);
-      old_ttou = set_signal_handler (SIGTTOU, sigstop_sighandler);
-    }
-  /* Leave these things alone for non-interactive shells without job
-     control. */
-}
-
-/* Here we handle CONT signals. */
-static sighandler
-sigcont_sighandler (sig)
-     int sig;
-{
-  initialize_job_signals ();
-  set_signal_handler (SIGCONT, old_cont);
-  kill (getpid (), SIGCONT);
-
-  SIGRETURN (0);
-}
-
-/* Here we handle stop signals while we are running not as a login shell. */
-static sighandler
-sigstop_sighandler (sig)
-     int sig;
-{
-  set_signal_handler (SIGTSTP, old_tstp);
-  set_signal_handler (SIGTTOU, old_ttou);
-  set_signal_handler (SIGTTIN, old_ttin);
-
-  old_cont = set_signal_handler (SIGCONT, sigcont_sighandler);
-
-  give_terminal_to (shell_pgrp, 0);
-
-  kill (getpid (), sig);
-
-  SIGRETURN (0);
-}
-
-/* Give the terminal to PGRP.  */
-int
-give_terminal_to (pgrp, force)
-     pid_t pgrp;
-     int force;
-{
-  sigset_t set, oset;
-  int r, e;
-
-  r = 0;
-  if (job_control || force)
-    {
-      sigemptyset (&set);
-      sigaddset (&set, SIGTTOU);
-      sigaddset (&set, SIGTTIN);
-      sigaddset (&set, SIGTSTP);
-      sigaddset (&set, SIGCHLD);
-      sigemptyset (&oset);
-      sigprocmask (SIG_BLOCK, &set, &oset);
-
-      if (tcsetpgrp (shell_tty, pgrp) < 0)
-       {
-         /* Maybe we should print an error message? */
-#if 0
-         sys_error ("tcsetpgrp(%d) failed: pid %ld to pgrp %ld",
-           shell_tty, (long)getpid(), (long)pgrp);
-#endif
-         r = -1;
-         e = errno;
-       }
-      else
-       terminal_pgrp = pgrp;
-      sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
-    }
-
-  if (r == -1)
-    errno = e;
-
-  return r;
-}
-
-/* Give terminal to NPGRP iff it's currently owned by OPGRP.  FLAGS are the
-   flags to pass to give_terminal_to(). */
-static int
-maybe_give_terminal_to (opgrp, npgrp, flags)
-     pid_t opgrp, npgrp;
-     int flags;
-{
-  int tpgrp;
-
-  tpgrp = tcgetpgrp (shell_tty);
-  if (tpgrp < 0 && errno == ENOTTY)
-    return -1;
-  if (tpgrp == npgrp)
-    {
-      terminal_pgrp = npgrp;
-      return 0;
-    }
-  else if (tpgrp != opgrp)
-    {
-#if defined (DEBUG)
-      internal_warning ("maybe_give_terminal_to: terminal pgrp == %d shell pgrp = %d new pgrp = %d", tpgrp, opgrp, npgrp);
-#endif
-      return -1;
-    }
-  else
-    return (give_terminal_to (npgrp, flags));     
-}
-
-/* Clear out any jobs in the job array.  This is intended to be used by
-   children of the shell, who should not have any job structures as baggage
-   when they start executing (forking subshells for parenthesized execution
-   and functions with pipes are the two that spring to mind).  If RUNNING_ONLY
-   is nonzero, only running jobs are removed from the table. */
-void
-delete_all_jobs (running_only)
-     int running_only;
-{
-  register int i;
-  sigset_t set, oset;
-
-  BLOCK_CHILD (set, oset);
-
-  /* XXX - need to set j_lastj, j_firstj appropriately if running_only != 0. */
-  if (js.j_jobslots)
-    {
-      js.j_current = js.j_previous = NO_JOB;
-
-      /* XXX could use js.j_firstj here */
-      for (i = 0; i < js.j_jobslots; i++)
-       {
-#if defined (DEBUG)
-         if (i < js.j_firstj && jobs[i])
-           itrace("delete_all_jobs: job %d non-null before js.j_firstj (%d)", i, js.j_firstj);
-         if (i > js.j_lastj && jobs[i])
-           itrace("delete_all_jobs: job %d non-null after js.j_lastj (%d)", i, js.j_lastj);
-#endif
-         if (jobs[i] && (running_only == 0 || (running_only && RUNNING(i))))
-           delete_job (i, DEL_WARNSTOPPED);
-       }
-      if (running_only == 0)
-       {
-         free ((char *)jobs);
-         js.j_jobslots = 0;
-         js.j_firstj = js.j_lastj = js.j_njobs = 0;
-       }
-    }
-
-  if (running_only == 0)
-    bgp_clear ();
-
-  UNBLOCK_CHILD (oset);
-}
-
-/* Mark all jobs in the job array so that they don't get a SIGHUP when the
-   shell gets one.  If RUNNING_ONLY is nonzero, mark only running jobs. */
-void
-nohup_all_jobs (running_only)
-     int running_only;
-{
-  register int i;
-  sigset_t set, oset;
-
-  BLOCK_CHILD (set, oset);
-
-  if (js.j_jobslots)
-    {
-      /* XXX could use js.j_firstj here */
-      for (i = 0; i < js.j_jobslots; i++)
-       if (jobs[i] && (running_only == 0 || (running_only && RUNNING(i))))
-         nohup_job (i);
-    }
-
-  UNBLOCK_CHILD (oset);
-}
-
-int
-count_all_jobs ()
-{
-  int i, n;
-  sigset_t set, oset;
-
-  /* This really counts all non-dead jobs. */
-  BLOCK_CHILD (set, oset);
-  /* XXX could use js.j_firstj here */
-  for (i = n = 0; i < js.j_jobslots; i++)
-    {
-#if defined (DEBUG)
-      if (i < js.j_firstj && jobs[i])
-       itrace("count_all_jobs: job %d non-null before js.j_firstj (%d)", i, js.j_firstj);
-      if (i > js.j_lastj && jobs[i])
-       itrace("count_all_jobs: job %d non-null after js.j_lastj (%d)", i, js.j_lastj);
-#endif
-      if (jobs[i] && DEADJOB(i) == 0)
-       n++;
-    }
-  UNBLOCK_CHILD (oset);
-  return n;
-}
-
-static void
-mark_all_jobs_as_dead ()
-{
-  register int i;
-  sigset_t set, oset;
-
-  if (js.j_jobslots == 0)
-    return;
-
-  BLOCK_CHILD (set, oset);
-
-  /* XXX could use js.j_firstj here */
-  for (i = 0; i < js.j_jobslots; i++)
-    if (jobs[i])
-      {
-       jobs[i]->state = JDEAD;
-       js.j_ndead++;
-      }
-
-  UNBLOCK_CHILD (oset);
-}
-
-/* Mark all dead jobs as notified, so delete_job () cleans them out
-   of the job table properly.  POSIX.2 says we need to save the
-   status of the last CHILD_MAX jobs, so we count the number of dead
-   jobs and mark only enough as notified to save CHILD_MAX statuses. */
-static void
-mark_dead_jobs_as_notified (force)
-     int force;
-{
-  register int i, ndead, ndeadproc;
-  sigset_t set, oset;
-
-  if (js.j_jobslots == 0)
-    return;
-
-  BLOCK_CHILD (set, oset);
-
-  /* If FORCE is non-zero, we don't have to keep CHILD_MAX statuses
-     around; just run through the array. */
-  if (force)
-    {
-    /* XXX could use js.j_firstj here */
-      for (i = 0; i < js.j_jobslots; i++)
-       {
-         if (jobs[i] && DEADJOB (i) && (interactive_shell || (find_last_pid (i, 0) != last_asynchronous_pid)))
-           jobs[i]->flags |= J_NOTIFIED;
-       }
-      UNBLOCK_CHILD (oset);
-      return;
-    }
-
-  /* Mark enough dead jobs as notified to keep CHILD_MAX processes left in the
-     array with the corresponding not marked as notified.  This is a better
-     way to avoid pid aliasing and reuse problems than keeping the POSIX-
-     mandated CHILD_MAX jobs around.  delete_job() takes care of keeping the
-     bgpids list regulated. */
-          
-  /* Count the number of dead jobs */
-  /* XXX could use js.j_firstj here */
-  for (i = ndead = ndeadproc = 0; i < js.j_jobslots; i++)
-    {
-#if defined (DEBUG)
-      if (i < js.j_firstj && jobs[i])
-       itrace("mark_dead_jobs_as_notified: job %d non-null before js.j_firstj (%d)", i, js.j_firstj);
-      if (i > js.j_lastj && jobs[i])
-       itrace("mark_dead_jobs_as_notified: job %d non-null after js.j_lastj (%d)", i, js.j_lastj);
-#endif
-      if (jobs[i] && DEADJOB (i))
-       {
-         ndead++;
-         ndeadproc += processes_in_job (i);
-       }
-    }
-
-#ifdef DEBUG
-  if (ndeadproc != js.c_reaped)
-    itrace("mark_dead_jobs_as_notified: ndeadproc (%d) != js.c_reaped (%d)", ndeadproc, js.c_reaped);
-  if (ndead != js.j_ndead)
-    itrace("mark_dead_jobs_as_notified: ndead (%d) != js.j_ndead (%d)", ndead, js.j_ndead);
-#endif
-
-  if (js.c_childmax < 0)
-    js.c_childmax = getmaxchild ();
-  if (js.c_childmax < 0)
-    js.c_childmax = DEFAULT_CHILD_MAX;
-
-  /* Don't do anything if the number of dead processes is less than CHILD_MAX
-     and we're not forcing a cleanup. */
-  if (ndeadproc <= js.c_childmax)
-    {
-      UNBLOCK_CHILD (oset);
-      return;
-    }
-
-#if 0
-itrace("mark_dead_jobs_as_notified: child_max = %d ndead = %d ndeadproc = %d", js.c_childmax, ndead, ndeadproc);
-#endif
-
-  /* Mark enough dead jobs as notified that we keep CHILD_MAX jobs in
-     the list.  This isn't exactly right yet; changes need to be made
-     to stop_pipeline so we don't mark the newer jobs after we've
-     created CHILD_MAX slots in the jobs array.  This needs to be
-     integrated with a way to keep the jobs array from growing without
-     bound.  Maybe we wrap back around to 0 after we reach some max
-     limit, and there are sufficient job slots free (keep track of total
-     size of jobs array (js.j_jobslots) and running count of number of jobs
-     in jobs array.  Then keep a job index corresponding to the `oldest job'
-     and start this loop there, wrapping around as necessary.  In effect,
-     we turn the list into a circular buffer. */
-  /* XXX could use js.j_firstj here */
-  for (i = 0; i < js.j_jobslots; i++)
-    {
-      if (jobs[i] && DEADJOB (i) && (interactive_shell || (find_last_pid (i, 0) != last_asynchronous_pid)))
-       {
-#if defined (DEBUG)
-         if (i < js.j_firstj && jobs[i])
-           itrace("mark_dead_jobs_as_notified: job %d non-null before js.j_firstj (%d)", i, js.j_firstj);
-         if (i > js.j_lastj && jobs[i])
-           itrace("mark_dead_jobs_as_notified: job %d non-null after js.j_lastj (%d)", i, js.j_lastj);
-#endif
-         /* If marking this job as notified would drop us down below
-            child_max, don't mark it so we can keep at least child_max
-            statuses.  XXX -- need to check what Posix actually says
-            about keeping statuses. */
-         if ((ndeadproc -= processes_in_job (i)) <= js.c_childmax)
-           break;
-         jobs[i]->flags |= J_NOTIFIED;
-       }
-    }
-
-  UNBLOCK_CHILD (oset);
-}
-
-/* Here to allow other parts of the shell (like the trap stuff) to
-   unfreeze the jobs list. */
-void
-unfreeze_jobs_list ()
-{
-  jobs_list_frozen = 0;
-}
-
-/* Allow or disallow job control to take place.  Returns the old value
-   of job_control. */
-int
-set_job_control (arg)
-     int arg;
-{
-  int old;
-
-  old = job_control;
-  job_control = arg;
-
-  /* If we're turning on job control, reset pipeline_pgrp so make_child will
-     put new child processes into the right pgrp */
-  if (job_control != old && job_control)
-    pipeline_pgrp = 0;
-
-  return (old);
-}
-
-/* Turn off all traces of job control.  This is run by children of the shell
-   which are going to do shellsy things, like wait (), etc. */
-void
-without_job_control ()
-{
-  stop_making_children ();
-  start_pipeline ();
-#if defined (PGRP_PIPE)
-  sh_closepipe (pgrp_pipe);
-#endif
-  delete_all_jobs (0);
-  set_job_control (0);
-}
-
-/* If this shell is interactive, terminate all stopped jobs and
-   restore the original terminal process group.  This is done
-   before the `exec' builtin calls shell_execve. */
-void
-end_job_control ()
-{
-  if (interactive_shell)               /* XXX - should it be interactive? */
-    {
-      terminate_stopped_jobs ();
-
-      if (original_pgrp >= 0)
-       give_terminal_to (original_pgrp, 1);
-    }
-
-  if (original_pgrp >= 0)
-    setpgid (0, original_pgrp);
-}
-
-/* Restart job control by closing shell tty and reinitializing.  This is
-   called after an exec fails in an interactive shell and we do not exit. */
-void
-restart_job_control ()
-{
-  if (shell_tty != -1)
-    close (shell_tty);
-  initialize_job_control (0);
-}
-
-/* Set the handler to run when the shell receives a SIGCHLD signal. */
-void
-set_sigchld_handler ()
-{
-  set_signal_handler (SIGCHLD, sigchld_handler);
-}
-
-#if defined (PGRP_PIPE)
-/* Read from the read end of a pipe.  This is how the process group leader
-   blocks until all of the processes in a pipeline have been made. */
-static void
-pipe_read (pp)
-     int *pp;
-{
-  char ch;
-
-  if (pp[1] >= 0)
-    {
-      close (pp[1]);
-      pp[1] = -1;
-    }
-
-  if (pp[0] >= 0)
-    {
-      while (read (pp[0], &ch, 1) == -1 && errno == EINTR)
-       ;
-    }
-}
-
-/* Functional interface closes our local-to-job-control pipes. */
-void
-close_pgrp_pipe ()
-{
-  sh_closepipe (pgrp_pipe);
-}
-
-void
-save_pgrp_pipe (p, clear)
-     int *p;
-     int clear;
-{
-  p[0] = pgrp_pipe[0];
-  p[1] = pgrp_pipe[1];
-  if (clear)
-    pgrp_pipe[0] = pgrp_pipe[1] = -1;
-}
-
-void
-restore_pgrp_pipe (p)
-     int *p;
-{
-  pgrp_pipe[0] = p[0];
-  pgrp_pipe[1] = p[1];
-}
-
-#endif /* PGRP_PIPE */
diff --git a/jobs.h~ b/jobs.h~
deleted file mode 100644 (file)
index 6e82f76..0000000
--- a/jobs.h~
+++ /dev/null
@@ -1,243 +0,0 @@
-/* jobs.h -- structures and definitions used by the jobs.c file. */
-
-/* Copyright (C) 1993-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 (_JOBS_H_)
-#  define _JOBS_H_
-
-#include "quit.h"
-#include "siglist.h"
-
-#include "stdc.h"
-
-#include "posixwait.h"
-
-/* Defines controlling the fashion in which jobs are listed. */
-#define JLIST_STANDARD       0
-#define JLIST_LONG          1
-#define JLIST_PID_ONLY      2
-#define JLIST_CHANGED_ONLY   3
-#define JLIST_NONINTERACTIVE 4
-
-/* I looked it up.  For pretty_print_job ().  The real answer is 24. */
-#define LONGEST_SIGNAL_DESC 24
-
-/* The max time to sleep while retrying fork() on EAGAIN failure */
-#define FORKSLEEP_MAX  16
-
-/* We keep an array of jobs.  Each entry in the array is a linked list
-   of processes that are piped together.  The first process encountered is
-   the group leader. */
-
-/* Values for the `running' field of a struct process. */
-#define PS_DONE                0
-#define PS_RUNNING     1
-#define PS_STOPPED     2
-#define PS_RECYCLED    4
-
-/* Each child of the shell is remembered in a STRUCT PROCESS.  A circular
-   chain of such structures is a pipeline. */
-typedef struct process {
-  struct process *next;        /* Next process in the pipeline.  A circular chain. */
-  pid_t pid;           /* Process ID. */
-  WAIT status;         /* The status of this command as returned by wait. */
-  int running;         /* Non-zero if this process is running. */
-  char *command;       /* The particular program that is running. */
-} PROCESS;
-
-/* PALIVE really means `not exited' */
-#define PSTOPPED(p)    (WIFSTOPPED((p)->status))
-#define PRUNNING(p)    ((p)->running == PS_RUNNING)
-#define PALIVE(p)      (PRUNNING(p) || PSTOPPED(p))
-
-#define PEXITED(p)     ((p)->running == PS_DONE)
-#if defined (RECYCLES_PIDS)
-#  define PRECYCLED(p) ((p)->running == PS_RECYCLED)
-#else
-#  define PRECYCLED(p) (0)
-#endif
-#define PDEADPROC(p)   (PEXITED(p) || PRECYCLED(p))
-
-#define get_job_by_jid(ind)    (jobs[(ind)])
-
-/* A description of a pipeline's state. */
-typedef enum { JNONE = -1, JRUNNING = 1, JSTOPPED = 2, JDEAD = 4, JMIXED = 8 } JOB_STATE;
-#define JOBSTATE(job)  (jobs[(job)]->state)
-#define J_JOBSTATE(j)  ((j)->state)
-
-#define STOPPED(j)     (jobs[(j)]->state == JSTOPPED)
-#define RUNNING(j)     (jobs[(j)]->state == JRUNNING)
-#define DEADJOB(j)     (jobs[(j)]->state == JDEAD)
-
-#define INVALID_JOB(j) ((j) < 0 || (j) >= js.j_jobslots || get_job_by_jid(j) == 0)
-
-/* Values for the FLAGS field in the JOB struct below. */
-#define J_FOREGROUND 0x01 /* Non-zero if this is running in the foreground.  */
-#define J_NOTIFIED   0x02 /* Non-zero if already notified about job state.   */
-#define J_JOBCONTROL 0x04 /* Non-zero if this job started under job control. */
-#define J_NOHUP      0x08 /* Don't send SIGHUP to job if shell gets SIGHUP. */
-#define J_STATSAVED  0x10 /* A process in this job had had status saved via $! */
-#define J_ASYNC             0x20 /* Job was started asynchronously */
-
-#define IS_FOREGROUND(j)       ((jobs[j]->flags & J_FOREGROUND) != 0)
-#define IS_NOTIFIED(j)         ((jobs[j]->flags & J_NOTIFIED) != 0)
-#define IS_JOBCONTROL(j)       ((jobs[j]->flags & J_JOBCONTROL) != 0)
-#define IS_ASYNC(j)            ((jobs[j]->flags & J_ASYNC) != 0)
-
-typedef struct job {
-  char *wd;       /* The working directory at time of invocation. */
-  PROCESS *pipe;   /* The pipeline of processes that make up this job. */
-  pid_t pgrp;     /* The process ID of the process group (necessary). */
-  JOB_STATE state; /* The state that this job is in. */
-  int flags;      /* Flags word: J_NOTIFIED, J_FOREGROUND, or J_JOBCONTROL. */
-#if defined (JOB_CONTROL)
-  COMMAND *deferred;   /* Commands that will execute when this job is done. */
-  sh_vptrfunc_t *j_cleanup; /* Cleanup function to call when job marked JDEAD */
-  PTR_T cleanarg;      /* Argument passed to (*j_cleanup)() */
-#endif /* JOB_CONTROL */
-} JOB;
-
-struct jobstats {
-  /* limits */
-  long c_childmax;
-  /* child process statistics */
-  int c_living;                /* running or stopped child processes */
-  int c_reaped;                /* exited child processes still in jobs list */
-  int c_injobs;                /* total number of child processes in jobs list */
-  /* child process totals */
-  int c_totforked;     /* total number of children this shell has forked */
-  int c_totreaped;     /* total number of children this shell has reaped */
-  /* job counters and indices */
-  int j_jobslots;      /* total size of jobs array */
-  int j_lastj;         /* last (newest) job allocated */
-  int j_firstj;                /* first (oldest) job allocated */
-  int j_njobs;         /* number of non-NULL jobs in jobs array */
-  int j_ndead;         /* number of JDEAD jobs in jobs array */
-  /* */
-  int j_current;       /* current job */
-  int j_previous;      /* previous job */
-  /* */
-  JOB *j_lastmade;     /* last job allocated by stop_pipeline */
-  JOB *j_lastasync;    /* last async job allocated by stop_pipeline */
-};
-
-struct pidstat {
- struct pidstat *next;
- pid_t pid;
- int status;
-};
-
-struct bgpids {
-  struct pidstat *list;
-  struct pidstat *end;
-  int npid;
-};
-
-#define NO_JOB  -1     /* An impossible job array index. */
-#define DUP_JOB -2     /* A possible return value for get_job_spec (). */
-#define BAD_JOBSPEC -3 /* Bad syntax for job spec. */
-
-/* A value which cannot be a process ID. */
-#define NO_PID (pid_t)-1
-
-/* System calls. */
-#if !defined (HAVE_UNISTD_H)
-extern pid_t fork (), getpid (), getpgrp ();
-#endif /* !HAVE_UNISTD_H */
-
-/* Stuff from the jobs.c file. */
-extern struct jobstats js;
-
-extern pid_t original_pgrp, shell_pgrp, pipeline_pgrp;
-extern pid_t last_made_pid, last_asynchronous_pid;
-extern int asynchronous_notification;
-
-extern JOB **jobs;
-
-extern void making_children __P((void));
-extern void stop_making_children __P((void));
-extern void cleanup_the_pipeline __P((void));
-extern void save_pipeline __P((int));
-extern void restore_pipeline __P((int));
-extern void start_pipeline __P((void));
-extern int stop_pipeline __P((int, COMMAND *));
-
-extern void delete_job __P((int, int));
-extern void nohup_job __P((int));
-extern void delete_all_jobs __P((int));
-extern void nohup_all_jobs __P((int));
-
-extern int count_all_jobs __P((void));
-
-extern void terminate_current_pipeline __P((void));
-extern void terminate_stopped_jobs __P((void));
-extern void hangup_all_jobs __P((void));
-extern void kill_current_pipeline __P((void));
-
-#if defined (__STDC__) && defined (pid_t)
-extern int get_job_by_pid __P((int, int));
-extern void describe_pid __P((int));
-#else
-extern int get_job_by_pid __P((pid_t, int));
-extern void describe_pid __P((pid_t));
-#endif
-
-extern void list_one_job __P((JOB *, int, int, int));
-extern void list_all_jobs __P((int));
-extern void list_stopped_jobs __P((int));
-extern void list_running_jobs __P((int));
-
-extern pid_t make_child __P((char *, int));
-
-extern int get_tty_state __P((void));
-extern int set_tty_state __P((void));
-
-extern int wait_for_single_pid __P((pid_t));
-extern void wait_for_background_pids __P((void));
-extern int wait_for __P((pid_t));
-extern int wait_for_job __P((int));
-
-extern void notify_and_cleanup __P((void));
-extern void reap_dead_jobs __P((void));
-extern int start_job __P((int, int));
-extern int kill_pid __P((pid_t, int, int));
-extern int initialize_job_control __P((int));
-extern void initialize_job_signals __P((void));
-extern int give_terminal_to __P((pid_t, int));
-
-extern void run_sigchld_trap __P((int));
-
-extern void unfreeze_jobs_list __P((void));
-extern int set_job_control __P((int));
-extern void without_job_control __P((void));
-extern void end_job_control __P((void));
-extern void restart_job_control __P((void));
-extern void set_sigchld_handler __P((void));
-extern void ignore_tty_job_signals __P((void));
-extern void default_tty_job_signals __P((void));
-
-extern void init_job_stats __P((void));
-
-extern void close_pgrp_pipe __P((void));
-
-#if defined (JOB_CONTROL)
-extern int job_control;
-#endif
-
-#endif /* _JOBS_H_ */
diff --git a/lib/glob/glob.c.orig b/lib/glob/glob.c.orig
deleted file mode 100644 (file)
index 7b2cf7f..0000000
+++ /dev/null
@@ -1,1073 +0,0 @@
-/* glob.c -- file-name wildcard pattern matching for Bash.
-
-   Copyright (C) 1985-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/>.
-*/
-
-/* To whomever it may concern: I have never seen the code which most
-   Unix programs use to perform this function.  I wrote this from scratch
-   based on specifications for the pattern matching.  --RMS.  */
-
-#include <config.h>
-
-#if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX)
-  #pragma alloca
-#endif /* _AIX && RISC6000 && !__GNUC__ */
-
-#include "bashtypes.h"
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include "bashansi.h"
-#include "posixdir.h"
-#include "posixstat.h"
-#include "shmbutil.h"
-#include "xmalloc.h"
-
-#include "filecntl.h"
-#if !defined (F_OK)
-#  define F_OK 0
-#endif
-
-#include "stdc.h"
-#include "memalloc.h"
-
-#include "shell.h"
-
-#include "glob.h"
-#include "strmatch.h"
-
-#if !defined (HAVE_BCOPY) && !defined (bcopy)
-#  define bcopy(s, d, n) ((void) memcpy ((d), (s), (n)))
-#endif /* !HAVE_BCOPY && !bcopy */
-
-#if !defined (NULL)
-#  if defined (__STDC__)
-#    define NULL ((void *) 0)
-#  else
-#    define NULL 0x0
-#  endif /* __STDC__ */
-#endif /* !NULL */
-
-#if !defined (FREE)
-#  define FREE(x)      if (x) free (x)
-#endif
-
-/* Don't try to alloca() more than this much memory for `struct globval'
-   in glob_vector() */
-#ifndef ALLOCA_MAX
-#  define ALLOCA_MAX   100000
-#endif
-
-struct globval
-  {
-    struct globval *next;
-    char *name;
-  };
-
-extern void throw_to_top_level __P((void));
-extern int sh_eaccess __P((char *, int));
-extern char *sh_makepath __P((const char *, const char *, int));
-
-extern int extended_glob;
-
-/* Global variable which controls whether or not * matches .*.
-   Non-zero means don't match .*.  */
-int noglob_dot_filenames = 1;
-
-/* Global variable which controls whether or not filename globbing
-   is done without regard to case. */
-int glob_ignore_case = 0;
-
-/* Global variable to return to signify an error in globbing. */
-char *glob_error_return;
-
-static struct globval finddirs_error_return;
-
-/* Some forward declarations. */
-static int skipname __P((char *, char *, int));
-#if HANDLE_MULTIBYTE
-static int mbskipname __P((char *, char *, int));
-#endif
-#if HANDLE_MULTIBYTE
-static void udequote_pathname __P((char *));
-static void wdequote_pathname __P((char *));
-#else
-#  define dequote_pathname udequote_pathname
-#endif
-static void dequote_pathname __P((char *));
-static int glob_testdir __P((char *));
-static char **glob_dir_to_array __P((char *, char **, int));
-
-/* Compile `glob_loop.c' for single-byte characters. */
-#define CHAR   unsigned char
-#define INT    int
-#define L(CS)  CS
-#define INTERNAL_GLOB_PATTERN_P internal_glob_pattern_p
-#include "glob_loop.c"
-
-/* Compile `glob_loop.c' again for multibyte characters. */
-#if HANDLE_MULTIBYTE
-
-#define CHAR   wchar_t
-#define INT    wint_t
-#define L(CS)  L##CS
-#define INTERNAL_GLOB_PATTERN_P internal_glob_wpattern_p
-#include "glob_loop.c"
-
-#endif /* HANDLE_MULTIBYTE */
-
-/* And now a function that calls either the single-byte or multibyte version
-   of internal_glob_pattern_p. */
-int
-glob_pattern_p (pattern)
-     const char *pattern;
-{
-#if HANDLE_MULTIBYTE
-  size_t n;
-  wchar_t *wpattern;
-  int r;
-
-  if (MB_CUR_MAX == 1)
-    return (internal_glob_pattern_p ((unsigned char *)pattern));
-
-  /* Convert strings to wide chars, and call the multibyte version. */
-  n = xdupmbstowcs (&wpattern, NULL, pattern);
-  if (n == (size_t)-1)
-    /* Oops.  Invalid multibyte sequence.  Try it as single-byte sequence. */
-    return (internal_glob_pattern_p ((unsigned char *)pattern));
-
-  r = internal_glob_wpattern_p (wpattern);
-  free (wpattern);
-
-  return r;
-#else
-  return (internal_glob_pattern_p (pattern));
-#endif
-}
-
-/* Return 1 if DNAME should be skipped according to PAT.  Mostly concerned
-   with matching leading `.'. */
-
-static int
-skipname (pat, dname, flags)
-     char *pat;
-     char *dname;
-     int flags;
-{
-  /* If a leading dot need not be explicitly matched, and the pattern
-     doesn't start with a `.', don't match `.' or `..' */
-  if (noglob_dot_filenames == 0 && pat[0] != '.' &&
-       (pat[0] != '\\' || pat[1] != '.') &&
-       (dname[0] == '.' &&
-         (dname[1] == '\0' || (dname[1] == '.' && dname[2] == '\0'))))
-    return 1;
-
-  /* If a dot must be explicity matched, check to see if they do. */
-  else if (noglob_dot_filenames && dname[0] == '.' && pat[0] != '.' &&
-       (pat[0] != '\\' || pat[1] != '.'))
-    return 1;
-
-  return 0;
-}
-
-#if HANDLE_MULTIBYTE
-/* Return 1 if DNAME should be skipped according to PAT.  Handles multibyte
-   characters in PAT and DNAME.  Mostly concerned with matching leading `.'. */
-
-static int
-mbskipname (pat, dname, flags)
-     char *pat, *dname;
-     int flags;
-{
-  int ret;
-  wchar_t *pat_wc, *dn_wc;
-  size_t pat_n, dn_n;
-
-  pat_n = xdupmbstowcs (&pat_wc, NULL, pat);
-  dn_n = xdupmbstowcs (&dn_wc, NULL, dname);
-
-  ret = 0;
-  if (pat_n != (size_t)-1 && dn_n !=(size_t)-1)
-    {
-      /* If a leading dot need not be explicitly matched, and the
-        pattern doesn't start with a `.', don't match `.' or `..' */
-      if (noglob_dot_filenames == 0 && pat_wc[0] != L'.' &&
-           (pat_wc[0] != L'\\' || pat_wc[1] != L'.') &&
-           (dn_wc[0] == L'.' &&
-             (dn_wc[1] == L'\0' || (dn_wc[1] == L'.' && dn_wc[2] == L'\0'))))
-       ret = 1;
-
-      /* If a leading dot must be explicity matched, check to see if the
-        pattern and dirname both have one. */
-     else if (noglob_dot_filenames && dn_wc[0] == L'.' &&
-          pat_wc[0] != L'.' &&
-          (pat_wc[0] != L'\\' || pat_wc[1] != L'.'))
-       ret = 1;
-    }
-
-  FREE (pat_wc);
-  FREE (dn_wc);
-
-  return ret;
-}
-#endif /* HANDLE_MULTIBYTE */
-
-/* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */
-static void
-udequote_pathname (pathname)
-     char *pathname;
-{
-  register int i, j;
-
-  for (i = j = 0; pathname && pathname[i]; )
-    {
-      if (pathname[i] == '\\')
-       i++;
-
-      pathname[j++] = pathname[i++];
-
-      if (pathname[i - 1] == 0)
-       break;
-    }
-  pathname[j] = '\0';
-}
-
-#if HANDLE_MULTIBYTE
-/* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */
-static void
-wdequote_pathname (pathname)
-     char *pathname;
-{
-  mbstate_t ps;
-  size_t len, n;
-  wchar_t *wpathname;
-  int i, j;
-  wchar_t *orig_wpathname;
-
-  len = strlen (pathname);
-  /* Convert the strings into wide characters.  */
-  n = xdupmbstowcs (&wpathname, NULL, pathname);
-  if (n == (size_t) -1)
-    /* Something wrong. */
-    return;
-  orig_wpathname = wpathname;
-
-  for (i = j = 0; wpathname && wpathname[i]; )
-    {
-      if (wpathname[i] == L'\\')
-       i++;
-
-      wpathname[j++] = wpathname[i++];
-
-      if (wpathname[i - 1] == L'\0')
-       break;
-    }
-  wpathname[j] = L'\0';
-
-  /* Convert the wide character string into unibyte character set. */
-  memset (&ps, '\0', sizeof(mbstate_t));
-  n = wcsrtombs(pathname, (const wchar_t **)&wpathname, len, &ps);
-  pathname[len] = '\0';
-
-  /* Can't just free wpathname here; wcsrtombs changes it in many cases. */
-  free (orig_wpathname);
-}
-
-static void
-dequote_pathname (pathname)
-     char *pathname;
-{
-  if (MB_CUR_MAX > 1)
-    wdequote_pathname (pathname);
-  else
-    udequote_pathname (pathname);
-}
-#endif /* HANDLE_MULTIBYTE */
-
-/* Test whether NAME exists. */
-
-#if defined (HAVE_LSTAT)
-#  define GLOB_TESTNAME(name)  (lstat (name, &finfo))
-#else /* !HAVE_LSTAT */
-#  if !defined (AFS)
-#    define GLOB_TESTNAME(name)  (sh_eaccess (nextname, F_OK))
-#  else /* AFS */
-#    define GLOB_TESTNAME(name)  (access (nextname, F_OK))
-#  endif /* AFS */
-#endif /* !HAVE_LSTAT */
-
-/* Return 0 if DIR is a directory, -1 otherwise. */
-static int
-glob_testdir (dir)
-     char *dir;
-{
-  struct stat finfo;
-
-  if (stat (dir, &finfo) < 0)
-    return (-1);
-
-  if (S_ISDIR (finfo.st_mode) == 0)
-    return (-1);
-
-  return (0);
-}
-
-/* Recursively scan SDIR for directories matching PAT (PAT is always `**').
-   FLAGS is simply passed down to the recursive call to glob_vector.  Returns
-   a list of matching directory names.  EP, if non-null, is set to the last
-   element of the returned list.  NP, if non-null, is set to the number of
-   directories in the returned list.  These two variables exist for the
-   convenience of the caller (always glob_vector). */
-static struct globval *
-finddirs (pat, sdir, flags, ep, np)
-     char *pat;
-     char *sdir;
-     int flags;
-     struct globval **ep;
-     int *np;
-{
-  char **r, *n;
-  int ndirs;
-  struct globval *ret, *e, *g;
-
-/*itrace("finddirs: pat = `%s' sdir = `%s' flags = 0x%x", pat, sdir, flags);*/
-  e = ret = 0;
-  r = glob_vector (pat, sdir, flags);
-  if (r == 0 || r[0] == 0)
-    {
-      if (np)
-       *np = 0;
-      if (ep)
-        *ep = 0;
-      if (r && r != &glob_error_return)
-       free (r);
-      return (struct globval *)0;
-    }
-  for (ndirs = 0; r[ndirs] != 0; ndirs++)
-    {
-      g = (struct globval *) malloc (sizeof (struct globval));
-      if (g == 0)
-       {
-         while (ret)           /* free list built so far */
-           {
-             g = ret->next;
-             free (ret);
-             ret = g;
-           }
-
-         free (r);
-         if (np)
-           *np = 0;
-         if (ep)
-           *ep = 0;
-         return (&finddirs_error_return);
-       }
-      if (e == 0)
-       e = g;
-
-      g->next = ret;
-      ret = g;
-
-      g->name = r[ndirs];
-    }
-
-  free (r);
-  if (ep)
-    *ep = e;
-  if (np)
-    *np = ndirs;
-
-  return ret;
-}
-
-       
-/* Return a vector of names of files in directory DIR
-   whose names match glob pattern PAT.
-   The names are not in any particular order.
-   Wildcards at the beginning of PAT do not match an initial period.
-
-   The vector is terminated by an element that is a null pointer.
-
-   To free the space allocated, first free the vector's elements,
-   then free the vector.
-
-   Return 0 if cannot get enough memory to hold the pointer
-   and the names.
-
-   Return -1 if cannot access directory DIR.
-   Look in errno for more information.  */
-
-char **
-glob_vector (pat, dir, flags)
-     char *pat;
-     char *dir;
-     int flags;
-{
-  DIR *d;
-  register struct dirent *dp;
-  struct globval *lastlink, *e, *dirlist;
-  register struct globval *nextlink;
-  register char *nextname, *npat, *subdir;
-  unsigned int count;
-  int lose, skip, ndirs, isdir, sdlen, add_current;
-  register char **name_vector;
-  register unsigned int i;
-  int mflags;          /* Flags passed to strmatch (). */
-  int pflags;          /* flags passed to sh_makepath () */
-  int nalloca;
-  struct globval *firstmalloc, *tmplink;
-
-  lastlink = 0;
-  count = lose = skip = add_current = 0;
-
-  firstmalloc = 0;
-  nalloca = 0;
-
-/*itrace("glob_vector: pat = `%s' dir = `%s' flags = 0x%x", pat, dir, flags);*/
-  /* If PAT is empty, skip the loop, but return one (empty) filename. */
-  if (pat == 0 || *pat == '\0')
-    {
-      if (glob_testdir (dir) < 0)
-       return ((char **) &glob_error_return);
-
-      nextlink = (struct globval *)alloca (sizeof (struct globval));
-      if (nextlink == NULL)
-       return ((char **) NULL);
-
-      nextlink->next = (struct globval *)0;
-      nextname = (char *) malloc (1);
-      if (nextname == 0)
-       lose = 1;
-      else
-       {
-         lastlink = nextlink;
-         nextlink->name = nextname;
-         nextname[0] = '\0';
-         count = 1;
-       }
-
-      skip = 1;
-    }
-
-  /* If the filename pattern (PAT) does not contain any globbing characters,
-     we can dispense with reading the directory, and just see if there is
-     a filename `DIR/PAT'.  If there is, and we can access it, just make the
-     vector to return and bail immediately. */
-  if (skip == 0 && glob_pattern_p (pat) == 0)
-    {
-      int dirlen;
-      struct stat finfo;
-
-      if (glob_testdir (dir) < 0)
-       return ((char **) &glob_error_return);
-
-      dirlen = strlen (dir);
-      nextname = (char *)malloc (dirlen + strlen (pat) + 2);
-      npat = (char *)malloc (strlen (pat) + 1);
-      if (nextname == 0 || npat == 0)
-       lose = 1;
-      else
-       {
-         strcpy (npat, pat);
-         dequote_pathname (npat);
-
-         strcpy (nextname, dir);
-         nextname[dirlen++] = '/';
-         strcpy (nextname + dirlen, npat);
-
-         if (GLOB_TESTNAME (nextname) >= 0)
-           {
-             free (nextname);
-             nextlink = (struct globval *)alloca (sizeof (struct globval));
-             if (nextlink)
-               {
-                 nextlink->next = (struct globval *)0;
-                 lastlink = nextlink;
-                 nextlink->name = npat;
-                 count = 1;
-               }
-             else
-               lose = 1;
-           }
-         else
-           {
-             free (nextname);
-             free (npat);
-           }
-       }
-
-      skip = 1;
-    }
-
-  if (skip == 0)
-    {
-      /* Open the directory, punting immediately if we cannot.  If opendir
-        is not robust (i.e., it opens non-directories successfully), test
-        that DIR is a directory and punt if it's not. */
-#if defined (OPENDIR_NOT_ROBUST)
-      if (glob_testdir (dir) < 0)
-       return ((char **) &glob_error_return);
-#endif
-
-      d = opendir (dir);
-      if (d == NULL)
-       return ((char **) &glob_error_return);
-
-      /* Compute the flags that will be passed to strmatch().  We don't
-        need to do this every time through the loop. */
-      mflags = (noglob_dot_filenames ? FNM_PERIOD : 0) | FNM_PATHNAME;
-
-#ifdef FNM_CASEFOLD
-      if (glob_ignore_case)
-       mflags |= FNM_CASEFOLD;
-#endif
-
-      if (extended_glob)
-       mflags |= FNM_EXTMATCH;
-
-      add_current = ((flags & (GX_ALLDIRS|GX_ADDCURDIR)) == (GX_ALLDIRS|GX_ADDCURDIR));
-
-      /* Scan the directory, finding all names that match.
-        For each name that matches, allocate a struct globval
-        on the stack and store the name in it.
-        Chain those structs together; lastlink is the front of the chain.  */
-      while (1)
-       {
-         /* Make globbing interruptible in the shell. */
-         if (interrupt_state || terminating_signal)
-           {
-             lose = 1;
-             break;
-           }
-         
-         dp = readdir (d);
-         if (dp == NULL)
-           break;
-
-         /* If this directory entry is not to be used, try again. */
-         if (REAL_DIR_ENTRY (dp) == 0)
-           continue;
-
-#if 0
-         if (dp->d_name == 0 || *dp->d_name == 0)
-           continue;
-#endif
-
-#if HANDLE_MULTIBYTE
-         if (MB_CUR_MAX > 1 && mbskipname (pat, dp->d_name, flags))
-           continue;
-         else
-#endif
-         if (skipname (pat, dp->d_name, flags))
-           continue;
-
-         /* If we're only interested in directories, don't bother with files */
-         if (flags & (GX_MATCHDIRS|GX_ALLDIRS))
-           {
-             pflags = (flags & GX_ALLDIRS) ? MP_RMDOT : 0;
-             if (flags & GX_NULLDIR)
-               pflags |= MP_IGNDOT;
-             subdir = sh_makepath (dir, dp->d_name, pflags);
-             isdir = glob_testdir (subdir);
-             if (isdir < 0 && (flags & GX_MATCHDIRS))
-               {
-                 free (subdir);
-                 continue;
-               }
-           }
-
-         if (flags & GX_ALLDIRS)
-           {
-             if (isdir == 0)
-               {
-                 dirlist = finddirs (pat, subdir, (flags & ~GX_ADDCURDIR), &e, &ndirs);
-                 if (dirlist == &finddirs_error_return)
-                   {
-                     free (subdir);
-                     lose = 1;
-                     break;
-                   }
-                 if (ndirs)            /* add recursive directories to list */
-                   {
-                     if (firstmalloc == 0)
-                       firstmalloc = e;
-                     e->next = lastlink;
-                     lastlink = dirlist;
-                     count += ndirs;
-                   }
-               }
-
-             nextlink = (struct globval *) malloc (sizeof (struct globval));
-             if (firstmalloc == 0)
-               firstmalloc = nextlink;
-             sdlen = strlen (subdir);
-             nextname = (char *) malloc (sdlen + 1);
-             if (nextlink == 0 || nextname == 0)
-               {
-                 free (subdir);
-                 lose = 1;
-                 break;
-               }
-             nextlink->next = lastlink;
-             lastlink = nextlink;
-             nextlink->name = nextname;
-             bcopy (subdir, nextname, sdlen + 1);
-             free (subdir);
-             ++count;
-             continue;
-           }
-             
-         if (strmatch (pat, dp->d_name, mflags) != FNM_NOMATCH)
-           {
-             if (nalloca < ALLOCA_MAX)
-               {
-                 nextlink = (struct globval *) alloca (sizeof (struct globval));
-                 nalloca += sizeof (struct globval);
-               }
-             else
-               {
-                 nextlink = (struct globval *) malloc (sizeof (struct globval));
-                 if (firstmalloc == 0)
-                   firstmalloc = nextlink;
-               }
-
-             nextname = (char *) malloc (D_NAMLEN (dp) + 1);
-             if (nextlink == 0 || nextname == 0)
-               {
-                 lose = 1;
-                 break;
-               }
-             nextlink->next = lastlink;
-             lastlink = nextlink;
-             nextlink->name = nextname;
-             bcopy (dp->d_name, nextname, D_NAMLEN (dp) + 1);
-             ++count;
-           }
-       }
-
-      (void) closedir (d);
-    }
-
-  /* compat: if GX_ALLDIRS, add the passed directory also, but don't add an
-     empty directory name. */
-  if (add_current && (flags & GX_NULLDIR) == 0)
-    {
-      sdlen = strlen (dir);
-      nextname = (char *)malloc (sdlen + 1);
-      nextlink = (struct globval *) malloc (sizeof (struct globval));
-      if (nextlink == 0 || nextname == 0)
-       lose = 1;
-      else
-       {
-         nextlink->name = nextname;
-         nextlink->next = lastlink;
-         lastlink = nextlink;
-         bcopy (dir, nextname, sdlen + 1);
-         ++count;
-       }
-    }
-
-  if (lose == 0)
-    {
-      name_vector = (char **) malloc ((count + 1) * sizeof (char *));
-      lose |= name_vector == NULL;
-    }
-
-  /* Have we run out of memory?         */
-  if (lose)
-    {
-      tmplink = 0;
-
-      /* Here free the strings we have got.  */
-      while (lastlink)
-       {
-         /* Since we build the list in reverse order, the first N entries
-            will be allocated with malloc, if firstmalloc is set, from
-            lastlink to firstmalloc. */
-         if (firstmalloc)
-           {
-             if (lastlink == firstmalloc)
-               firstmalloc = 0;
-             tmplink = lastlink;
-           }
-         else
-           tmplink = 0;
-         free (lastlink->name);
-         lastlink = lastlink->next;
-         FREE (tmplink);
-       }
-
-      QUIT;
-
-      return ((char **)NULL);
-    }
-
-  /* Copy the name pointers from the linked list into the vector.  */
-  for (tmplink = lastlink, i = 0; i < count; ++i)
-    {
-      name_vector[i] = tmplink->name;
-      tmplink = tmplink->next;
-    }
-
-  name_vector[count] = NULL;
-
-  /* If we allocated some of the struct globvals, free them now. */
-  if (firstmalloc)
-    {
-      tmplink = 0;
-      while (lastlink)
-       {
-         tmplink = lastlink;
-         if (lastlink == firstmalloc)
-           lastlink = firstmalloc = 0;
-         else
-           lastlink = lastlink->next;
-         free (tmplink);
-       }
-    }
-
-  return (name_vector);
-}
-
-/* Return a new array which is the concatenation of each string in ARRAY
-   to DIR.  This function expects you to pass in an allocated ARRAY, and
-   it takes care of free()ing that array.  Thus, you might think of this
-   function as side-effecting ARRAY.  This should handle GX_MARKDIRS. */
-static char **
-glob_dir_to_array (dir, array, flags)
-     char *dir, **array;
-     int flags;
-{
-  register unsigned int i, l;
-  int add_slash;
-  char **result, *new;
-  struct stat sb;
-
-  l = strlen (dir);
-  if (l == 0)
-    {
-      if (flags & GX_MARKDIRS)
-       for (i = 0; array[i]; i++)
-         {
-           if ((stat (array[i], &sb) == 0) && S_ISDIR (sb.st_mode))
-             {
-               l = strlen (array[i]);
-               new = (char *)realloc (array[i], l + 2);
-               if (new == 0)
-                 return NULL;
-               new[l] = '/';
-               new[l+1] = '\0';
-               array[i] = new;
-             }
-         }
-      return (array);
-    }
-
-  add_slash = dir[l - 1] != '/';
-
-  i = 0;
-  while (array[i] != NULL)
-    ++i;
-
-  result = (char **) malloc ((i + 1) * sizeof (char *));
-  if (result == NULL)
-    return (NULL);
-
-  for (i = 0; array[i] != NULL; i++)
-    {
-      /* 3 == 1 for NUL, 1 for slash at end of DIR, 1 for GX_MARKDIRS */
-      result[i] = (char *) malloc (l + strlen (array[i]) + 3);
-
-      if (result[i] == NULL)
-       return (NULL);
-
-      strcpy (result[i], dir);
-      if (add_slash)
-       result[i][l] = '/';
-      strcpy (result[i] + l + add_slash, array[i]);
-      if (flags & GX_MARKDIRS)
-       {
-         if ((stat (result[i], &sb) == 0) && S_ISDIR (sb.st_mode))
-           {
-             size_t rlen;
-             rlen = strlen (result[i]);
-             result[i][rlen] = '/';
-             result[i][rlen+1] = '\0';
-           }
-       }
-    }
-  result[i] = NULL;
-
-  /* Free the input array.  */
-  for (i = 0; array[i] != NULL; i++)
-    free (array[i]);
-  free ((char *) array);
-
-  return (result);
-}
-
-/* Do globbing on PATHNAME.  Return an array of pathnames that match,
-   marking the end of the array with a null-pointer as an element.
-   If no pathnames match, then the array is empty (first element is null).
-   If there isn't enough memory, then return NULL.
-   If a file system error occurs, return -1; `errno' has the error code.  */
-char **
-glob_filename (pathname, flags)
-     char *pathname;
-     int flags;
-{
-  char **result;
-  unsigned int result_size;
-  char *directory_name, *filename, *dname;
-  unsigned int directory_len;
-  int free_dirname;                    /* flag */
-  int dflags;
-
-  result = (char **) malloc (sizeof (char *));
-  result_size = 1;
-  if (result == NULL)
-    return (NULL);
-
-  result[0] = NULL;
-
-  directory_name = NULL;
-
-  /* Find the filename.  */
-  filename = strrchr (pathname, '/');
-  if (filename == NULL)
-    {
-      filename = pathname;
-      directory_name = "";
-      directory_len = 0;
-      free_dirname = 0;
-    }
-  else
-    {
-      directory_len = (filename - pathname) + 1;
-      directory_name = (char *) malloc (directory_len + 1);
-
-      if (directory_name == 0)         /* allocation failed? */
-       return (NULL);
-
-      bcopy (pathname, directory_name, directory_len);
-      directory_name[directory_len] = '\0';
-      ++filename;
-      free_dirname = 1;
-    }
-
-  /* If directory_name contains globbing characters, then we
-     have to expand the previous levels.  Just recurse. */
-  if (glob_pattern_p (directory_name))
-    {
-      char **directories;
-      register unsigned int i;
-
-      dflags = flags & ~GX_MARKDIRS;
-      if ((flags & GX_GLOBSTAR) && directory_name[0] == '*' && directory_name[1] == '*' && (directory_name[2] == '/' || directory_name[2] == '\0'))
-       dflags |= GX_ALLDIRS|GX_ADDCURDIR;
-
-      if (directory_name[directory_len - 1] == '/')
-       directory_name[directory_len - 1] = '\0';
-
-      directories = glob_filename (directory_name, dflags);
-
-      if (free_dirname)
-       {
-         free (directory_name);
-         directory_name = NULL;
-       }
-
-      if (directories == NULL)
-       goto memory_error;
-      else if (directories == (char **)&glob_error_return)
-       {
-         free ((char *) result);
-         return ((char **) &glob_error_return);
-       }
-      else if (*directories == NULL)
-       {
-         free ((char *) directories);
-         free ((char *) result);
-         return ((char **) &glob_error_return);
-       }
-
-      /* We have successfully globbed the preceding directory name.
-        For each name in DIRECTORIES, call glob_vector on it and
-        FILENAME.  Concatenate the results together.  */
-      for (i = 0; directories[i] != NULL; ++i)
-       {
-         char **temp_results;
-
-         /* Scan directory even on a NULL filename.  That way, `*h/'
-            returns only directories ending in `h', instead of all
-            files ending in `h' with a `/' appended. */
-         dname = directories[i];
-         dflags = flags & ~GX_MARKDIRS;
-         if ((flags & GX_GLOBSTAR) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
-           dflags |= GX_ALLDIRS|GX_ADDCURDIR;
-         if (dname[0] == '\0' && filename[0])
-           {
-             dflags |= GX_NULLDIR;
-             dname = ".";      /* treat null directory name and non-null filename as current directory */
-           }
-         temp_results = glob_vector (filename, dname, dflags);
-
-         /* Handle error cases. */
-         if (temp_results == NULL)
-           goto memory_error;
-         else if (temp_results == (char **)&glob_error_return)
-           /* This filename is probably not a directory.  Ignore it.  */
-           ;
-         else
-           {
-             char **array;
-             register unsigned int l;
-
-             /* If we're expanding **, we don't need to glue the directory
-                name to the results; we've already done it in glob_vector */
-             if ((dflags & GX_ALLDIRS) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
-               array = temp_results;
-             else
-               array = glob_dir_to_array (directories[i], temp_results, flags);
-             l = 0;
-             while (array[l] != NULL)
-               ++l;
-
-             result =
-               (char **)realloc (result, (result_size + l) * sizeof (char *));
-
-             if (result == NULL)
-               goto memory_error;
-
-             for (l = 0; array[l] != NULL; ++l)
-               result[result_size++ - 1] = array[l];
-
-             result[result_size - 1] = NULL;
-
-             /* Note that the elements of ARRAY are not freed.  */
-             if (array != temp_results)
-               free ((char *) array);
-           }
-       }
-      /* Free the directories.  */
-      for (i = 0; directories[i]; i++)
-       free (directories[i]);
-
-      free ((char *) directories);
-
-      return (result);
-    }
-
-  /* If there is only a directory name, return it. */
-  if (*filename == '\0')
-    {
-      result = (char **) realloc ((char *) result, 2 * sizeof (char *));
-      if (result == NULL)
-       return (NULL);
-      /* Handle GX_MARKDIRS here. */
-      result[0] = (char *) malloc (directory_len + 1);
-      if (result[0] == NULL)
-       goto memory_error;
-      bcopy (directory_name, result[0], directory_len + 1);
-      if (free_dirname)
-       free (directory_name);
-      result[1] = NULL;
-      return (result);
-    }
-  else
-    {
-      char **temp_results;
-
-      /* There are no unquoted globbing characters in DIRECTORY_NAME.
-        Dequote it before we try to open the directory since there may
-        be quoted globbing characters which should be treated verbatim. */
-      if (directory_len > 0)
-       dequote_pathname (directory_name);
-
-      /* We allocated a small array called RESULT, which we won't be using.
-        Free that memory now. */
-      free (result);
-
-      /* Just return what glob_vector () returns appended to the
-        directory name. */
-      dflags = flags & ~GX_MARKDIRS;
-      if (directory_len == 0)
-       dflags |= GX_NULLDIR;
-      if ((flags & GX_GLOBSTAR) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
-       dflags |= GX_ALLDIRS|GX_ADDCURDIR;
-      temp_results = glob_vector (filename,
-                                 (directory_len == 0 ? "." : directory_name),
-                                 dflags);
-
-      if (temp_results == NULL || temp_results == (char **)&glob_error_return)
-       {
-         if (free_dirname)
-           free (directory_name);
-         return (temp_results);
-       }
-
-      result = glob_dir_to_array ((dflags & GX_ALLDIRS) ? "" : directory_name, temp_results, flags);
-      if (free_dirname)
-       free (directory_name);
-      return (result);
-    }
-
-  /* We get to memory_error if the program has run out of memory, or
-     if this is the shell, and we have been interrupted. */
- memory_error:
-  if (result != NULL)
-    {
-      register unsigned int i;
-      for (i = 0; result[i] != NULL; ++i)
-       free (result[i]);
-      free ((char *) result);
-    }
-
-  if (free_dirname && directory_name)
-    free (directory_name);
-
-  QUIT;
-
-  return (NULL);
-}
-
-#if defined (TEST)
-
-main (argc, argv)
-     int argc;
-     char **argv;
-{
-  unsigned int i;
-
-  for (i = 1; i < argc; ++i)
-    {
-      char **value = glob_filename (argv[i], 0);
-      if (value == NULL)
-       puts ("Out of memory.");
-      else if (value == &glob_error_return)
-       perror (argv[i]);
-      else
-       for (i = 0; value[i] != NULL; i++)
-         puts (value[i]);
-    }
-
-  exit (0);
-}
-#endif /* TEST.  */
diff --git a/lib/glob/glob.c.save1 b/lib/glob/glob.c.save1
deleted file mode 100644 (file)
index 2ab770b..0000000
+++ /dev/null
@@ -1,1113 +0,0 @@
-/* glob.c -- file-name wildcard pattern matching for Bash.
-
-   Copyright (C) 1985-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/>.
-*/
-
-/* To whomever it may concern: I have never seen the code which most
-   Unix programs use to perform this function.  I wrote this from scratch
-   based on specifications for the pattern matching.  --RMS.  */
-
-#include <config.h>
-
-#if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX)
-  #pragma alloca
-#endif /* _AIX && RISC6000 && !__GNUC__ */
-
-#include "bashtypes.h"
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include "bashansi.h"
-#include "posixdir.h"
-#include "posixstat.h"
-#include "shmbutil.h"
-#include "xmalloc.h"
-
-#include "filecntl.h"
-#if !defined (F_OK)
-#  define F_OK 0
-#endif
-
-#include "stdc.h"
-#include "memalloc.h"
-
-#include "shell.h"
-
-#include "glob.h"
-#include "strmatch.h"
-
-#if !defined (HAVE_BCOPY) && !defined (bcopy)
-#  define bcopy(s, d, n) ((void) memcpy ((d), (s), (n)))
-#endif /* !HAVE_BCOPY && !bcopy */
-
-#if !defined (NULL)
-#  if defined (__STDC__)
-#    define NULL ((void *) 0)
-#  else
-#    define NULL 0x0
-#  endif /* __STDC__ */
-#endif /* !NULL */
-
-#if !defined (FREE)
-#  define FREE(x)      if (x) free (x)
-#endif
-
-/* Don't try to alloca() more than this much memory for `struct globval'
-   in glob_vector() */
-#ifndef ALLOCA_MAX
-#  define ALLOCA_MAX   100000
-#endif
-
-struct globval
-  {
-    struct globval *next;
-    char *name;
-  };
-
-extern void throw_to_top_level __P((void));
-extern int sh_eaccess __P((char *, int));
-extern char *sh_makepath __P((const char *, const char *, int));
-
-extern int extended_glob;
-
-/* Global variable which controls whether or not * matches .*.
-   Non-zero means don't match .*.  */
-int noglob_dot_filenames = 1;
-
-/* Global variable which controls whether or not filename globbing
-   is done without regard to case. */
-int glob_ignore_case = 0;
-
-/* Global variable to return to signify an error in globbing. */
-char *glob_error_return;
-
-static struct globval finddirs_error_return;
-
-/* Some forward declarations. */
-static int skipname __P((char *, char *, int));
-#if HANDLE_MULTIBYTE
-static int mbskipname __P((char *, char *, int));
-#endif
-#if HANDLE_MULTIBYTE
-static void udequote_pathname __P((char *));
-static void wdequote_pathname __P((char *));
-#else
-#  define dequote_pathname udequote_pathname
-#endif
-static void dequote_pathname __P((char *));
-static int glob_testdir __P((char *));
-static char **glob_dir_to_array __P((char *, char **, int));
-
-/* Compile `glob_loop.c' for single-byte characters. */
-#define CHAR   unsigned char
-#define INT    int
-#define L(CS)  CS
-#define INTERNAL_GLOB_PATTERN_P internal_glob_pattern_p
-#include "glob_loop.c"
-
-/* Compile `glob_loop.c' again for multibyte characters. */
-#if HANDLE_MULTIBYTE
-
-#define CHAR   wchar_t
-#define INT    wint_t
-#define L(CS)  L##CS
-#define INTERNAL_GLOB_PATTERN_P internal_glob_wpattern_p
-#include "glob_loop.c"
-
-#endif /* HANDLE_MULTIBYTE */
-
-/* And now a function that calls either the single-byte or multibyte version
-   of internal_glob_pattern_p. */
-int
-glob_pattern_p (pattern)
-     const char *pattern;
-{
-#if HANDLE_MULTIBYTE
-  size_t n;
-  wchar_t *wpattern;
-  int r;
-
-  if (MB_CUR_MAX == 1)
-    return (internal_glob_pattern_p ((unsigned char *)pattern));
-
-  /* Convert strings to wide chars, and call the multibyte version. */
-  n = xdupmbstowcs (&wpattern, NULL, pattern);
-  if (n == (size_t)-1)
-    /* Oops.  Invalid multibyte sequence.  Try it as single-byte sequence. */
-    return (internal_glob_pattern_p ((unsigned char *)pattern));
-
-  r = internal_glob_wpattern_p (wpattern);
-  free (wpattern);
-
-  return r;
-#else
-  return (internal_glob_pattern_p (pattern));
-#endif
-}
-
-/* Return 1 if DNAME should be skipped according to PAT.  Mostly concerned
-   with matching leading `.'. */
-
-static int
-skipname (pat, dname, flags)
-     char *pat;
-     char *dname;
-     int flags;
-{
-  /* If a leading dot need not be explicitly matched, and the pattern
-     doesn't start with a `.', don't match `.' or `..' */
-  if (noglob_dot_filenames == 0 && pat[0] != '.' &&
-       (pat[0] != '\\' || pat[1] != '.') &&
-       (dname[0] == '.' &&
-         (dname[1] == '\0' || (dname[1] == '.' && dname[2] == '\0'))))
-    return 1;
-
-  /* If a dot must be explicity matched, check to see if they do. */
-  else if (noglob_dot_filenames && dname[0] == '.' && pat[0] != '.' &&
-       (pat[0] != '\\' || pat[1] != '.'))
-    return 1;
-
-  return 0;
-}
-
-#if HANDLE_MULTIBYTE
-/* Return 1 if DNAME should be skipped according to PAT.  Handles multibyte
-   characters in PAT and DNAME.  Mostly concerned with matching leading `.'. */
-
-static int
-mbskipname (pat, dname, flags)
-     char *pat, *dname;
-     int flags;
-{
-  int ret;
-  wchar_t *pat_wc, *dn_wc;
-  size_t pat_n, dn_n;
-
-  pat_n = xdupmbstowcs (&pat_wc, NULL, pat);
-  dn_n = xdupmbstowcs (&dn_wc, NULL, dname);
-
-  ret = 0;
-  if (pat_n != (size_t)-1 && dn_n !=(size_t)-1)
-    {
-      /* If a leading dot need not be explicitly matched, and the
-        pattern doesn't start with a `.', don't match `.' or `..' */
-      if (noglob_dot_filenames == 0 && pat_wc[0] != L'.' &&
-           (pat_wc[0] != L'\\' || pat_wc[1] != L'.') &&
-           (dn_wc[0] == L'.' &&
-             (dn_wc[1] == L'\0' || (dn_wc[1] == L'.' && dn_wc[2] == L'\0'))))
-       ret = 1;
-
-      /* If a leading dot must be explicity matched, check to see if the
-        pattern and dirname both have one. */
-     else if (noglob_dot_filenames && dn_wc[0] == L'.' &&
-          pat_wc[0] != L'.' &&
-          (pat_wc[0] != L'\\' || pat_wc[1] != L'.'))
-       ret = 1;
-    }
-
-  FREE (pat_wc);
-  FREE (dn_wc);
-
-  return ret;
-}
-#endif /* HANDLE_MULTIBYTE */
-
-/* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */
-static void
-udequote_pathname (pathname)
-     char *pathname;
-{
-  register int i, j;
-
-  for (i = j = 0; pathname && pathname[i]; )
-    {
-      if (pathname[i] == '\\')
-       i++;
-
-      pathname[j++] = pathname[i++];
-
-      if (pathname[i - 1] == 0)
-       break;
-    }
-  pathname[j] = '\0';
-}
-
-#if HANDLE_MULTIBYTE
-/* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */
-static void
-wdequote_pathname (pathname)
-     char *pathname;
-{
-  mbstate_t ps;
-  size_t len, n;
-  wchar_t *wpathname;
-  int i, j;
-  wchar_t *orig_wpathname;
-
-  len = strlen (pathname);
-  /* Convert the strings into wide characters.  */
-  n = xdupmbstowcs (&wpathname, NULL, pathname);
-  if (n == (size_t) -1)
-    /* Something wrong. */
-    return;
-  orig_wpathname = wpathname;
-
-  for (i = j = 0; wpathname && wpathname[i]; )
-    {
-      if (wpathname[i] == L'\\')
-       i++;
-
-      wpathname[j++] = wpathname[i++];
-
-      if (wpathname[i - 1] == L'\0')
-       break;
-    }
-  wpathname[j] = L'\0';
-
-  /* Convert the wide character string into unibyte character set. */
-  memset (&ps, '\0', sizeof(mbstate_t));
-  n = wcsrtombs(pathname, (const wchar_t **)&wpathname, len, &ps);
-  pathname[len] = '\0';
-
-  /* Can't just free wpathname here; wcsrtombs changes it in many cases. */
-  free (orig_wpathname);
-}
-
-static void
-dequote_pathname (pathname)
-     char *pathname;
-{
-  if (MB_CUR_MAX > 1)
-    wdequote_pathname (pathname);
-  else
-    udequote_pathname (pathname);
-}
-#endif /* HANDLE_MULTIBYTE */
-
-/* Test whether NAME exists. */
-
-#if defined (HAVE_LSTAT)
-#  define GLOB_TESTNAME(name)  (lstat (name, &finfo))
-#else /* !HAVE_LSTAT */
-#  if !defined (AFS)
-#    define GLOB_TESTNAME(name)  (sh_eaccess (nextname, F_OK))
-#  else /* AFS */
-#    define GLOB_TESTNAME(name)  (access (nextname, F_OK))
-#  endif /* AFS */
-#endif /* !HAVE_LSTAT */
-
-/* Return 0 if DIR is a directory, -1 otherwise. */
-static int
-glob_testdir (dir)
-     char *dir;
-{
-  struct stat finfo;
-
-  if (stat (dir, &finfo) < 0)
-    return (-1);
-
-  if (S_ISDIR (finfo.st_mode) == 0)
-    return (-1);
-
-  return (0);
-}
-
-/* Recursively scan SDIR for directories matching PAT (PAT is always `**').
-   FLAGS is simply passed down to the recursive call to glob_vector.  Returns
-   a list of matching directory names.  EP, if non-null, is set to the last
-   element of the returned list.  NP, if non-null, is set to the number of
-   directories in the returned list.  These two variables exist for the
-   convenience of the caller (always glob_vector). */
-static struct globval *
-finddirs (pat, sdir, flags, ep, np)
-     char *pat;
-     char *sdir;
-     int flags;
-     struct globval **ep;
-     int *np;
-{
-  char **r, *n;
-  int ndirs;
-  struct globval *ret, *e, *g;
-
-/*itrace("finddirs: pat = `%s' sdir = `%s' flags = 0x%x", pat, sdir, flags);*/
-  e = ret = 0;
-  r = glob_vector (pat, sdir, flags);
-  if (r == 0 || r[0] == 0)
-    {
-      if (np)
-       *np = 0;
-      if (ep)
-        *ep = 0;
-      if (r && r != &glob_error_return)
-       free (r);
-      return (struct globval *)0;
-    }
-  for (ndirs = 0; r[ndirs] != 0; ndirs++)
-    {
-      g = (struct globval *) malloc (sizeof (struct globval));
-      if (g == 0)
-       {
-         while (ret)           /* free list built so far */
-           {
-             g = ret->next;
-             free (ret);
-             ret = g;
-           }
-
-         free (r);
-         if (np)
-           *np = 0;
-         if (ep)
-           *ep = 0;
-         return (&finddirs_error_return);
-       }
-      if (e == 0)
-       e = g;
-
-      g->next = ret;
-      ret = g;
-
-      g->name = r[ndirs];
-    }
-
-  free (r);
-  if (ep)
-    *ep = e;
-  if (np)
-    *np = ndirs;
-
-  return ret;
-}
-
-       
-/* Return a vector of names of files in directory DIR
-   whose names match glob pattern PAT.
-   The names are not in any particular order.
-   Wildcards at the beginning of PAT do not match an initial period.
-
-   The vector is terminated by an element that is a null pointer.
-
-   To free the space allocated, first free the vector's elements,
-   then free the vector.
-
-   Return 0 if cannot get enough memory to hold the pointer
-   and the names.
-
-   Return -1 if cannot access directory DIR.
-   Look in errno for more information.  */
-
-char **
-glob_vector (pat, dir, flags)
-     char *pat;
-     char *dir;
-     int flags;
-{
-  DIR *d;
-  register struct dirent *dp;
-  struct globval *lastlink, *e, *dirlist;
-  register struct globval *nextlink;
-  register char *nextname, *npat, *subdir;
-  unsigned int count;
-  int lose, skip, ndirs, isdir, sdlen, add_current;
-  register char **name_vector;
-  register unsigned int i;
-  int mflags;          /* Flags passed to strmatch (). */
-  int pflags;          /* flags passed to sh_makepath () */
-  int nalloca;
-  struct globval *firstmalloc, *tmplink;
-
-  lastlink = 0;
-  count = lose = skip = add_current = 0;
-
-  firstmalloc = 0;
-  nalloca = 0;
-
-/*itrace("glob_vector: pat = `%s' dir = `%s' flags = 0x%x", pat, dir, flags);*/
-  /* If PAT is empty, skip the loop, but return one (empty) filename. */
-  if (pat == 0 || *pat == '\0')
-    {
-      if (glob_testdir (dir) < 0)
-       return ((char **) &glob_error_return);
-
-      nextlink = (struct globval *)alloca (sizeof (struct globval));
-      if (nextlink == NULL)
-       return ((char **) NULL);
-
-      nextlink->next = (struct globval *)0;
-      nextname = (char *) malloc (1);
-      if (nextname == 0)
-       lose = 1;
-      else
-       {
-         lastlink = nextlink;
-         nextlink->name = nextname;
-         nextname[0] = '\0';
-         count = 1;
-       }
-
-      skip = 1;
-    }
-
-  /* If the filename pattern (PAT) does not contain any globbing characters,
-     we can dispense with reading the directory, and just see if there is
-     a filename `DIR/PAT'.  If there is, and we can access it, just make the
-     vector to return and bail immediately. */
-  if (skip == 0 && glob_pattern_p (pat) == 0)
-    {
-      int dirlen;
-      struct stat finfo;
-
-      if (glob_testdir (dir) < 0)
-       return ((char **) &glob_error_return);
-
-      dirlen = strlen (dir);
-      nextname = (char *)malloc (dirlen + strlen (pat) + 2);
-      npat = (char *)malloc (strlen (pat) + 1);
-      if (nextname == 0 || npat == 0)
-       lose = 1;
-      else
-       {
-         strcpy (npat, pat);
-         dequote_pathname (npat);
-
-         strcpy (nextname, dir);
-         nextname[dirlen++] = '/';
-         strcpy (nextname + dirlen, npat);
-
-         if (GLOB_TESTNAME (nextname) >= 0)
-           {
-             free (nextname);
-             nextlink = (struct globval *)alloca (sizeof (struct globval));
-             if (nextlink)
-               {
-                 nextlink->next = (struct globval *)0;
-                 lastlink = nextlink;
-                 nextlink->name = npat;
-                 count = 1;
-               }
-             else
-               lose = 1;
-           }
-         else
-           {
-             free (nextname);
-             free (npat);
-           }
-       }
-
-      skip = 1;
-    }
-
-  if (skip == 0)
-    {
-      /* Open the directory, punting immediately if we cannot.  If opendir
-        is not robust (i.e., it opens non-directories successfully), test
-        that DIR is a directory and punt if it's not. */
-#if defined (OPENDIR_NOT_ROBUST)
-      if (glob_testdir (dir) < 0)
-       return ((char **) &glob_error_return);
-#endif
-
-      d = opendir (dir);
-      if (d == NULL)
-       return ((char **) &glob_error_return);
-
-      /* Compute the flags that will be passed to strmatch().  We don't
-        need to do this every time through the loop. */
-      mflags = (noglob_dot_filenames ? FNM_PERIOD : 0) | FNM_PATHNAME;
-
-#ifdef FNM_CASEFOLD
-      if (glob_ignore_case)
-       mflags |= FNM_CASEFOLD;
-#endif
-
-      if (extended_glob)
-       mflags |= FNM_EXTMATCH;
-
-      add_current = ((flags & (GX_ALLDIRS|GX_ADDCURDIR)) == (GX_ALLDIRS|GX_ADDCURDIR));
-
-      /* Scan the directory, finding all names that match.
-        For each name that matches, allocate a struct globval
-        on the stack and store the name in it.
-        Chain those structs together; lastlink is the front of the chain.  */
-      while (1)
-       {
-         /* Make globbing interruptible in the shell. */
-         if (interrupt_state || terminating_signal)
-           {
-             lose = 1;
-             break;
-           }
-         
-         dp = readdir (d);
-         if (dp == NULL)
-           break;
-
-         /* If this directory entry is not to be used, try again. */
-         if (REAL_DIR_ENTRY (dp) == 0)
-           continue;
-
-#if 0
-         if (dp->d_name == 0 || *dp->d_name == 0)
-           continue;
-#endif
-
-#if HANDLE_MULTIBYTE
-         if (MB_CUR_MAX > 1 && mbskipname (pat, dp->d_name, flags))
-           continue;
-         else
-#endif
-         if (skipname (pat, dp->d_name, flags))
-           continue;
-
-         /* If we're only interested in directories, don't bother with files */
-         if (flags & (GX_MATCHDIRS|GX_ALLDIRS))
-           {
-             pflags = (flags & GX_ALLDIRS) ? MP_RMDOT : 0;
-             if (flags & GX_NULLDIR)
-               pflags |= MP_IGNDOT;
-             subdir = sh_makepath (dir, dp->d_name, pflags);
-             isdir = glob_testdir (subdir);
-             if (isdir < 0 && (flags & GX_MATCHDIRS))
-               {
-                 free (subdir);
-                 continue;
-               }
-           }
-
-         if (flags & GX_ALLDIRS)
-           {
-             if (isdir == 0)
-               {
-                 dirlist = finddirs (pat, subdir, (flags & ~GX_ADDCURDIR), &e, &ndirs);
-                 if (dirlist == &finddirs_error_return)
-                   {
-                     free (subdir);
-                     lose = 1;
-                     break;
-                   }
-                 if (ndirs)            /* add recursive directories to list */
-                   {
-                     if (firstmalloc == 0)
-                       firstmalloc = e;
-                     e->next = lastlink;
-                     lastlink = dirlist;
-                     count += ndirs;
-                   }
-               }
-
-             nextlink = (struct globval *) malloc (sizeof (struct globval));
-             if (firstmalloc == 0)
-               firstmalloc = nextlink;
-             sdlen = strlen (subdir);
-             nextname = (char *) malloc (sdlen + 1);
-             if (nextlink == 0 || nextname == 0)
-               {
-                 free (subdir);
-                 lose = 1;
-                 break;
-               }
-             nextlink->next = lastlink;
-             lastlink = nextlink;
-             nextlink->name = nextname;
-             bcopy (subdir, nextname, sdlen + 1);
-             free (subdir);
-             ++count;
-             continue;
-           }
-             
-         if (strmatch (pat, dp->d_name, mflags) != FNM_NOMATCH)
-           {
-             if (nalloca < ALLOCA_MAX)
-               {
-                 nextlink = (struct globval *) alloca (sizeof (struct globval));
-                 nalloca += sizeof (struct globval);
-               }
-             else
-               {
-                 nextlink = (struct globval *) malloc (sizeof (struct globval));
-                 if (firstmalloc == 0)
-                   firstmalloc = nextlink;
-               }
-
-             nextname = (char *) malloc (D_NAMLEN (dp) + 1);
-             if (nextlink == 0 || nextname == 0)
-               {
-                 lose = 1;
-                 break;
-               }
-             nextlink->next = lastlink;
-             lastlink = nextlink;
-             nextlink->name = nextname;
-             bcopy (dp->d_name, nextname, D_NAMLEN (dp) + 1);
-             ++count;
-           }
-       }
-
-      (void) closedir (d);
-    }
-
-  /* compat: if GX_ALLDIRS, add the passed directory also, but don't add an
-     empty directory name. */
-  if (add_current)
-    {
-/*itrace("glob_vector: add_current = %d flags = %d", add_current, flags);*/
-      sdlen = strlen (dir);
-      nextname = (char *)malloc (sdlen + 1);
-      nextlink = (struct globval *) malloc (sizeof (struct globval));
-      if (nextlink == 0 || nextname == 0)
-       lose = 1;
-      else
-       {
-         nextlink->name = nextname;
-         nextlink->next = lastlink;
-         lastlink = nextlink;
-         if (flags & GX_NULLDIR)
-           nextname[0] = '\0';
-         else
-           bcopy (dir, nextname, sdlen + 1);
-         ++count;
-       }
-    }
-
-  if (lose == 0)
-    {
-      name_vector = (char **) malloc ((count + 1) * sizeof (char *));
-      lose |= name_vector == NULL;
-    }
-
-  /* Have we run out of memory?         */
-  if (lose)
-    {
-      tmplink = 0;
-
-      /* Here free the strings we have got.  */
-      while (lastlink)
-       {
-         /* Since we build the list in reverse order, the first N entries
-            will be allocated with malloc, if firstmalloc is set, from
-            lastlink to firstmalloc. */
-         if (firstmalloc)
-           {
-             if (lastlink == firstmalloc)
-               firstmalloc = 0;
-             tmplink = lastlink;
-           }
-         else
-           tmplink = 0;
-         free (lastlink->name);
-         lastlink = lastlink->next;
-         FREE (tmplink);
-       }
-
-      QUIT;
-
-      return ((char **)NULL);
-    }
-
-  /* Copy the name pointers from the linked list into the vector.  */
-  for (tmplink = lastlink, i = 0; i < count; ++i)
-    {
-      name_vector[i] = tmplink->name;
-      tmplink = tmplink->next;
-    }
-
-  name_vector[count] = NULL;
-
-  /* If we allocated some of the struct globvals, free them now. */
-  if (firstmalloc)
-    {
-      tmplink = 0;
-      while (lastlink)
-       {
-         tmplink = lastlink;
-         if (lastlink == firstmalloc)
-           lastlink = firstmalloc = 0;
-         else
-           lastlink = lastlink->next;
-         free (tmplink);
-       }
-    }
-
-  return (name_vector);
-}
-
-/* Return a new array which is the concatenation of each string in ARRAY
-   to DIR.  This function expects you to pass in an allocated ARRAY, and
-   it takes care of free()ing that array.  Thus, you might think of this
-   function as side-effecting ARRAY.  This should handle GX_MARKDIRS. */
-static char **
-glob_dir_to_array (dir, array, flags)
-     char *dir, **array;
-     int flags;
-{
-  register unsigned int i, l;
-  int add_slash;
-  char **result, *new;
-  struct stat sb;
-
-  l = strlen (dir);
-  if (l == 0)
-    {
-      if (flags & GX_MARKDIRS)
-       for (i = 0; array[i]; i++)
-         {
-           if ((stat (array[i], &sb) == 0) && S_ISDIR (sb.st_mode))
-             {
-               l = strlen (array[i]);
-               new = (char *)realloc (array[i], l + 2);
-               if (new == 0)
-                 return NULL;
-               new[l] = '/';
-               new[l+1] = '\0';
-               array[i] = new;
-             }
-         }
-      return (array);
-    }
-
-  add_slash = dir[l - 1] != '/';
-
-  i = 0;
-  while (array[i] != NULL)
-    ++i;
-
-  result = (char **) malloc ((i + 1) * sizeof (char *));
-  if (result == NULL)
-    return (NULL);
-
-  for (i = 0; array[i] != NULL; i++)
-    {
-      /* 3 == 1 for NUL, 1 for slash at end of DIR, 1 for GX_MARKDIRS */
-      result[i] = (char *) malloc (l + strlen (array[i]) + 3);
-
-      if (result[i] == NULL)
-       return (NULL);
-
-      strcpy (result[i], dir);
-      if (add_slash)
-       result[i][l] = '/';
-      strcpy (result[i] + l + add_slash, array[i]);
-      if (flags & GX_MARKDIRS)
-       {
-         if ((stat (result[i], &sb) == 0) && S_ISDIR (sb.st_mode))
-           {
-             size_t rlen;
-             rlen = strlen (result[i]);
-             result[i][rlen] = '/';
-             result[i][rlen+1] = '\0';
-           }
-       }
-    }
-  result[i] = NULL;
-
-  /* Free the input array.  */
-  for (i = 0; array[i] != NULL; i++)
-    free (array[i]);
-  free ((char *) array);
-
-  return (result);
-}
-
-/* Do globbing on PATHNAME.  Return an array of pathnames that match,
-   marking the end of the array with a null-pointer as an element.
-   If no pathnames match, then the array is empty (first element is null).
-   If there isn't enough memory, then return NULL.
-   If a file system error occurs, return -1; `errno' has the error code.  */
-char **
-glob_filename (pathname, flags)
-     char *pathname;
-     int flags;
-{
-  char **result;
-  unsigned int result_size;
-  char *directory_name, *filename, *dname;
-  unsigned int directory_len;
-  int free_dirname;                    /* flag */
-  int dflags;
-
-  result = (char **) malloc (sizeof (char *));
-  result_size = 1;
-  if (result == NULL)
-    return (NULL);
-
-  result[0] = NULL;
-
-  directory_name = NULL;
-
-  /* Find the filename.  */
-  filename = strrchr (pathname, '/');
-  if (filename == NULL)
-    {
-      filename = pathname;
-      directory_name = "";
-      directory_len = 0;
-      free_dirname = 0;
-    }
-  else
-    {
-      directory_len = (filename - pathname) + 1;
-      directory_name = (char *) malloc (directory_len + 1);
-
-      if (directory_name == 0)         /* allocation failed? */
-       return (NULL);
-
-      bcopy (pathname, directory_name, directory_len);
-      directory_name[directory_len] = '\0';
-      ++filename;
-      free_dirname = 1;
-    }
-
-  /* If directory_name contains globbing characters, then we
-     have to expand the previous levels.  Just recurse. */
-  if (glob_pattern_p (directory_name))
-    {
-      char **directories;
-      register unsigned int i;
-
-      dflags = flags & ~GX_MARKDIRS;
-      if ((flags & GX_GLOBSTAR) && directory_name[0] == '*' && directory_name[1] == '*' && (directory_name[2] == '/' || directory_name[2] == '\0'))
-       dflags |= GX_ALLDIRS|GX_ADDCURDIR;
-
-      if (directory_name[directory_len - 1] == '/')
-       directory_name[directory_len - 1] = '\0';
-
-      directories = glob_filename (directory_name, dflags);
-
-      if (free_dirname)
-       {
-         free (directory_name);
-         directory_name = NULL;
-       }
-
-      if (directories == NULL)
-       goto memory_error;
-      else if (directories == (char **)&glob_error_return)
-       {
-         free ((char *) result);
-         return ((char **) &glob_error_return);
-       }
-      else if (*directories == NULL)
-       {
-         free ((char *) directories);
-         free ((char *) result);
-         return ((char **) &glob_error_return);
-       }
-
-      /* We have successfully globbed the preceding directory name.
-        For each name in DIRECTORIES, call glob_vector on it and
-        FILENAME.  Concatenate the results together.  */
-      for (i = 0; directories[i] != NULL; ++i)
-       {
-         char **temp_results;
-
-         /* Scan directory even on a NULL filename.  That way, `*h/'
-            returns only directories ending in `h', instead of all
-            files ending in `h' with a `/' appended. */
-         dname = directories[i];
-         dflags = flags & ~GX_MARKDIRS;
-         if ((flags & GX_GLOBSTAR) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
-           dflags |= GX_ALLDIRS|GX_ADDCURDIR;
-         if (dname[0] == '\0' && filename[0])
-           {
-             dflags |= GX_NULLDIR;
-             dname = ".";      /* treat null directory name and non-null filename as current directory */
-           }
-         temp_results = glob_vector (filename, dname, dflags);
-
-         /* Handle error cases. */
-         if (temp_results == NULL)
-           goto memory_error;
-         else if (temp_results == (char **)&glob_error_return)
-           /* This filename is probably not a directory.  Ignore it.  */
-           ;
-         else
-           {
-             char **array;
-             register unsigned int l;
-
-             /* If we're expanding **, we don't need to glue the directory
-                name to the results; we've already done it in glob_vector */
-             if ((dflags & GX_ALLDIRS) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
-               array = temp_results;
-             else
-               array = glob_dir_to_array (directories[i], temp_results, flags);
-             l = 0;
-             while (array[l] != NULL)
-               ++l;
-
-             result =
-               (char **)realloc (result, (result_size + l) * sizeof (char *));
-
-             if (result == NULL)
-               goto memory_error;
-
-             for (l = 0; array[l] != NULL; ++l)
-               result[result_size++ - 1] = array[l];
-
-             result[result_size - 1] = NULL;
-
-             /* Note that the elements of ARRAY are not freed.  */
-             if (array != temp_results)
-               free ((char *) array);
-           }
-       }
-      /* Free the directories.  */
-      for (i = 0; directories[i]; i++)
-       free (directories[i]);
-
-      free ((char *) directories);
-
-      return (result);
-    }
-
-  /* If there is only a directory name, return it. */
-  if (*filename == '\0')
-    {
-      result = (char **) realloc ((char *) result, 2 * sizeof (char *));
-      if (result == NULL)
-       return (NULL);
-      /* Handle GX_MARKDIRS here. */
-      result[0] = (char *) malloc (directory_len + 1);
-      if (result[0] == NULL)
-       goto memory_error;
-      bcopy (directory_name, result[0], directory_len + 1);
-      if (free_dirname)
-       free (directory_name);
-      result[1] = NULL;
-      return (result);
-    }
-  else
-    {
-      char **temp_results;
-
-      /* There are no unquoted globbing characters in DIRECTORY_NAME.
-        Dequote it before we try to open the directory since there may
-        be quoted globbing characters which should be treated verbatim. */
-      if (directory_len > 0)
-       dequote_pathname (directory_name);
-
-      /* We allocated a small array called RESULT, which we won't be using.
-        Free that memory now. */
-      free (result);
-
-      /* Just return what glob_vector () returns appended to the
-        directory name. */
-      /* If flags & GX_ALLDIRS, we're called recursively */
-      dflags = flags & ~GX_MARKDIRS;
-      if (directory_len == 0)
-       dflags |= GX_NULLDIR;
-      if ((flags & GX_GLOBSTAR) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
-       dflags |= GX_ALLDIRS|GX_ADDCURDIR;
-      temp_results = glob_vector (filename,
-                                 (directory_len == 0 ? "." : directory_name),
-                                 dflags);
-
-      if (temp_results == NULL || temp_results == (char **)&glob_error_return)
-       {
-         if (free_dirname)
-           free (directory_name);
-         return (temp_results);
-       }
-
-#if 0
-      /* If we want all directories (dflags & GX_ALLDIRS) and we're not being
-        called recursively as something like `echo **/*.o'
-        ((flags & GX_ALLDIRS) == 0), we want to remove the null directory
-        name glob_vector added to the front of the temp_results array.
-        Currently, we do this by copying the array to another.
-
-        We have to do it this way as long as glob_vector uses GX_NULLDIR for
-        two things: removing the `./' from the pathnames it adds to the
-        result vector and adding the "" placeholder directory name at the
-        front of the result vector for the current directory.  We could use
-        another flag to control the latter action.
-#endif
-      if ((flags & GX_ALLDIRS) == 0 && (dflags & GX_ALLDIRS) && (dflags & GX_NULLDIR))
-       {
-         register int x, y;
-         char **l;
-
-         for (x = 1; temp_results[x]; x++)
-           ;
-         l = (char **)malloc ((x + 1) * sizeof (char *));
-         if (l == 0)
-           {
-             if (free_dirname)
-               free (directory_name);
-             free (temp_results);
-             goto memory_error;
-           }
-         for (y = 0; y < x; y++)
-           l[y] = temp_results[y+1];
-         l[y] = (char *)NULL;
-         free (temp_results);
-         temp_results = l;
-       }
-
-      result = glob_dir_to_array ((dflags & GX_ALLDIRS) ? "" : directory_name, temp_results, flags);
-      if (free_dirname)
-       free (directory_name);
-      return (result);
-    }
-
-  /* We get to memory_error if the program has run out of memory, or
-     if this is the shell, and we have been interrupted. */
- memory_error:
-  if (result != NULL)
-    {
-      register unsigned int i;
-      for (i = 0; result[i] != NULL; ++i)
-       free (result[i]);
-      free ((char *) result);
-    }
-
-  if (free_dirname && directory_name)
-    free (directory_name);
-
-  QUIT;
-
-  return (NULL);
-}
-
-#if defined (TEST)
-
-main (argc, argv)
-     int argc;
-     char **argv;
-{
-  unsigned int i;
-
-  for (i = 1; i < argc; ++i)
-    {
-      char **value = glob_filename (argv[i], 0);
-      if (value == NULL)
-       puts ("Out of memory.");
-      else if (value == &glob_error_return)
-       perror (argv[i]);
-      else
-       for (i = 0; value[i] != NULL; i++)
-         puts (value[i]);
-    }
-
-  exit (0);
-}
-#endif /* TEST.  */
diff --git a/lib/glob/glob.c~ b/lib/glob/glob.c~
deleted file mode 100644 (file)
index 3a6ecc6..0000000
+++ /dev/null
@@ -1,1100 +0,0 @@
-/* glob.c -- file-name wildcard pattern matching for Bash.
-
-   Copyright (C) 1985-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/>.
-*/
-
-/* To whomever it may concern: I have never seen the code which most
-   Unix programs use to perform this function.  I wrote this from scratch
-   based on specifications for the pattern matching.  --RMS.  */
-
-#include <config.h>
-
-#if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX)
-  #pragma alloca
-#endif /* _AIX && RISC6000 && !__GNUC__ */
-
-#include "bashtypes.h"
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include "bashansi.h"
-#include "posixdir.h"
-#include "posixstat.h"
-#include "shmbutil.h"
-#include "xmalloc.h"
-
-#include "filecntl.h"
-#if !defined (F_OK)
-#  define F_OK 0
-#endif
-
-#include "stdc.h"
-#include "memalloc.h"
-
-#include "shell.h"
-
-#include "glob.h"
-#include "strmatch.h"
-
-#if !defined (HAVE_BCOPY) && !defined (bcopy)
-#  define bcopy(s, d, n) ((void) memcpy ((d), (s), (n)))
-#endif /* !HAVE_BCOPY && !bcopy */
-
-#if !defined (NULL)
-#  if defined (__STDC__)
-#    define NULL ((void *) 0)
-#  else
-#    define NULL 0x0
-#  endif /* __STDC__ */
-#endif /* !NULL */
-
-#if !defined (FREE)
-#  define FREE(x)      if (x) free (x)
-#endif
-
-/* Don't try to alloca() more than this much memory for `struct globval'
-   in glob_vector() */
-#ifndef ALLOCA_MAX
-#  define ALLOCA_MAX   100000
-#endif
-
-struct globval
-  {
-    struct globval *next;
-    char *name;
-  };
-
-extern void throw_to_top_level __P((void));
-extern int sh_eaccess __P((char *, int));
-extern char *sh_makepath __P((const char *, const char *, int));
-
-extern int extended_glob;
-
-/* Global variable which controls whether or not * matches .*.
-   Non-zero means don't match .*.  */
-int noglob_dot_filenames = 1;
-
-/* Global variable which controls whether or not filename globbing
-   is done without regard to case. */
-int glob_ignore_case = 0;
-
-/* Global variable to return to signify an error in globbing. */
-char *glob_error_return;
-
-static struct globval finddirs_error_return;
-
-/* Some forward declarations. */
-static int skipname __P((char *, char *, int));
-#if HANDLE_MULTIBYTE
-static int mbskipname __P((char *, char *, int));
-#endif
-#if HANDLE_MULTIBYTE
-static void udequote_pathname __P((char *));
-static void wdequote_pathname __P((char *));
-#else
-#  define dequote_pathname udequote_pathname
-#endif
-static void dequote_pathname __P((char *));
-static int glob_testdir __P((char *));
-static char **glob_dir_to_array __P((char *, char **, int));
-
-/* Compile `glob_loop.c' for single-byte characters. */
-#define CHAR   unsigned char
-#define INT    int
-#define L(CS)  CS
-#define INTERNAL_GLOB_PATTERN_P internal_glob_pattern_p
-#include "glob_loop.c"
-
-/* Compile `glob_loop.c' again for multibyte characters. */
-#if HANDLE_MULTIBYTE
-
-#define CHAR   wchar_t
-#define INT    wint_t
-#define L(CS)  L##CS
-#define INTERNAL_GLOB_PATTERN_P internal_glob_wpattern_p
-#include "glob_loop.c"
-
-#endif /* HANDLE_MULTIBYTE */
-
-/* And now a function that calls either the single-byte or multibyte version
-   of internal_glob_pattern_p. */
-int
-glob_pattern_p (pattern)
-     const char *pattern;
-{
-#if HANDLE_MULTIBYTE
-  size_t n;
-  wchar_t *wpattern;
-  int r;
-
-  if (MB_CUR_MAX == 1)
-    return (internal_glob_pattern_p ((unsigned char *)pattern));
-
-  /* Convert strings to wide chars, and call the multibyte version. */
-  n = xdupmbstowcs (&wpattern, NULL, pattern);
-  if (n == (size_t)-1)
-    /* Oops.  Invalid multibyte sequence.  Try it as single-byte sequence. */
-    return (internal_glob_pattern_p ((unsigned char *)pattern));
-
-  r = internal_glob_wpattern_p (wpattern);
-  free (wpattern);
-
-  return r;
-#else
-  return (internal_glob_pattern_p (pattern));
-#endif
-}
-
-/* Return 1 if DNAME should be skipped according to PAT.  Mostly concerned
-   with matching leading `.'. */
-
-static int
-skipname (pat, dname, flags)
-     char *pat;
-     char *dname;
-     int flags;
-{
-  /* If a leading dot need not be explicitly matched, and the pattern
-     doesn't start with a `.', don't match `.' or `..' */
-  if (noglob_dot_filenames == 0 && pat[0] != '.' &&
-       (pat[0] != '\\' || pat[1] != '.') &&
-       (dname[0] == '.' &&
-         (dname[1] == '\0' || (dname[1] == '.' && dname[2] == '\0'))))
-    return 1;
-
-  /* If a dot must be explicity matched, check to see if they do. */
-  else if (noglob_dot_filenames && dname[0] == '.' && pat[0] != '.' &&
-       (pat[0] != '\\' || pat[1] != '.'))
-    return 1;
-
-  return 0;
-}
-
-#if HANDLE_MULTIBYTE
-/* Return 1 if DNAME should be skipped according to PAT.  Handles multibyte
-   characters in PAT and DNAME.  Mostly concerned with matching leading `.'. */
-
-static int
-mbskipname (pat, dname, flags)
-     char *pat, *dname;
-     int flags;
-{
-  int ret;
-  wchar_t *pat_wc, *dn_wc;
-  size_t pat_n, dn_n;
-
-  pat_n = xdupmbstowcs (&pat_wc, NULL, pat);
-  dn_n = xdupmbstowcs (&dn_wc, NULL, dname);
-
-  ret = 0;
-  if (pat_n != (size_t)-1 && dn_n !=(size_t)-1)
-    {
-      /* If a leading dot need not be explicitly matched, and the
-        pattern doesn't start with a `.', don't match `.' or `..' */
-      if (noglob_dot_filenames == 0 && pat_wc[0] != L'.' &&
-           (pat_wc[0] != L'\\' || pat_wc[1] != L'.') &&
-           (dn_wc[0] == L'.' &&
-             (dn_wc[1] == L'\0' || (dn_wc[1] == L'.' && dn_wc[2] == L'\0'))))
-       ret = 1;
-
-      /* If a leading dot must be explicity matched, check to see if the
-        pattern and dirname both have one. */
-     else if (noglob_dot_filenames && dn_wc[0] == L'.' &&
-          pat_wc[0] != L'.' &&
-          (pat_wc[0] != L'\\' || pat_wc[1] != L'.'))
-       ret = 1;
-    }
-
-  FREE (pat_wc);
-  FREE (dn_wc);
-
-  return ret;
-}
-#endif /* HANDLE_MULTIBYTE */
-
-/* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */
-static void
-udequote_pathname (pathname)
-     char *pathname;
-{
-  register int i, j;
-
-  for (i = j = 0; pathname && pathname[i]; )
-    {
-      if (pathname[i] == '\\')
-       i++;
-
-      pathname[j++] = pathname[i++];
-
-      if (pathname[i - 1] == 0)
-       break;
-    }
-  if (pathname)
-    pathname[j] = '\0';
-}
-
-#if HANDLE_MULTIBYTE
-/* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */
-static void
-wdequote_pathname (pathname)
-     char *pathname;
-{
-  mbstate_t ps;
-  size_t len, n;
-  wchar_t *wpathname;
-  int i, j;
-  wchar_t *orig_wpathname;
-
-  len = strlen (pathname);
-  /* Convert the strings into wide characters.  */
-  n = xdupmbstowcs (&wpathname, NULL, pathname);
-  if (n == (size_t) -1)
-    /* Something wrong. */
-    return;
-  orig_wpathname = wpathname;
-
-  for (i = j = 0; wpathname && wpathname[i]; )
-    {
-      if (wpathname[i] == L'\\')
-       i++;
-
-      wpathname[j++] = wpathname[i++];
-
-      if (wpathname[i - 1] == L'\0')
-       break;
-    }
-  if (wpathname)
-    wpathname[j] = L'\0';
-
-  /* Convert the wide character string into unibyte character set. */
-  memset (&ps, '\0', sizeof(mbstate_t));
-  n = wcsrtombs(pathname, (const wchar_t **)&wpathname, len, &ps);
-  pathname[len] = '\0';
-
-  /* Can't just free wpathname here; wcsrtombs changes it in many cases. */
-  free (orig_wpathname);
-}
-
-static void
-dequote_pathname (pathname)
-     char *pathname;
-{
-  if (MB_CUR_MAX > 1)
-    wdequote_pathname (pathname);
-  else
-    udequote_pathname (pathname);
-}
-#endif /* HANDLE_MULTIBYTE */
-
-/* Test whether NAME exists. */
-
-#if defined (HAVE_LSTAT)
-#  define GLOB_TESTNAME(name)  (lstat (name, &finfo))
-#else /* !HAVE_LSTAT */
-#  if !defined (AFS)
-#    define GLOB_TESTNAME(name)  (sh_eaccess (name, F_OK))
-#  else /* AFS */
-#    define GLOB_TESTNAME(name)  (access (name, F_OK))
-#  endif /* AFS */
-#endif /* !HAVE_LSTAT */
-
-/* Return 0 if DIR is a directory, -1 otherwise. */
-static int
-glob_testdir (dir)
-     char *dir;
-{
-  struct stat finfo;
-
-/*itrace("glob_testdir: testing %s", dir);*/
-  if (stat (dir, &finfo) < 0)
-    return (-1);
-
-  if (S_ISDIR (finfo.st_mode) == 0)
-    return (-1);
-
-  return (0);
-}
-
-/* Recursively scan SDIR for directories matching PAT (PAT is always `**').
-   FLAGS is simply passed down to the recursive call to glob_vector.  Returns
-   a list of matching directory names.  EP, if non-null, is set to the last
-   element of the returned list.  NP, if non-null, is set to the number of
-   directories in the returned list.  These two variables exist for the
-   convenience of the caller (always glob_vector). */
-static struct globval *
-finddirs (pat, sdir, flags, ep, np)
-     char *pat;
-     char *sdir;
-     int flags;
-     struct globval **ep;
-     int *np;
-{
-  char **r, *n;
-  int ndirs;
-  struct globval *ret, *e, *g;
-
-/*itrace("finddirs: pat = `%s' sdir = `%s' flags = 0x%x", pat, sdir, flags);*/
-  e = ret = 0;
-  r = glob_vector (pat, sdir, flags);
-  if (r == 0 || r[0] == 0)
-    {
-      if (np)
-       *np = 0;
-      if (ep)
-        *ep = 0;
-      if (r && r != &glob_error_return)
-       free (r);
-      return (struct globval *)0;
-    }
-  for (ndirs = 0; r[ndirs] != 0; ndirs++)
-    {
-      g = (struct globval *) malloc (sizeof (struct globval));
-      if (g == 0)
-       {
-         while (ret)           /* free list built so far */
-           {
-             g = ret->next;
-             free (ret);
-             ret = g;
-           }
-
-         free (r);
-         if (np)
-           *np = 0;
-         if (ep)
-           *ep = 0;
-         return (&finddirs_error_return);
-       }
-      if (e == 0)
-       e = g;
-
-      g->next = ret;
-      ret = g;
-
-      g->name = r[ndirs];
-    }
-
-  free (r);
-  if (ep)
-    *ep = e;
-  if (np)
-    *np = ndirs;
-
-  return ret;
-}
-
-       
-/* Return a vector of names of files in directory DIR
-   whose names match glob pattern PAT.
-   The names are not in any particular order.
-   Wildcards at the beginning of PAT do not match an initial period.
-
-   The vector is terminated by an element that is a null pointer.
-
-   To free the space allocated, first free the vector's elements,
-   then free the vector.
-
-   Return 0 if cannot get enough memory to hold the pointer
-   and the names.
-
-   Return -1 if cannot access directory DIR.
-   Look in errno for more information.  */
-
-char **
-glob_vector (pat, dir, flags)
-     char *pat;
-     char *dir;
-     int flags;
-{
-  DIR *d;
-  register struct dirent *dp;
-  struct globval *lastlink, *e, *dirlist;
-  register struct globval *nextlink;
-  register char *nextname, *npat, *subdir;
-  unsigned int count;
-  int lose, skip, ndirs, isdir, sdlen, add_current, patlen;
-  register char **name_vector;
-  register unsigned int i;
-  int mflags;          /* Flags passed to strmatch (). */
-  int pflags;          /* flags passed to sh_makepath () */
-  int nalloca;
-  struct globval *firstmalloc, *tmplink;
-  char *convfn;
-
-  lastlink = 0;
-  count = lose = skip = add_current = 0;
-
-  firstmalloc = 0;
-  nalloca = 0;
-
-/*itrace("glob_vector: pat = `%s' dir = `%s' flags = 0x%x", pat, dir, flags);*/
-  /* If PAT is empty, skip the loop, but return one (empty) filename. */
-  if (pat == 0 || *pat == '\0')
-    {
-      if (glob_testdir (dir) < 0)
-       return ((char **) &glob_error_return);
-
-      nextlink = (struct globval *)alloca (sizeof (struct globval));
-      if (nextlink == NULL)
-       return ((char **) NULL);
-
-      nextlink->next = (struct globval *)0;
-      nextname = (char *) malloc (1);
-      if (nextname == 0)
-       lose = 1;
-      else
-       {
-         lastlink = nextlink;
-         nextlink->name = nextname;
-         nextname[0] = '\0';
-         count = 1;
-       }
-
-      skip = 1;
-    }
-
-  patlen = strlen (pat);
-
-  /* If the filename pattern (PAT) does not contain any globbing characters,
-     we can dispense with reading the directory, and just see if there is
-     a filename `DIR/PAT'.  If there is, and we can access it, just make the
-     vector to return and bail immediately. */
-  if (skip == 0 && glob_pattern_p (pat) == 0)
-    {
-      int dirlen;
-      struct stat finfo;
-
-      if (glob_testdir (dir) < 0)
-       return ((char **) &glob_error_return);
-
-      dirlen = strlen (dir);
-      nextname = (char *)malloc (dirlen + patlen + 2);
-      npat = (char *)malloc (patlen + 1);
-      if (nextname == 0 || npat == 0)
-       lose = 1;
-      else
-       {
-         strcpy (npat, pat);
-         dequote_pathname (npat);
-
-         strcpy (nextname, dir);
-         nextname[dirlen++] = '/';
-         strcpy (nextname + dirlen, npat);
-
-         if (GLOB_TESTNAME (nextname) >= 0)
-           {
-             free (nextname);
-             nextlink = (struct globval *)alloca (sizeof (struct globval));
-             if (nextlink)
-               {
-                 nextlink->next = (struct globval *)0;
-                 lastlink = nextlink;
-                 nextlink->name = npat;
-                 count = 1;
-               }
-             else
-               lose = 1;
-           }
-         else
-           {
-             free (nextname);
-             free (npat);
-           }
-       }
-
-      skip = 1;
-    }
-
-  if (skip == 0)
-    {
-      /* Open the directory, punting immediately if we cannot.  If opendir
-        is not robust (i.e., it opens non-directories successfully), test
-        that DIR is a directory and punt if it's not. */
-#if defined (OPENDIR_NOT_ROBUST)
-      if (glob_testdir (dir) < 0)
-       return ((char **) &glob_error_return);
-#endif
-
-      d = opendir (dir);
-      if (d == NULL)
-       return ((char **) &glob_error_return);
-
-      /* Compute the flags that will be passed to strmatch().  We don't
-        need to do this every time through the loop. */
-      mflags = (noglob_dot_filenames ? FNM_PERIOD : 0) | FNM_PATHNAME;
-
-#ifdef FNM_CASEFOLD
-      if (glob_ignore_case)
-       mflags |= FNM_CASEFOLD;
-#endif
-
-      if (extended_glob)
-       mflags |= FNM_EXTMATCH;
-
-      add_current = ((flags & (GX_ALLDIRS|GX_ADDCURDIR)) == (GX_ALLDIRS|GX_ADDCURDIR));
-
-      /* Scan the directory, finding all names that match.
-        For each name that matches, allocate a struct globval
-        on the stack and store the name in it.
-        Chain those structs together; lastlink is the front of the chain.  */
-      while (1)
-       {
-         /* Make globbing interruptible in the shell. */
-         if (interrupt_state || terminating_signal)
-           {
-             lose = 1;
-             break;
-           }
-         
-         dp = readdir (d);
-         if (dp == NULL)
-           break;
-
-         /* If this directory entry is not to be used, try again. */
-         if (REAL_DIR_ENTRY (dp) == 0)
-           continue;
-
-#if 0
-         if (dp->d_name == 0 || *dp->d_name == 0)
-           continue;
-#endif
-
-#if HANDLE_MULTIBYTE
-         if (MB_CUR_MAX > 1 && mbskipname (pat, dp->d_name, flags))
-           continue;
-         else
-#endif
-         if (skipname (pat, dp->d_name, flags))
-           continue;
-
-         /* If we're only interested in directories, don't bother with files */
-         if (flags & (GX_MATCHDIRS|GX_ALLDIRS))
-           {
-             pflags = (flags & GX_ALLDIRS) ? MP_RMDOT : 0;
-             if (flags & GX_NULLDIR)
-               pflags |= MP_IGNDOT;
-             subdir = sh_makepath (dir, dp->d_name, pflags);
-             isdir = glob_testdir (subdir);
-             if (isdir < 0 && (flags & GX_MATCHDIRS))
-               {
-                 free (subdir);
-                 continue;
-               }
-           }
-
-         if (flags & GX_ALLDIRS)
-           {
-             if (isdir == 0)
-               {
-                 dirlist = finddirs (pat, subdir, (flags & ~GX_ADDCURDIR), &e, &ndirs);
-                 if (dirlist == &finddirs_error_return)
-                   {
-                     free (subdir);
-                     lose = 1;
-                     break;
-                   }
-                 if (ndirs)            /* add recursive directories to list */
-                   {
-                     if (firstmalloc == 0)
-                       firstmalloc = e;
-                     e->next = lastlink;
-                     lastlink = dirlist;
-                     count += ndirs;
-                   }
-               }
-
-             nextlink = (struct globval *) malloc (sizeof (struct globval));
-             if (firstmalloc == 0)
-               firstmalloc = nextlink;
-             sdlen = strlen (subdir);
-             nextname = (char *) malloc (sdlen + 1);
-             if (nextlink == 0 || nextname == 0)
-               {
-                 free (subdir);
-                 lose = 1;
-                 break;
-               }
-             nextlink->next = lastlink;
-             lastlink = nextlink;
-             nextlink->name = nextname;
-             bcopy (subdir, nextname, sdlen + 1);
-             free (subdir);
-             ++count;
-             continue;
-           }
-
-         convfn = fnx_fromfs (dp->d_name, D_NAMLEN (dp));
-         if (strmatch (pat, convfn, mflags) != FNM_NOMATCH)
-           {
-             if (nalloca < ALLOCA_MAX)
-               {
-                 nextlink = (struct globval *) alloca (sizeof (struct globval));
-                 nalloca += sizeof (struct globval);
-               }
-             else
-               {
-                 nextlink = (struct globval *) malloc (sizeof (struct globval));
-                 if (firstmalloc == 0)
-                   firstmalloc = nextlink;
-               }
-
-             nextname = (char *) malloc (D_NAMLEN (dp) + 1);
-             if (nextlink == 0 || nextname == 0)
-               {
-                 lose = 1;
-                 break;
-               }
-             nextlink->next = lastlink;
-             lastlink = nextlink;
-             nextlink->name = nextname;
-             bcopy (dp->d_name, nextname, D_NAMLEN (dp) + 1);
-             ++count;
-           }
-       }
-
-      (void) closedir (d);
-    }
-
-  /* compat: if GX_ADDCURDIR, add the passed directory also.  Add an empty
-     directory name as a placeholder if GX_NULLDIR (in which case the passed
-     directory name is "."). */
-  if (add_current)
-    {
-      sdlen = strlen (dir);
-      nextname = (char *)malloc (sdlen + 1);
-      nextlink = (struct globval *) malloc (sizeof (struct globval));
-      if (nextlink == 0 || nextname == 0)
-       lose = 1;
-      else
-       {
-         nextlink->name = nextname;
-         nextlink->next = lastlink;
-         lastlink = nextlink;
-         if (flags & GX_NULLDIR)
-           nextname[0] = '\0';
-         else
-           bcopy (dir, nextname, sdlen + 1);
-         ++count;
-       }
-    }
-
-  if (lose == 0)
-    {
-      name_vector = (char **) malloc ((count + 1) * sizeof (char *));
-      lose |= name_vector == NULL;
-    }
-
-  /* Have we run out of memory?         */
-  if (lose)
-    {
-      tmplink = 0;
-
-      /* Here free the strings we have got.  */
-      while (lastlink)
-       {
-         /* Since we build the list in reverse order, the first N entries
-            will be allocated with malloc, if firstmalloc is set, from
-            lastlink to firstmalloc. */
-         if (firstmalloc)
-           {
-             if (lastlink == firstmalloc)
-               firstmalloc = 0;
-             tmplink = lastlink;
-           }
-         else
-           tmplink = 0;
-         free (lastlink->name);
-         lastlink = lastlink->next;
-         FREE (tmplink);
-       }
-
-      QUIT;
-
-      return ((char **)NULL);
-    }
-
-  /* Copy the name pointers from the linked list into the vector.  */
-  for (tmplink = lastlink, i = 0; i < count; ++i)
-    {
-      name_vector[i] = tmplink->name;
-      tmplink = tmplink->next;
-    }
-
-  name_vector[count] = NULL;
-
-  /* If we allocated some of the struct globvals, free them now. */
-  if (firstmalloc)
-    {
-      tmplink = 0;
-      while (lastlink)
-       {
-         tmplink = lastlink;
-         if (lastlink == firstmalloc)
-           lastlink = firstmalloc = 0;
-         else
-           lastlink = lastlink->next;
-         free (tmplink);
-       }
-    }
-
-  return (name_vector);
-}
-
-/* Return a new array which is the concatenation of each string in ARRAY
-   to DIR.  This function expects you to pass in an allocated ARRAY, and
-   it takes care of free()ing that array.  Thus, you might think of this
-   function as side-effecting ARRAY.  This should handle GX_MARKDIRS. */
-static char **
-glob_dir_to_array (dir, array, flags)
-     char *dir, **array;
-     int flags;
-{
-  register unsigned int i, l;
-  int add_slash;
-  char **result, *new;
-  struct stat sb;
-
-  l = strlen (dir);
-  if (l == 0)
-    {
-      if (flags & GX_MARKDIRS)
-       for (i = 0; array[i]; i++)
-         {
-           if ((stat (array[i], &sb) == 0) && S_ISDIR (sb.st_mode))
-             {
-               l = strlen (array[i]);
-               new = (char *)realloc (array[i], l + 2);
-               if (new == 0)
-                 return NULL;
-               new[l] = '/';
-               new[l+1] = '\0';
-               array[i] = new;
-             }
-         }
-      return (array);
-    }
-
-  add_slash = dir[l - 1] != '/';
-
-  i = 0;
-  while (array[i] != NULL)
-    ++i;
-
-  result = (char **) malloc ((i + 1) * sizeof (char *));
-  if (result == NULL)
-    return (NULL);
-
-  for (i = 0; array[i] != NULL; i++)
-    {
-      /* 3 == 1 for NUL, 1 for slash at end of DIR, 1 for GX_MARKDIRS */
-      result[i] = (char *) malloc (l + strlen (array[i]) + 3);
-
-      if (result[i] == NULL)
-       return (NULL);
-
-      strcpy (result[i], dir);
-      if (add_slash)
-       result[i][l] = '/';
-      strcpy (result[i] + l + add_slash, array[i]);
-      if (flags & GX_MARKDIRS)
-       {
-         if ((stat (result[i], &sb) == 0) && S_ISDIR (sb.st_mode))
-           {
-             size_t rlen;
-             rlen = strlen (result[i]);
-             result[i][rlen] = '/';
-             result[i][rlen+1] = '\0';
-           }
-       }
-    }
-  result[i] = NULL;
-
-  /* Free the input array.  */
-  for (i = 0; array[i] != NULL; i++)
-    free (array[i]);
-  free ((char *) array);
-
-  return (result);
-}
-
-/* Do globbing on PATHNAME.  Return an array of pathnames that match,
-   marking the end of the array with a null-pointer as an element.
-   If no pathnames match, then the array is empty (first element is null).
-   If there isn't enough memory, then return NULL.
-   If a file system error occurs, return -1; `errno' has the error code.  */
-char **
-glob_filename (pathname, flags)
-     char *pathname;
-     int flags;
-{
-  char **result;
-  unsigned int result_size;
-  char *directory_name, *filename, *dname;
-  unsigned int directory_len;
-  int free_dirname;                    /* flag */
-  int dflags;
-
-  result = (char **) malloc (sizeof (char *));
-  result_size = 1;
-  if (result == NULL)
-    return (NULL);
-
-  result[0] = NULL;
-
-  directory_name = NULL;
-
-  /* Find the filename.  */
-  filename = strrchr (pathname, '/');
-  if (filename == NULL)
-    {
-      filename = pathname;
-      directory_name = "";
-      directory_len = 0;
-      free_dirname = 0;
-    }
-  else
-    {
-      directory_len = (filename - pathname) + 1;
-      directory_name = (char *) malloc (directory_len + 1);
-
-      if (directory_name == 0)         /* allocation failed? */
-       return (NULL);
-
-      bcopy (pathname, directory_name, directory_len);
-      directory_name[directory_len] = '\0';
-      ++filename;
-      free_dirname = 1;
-    }
-
-  /* If directory_name contains globbing characters, then we
-     have to expand the previous levels.  Just recurse. */
-  if (glob_pattern_p (directory_name))
-    {
-      char **directories;
-      register unsigned int i;
-
-      dflags = flags & ~GX_MARKDIRS;
-      if ((flags & GX_GLOBSTAR) && directory_name[0] == '*' && directory_name[1] == '*' && (directory_name[2] == '/' || directory_name[2] == '\0'))
-       dflags |= GX_ALLDIRS|GX_ADDCURDIR;
-
-      if (directory_name[directory_len - 1] == '/')
-       directory_name[directory_len - 1] = '\0';
-
-      directories = glob_filename (directory_name, dflags);
-
-      if (free_dirname)
-       {
-         free (directory_name);
-         directory_name = NULL;
-       }
-
-      if (directories == NULL)
-       goto memory_error;
-      else if (directories == (char **)&glob_error_return)
-       {
-         free ((char *) result);
-         return ((char **) &glob_error_return);
-       }
-      else if (*directories == NULL)
-       {
-         free ((char *) directories);
-         free ((char *) result);
-         return ((char **) &glob_error_return);
-       }
-
-      /* We have successfully globbed the preceding directory name.
-        For each name in DIRECTORIES, call glob_vector on it and
-        FILENAME.  Concatenate the results together.  */
-      for (i = 0; directories[i] != NULL; ++i)
-       {
-         char **temp_results;
-
-         /* XXX -- we've recursively scanned any directories resulting from
-            a `**', so turn off the flag.  We turn it on below if
-            necessary. */
-         /* Scan directory even on a NULL filename.  That way, `*h/'
-            returns only directories ending in `h', instead of all
-            files ending in `h' with a `/' appended. */
-         dname = directories[i];
-         dflags = flags & ~(GX_MARKDIRS|GX_ALLDIRS|GX_ADDCURDIR);
-         if ((flags & GX_GLOBSTAR) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
-           dflags |= GX_ALLDIRS|GX_ADDCURDIR;
-         if (dname[0] == '\0' && filename[0])
-           {
-             dflags |= GX_NULLDIR;
-             dname = ".";      /* treat null directory name and non-null filename as current directory */
-           }
-         temp_results = glob_vector (filename, dname, dflags);
-
-         /* Handle error cases. */
-         if (temp_results == NULL)
-           goto memory_error;
-         else if (temp_results == (char **)&glob_error_return)
-           /* This filename is probably not a directory.  Ignore it.  */
-           ;
-         else
-           {
-             char **array;
-             register unsigned int l;
-
-             /* If we're expanding **, we don't need to glue the directory
-                name to the results; we've already done it in glob_vector */
-             if ((dflags & GX_ALLDIRS) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
-               array = temp_results;
-             else
-               array = glob_dir_to_array (directories[i], temp_results, flags);
-             l = 0;
-             while (array[l] != NULL)
-               ++l;
-
-             result =
-               (char **)realloc (result, (result_size + l) * sizeof (char *));
-
-             if (result == NULL)
-               goto memory_error;
-
-             for (l = 0; array[l] != NULL; ++l)
-               result[result_size++ - 1] = array[l];
-
-             result[result_size - 1] = NULL;
-
-             /* Note that the elements of ARRAY are not freed.  */
-             if (array != temp_results)
-               free ((char *) array);
-           }
-       }
-      /* Free the directories.  */
-      for (i = 0; directories[i]; i++)
-       free (directories[i]);
-
-      free ((char *) directories);
-
-      return (result);
-    }
-
-  /* If there is only a directory name, return it. */
-  if (*filename == '\0')
-    {
-      result = (char **) realloc ((char *) result, 2 * sizeof (char *));
-      if (result == NULL)
-       return (NULL);
-      /* Handle GX_MARKDIRS here. */
-      result[0] = (char *) malloc (directory_len + 1);
-      if (result[0] == NULL)
-       goto memory_error;
-      bcopy (directory_name, result[0], directory_len + 1);
-      if (free_dirname)
-       free (directory_name);
-      result[1] = NULL;
-      return (result);
-    }
-  else
-    {
-      char **temp_results;
-
-      /* There are no unquoted globbing characters in DIRECTORY_NAME.
-        Dequote it before we try to open the directory since there may
-        be quoted globbing characters which should be treated verbatim. */
-      if (directory_len > 0)
-       dequote_pathname (directory_name);
-
-      /* We allocated a small array called RESULT, which we won't be using.
-        Free that memory now. */
-      free (result);
-
-      /* Just return what glob_vector () returns appended to the
-        directory name. */
-      /* If flags & GX_ALLDIRS, we're called recursively */
-      dflags = flags & ~GX_MARKDIRS;
-      if (directory_len == 0)
-       dflags |= GX_NULLDIR;
-      if ((flags & GX_GLOBSTAR) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
-       {
-         dflags |= GX_ALLDIRS|GX_ADDCURDIR;
-#if 0
-         /* If we want all directories (dflags & GX_ALLDIRS) and we're not
-            being called recursively as something like `echo **/*.o'
-            ((flags & GX_ALLDIRS) == 0), we want to prevent glob_vector from
-            adding a null directory name to the front of the temp_results
-            array.  We turn off ADDCURDIR if not called recursively and
-            dlen == 0 */
-#endif
-         if (directory_len == 0 && (flags & GX_ALLDIRS) == 0)
-           dflags &= ~GX_ADDCURDIR;
-       }
-      temp_results = glob_vector (filename,
-                                 (directory_len == 0 ? "." : directory_name),
-                                 dflags);
-
-      if (temp_results == NULL || temp_results == (char **)&glob_error_return)
-       {
-         if (free_dirname)
-           free (directory_name);
-         return (temp_results);
-       }
-
-      result = glob_dir_to_array ((dflags & GX_ALLDIRS) ? "" : directory_name, temp_results, flags);
-      if (free_dirname)
-       free (directory_name);
-      return (result);
-    }
-
-  /* We get to memory_error if the program has run out of memory, or
-     if this is the shell, and we have been interrupted. */
- memory_error:
-  if (result != NULL)
-    {
-      register unsigned int i;
-      for (i = 0; result[i] != NULL; ++i)
-       free (result[i]);
-      free ((char *) result);
-    }
-
-  if (free_dirname && directory_name)
-    free (directory_name);
-
-  QUIT;
-
-  return (NULL);
-}
-
-#if defined (TEST)
-
-main (argc, argv)
-     int argc;
-     char **argv;
-{
-  unsigned int i;
-
-  for (i = 1; i < argc; ++i)
-    {
-      char **value = glob_filename (argv[i], 0);
-      if (value == NULL)
-       puts ("Out of memory.");
-      else if (value == &glob_error_return)
-       perror (argv[i]);
-      else
-       for (i = 0; value[i] != NULL; i++)
-         puts (value[i]);
-    }
-
-  exit (0);
-}
-#endif /* TEST.  */
diff --git a/lib/readline/COPYING.old b/lib/readline/COPYING.old
deleted file mode 100644 (file)
index 1bf1526..0000000
+++ /dev/null
@@ -1,339 +0,0 @@
-                   GNU GENERAL PUBLIC LICENSE
-                      Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-                          59 Temple Place, Suite 330, Boston, MA 02111 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                           Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-\f
-                   GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-\f
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-\f
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-\f
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-                           NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-                    END OF TERMS AND CONDITIONS
-\f
-       Appendix: How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) 19yy  <name of author>
-
-    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 of the License, 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-1307, USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) 19yy name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Library General
-Public License instead of this License.
diff --git a/lib/readline/bind.c~ b/lib/readline/bind.c~
deleted file mode 100644 (file)
index e24e350..0000000
+++ /dev/null
@@ -1,2370 +0,0 @@
-/* bind.c -- key binding and startup file support for the readline library. */
-
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
-
-   This file is part of the GNU Readline Library (Readline), a library
-   for reading lines of text with interactive input and history editing.
-
-   Readline is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   Readline is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#define READLINE_LIBRARY
-
-#if defined (__TANDEM)
-#  include <floss.h>
-#endif
-
-#if defined (HAVE_CONFIG_H)
-#  include <config.h>
-#endif
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#if defined (HAVE_SYS_FILE_H)
-#  include <sys/file.h>
-#endif /* HAVE_SYS_FILE_H */
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#if defined (HAVE_STDLIB_H)
-#  include <stdlib.h>
-#else
-#  include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#include <errno.h>
-
-#if !defined (errno)
-extern int errno;
-#endif /* !errno */
-
-#include "posixstat.h"
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-
-/* Some standard library routines. */
-#include "readline.h"
-#include "history.h"
-
-#include "rlprivate.h"
-#include "rlshell.h"
-#include "xmalloc.h"
-
-#if !defined (strchr) && !defined (__STDC__)
-extern char *strchr (), *strrchr ();
-#endif /* !strchr && !__STDC__ */
-
-/* Variables exported by this file. */
-Keymap rl_binding_keymap;
-
-static char *_rl_read_file PARAMS((char *, size_t *));
-static void _rl_init_file_error PARAMS((const char *));
-static int _rl_read_init_file PARAMS((const char *, int));
-static int glean_key_from_name PARAMS((char *));
-static int find_boolean_var PARAMS((const char *));
-
-static char *_rl_get_string_variable_value PARAMS((const char *));
-static int substring_member_of_array PARAMS((const char *, const char * const *));
-
-static int currently_reading_init_file;
-
-/* used only in this file */
-static int _rl_prefer_visible_bell = 1;
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Binding keys                                */
-/*                                                                 */
-/* **************************************************************** */
-
-/* rl_add_defun (char *name, rl_command_func_t *function, int key)
-   Add NAME to the list of named functions.  Make FUNCTION be the function
-   that gets called.  If KEY is not -1, then bind it. */
-int
-rl_add_defun (name, function, key)
-     const char *name;
-     rl_command_func_t *function;
-     int key;
-{
-  if (key != -1)
-    rl_bind_key (key, function);
-  rl_add_funmap_entry (name, function);
-  return 0;
-}
-
-/* Bind KEY to FUNCTION.  Returns non-zero if KEY is out of range. */
-int
-rl_bind_key (key, function)
-     int key;
-     rl_command_func_t *function;
-{
-  if (key < 0)
-    return (key);
-
-  if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii)
-    {
-      if (_rl_keymap[ESC].type == ISKMAP)
-       {
-         Keymap escmap;
-
-         escmap = FUNCTION_TO_KEYMAP (_rl_keymap, ESC);
-         key = UNMETA (key);
-         escmap[key].type = ISFUNC;
-         escmap[key].function = function;
-         return (0);
-       }
-      return (key);
-    }
-
-  _rl_keymap[key].type = ISFUNC;
-  _rl_keymap[key].function = function;
-  rl_binding_keymap = _rl_keymap;
-  return (0);
-}
-
-/* Bind KEY to FUNCTION in MAP.  Returns non-zero in case of invalid
-   KEY. */
-int
-rl_bind_key_in_map (key, function, map)
-     int key;
-     rl_command_func_t *function;
-     Keymap map;
-{
-  int result;
-  Keymap oldmap;
-
-  oldmap = _rl_keymap;
-  _rl_keymap = map;
-  result = rl_bind_key (key, function);
-  _rl_keymap = oldmap;
-  return (result);
-}
-
-/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound.  Right
-   now, this is always used to attempt to bind the arrow keys, hence the
-   check for rl_vi_movement_mode. */
-int
-rl_bind_key_if_unbound_in_map (key, default_func, kmap)
-     int key;
-     rl_command_func_t *default_func;
-     Keymap kmap;
-{
-  char keyseq[2];
-
-  keyseq[0] = (unsigned char)key;
-  keyseq[1] = '\0';
-  return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap));
-}
-
-int
-rl_bind_key_if_unbound (key, default_func)
-     int key;
-     rl_command_func_t *default_func;
-{
-  char keyseq[2];
-
-  keyseq[0] = (unsigned char)key;
-  keyseq[1] = '\0';
-  return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap));
-}
-
-/* Make KEY do nothing in the currently selected keymap.
-   Returns non-zero in case of error. */
-int
-rl_unbind_key (key)
-     int key;
-{
-  return (rl_bind_key (key, (rl_command_func_t *)NULL));
-}
-
-/* Make KEY do nothing in MAP.
-   Returns non-zero in case of error. */
-int
-rl_unbind_key_in_map (key, map)
-     int key;
-     Keymap map;
-{
-  return (rl_bind_key_in_map (key, (rl_command_func_t *)NULL, map));
-}
-
-/* Unbind all keys bound to FUNCTION in MAP. */
-int
-rl_unbind_function_in_map (func, map)
-     rl_command_func_t *func;
-     Keymap map;
-{
-  register int i, rval;
-
-  for (i = rval = 0; i < KEYMAP_SIZE; i++)
-    {
-      if (map[i].type == ISFUNC && map[i].function == func)
-       {
-         map[i].function = (rl_command_func_t *)NULL;
-         rval = 1;
-       }
-    }
-  return rval;
-}
-
-int
-rl_unbind_command_in_map (command, map)
-     const char *command;
-     Keymap map;
-{
-  rl_command_func_t *func;
-
-  func = rl_named_function (command);
-  if (func == 0)
-    return 0;
-  return (rl_unbind_function_in_map (func, map));
-}
-
-/* Bind the key sequence represented by the string KEYSEQ to
-   FUNCTION, starting in the current keymap.  This makes new
-   keymaps as necessary. */
-int
-rl_bind_keyseq (keyseq, function)
-     const char *keyseq;
-     rl_command_func_t *function;
-{
-  return (rl_generic_bind (ISFUNC, keyseq, (char *)function, _rl_keymap));
-}
-
-/* Bind the key sequence represented by the string KEYSEQ to
-   FUNCTION.  This makes new keymaps as necessary.  The initial
-   place to do bindings is in MAP. */
-int
-rl_bind_keyseq_in_map (keyseq, function, map)
-     const char *keyseq;
-     rl_command_func_t *function;
-     Keymap map;
-{
-  return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map));
-}
-
-/* Backwards compatibility; equivalent to rl_bind_keyseq_in_map() */
-int
-rl_set_key (keyseq, function, map)
-     const char *keyseq;
-     rl_command_func_t *function;
-     Keymap map;
-{
-  return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map));
-}
-
-/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound.  Right
-   now, this is always used to attempt to bind the arrow keys, hence the
-   check for rl_vi_movement_mode. */
-int
-rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap)
-     const char *keyseq;
-     rl_command_func_t *default_func;
-     Keymap kmap;
-{
-  rl_command_func_t *func;
-
-  if (keyseq)
-    {
-      func = rl_function_of_keyseq (keyseq, kmap, (int *)NULL);
-#if defined (VI_MODE)
-      if (!func || func == rl_do_lowercase_version || func == rl_vi_movement_mode)
-#else
-      if (!func || func == rl_do_lowercase_version)
-#endif
-       return (rl_bind_keyseq_in_map (keyseq, default_func, kmap));
-      else
-       return 1;
-    }
-  return 0;
-}
-
-int
-rl_bind_keyseq_if_unbound (keyseq, default_func)
-     const char *keyseq;
-     rl_command_func_t *default_func;
-{
-  return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap));
-}
-
-/* Bind the key sequence represented by the string KEYSEQ to
-   the string of characters MACRO.  This makes new keymaps as
-   necessary.  The initial place to do bindings is in MAP. */
-int
-rl_macro_bind (keyseq, macro, map)
-     const char *keyseq, *macro;
-     Keymap map;
-{
-  char *macro_keys;
-  int macro_keys_len;
-
-  macro_keys = (char *)xmalloc ((2 * strlen (macro)) + 1);
-
-  if (rl_translate_keyseq (macro, macro_keys, &macro_keys_len))
-    {
-      xfree (macro_keys);
-      return -1;
-    }
-  rl_generic_bind (ISMACR, keyseq, macro_keys, map);
-  return 0;
-}
-
-/* Bind the key sequence represented by the string KEYSEQ to
-   the arbitrary pointer DATA.  TYPE says what kind of data is
-   pointed to by DATA, right now this can be a function (ISFUNC),
-   a macro (ISMACR), or a keymap (ISKMAP).  This makes new keymaps
-   as necessary.  The initial place to do bindings is in MAP. */
-int
-rl_generic_bind (type, keyseq, data, map)
-     int type;
-     const char *keyseq;
-     char *data;
-     Keymap map;
-{
-  char *keys;
-  int keys_len;
-  register int i;
-  KEYMAP_ENTRY k;
-
-  k.function = 0;
-
-  /* If no keys to bind to, exit right away. */
-  if (keyseq == 0 || *keyseq == 0)
-    {
-      if (type == ISMACR)
-       xfree (data);
-      return -1;
-    }
-
-  keys = (char *)xmalloc (1 + (2 * strlen (keyseq)));
-
-  /* Translate the ASCII representation of KEYSEQ into an array of
-     characters.  Stuff the characters into KEYS, and the length of
-     KEYS into KEYS_LEN. */
-  if (rl_translate_keyseq (keyseq, keys, &keys_len))
-    {
-      xfree (keys);
-      return -1;
-    }
-
-  /* Bind keys, making new keymaps as necessary. */
-  for (i = 0; i < keys_len; i++)
-    {
-      unsigned char uc = keys[i];
-      int ic;
-
-      ic = uc;
-      if (ic < 0 || ic >= KEYMAP_SIZE)
-        {
-          xfree (keys);
-         return -1;
-        }
-
-      if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii)
-       {
-         ic = UNMETA (ic);
-         if (map[ESC].type == ISKMAP)
-           map = FUNCTION_TO_KEYMAP (map, ESC);
-       }
-
-      if ((i + 1) < keys_len)
-       {
-         if (map[ic].type != ISKMAP)
-           {
-             /* We allow subsequences of keys.  If a keymap is being
-                created that will `shadow' an existing function or macro
-                key binding, we save that keybinding into the ANYOTHERKEY
-                index in the new map.  The dispatch code will look there
-                to find the function to execute if the subsequence is not
-                matched.  ANYOTHERKEY was chosen to be greater than
-                UCHAR_MAX. */
-             k = map[ic];
-
-             map[ic].type = ISKMAP;
-             map[ic].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap());
-           }
-         map = FUNCTION_TO_KEYMAP (map, ic);
-         /* The dispatch code will return this function if no matching
-            key sequence is found in the keymap.  This (with a little
-            help from the dispatch code in readline.c) allows `a' to be
-            mapped to something, `abc' to be mapped to something else,
-            and the function bound  to `a' to be executed when the user
-            types `abx', leaving `bx' in the input queue. */
-         if (k.function && ((k.type == ISFUNC && k.function != rl_do_lowercase_version) || k.type == ISMACR))
-           {
-             map[ANYOTHERKEY] = k;
-             k.function = 0;
-           }
-       }
-      else
-       {
-         if (map[ic].type == ISMACR)
-           xfree ((char *)map[ic].function);
-         else if (map[ic].type == ISKMAP)
-           {
-             map = FUNCTION_TO_KEYMAP (map, ic);
-             ic = ANYOTHERKEY;
-             /* If we're trying to override a keymap with a null function
-                (e.g., trying to unbind it), we can't use a null pointer
-                here because that's indistinguishable from having not been
-                overridden.  We use a special bindable function that does
-                nothing. */
-             if (type == ISFUNC && data == 0)
-               data = (char *)_rl_null_function;
-           }
-
-         map[ic].function = KEYMAP_TO_FUNCTION (data);
-         map[ic].type = type;
-       }
-
-      rl_binding_keymap = map;
-    }
-  xfree (keys);
-  return 0;
-}
-
-/* Translate the ASCII representation of SEQ, stuffing the values into ARRAY,
-   an array of characters.  LEN gets the final length of ARRAY.  Return
-   non-zero if there was an error parsing SEQ. */
-int
-rl_translate_keyseq (seq, array, len)
-     const char *seq;
-     char *array;
-     int *len;
-{
-  register int i, c, l, temp;
-
-  for (i = l = 0; c = seq[i]; i++)
-    {
-      if (c == '\\')
-       {
-         c = seq[++i];
-
-         if (c == 0)
-           break;
-
-         /* Handle \C- and \M- prefixes. */
-         if ((c == 'C' || c == 'M') && seq[i + 1] == '-')
-           {
-             /* Handle special case of backwards define. */
-             if (strncmp (&seq[i], "C-\\M-", 5) == 0)
-               {
-                 array[l++] = ESC;     /* ESC is meta-prefix */
-                 i += 5;
-                 array[l++] = CTRL (_rl_to_upper (seq[i]));
-                 if (seq[i] == '\0')
-                   i--;
-               }
-             else if (c == 'M')
-               {
-                 i++;          /* seq[i] == '-' */
-                 /* XXX - obey convert-meta setting */
-                 if (_rl_convert_meta_chars_to_ascii && _rl_keymap[ESC].type == ISKMAP)
-                   array[l++] = ESC;   /* ESC is meta-prefix */
-                 else if (seq[i+1] == '\\' && seq[i+2] == 'C' && seq[i+3] == '-')
-                   {
-                     i += 4;
-                     temp = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i]));
-                     array[l++] = META (temp);
-                   }
-                 else
-                   {
-                     /* This doesn't yet handle things like \M-\a, which may
-                        or may not have any reasonable meaning.  You're
-                        probably better off using straight octal or hex. */
-                     i++;
-                     array[l++] = META (seq[i]);
-                   }
-               }
-             else if (c == 'C')
-               {
-                 i += 2;
-                 /* Special hack for C-?... */
-                 array[l++] = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i]));
-               }
-             continue;
-           }         
-
-         /* Translate other backslash-escaped characters.  These are the
-            same escape sequences that bash's `echo' and `printf' builtins
-            handle, with the addition of \d -> RUBOUT.  A backslash
-            preceding a character that is not special is stripped. */
-         switch (c)
-           {
-           case 'a':
-             array[l++] = '\007';
-             break;
-           case 'b':
-             array[l++] = '\b';
-             break;
-           case 'd':
-             array[l++] = RUBOUT;      /* readline-specific */
-             break;
-           case 'e':
-             array[l++] = ESC;
-             break;
-           case 'f':
-             array[l++] = '\f';
-             break;
-           case 'n':
-             array[l++] = NEWLINE;
-             break;
-           case 'r':
-             array[l++] = RETURN;
-             break;
-           case 't':
-             array[l++] = TAB;
-             break;
-           case 'v':
-             array[l++] = 0x0B;
-             break;
-           case '\\':
-             array[l++] = '\\';
-             break;
-           case '0': case '1': case '2': case '3':
-           case '4': case '5': case '6': case '7':
-             i++;
-             for (temp = 2, c -= '0'; ISOCTAL (seq[i]) && temp--; i++)
-               c = (c * 8) + OCTVALUE (seq[i]);
-             i--;      /* auto-increment in for loop */
-             array[l++] = c & largest_char;
-             break;
-           case 'x':
-             i++;
-             for (temp = 2, c = 0; ISXDIGIT ((unsigned char)seq[i]) && temp--; i++)
-               c = (c * 16) + HEXVALUE (seq[i]);
-             if (temp == 2)
-               c = 'x';
-             i--;      /* auto-increment in for loop */
-             array[l++] = c & largest_char;
-             break;
-           default:    /* backslashes before non-special chars just add the char */
-             array[l++] = c;
-             break;    /* the backslash is stripped */
-           }
-         continue;
-       }
-
-      array[l++] = c;
-    }
-
-  *len = l;
-  array[l] = '\0';
-  return (0);
-}
-
-char *
-rl_untranslate_keyseq (seq)
-     int seq;
-{
-  static char kseq[16];
-  int i, c;
-
-  i = 0;
-  c = seq;
-  if (META_CHAR (c))
-    {
-      kseq[i++] = '\\';
-      kseq[i++] = 'M';
-      kseq[i++] = '-';
-      c = UNMETA (c);
-    }
-  else if (c == ESC)
-    {
-      kseq[i++] = '\\';
-      c = 'e';
-    }
-  else if (CTRL_CHAR (c))
-    {
-      kseq[i++] = '\\';
-      kseq[i++] = 'C';
-      kseq[i++] = '-';
-      c = _rl_to_lower (UNCTRL (c));
-    }
-  else if (c == RUBOUT)
-    {
-      kseq[i++] = '\\';
-      kseq[i++] = 'C';
-      kseq[i++] = '-';
-      c = '?';
-    }
-
-  if (c == ESC)
-    {
-      kseq[i++] = '\\';
-      c = 'e';
-    }
-  else if (c == '\\' || c == '"')
-    {
-      kseq[i++] = '\\';
-    }
-
-  kseq[i++] = (unsigned char) c;
-  kseq[i] = '\0';
-  return kseq;
-}
-
-static char *
-_rl_untranslate_macro_value (seq)
-     char *seq;
-{
-  char *ret, *r, *s;
-  int c;
-
-  r = ret = (char *)xmalloc (7 * strlen (seq) + 1);
-  for (s = seq; *s; s++)
-    {
-      c = *s;
-      if (META_CHAR (c))
-       {
-         *r++ = '\\';
-         *r++ = 'M';
-         *r++ = '-';
-         c = UNMETA (c);
-       }
-      else if (c == ESC)
-       {
-         *r++ = '\\';
-         c = 'e';
-       }
-      else if (CTRL_CHAR (c))
-       {
-         *r++ = '\\';
-         *r++ = 'C';
-         *r++ = '-';
-         c = _rl_to_lower (UNCTRL (c));
-       }
-      else if (c == RUBOUT)
-       {
-         *r++ = '\\';
-         *r++ = 'C';
-         *r++ = '-';
-         c = '?';
-       }
-
-      if (c == ESC)
-       {
-         *r++ = '\\';
-         c = 'e';
-       }
-      else if (c == '\\' || c == '"')
-       *r++ = '\\';
-
-      *r++ = (unsigned char)c;
-    }
-  *r = '\0';
-  return ret;
-}
-
-/* Return a pointer to the function that STRING represents.
-   If STRING doesn't have a matching function, then a NULL pointer
-   is returned. */
-rl_command_func_t *
-rl_named_function (string)
-     const char *string;
-{
-  register int i;
-
-  rl_initialize_funmap ();
-
-  for (i = 0; funmap[i]; i++)
-    if (_rl_stricmp (funmap[i]->name, string) == 0)
-      return (funmap[i]->function);
-  return ((rl_command_func_t *)NULL);
-}
-
-/* Return the function (or macro) definition which would be invoked via
-   KEYSEQ if executed in MAP.  If MAP is NULL, then the current keymap is
-   used.  TYPE, if non-NULL, is a pointer to an int which will receive the
-   type of the object pointed to.  One of ISFUNC (function), ISKMAP (keymap),
-   or ISMACR (macro). */
-rl_command_func_t *
-rl_function_of_keyseq (keyseq, map, type)
-     const char *keyseq;
-     Keymap map;
-     int *type;
-{
-  register int i;
-
-  if (map == 0)
-    map = _rl_keymap;
-
-  for (i = 0; keyseq && keyseq[i]; i++)
-    {
-      unsigned char ic = keyseq[i];
-
-      if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii)
-       {
-         if (map[ESC].type == ISKMAP)
-           {
-             map = FUNCTION_TO_KEYMAP (map, ESC);
-             ic = UNMETA (ic);
-           }
-         /* XXX - should we just return NULL here, since this obviously
-            doesn't match? */
-         else
-           {
-             if (type)
-               *type = map[ESC].type;
-
-             return (map[ESC].function);
-           }
-       }
-
-      if (map[ic].type == ISKMAP)
-       {
-         /* If this is the last key in the key sequence, return the
-            map. */
-         if (keyseq[i + 1] == '\0')
-           {
-             if (type)
-               *type = ISKMAP;
-
-             return (map[ic].function);
-           }
-         else
-           map = FUNCTION_TO_KEYMAP (map, ic);
-       }
-      /* If we're not at the end of the key sequence, and the current key
-        is bound to something other than a keymap, then the entire key
-        sequence is not bound. */
-      else if (map[ic].type != ISKMAP && keyseq[i+1])
-       return ((rl_command_func_t *)NULL);
-      else     /* map[ic].type != ISKMAP && keyseq[i+1] == 0 */
-       {
-         if (type)
-           *type = map[ic].type;
-
-         return (map[ic].function);
-       }
-    }
-  return ((rl_command_func_t *) NULL);
-}
-
-/* The last key bindings file read. */
-static char *last_readline_init_file = (char *)NULL;
-
-/* The file we're currently reading key bindings from. */
-static const char *current_readline_init_file;
-static int current_readline_init_include_level;
-static int current_readline_init_lineno;
-
-/* Read FILENAME into a locally-allocated buffer and return the buffer.
-   The size of the buffer is returned in *SIZEP.  Returns NULL if any
-   errors were encountered. */
-static char *
-_rl_read_file (filename, sizep)
-     char *filename;
-     size_t *sizep;
-{
-  struct stat finfo;
-  size_t file_size;
-  char *buffer;
-  int i, file;
-
-  if ((stat (filename, &finfo) < 0) || (file = open (filename, O_RDONLY, 0666)) < 0)
-    return ((char *)NULL);
-
-  file_size = (size_t)finfo.st_size;
-
-  /* check for overflow on very large files */
-  if (file_size != finfo.st_size || file_size + 1 < file_size)
-    {
-      if (file >= 0)
-       close (file);
-#if defined (EFBIG)
-      errno = EFBIG;
-#endif
-      return ((char *)NULL);
-    }
-
-  /* Read the file into BUFFER. */
-  buffer = (char *)xmalloc (file_size + 1);
-  i = read (file, buffer, file_size);
-  close (file);
-
-  if (i < 0)
-    {
-      xfree (buffer);
-      return ((char *)NULL);
-    }
-
-  RL_CHECK_SIGNALS ();
-
-  buffer[i] = '\0';
-  if (sizep)
-    *sizep = i;
-
-  return (buffer);
-}
-
-/* Re-read the current keybindings file. */
-int
-rl_re_read_init_file (count, ignore)
-     int count, ignore;
-{
-  int r;
-  r = rl_read_init_file ((const char *)NULL);
-  rl_set_keymap_from_edit_mode ();
-  return r;
-}
-
-/* Do key bindings from a file.  If FILENAME is NULL it defaults
-   to the first non-null filename from this list:
-     1. the filename used for the previous call
-     2. the value of the shell variable `INPUTRC'
-     3. ~/.inputrc
-     4. /etc/inputrc
-   If the file existed and could be opened and read, 0 is returned,
-   otherwise errno is returned. */
-int
-rl_read_init_file (filename)
-     const char *filename;
-{
-  /* Default the filename. */
-  if (filename == 0)
-    filename = last_readline_init_file;
-  if (filename == 0)
-    filename = sh_get_env_value ("INPUTRC");
-  if (filename == 0 || *filename == 0)
-    {
-      filename = DEFAULT_INPUTRC;
-      /* Try to read DEFAULT_INPUTRC; fall back to SYS_INPUTRC on failure */
-      if (_rl_read_init_file (filename, 0) == 0)
-       return 0;
-      filename = SYS_INPUTRC;
-    }
-
-#if defined (__MSDOS__)
-  if (_rl_read_init_file (filename, 0) == 0)
-    return 0;
-  filename = "~/_inputrc";
-#endif
-  return (_rl_read_init_file (filename, 0));
-}
-
-static int
-_rl_read_init_file (filename, include_level)
-     const char *filename;
-     int include_level;
-{
-  register int i;
-  char *buffer, *openname, *line, *end;
-  size_t file_size;
-
-  current_readline_init_file = filename;
-  current_readline_init_include_level = include_level;
-
-  openname = tilde_expand (filename);
-  buffer = _rl_read_file (openname, &file_size);
-  xfree (openname);
-
-  RL_CHECK_SIGNALS ();
-  if (buffer == 0)
-    return (errno);
-  
-  if (include_level == 0 && filename != last_readline_init_file)
-    {
-      FREE (last_readline_init_file);
-      last_readline_init_file = savestring (filename);
-    }
-
-  currently_reading_init_file = 1;
-
-  /* Loop over the lines in the file.  Lines that start with `#' are
-     comments; all other lines are commands for readline initialization. */
-  current_readline_init_lineno = 1;
-  line = buffer;
-  end = buffer + file_size;
-  while (line < end)
-    {
-      /* Find the end of this line. */
-      for (i = 0; line + i != end && line[i] != '\n'; i++);
-
-#if defined (__CYGWIN__)
-      /* ``Be liberal in what you accept.'' */
-      if (line[i] == '\n' && line[i-1] == '\r')
-       line[i - 1] = '\0';
-#endif
-
-      /* Mark end of line. */
-      line[i] = '\0';
-
-      /* Skip leading whitespace. */
-      while (*line && whitespace (*line))
-        {
-         line++;
-         i--;
-        }
-
-      /* If the line is not a comment, then parse it. */
-      if (*line && *line != '#')
-       rl_parse_and_bind (line);
-
-      /* Move to the next line. */
-      line += i + 1;
-      current_readline_init_lineno++;
-    }
-
-  xfree (buffer);
-  currently_reading_init_file = 0;
-  return (0);
-}
-
-static void
-_rl_init_file_error (msg)
-     const char *msg;
-{
-  if (currently_reading_init_file)
-    _rl_errmsg ("%s: line %d: %s\n", current_readline_init_file,
-                    current_readline_init_lineno, msg);
-  else
-    _rl_errmsg ("%s", msg);
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Parser Directives                           */
-/*                                                                 */
-/* **************************************************************** */
-
-typedef int _rl_parser_func_t PARAMS((char *));
-
-/* Things that mean `Control'. */
-const char * const _rl_possible_control_prefixes[] = {
-  "Control-", "C-", "CTRL-", (const char *)NULL
-};
-
-const char * const _rl_possible_meta_prefixes[] = {
-  "Meta", "M-", (const char *)NULL
-};
-
-/* Conditionals. */
-
-/* Calling programs set this to have their argv[0]. */
-const char *rl_readline_name = "other";
-
-/* Stack of previous values of parsing_conditionalized_out. */
-static unsigned char *if_stack = (unsigned char *)NULL;
-static int if_stack_depth;
-static int if_stack_size;
-
-/* Push _rl_parsing_conditionalized_out, and set parser state based
-   on ARGS. */
-static int
-parser_if (args)
-     char *args;
-{
-  register int i;
-
-  /* Push parser state. */
-  if (if_stack_depth + 1 >= if_stack_size)
-    {
-      if (!if_stack)
-       if_stack = (unsigned char *)xmalloc (if_stack_size = 20);
-      else
-       if_stack = (unsigned char *)xrealloc (if_stack, if_stack_size += 20);
-    }
-  if_stack[if_stack_depth++] = _rl_parsing_conditionalized_out;
-
-  /* If parsing is turned off, then nothing can turn it back on except
-     for finding the matching endif.  In that case, return right now. */
-  if (_rl_parsing_conditionalized_out)
-    return 0;
-
-  /* Isolate first argument. */
-  for (i = 0; args[i] && !whitespace (args[i]); i++);
-
-  if (args[i])
-    args[i++] = '\0';
-
-  /* Handle "$if term=foo" and "$if mode=emacs" constructs.  If this
-     isn't term=foo, or mode=emacs, then check to see if the first
-     word in ARGS is the same as the value stored in rl_readline_name. */
-  if (rl_terminal_name && _rl_strnicmp (args, "term=", 5) == 0)
-    {
-      char *tem, *tname;
-
-      /* Terminals like "aaa-60" are equivalent to "aaa". */
-      tname = savestring (rl_terminal_name);
-      tem = strchr (tname, '-');
-      if (tem)
-       *tem = '\0';
-
-      /* Test the `long' and `short' forms of the terminal name so that
-        if someone has a `sun-cmd' and does not want to have bindings
-        that will be executed if the terminal is a `sun', they can put
-        `$if term=sun-cmd' into their .inputrc. */
-      _rl_parsing_conditionalized_out = _rl_stricmp (args + 5, tname) &&
-                                       _rl_stricmp (args + 5, rl_terminal_name);
-      xfree (tname);
-    }
-#if defined (VI_MODE)
-  else if (_rl_strnicmp (args, "mode=", 5) == 0)
-    {
-      int mode;
-
-      if (_rl_stricmp (args + 5, "emacs") == 0)
-       mode = emacs_mode;
-      else if (_rl_stricmp (args + 5, "vi") == 0)
-       mode = vi_mode;
-      else
-       mode = no_mode;
-
-      _rl_parsing_conditionalized_out = mode != rl_editing_mode;
-    }
-#endif /* VI_MODE */
-  /* Check to see if the first word in ARGS is the same as the
-     value stored in rl_readline_name. */
-  else if (_rl_stricmp (args, rl_readline_name) == 0)
-    _rl_parsing_conditionalized_out = 0;
-  else
-    _rl_parsing_conditionalized_out = 1;
-  return 0;
-}
-
-/* Invert the current parser state if there is anything on the stack. */
-static int
-parser_else (args)
-     char *args;
-{
-  register int i;
-
-  if (if_stack_depth == 0)
-    {
-      _rl_init_file_error ("$else found without matching $if");
-      return 0;
-    }
-
-#if 0
-  /* Check the previous (n - 1) levels of the stack to make sure that
-     we haven't previously turned off parsing. */
-  for (i = 0; i < if_stack_depth - 1; i++)
-#else
-  /* Check the previous (n) levels of the stack to make sure that
-     we haven't previously turned off parsing. */
-  for (i = 0; i < if_stack_depth; i++)
-#endif
-    if (if_stack[i] == 1)
-      return 0;
-
-  /* Invert the state of parsing if at top level. */
-  _rl_parsing_conditionalized_out = !_rl_parsing_conditionalized_out;
-  return 0;
-}
-
-/* Terminate a conditional, popping the value of
-   _rl_parsing_conditionalized_out from the stack. */
-static int
-parser_endif (args)
-     char *args;
-{
-  if (if_stack_depth)
-    _rl_parsing_conditionalized_out = if_stack[--if_stack_depth];
-  else
-    _rl_init_file_error ("$endif without matching $if");
-  return 0;
-}
-
-static int
-parser_include (args)
-     char *args;
-{
-  const char *old_init_file;
-  char *e;
-  int old_line_number, old_include_level, r;
-
-  if (_rl_parsing_conditionalized_out)
-    return (0);
-
-  old_init_file = current_readline_init_file;
-  old_line_number = current_readline_init_lineno;
-  old_include_level = current_readline_init_include_level;
-
-  e = strchr (args, '\n');
-  if (e)
-    *e = '\0';
-  r = _rl_read_init_file ((const char *)args, old_include_level + 1);
-
-  current_readline_init_file = old_init_file;
-  current_readline_init_lineno = old_line_number;
-  current_readline_init_include_level = old_include_level;
-
-  return r;
-}
-  
-/* Associate textual names with actual functions. */
-static const struct {
-  const char * const name;
-  _rl_parser_func_t *function;
-} parser_directives [] = {
-  { "if", parser_if },
-  { "endif", parser_endif },
-  { "else", parser_else },
-  { "include", parser_include },
-  { (char *)0x0, (_rl_parser_func_t *)0x0 }
-};
-
-/* Handle a parser directive.  STATEMENT is the line of the directive
-   without any leading `$'. */
-static int
-handle_parser_directive (statement)
-     char *statement;
-{
-  register int i;
-  char *directive, *args;
-
-  /* Isolate the actual directive. */
-
-  /* Skip whitespace. */
-  for (i = 0; whitespace (statement[i]); i++);
-
-  directive = &statement[i];
-
-  for (; statement[i] && !whitespace (statement[i]); i++);
-
-  if (statement[i])
-    statement[i++] = '\0';
-
-  for (; statement[i] && whitespace (statement[i]); i++);
-
-  args = &statement[i];
-
-  /* Lookup the command, and act on it. */
-  for (i = 0; parser_directives[i].name; i++)
-    if (_rl_stricmp (directive, parser_directives[i].name) == 0)
-      {
-       (*parser_directives[i].function) (args);
-       return (0);
-      }
-
-  /* display an error message about the unknown parser directive */
-  _rl_init_file_error ("unknown parser directive");
-  return (1);
-}
-
-/* Read the binding command from STRING and perform it.
-   A key binding command looks like: Keyname: function-name\0,
-   a variable binding command looks like: set variable value.
-   A new-style keybinding looks like "\C-x\C-x": exchange-point-and-mark. */
-int
-rl_parse_and_bind (string)
-     char *string;
-{
-  char *funname, *kname;
-  register int c, i;
-  int key, equivalency;
-
-  while (string && whitespace (*string))
-    string++;
-
-  if (!string || !*string || *string == '#')
-    return 0;
-
-  /* If this is a parser directive, act on it. */
-  if (*string == '$')
-    {
-      handle_parser_directive (&string[1]);
-      return 0;
-    }
-
-  /* If we aren't supposed to be parsing right now, then we're done. */
-  if (_rl_parsing_conditionalized_out)
-    return 0;
-
-  i = 0;
-  /* If this keyname is a complex key expression surrounded by quotes,
-     advance to after the matching close quote.  This code allows the
-     backslash to quote characters in the key expression. */
-  if (*string == '"')
-    {
-      int passc = 0;
-
-      for (i = 1; c = string[i]; i++)
-       {
-         if (passc)
-           {
-             passc = 0;
-             continue;
-           }
-
-         if (c == '\\')
-           {
-             passc++;
-             continue;
-           }
-
-         if (c == '"')
-           break;
-       }
-      /* If we didn't find a closing quote, abort the line. */
-      if (string[i] == '\0')
-        {
-          _rl_init_file_error ("no closing `\"' in key binding");
-          return 1;
-        }
-    }
-
-  /* Advance to the colon (:) or whitespace which separates the two objects. */
-  for (; (c = string[i]) && c != ':' && c != ' ' && c != '\t'; i++ );
-
-  equivalency = (c == ':' && string[i + 1] == '=');
-
-  /* Mark the end of the command (or keyname). */
-  if (string[i])
-    string[i++] = '\0';
-
-  /* If doing assignment, skip the '=' sign as well. */
-  if (equivalency)
-    string[i++] = '\0';
-
-  /* If this is a command to set a variable, then do that. */
-  if (_rl_stricmp (string, "set") == 0)
-    {
-      char *var, *value, *e;
-
-      var = string + i;
-      /* Make VAR point to start of variable name. */
-      while (*var && whitespace (*var)) var++;
-
-      /* Make VALUE point to start of value string. */
-      value = var;
-      while (*value && !whitespace (*value)) value++;
-      if (*value)
-       *value++ = '\0';
-      while (*value && whitespace (*value)) value++;
-
-      /* Strip trailing whitespace from values to boolean variables.  Temp
-        fix until I get a real quoted-string parser here. */
-      i = find_boolean_var (var);
-      if (i >= 0)
-       {
-         /* remove trailing whitespace */
-         e = value + strlen (value) - 1;
-         while (e >= value && whitespace (*e))
-           e--;
-         e++;          /* skip back to whitespace or EOS */
-         if (*e && e >= value)
-           *e = '\0';
-       }
-
-      rl_variable_bind (var, value);
-      return 0;
-    }
-
-  /* Skip any whitespace between keyname and funname. */
-  for (; string[i] && whitespace (string[i]); i++);
-  funname = &string[i];
-
-  /* Now isolate funname.
-     For straight function names just look for whitespace, since
-     that will signify the end of the string.  But this could be a
-     macro definition.  In that case, the string is quoted, so skip
-     to the matching delimiter.  We allow the backslash to quote the
-     delimiter characters in the macro body. */
-  /* This code exists to allow whitespace in macro expansions, which
-     would otherwise be gobbled up by the next `for' loop.*/
-  /* XXX - it may be desirable to allow backslash quoting only if " is
-     the quoted string delimiter, like the shell. */
-  if (*funname == '\'' || *funname == '"')
-    {
-      int delimiter, passc;
-
-      delimiter = string[i++];
-      for (passc = 0; c = string[i]; i++)
-       {
-         if (passc)
-           {
-             passc = 0;
-             continue;
-           }
-
-         if (c == '\\')
-           {
-             passc = 1;
-             continue;
-           }
-
-         if (c == delimiter)
-           break;
-       }
-      if (c)
-       i++;
-    }
-
-  /* Advance to the end of the string.  */
-  for (; string[i] && !whitespace (string[i]); i++);
-
-  /* No extra whitespace at the end of the string. */
-  string[i] = '\0';
-
-  /* Handle equivalency bindings here.  Make the left-hand side be exactly
-     whatever the right-hand evaluates to, including keymaps. */
-  if (equivalency)
-    {
-      return 0;
-    }
-
-  /* If this is a new-style key-binding, then do the binding with
-     rl_bind_keyseq ().  Otherwise, let the older code deal with it. */
-  if (*string == '"')
-    {
-      char *seq;
-      register int j, k, passc;
-
-      seq = (char *)xmalloc (1 + strlen (string));
-      for (j = 1, k = passc = 0; string[j]; j++)
-       {
-         /* Allow backslash to quote characters, but leave them in place.
-            This allows a string to end with a backslash quoting another
-            backslash, or with a backslash quoting a double quote.  The
-            backslashes are left in place for rl_translate_keyseq (). */
-         if (passc || (string[j] == '\\'))
-           {
-             seq[k++] = string[j];
-             passc = !passc;
-             continue;
-           }
-
-         if (string[j] == '"')
-           break;
-
-         seq[k++] = string[j];
-       }
-      seq[k] = '\0';
-
-      /* Binding macro? */
-      if (*funname == '\'' || *funname == '"')
-       {
-         j = strlen (funname);
-
-         /* Remove the delimiting quotes from each end of FUNNAME. */
-         if (j && funname[j - 1] == *funname)
-           funname[j - 1] = '\0';
-
-         rl_macro_bind (seq, &funname[1], _rl_keymap);
-       }
-      else
-       rl_bind_keyseq (seq, rl_named_function (funname));
-
-      xfree (seq);
-      return 0;
-    }
-
-  /* Get the actual character we want to deal with. */
-  kname = strrchr (string, '-');
-  if (!kname)
-    kname = string;
-  else
-    kname++;
-
-  key = glean_key_from_name (kname);
-
-  /* Add in control and meta bits. */
-  if (substring_member_of_array (string, _rl_possible_control_prefixes))
-    key = CTRL (_rl_to_upper (key));
-
-  if (substring_member_of_array (string, _rl_possible_meta_prefixes))
-    key = META (key);
-
-  /* Temporary.  Handle old-style keyname with macro-binding. */
-  if (*funname == '\'' || *funname == '"')
-    {
-      char useq[2];
-      int fl = strlen (funname);
-
-      useq[0] = key; useq[1] = '\0';
-      if (fl && funname[fl - 1] == *funname)
-       funname[fl - 1] = '\0';
-
-      rl_macro_bind (useq, &funname[1], _rl_keymap);
-    }
-#if defined (PREFIX_META_HACK)
-  /* Ugly, but working hack to keep prefix-meta around. */
-  else if (_rl_stricmp (funname, "prefix-meta") == 0)
-    {
-      char seq[2];
-
-      seq[0] = key;
-      seq[1] = '\0';
-      rl_generic_bind (ISKMAP, seq, (char *)emacs_meta_keymap, _rl_keymap);
-    }
-#endif /* PREFIX_META_HACK */
-  else
-    rl_bind_key (key, rl_named_function (funname));
-  return 0;
-}
-
-/* Simple structure for boolean readline variables (i.e., those that can
-   have one of two values; either "On" or 1 for truth, or "Off" or 0 for
-   false. */
-
-#define V_SPECIAL      0x1
-
-static const struct {
-  const char * const name;
-  int *value;
-  int flags;
-} boolean_varlist [] = {
-  { "bind-tty-special-chars",  &_rl_bind_stty_chars,           0 },
-  { "blink-matching-paren",    &rl_blink_matching_paren,       V_SPECIAL },
-  { "byte-oriented",           &rl_byte_oriented,              0 },
-  { "completion-ignore-case",  &_rl_completion_case_fold,      0 },
-  { "convert-meta",            &_rl_convert_meta_chars_to_ascii, 0 },
-  { "disable-completion",      &rl_inhibit_completion,         0 },
-  { "echo-control-characters", &_rl_echo_control_chars,        0 },
-  { "enable-keypad",           &_rl_enable_keypad,             0 },
-  { "enable-meta-key",         &_rl_enable_meta_key,           0 },
-  { "expand-tilde",            &rl_complete_with_tilde_expansion, 0 },
-  { "history-preserve-point",  &_rl_history_preserve_point,    0 },
-  { "horizontal-scroll-mode",  &_rl_horizontal_scroll_mode,    0 },
-  { "input-meta",              &_rl_meta_flag,                 0 },
-  { "mark-directories",                &_rl_complete_mark_directories, 0 },
-  { "mark-modified-lines",     &_rl_mark_modified_lines,       0 },
-  { "mark-symlinked-directories", &_rl_complete_mark_symlink_dirs, 0 },
-  { "match-hidden-files",      &_rl_match_hidden_files,        0 },
-  { "meta-flag",               &_rl_meta_flag,                 0 },
-  { "output-meta",             &_rl_output_meta_chars,         0 },
-  { "page-completions",                &_rl_page_completions,          0 },
-  { "prefer-visible-bell",     &_rl_prefer_visible_bell,       V_SPECIAL },
-  { "print-completions-horizontally", &_rl_print_completions_horizontally, 0 },
-  { "revert-all-at-newline",   &_rl_revert_all_at_newline,     0 },
-  { "show-all-if-ambiguous",   &_rl_complete_show_all,         0 },
-  { "show-all-if-unmodified",  &_rl_complete_show_unmodified,  0 },
-  { "skip-completed-text",     &_rl_skip_completed_text,       0 },
-#if defined (VISIBLE_STATS)
-  { "visible-stats",           &rl_visible_stats,              0 },
-#endif /* VISIBLE_STATS */
-  { (char *)NULL, (int *)NULL }
-};
-
-static int
-find_boolean_var (name)
-     const char *name;
-{
-  register int i;
-
-  for (i = 0; boolean_varlist[i].name; i++)
-    if (_rl_stricmp (name, boolean_varlist[i].name) == 0)
-      return i;
-  return -1;
-}
-
-/* Hooks for handling special boolean variables, where a
-   function needs to be called or another variable needs
-   to be changed when they're changed. */
-static void
-hack_special_boolean_var (i)
-     int i;
-{
-  const char *name;
-
-  name = boolean_varlist[i].name;
-
-  if (_rl_stricmp (name, "blink-matching-paren") == 0)
-    _rl_enable_paren_matching (rl_blink_matching_paren);
-  else if (_rl_stricmp (name, "prefer-visible-bell") == 0)
-    {
-      if (_rl_prefer_visible_bell)
-       _rl_bell_preference = VISIBLE_BELL;
-      else
-       _rl_bell_preference = AUDIBLE_BELL;
-    }
-}
-
-typedef int _rl_sv_func_t PARAMS((const char *));
-
-/* These *must* correspond to the array indices for the appropriate
-   string variable.  (Though they're not used right now.) */
-#define V_BELLSTYLE    0
-#define V_COMBEGIN     1
-#define V_EDITMODE     2
-#define V_ISRCHTERM    3
-#define V_KEYMAP       4
-
-#define        V_STRING        1
-#define V_INT          2
-
-/* Forward declarations */
-static int sv_bell_style PARAMS((const char *));
-static int sv_combegin PARAMS((const char *));
-static int sv_dispprefix PARAMS((const char *));
-static int sv_compquery PARAMS((const char *));
-static int sv_editmode PARAMS((const char *));
-static int sv_histsize PARAMS((const char *));
-static int sv_isrchterm PARAMS((const char *));
-static int sv_keymap PARAMS((const char *));
-
-static const struct {
-  const char * const name;
-  int flags;
-  _rl_sv_func_t *set_func;
-} string_varlist[] = {
-  { "bell-style",      V_STRING,       sv_bell_style },
-  { "comment-begin",   V_STRING,       sv_combegin },
-  { "completion-prefix-display-length", V_INT, sv_dispprefix },
-  { "completion-query-items", V_INT,   sv_compquery },
-  { "editing-mode",    V_STRING,       sv_editmode },
-  { "history-size",    V_INT,          sv_histsize },
-  { "isearch-terminators", V_STRING,   sv_isrchterm },
-  { "keymap",          V_STRING,       sv_keymap },
-  { (char *)NULL,      0 }
-};
-
-static int
-find_string_var (name)
-     const char *name;
-{
-  register int i;
-
-  for (i = 0; string_varlist[i].name; i++)
-    if (_rl_stricmp (name, string_varlist[i].name) == 0)
-      return i;
-  return -1;
-}
-
-/* A boolean value that can appear in a `set variable' command is true if
-   the value is null or empty, `on' (case-insenstive), or "1".  Any other
-   values result in 0 (false). */
-static int
-bool_to_int (value)
-     const char *value;
-{
-  return (value == 0 || *value == '\0' ||
-               (_rl_stricmp (value, "on") == 0) ||
-               (value[0] == '1' && value[1] == '\0'));
-}
-
-char *
-rl_variable_value (name)
-     const char *name;
-{
-  register int i;
-
-  /* Check for simple variables first. */
-  i = find_boolean_var (name);
-  if (i >= 0)
-    return (*boolean_varlist[i].value ? "on" : "off");
-
-  i = find_string_var (name);
-  if (i >= 0)
-    return (_rl_get_string_variable_value (string_varlist[i].name));
-
-  /* Unknown variable names return NULL. */
-  return 0;
-}
-
-int
-rl_variable_bind (name, value)
-     const char *name, *value;
-{
-  register int i;
-  int  v;
-
-  /* Check for simple variables first. */
-  i = find_boolean_var (name);
-  if (i >= 0)
-    {
-      *boolean_varlist[i].value = bool_to_int (value);
-      if (boolean_varlist[i].flags & V_SPECIAL)
-       hack_special_boolean_var (i);
-      return 0;
-    }
-
-  i = find_string_var (name);
-
-  /* For the time being, unknown variable names or string names without a
-     handler function are simply ignored. */
-  if (i < 0 || string_varlist[i].set_func == 0)
-    return 0;
-
-  v = (*string_varlist[i].set_func) (value);
-  return v;
-}
-
-static int
-sv_editmode (value)
-     const char *value;
-{
-  if (_rl_strnicmp (value, "vi", 2) == 0)
-    {
-#if defined (VI_MODE)
-      _rl_keymap = vi_insertion_keymap;
-      rl_editing_mode = vi_mode;
-#endif /* VI_MODE */
-      return 0;
-    }
-  else if (_rl_strnicmp (value, "emacs", 5) == 0)
-    {
-      _rl_keymap = emacs_standard_keymap;
-      rl_editing_mode = emacs_mode;
-      return 0;
-    }
-  return 1;
-}
-
-static int
-sv_combegin (value)
-     const char *value;
-{
-  if (value && *value)
-    {
-      FREE (_rl_comment_begin);
-      _rl_comment_begin = savestring (value);
-      return 0;
-    }
-  return 1;
-}
-
-static int
-sv_dispprefix (value)
-     const char *value;
-{
-  int nval = 0;
-
-  if (value && *value)
-    {
-      nval = atoi (value);
-      if (nval < 0)
-       nval = 0;
-    }
-  _rl_completion_prefix_display_length = nval;
-  return 0;
-}
-
-static int
-sv_compquery (value)
-     const char *value;
-{
-  int nval = 100;
-
-  if (value && *value)
-    {
-      nval = atoi (value);
-      if (nval < 0)
-       nval = 0;
-    }
-  rl_completion_query_items = nval;
-  return 0;
-}
-
-static int
-sv_histsize (value)
-     const char *value;
-{
-  int nval = 500;
-
-  if (value && *value)
-    {
-      nval = atoi (value);
-      if (nval < 0)
-       return 1;
-    }
-  stifle_history (nval);
-  return 0;
-}
-
-static int
-sv_keymap (value)
-     const char *value;
-{
-  Keymap kmap;
-
-  kmap = rl_get_keymap_by_name (value);
-  if (kmap)
-    {
-      rl_set_keymap (kmap);
-      return 0;
-    }
-  return 1;
-}
-
-static int
-sv_bell_style (value)
-     const char *value;
-{
-  if (value == 0 || *value == '\0')
-    _rl_bell_preference = AUDIBLE_BELL;
-  else if (_rl_stricmp (value, "none") == 0 || _rl_stricmp (value, "off") == 0)
-    _rl_bell_preference = NO_BELL;
-  else if (_rl_stricmp (value, "audible") == 0 || _rl_stricmp (value, "on") == 0)
-    _rl_bell_preference = AUDIBLE_BELL;
-  else if (_rl_stricmp (value, "visible") == 0)
-    _rl_bell_preference = VISIBLE_BELL;
-  else
-    return 1;
-  return 0;
-}
-
-static int
-sv_isrchterm (value)
-     const char *value;
-{
-  int beg, end, delim;
-  char *v;
-
-  if (value == 0)
-    return 1;
-
-  /* Isolate the value and translate it into a character string. */
-  v = savestring (value);
-  FREE (_rl_isearch_terminators);
-  if (v[0] == '"' || v[0] == '\'')
-    {
-      delim = v[0];
-      for (beg = end = 1; v[end] && v[end] != delim; end++)
-       ;
-    }
-  else
-    {
-      for (beg = end = 0; whitespace (v[end]) == 0; end++)
-       ;
-    }
-
-  v[end] = '\0';
-
-  /* The value starts at v + beg.  Translate it into a character string. */
-  _rl_isearch_terminators = (char *)xmalloc (2 * strlen (v) + 1);
-  rl_translate_keyseq (v + beg, _rl_isearch_terminators, &end);
-  _rl_isearch_terminators[end] = '\0';
-
-  xfree (v);
-  return 0;
-}
-      
-/* Return the character which matches NAME.
-   For example, `Space' returns ' '. */
-
-typedef struct {
-  const char * const name;
-  int value;
-} assoc_list;
-
-static const assoc_list name_key_alist[] = {
-  { "DEL", 0x7f },
-  { "ESC", '\033' },
-  { "Escape", '\033' },
-  { "LFD", '\n' },
-  { "Newline", '\n' },
-  { "RET", '\r' },
-  { "Return", '\r' },
-  { "Rubout", 0x7f },
-  { "SPC", ' ' },
-  { "Space", ' ' },
-  { "Tab", 0x09 },
-  { (char *)0x0, 0 }
-};
-
-static int
-glean_key_from_name (name)
-     char *name;
-{
-  register int i;
-
-  for (i = 0; name_key_alist[i].name; i++)
-    if (_rl_stricmp (name, name_key_alist[i].name) == 0)
-      return (name_key_alist[i].value);
-
-  return (*(unsigned char *)name);     /* XXX was return (*name) */
-}
-
-/* Auxiliary functions to manage keymaps. */
-static const struct {
-  const char * const name;
-  Keymap map;
-} keymap_names[] = {
-  { "emacs", emacs_standard_keymap },
-  { "emacs-standard", emacs_standard_keymap },
-  { "emacs-meta", emacs_meta_keymap },
-  { "emacs-ctlx", emacs_ctlx_keymap },
-#if defined (VI_MODE)
-  { "vi", vi_movement_keymap },
-  { "vi-move", vi_movement_keymap },
-  { "vi-command", vi_movement_keymap },
-  { "vi-insert", vi_insertion_keymap },
-#endif /* VI_MODE */
-  { (char *)0x0, (Keymap)0x0 }
-};
-
-Keymap
-rl_get_keymap_by_name (name)
-     const char *name;
-{
-  register int i;
-
-  for (i = 0; keymap_names[i].name; i++)
-    if (_rl_stricmp (name, keymap_names[i].name) == 0)
-      return (keymap_names[i].map);
-  return ((Keymap) NULL);
-}
-
-char *
-rl_get_keymap_name (map)
-     Keymap map;
-{
-  register int i;
-  for (i = 0; keymap_names[i].name; i++)
-    if (map == keymap_names[i].map)
-      return ((char *)keymap_names[i].name);
-  return ((char *)NULL);
-}
-  
-void
-rl_set_keymap (map)
-     Keymap map;
-{
-  if (map)
-    _rl_keymap = map;
-}
-
-Keymap
-rl_get_keymap ()
-{
-  return (_rl_keymap);
-}
-
-void
-rl_set_keymap_from_edit_mode ()
-{
-  if (rl_editing_mode == emacs_mode)
-    _rl_keymap = emacs_standard_keymap;
-#if defined (VI_MODE)
-  else if (rl_editing_mode == vi_mode)
-    _rl_keymap = vi_insertion_keymap;
-#endif /* VI_MODE */
-}
-
-char *
-rl_get_keymap_name_from_edit_mode ()
-{
-  if (rl_editing_mode == emacs_mode)
-    return "emacs";
-#if defined (VI_MODE)
-  else if (rl_editing_mode == vi_mode)
-    return "vi";
-#endif /* VI_MODE */
-  else
-    return "none";
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*               Key Binding and Function Information              */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Each of the following functions produces information about the
-   state of keybindings and functions known to Readline.  The info
-   is always printed to rl_outstream, and in such a way that it can
-   be read back in (i.e., passed to rl_parse_and_bind ()). */
-
-/* Print the names of functions known to Readline. */
-void
-rl_list_funmap_names ()
-{
-  register int i;
-  const char **funmap_names;
-
-  funmap_names = rl_funmap_names ();
-
-  if (!funmap_names)
-    return;
-
-  for (i = 0; funmap_names[i]; i++)
-    fprintf (rl_outstream, "%s\n", funmap_names[i]);
-
-  xfree (funmap_names);
-}
-
-static char *
-_rl_get_keyname (key)
-     int key;
-{
-  char *keyname;
-  int i, c;
-
-  keyname = (char *)xmalloc (8);
-
-  c = key;
-  /* Since this is going to be used to write out keysequence-function
-     pairs for possible inclusion in an inputrc file, we don't want to
-     do any special meta processing on KEY. */
-
-#if 1
-  /* XXX - Experimental */
-  /* We might want to do this, but the old version of the code did not. */
-
-  /* If this is an escape character, we don't want to do any more processing.
-     Just add the special ESC key sequence and return. */
-  if (c == ESC)
-    {
-      keyname[0] = '\\';
-      keyname[1] = 'e';
-      keyname[2] = '\0';
-      return keyname;
-    }
-#endif
-
-  /* RUBOUT is translated directly into \C-? */
-  if (key == RUBOUT)
-    {
-      keyname[0] = '\\';
-      keyname[1] = 'C';
-      keyname[2] = '-';
-      keyname[3] = '?';
-      keyname[4] = '\0';
-      return keyname;
-    }
-
-  i = 0;
-  /* Now add special prefixes needed for control characters.  This can
-     potentially change C. */
-  if (CTRL_CHAR (c))
-    {
-      keyname[i++] = '\\';
-      keyname[i++] = 'C';
-      keyname[i++] = '-';
-      c = _rl_to_lower (UNCTRL (c));
-    }
-
-  /* XXX experimental code.  Turn the characters that are not ASCII or
-     ISO Latin 1 (128 - 159) into octal escape sequences (\200 - \237).
-     This changes C. */
-  if (c >= 128 && c <= 159)
-    {
-      keyname[i++] = '\\';
-      keyname[i++] = '2';
-      c -= 128;
-      keyname[i++] = (c / 8) + '0';
-      c = (c % 8) + '0';
-    }
-
-  /* Now, if the character needs to be quoted with a backslash, do that. */
-  if (c == '\\' || c == '"')
-    keyname[i++] = '\\';
-
-  /* Now add the key, terminate the string, and return it. */
-  keyname[i++] = (char) c;
-  keyname[i] = '\0';
-
-  return keyname;
-}
-
-/* Return a NULL terminated array of strings which represent the key
-   sequences that are used to invoke FUNCTION in MAP. */
-char **
-rl_invoking_keyseqs_in_map (function, map)
-     rl_command_func_t *function;
-     Keymap map;
-{
-  register int key;
-  char **result;
-  int result_index, result_size;
-
-  result = (char **)NULL;
-  result_index = result_size = 0;
-
-  for (key = 0; key < KEYMAP_SIZE; key++)
-    {
-      switch (map[key].type)
-       {
-       case ISMACR:
-         /* Macros match, if, and only if, the pointers are identical.
-            Thus, they are treated exactly like functions in here. */
-       case ISFUNC:
-         /* If the function in the keymap is the one we are looking for,
-            then add the current KEY to the list of invoking keys. */
-         if (map[key].function == function)
-           {
-             char *keyname;
-
-             keyname = _rl_get_keyname (key);
-
-             if (result_index + 2 > result_size)
-               {
-                 result_size += 10;
-                 result = (char **)xrealloc (result, result_size * sizeof (char *));
-               }
-
-             result[result_index++] = keyname;
-             result[result_index] = (char *)NULL;
-           }
-         break;
-
-       case ISKMAP:
-         {
-           char **seqs;
-           register int i;
-
-           /* Find the list of keyseqs in this map which have FUNCTION as
-              their target.  Add the key sequences found to RESULT. */
-           if (map[key].function)
-             seqs =
-               rl_invoking_keyseqs_in_map (function, FUNCTION_TO_KEYMAP (map, key));
-           else
-             break;
-
-           if (seqs == 0)
-             break;
-
-           for (i = 0; seqs[i]; i++)
-             {
-               char *keyname = (char *)xmalloc (6 + strlen (seqs[i]));
-
-               if (key == ESC)
-                 {
-                   /* If ESC is the meta prefix and we're converting chars
-                      with the eighth bit set to ESC-prefixed sequences, then
-                      we can use \M-.  Otherwise we need to use the sequence
-                      for ESC. */
-                   if (_rl_convert_meta_chars_to_ascii && map[ESC].type == ISKMAP)
-                     sprintf (keyname, "\\M-");
-                   else
-                     sprintf (keyname, "\\e");
-                 }
-               else if (CTRL_CHAR (key))
-                 sprintf (keyname, "\\C-%c", _rl_to_lower (UNCTRL (key)));
-               else if (key == RUBOUT)
-                 sprintf (keyname, "\\C-?");
-               else if (key == '\\' || key == '"')
-                 {
-                   keyname[0] = '\\';
-                   keyname[1] = (char) key;
-                   keyname[2] = '\0';
-                 }
-               else
-                 {
-                   keyname[0] = (char) key;
-                   keyname[1] = '\0';
-                 }
-               
-               strcat (keyname, seqs[i]);
-               xfree (seqs[i]);
-
-               if (result_index + 2 > result_size)
-                 {
-                   result_size += 10;
-                   result = (char **)xrealloc (result, result_size * sizeof (char *));
-                 }
-
-               result[result_index++] = keyname;
-               result[result_index] = (char *)NULL;
-             }
-
-           xfree (seqs);
-         }
-         break;
-       }
-    }
-  return (result);
-}
-
-/* Return a NULL terminated array of strings which represent the key
-   sequences that can be used to invoke FUNCTION using the current keymap. */
-char **
-rl_invoking_keyseqs (function)
-     rl_command_func_t *function;
-{
-  return (rl_invoking_keyseqs_in_map (function, _rl_keymap));
-}
-
-/* Print all of the functions and their bindings to rl_outstream.  If
-   PRINT_READABLY is non-zero, then print the output in such a way
-   that it can be read back in. */
-void
-rl_function_dumper (print_readably)
-     int print_readably;
-{
-  register int i;
-  const char **names;
-  const char *name;
-
-  names = rl_funmap_names ();
-
-  fprintf (rl_outstream, "\n");
-
-  for (i = 0; name = names[i]; i++)
-    {
-      rl_command_func_t *function;
-      char **invokers;
-
-      function = rl_named_function (name);
-      invokers = rl_invoking_keyseqs_in_map (function, _rl_keymap);
-
-      if (print_readably)
-       {
-         if (!invokers)
-           fprintf (rl_outstream, "# %s (not bound)\n", name);
-         else
-           {
-             register int j;
-
-             for (j = 0; invokers[j]; j++)
-               {
-                 fprintf (rl_outstream, "\"%s\": %s\n",
-                          invokers[j], name);
-                 xfree (invokers[j]);
-               }
-
-             xfree (invokers);
-           }
-       }
-      else
-       {
-         if (!invokers)
-           fprintf (rl_outstream, "%s is not bound to any keys\n",
-                    name);
-         else
-           {
-             register int j;
-
-             fprintf (rl_outstream, "%s can be found on ", name);
-
-             for (j = 0; invokers[j] && j < 5; j++)
-               {
-                 fprintf (rl_outstream, "\"%s\"%s", invokers[j],
-                          invokers[j + 1] ? ", " : ".\n");
-               }
-
-             if (j == 5 && invokers[j])
-               fprintf (rl_outstream, "...\n");
-
-             for (j = 0; invokers[j]; j++)
-               xfree (invokers[j]);
-
-             xfree (invokers);
-           }
-       }
-    }
-}
-
-/* Print all of the current functions and their bindings to
-   rl_outstream.  If an explicit argument is given, then print
-   the output in such a way that it can be read back in. */
-int
-rl_dump_functions (count, key)
-     int count, key;
-{
-  if (rl_dispatching)
-    fprintf (rl_outstream, "\r\n");
-  rl_function_dumper (rl_explicit_arg);
-  rl_on_new_line ();
-  return (0);
-}
-
-static void
-_rl_macro_dumper_internal (print_readably, map, prefix)
-     int print_readably;
-     Keymap map;
-     char *prefix;
-{
-  register int key;
-  char *keyname, *out;
-  int prefix_len;
-
-  for (key = 0; key < KEYMAP_SIZE; key++)
-    {
-      switch (map[key].type)
-       {
-       case ISMACR:
-         keyname = _rl_get_keyname (key);
-         out = _rl_untranslate_macro_value ((char *)map[key].function);
-
-         if (print_readably)
-           fprintf (rl_outstream, "\"%s%s\": \"%s\"\n", prefix ? prefix : "",
-                                                        keyname,
-                                                        out ? out : "");
-         else
-           fprintf (rl_outstream, "%s%s outputs %s\n", prefix ? prefix : "",
-                                                       keyname,
-                                                       out ? out : "");
-         xfree (keyname);
-         xfree (out);
-         break;
-       case ISFUNC:
-         break;
-       case ISKMAP:
-         prefix_len = prefix ? strlen (prefix) : 0;
-         if (key == ESC)
-           {
-             keyname = (char *)xmalloc (3 + prefix_len);
-             if (prefix)
-               strcpy (keyname, prefix);
-             keyname[prefix_len] = '\\';
-             keyname[prefix_len + 1] = 'e';
-             keyname[prefix_len + 2] = '\0';
-           }
-         else
-           {
-             keyname = _rl_get_keyname (key);
-             if (prefix)
-               {
-                 out = (char *)xmalloc (strlen (keyname) + prefix_len + 1);
-                 strcpy (out, prefix);
-                 strcpy (out + prefix_len, keyname);
-                 xfree (keyname);
-                 keyname = out;
-               }
-           }
-
-         _rl_macro_dumper_internal (print_readably, FUNCTION_TO_KEYMAP (map, key), keyname);
-         xfree (keyname);
-         break;
-       }
-    }
-}
-
-void
-rl_macro_dumper (print_readably)
-     int print_readably;
-{
-  _rl_macro_dumper_internal (print_readably, _rl_keymap, (char *)NULL);
-}
-
-int
-rl_dump_macros (count, key)
-     int count, key;
-{
-  if (rl_dispatching)
-    fprintf (rl_outstream, "\r\n");
-  rl_macro_dumper (rl_explicit_arg);
-  rl_on_new_line ();
-  return (0);
-}
-
-static char *
-_rl_get_string_variable_value (name)
-     const char *name;
-{
-  static char numbuf[32];
-  char *ret;
-
-  if (_rl_stricmp (name, "bell-style") == 0)
-    {
-      switch (_rl_bell_preference)
-       {
-         case NO_BELL:
-           return "none";
-         case VISIBLE_BELL:
-           return "visible";
-         case AUDIBLE_BELL:
-         default:
-           return "audible";
-       }
-    }
-  else if (_rl_stricmp (name, "comment-begin") == 0)
-    return (_rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT);
-  else if (_rl_stricmp (name, "completion-prefix-display-length") == 0)
-    {
-      sprintf (numbuf, "%d", _rl_completion_prefix_display_length);
-      return (numbuf);
-    }
-  else if (_rl_stricmp (name, "completion-query-items") == 0)
-    {
-      sprintf (numbuf, "%d", rl_completion_query_items);
-      return (numbuf);
-    }
-  else if (_rl_stricmp (name, "editing-mode") == 0)
-    return (rl_get_keymap_name_from_edit_mode ());
-  else if (_rl_stricmp (name, "history-size") == 0)
-    {
-      sprintf (numbuf, "%d", history_is_stifled() ? history_max_entries : 0);
-      return (numbuf);
-    }
-  else if (_rl_stricmp (name, "isearch-terminators") == 0)
-    {
-      if (_rl_isearch_terminators == 0)
-       return 0;
-      ret = _rl_untranslate_macro_value (_rl_isearch_terminators);
-      if (ret)
-       {
-         strncpy (numbuf, ret, sizeof (numbuf) - 1);
-         xfree (ret);
-         numbuf[sizeof(numbuf) - 1] = '\0';
-       }
-      else
-       numbuf[0] = '\0';
-      return numbuf;
-    }
-  else if (_rl_stricmp (name, "keymap") == 0)
-    {
-      ret = rl_get_keymap_name (_rl_keymap);
-      if (ret == 0)
-       ret = rl_get_keymap_name_from_edit_mode ();
-      return (ret ? ret : "none");
-    }
-  else
-    return (0);
-}
-
-void
-rl_variable_dumper (print_readably)
-     int print_readably;
-{
-  int i;
-  char *v;
-
-  for (i = 0; boolean_varlist[i].name; i++)
-    {
-      if (print_readably)
-        fprintf (rl_outstream, "set %s %s\n", boolean_varlist[i].name,
-                              *boolean_varlist[i].value ? "on" : "off");
-      else
-        fprintf (rl_outstream, "%s is set to `%s'\n", boolean_varlist[i].name,
-                              *boolean_varlist[i].value ? "on" : "off");
-    }
-
-  for (i = 0; string_varlist[i].name; i++)
-    {
-      v = _rl_get_string_variable_value (string_varlist[i].name);
-      if (v == 0)      /* _rl_isearch_terminators can be NULL */
-       continue;
-      if (print_readably)
-        fprintf (rl_outstream, "set %s %s\n", string_varlist[i].name, v);
-      else
-        fprintf (rl_outstream, "%s is set to `%s'\n", string_varlist[i].name, v);
-    }
-}
-
-/* Print all of the current variables and their values to
-   rl_outstream.  If an explicit argument is given, then print
-   the output in such a way that it can be read back in. */
-int
-rl_dump_variables (count, key)
-     int count, key;
-{
-  if (rl_dispatching)
-    fprintf (rl_outstream, "\r\n");
-  rl_variable_dumper (rl_explicit_arg);
-  rl_on_new_line ();
-  return (0);
-}
-
-/* Return non-zero if any members of ARRAY are a substring in STRING. */
-static int
-substring_member_of_array (string, array)
-     const char *string;
-     const char * const *array;
-{
-  while (*array)
-    {
-      if (_rl_strindex (string, *array))
-       return (1);
-      array++;
-    }
-  return (0);
-}
diff --git a/lib/readline/complete.c.save1 b/lib/readline/complete.c.save1
deleted file mode 100644 (file)
index 20bb1ea..0000000
+++ /dev/null
@@ -1,2462 +0,0 @@
-/* complete.c -- filename completion for readline. */
-
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
-
-   This file is part of the GNU Readline Library (Readline), a library
-   for reading lines of text with interactive input and history editing.
-
-   Readline is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   Readline is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#define READLINE_LIBRARY
-
-#if defined (HAVE_CONFIG_H)
-#  include <config.h>
-#endif
-
-#include <sys/types.h>
-#include <fcntl.h>
-#if defined (HAVE_SYS_FILE_H)
-#  include <sys/file.h>
-#endif
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#if defined (HAVE_STDLIB_H)
-#  include <stdlib.h>
-#else
-#  include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#include <stdio.h>
-
-#include <errno.h>
-#if !defined (errno)
-extern int errno;
-#endif /* !errno */
-
-#if defined (HAVE_PWD_H)
-#include <pwd.h>
-#endif
-
-#include "posixdir.h"
-#include "posixstat.h"
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-#include "rlmbutil.h"
-
-/* Some standard library routines. */
-#include "readline.h"
-#include "xmalloc.h"
-#include "rlprivate.h"
-
-#ifdef __STDC__
-typedef int QSFUNC (const void *, const void *);
-#else
-typedef int QSFUNC ();
-#endif
-
-#ifdef HAVE_LSTAT
-#  define LSTAT lstat
-#else
-#  define LSTAT stat
-#endif
-
-/* Unix version of a hidden file.  Could be different on other systems. */
-#define HIDDEN_FILE(fname)     ((fname)[0] == '.')
-
-/* Most systems don't declare getpwent in <pwd.h> if _POSIX_SOURCE is
-   defined. */
-#if defined (HAVE_GETPWENT) && (!defined (HAVE_GETPW_DECLS) || defined (_POSIX_SOURCE))
-extern struct passwd *getpwent PARAMS((void));
-#endif /* HAVE_GETPWENT && (!HAVE_GETPW_DECLS || _POSIX_SOURCE) */
-
-/* If non-zero, then this is the address of a function to call when
-   completing a word would normally display the list of possible matches.
-   This function is called instead of actually doing the display.
-   It takes three arguments: (char **matches, int num_matches, int max_length)
-   where MATCHES is the array of strings that matched, NUM_MATCHES is the
-   number of strings in that array, and MAX_LENGTH is the length of the
-   longest string in that array. */
-rl_compdisp_func_t *rl_completion_display_matches_hook = (rl_compdisp_func_t *)NULL;
-
-#if defined (VISIBLE_STATS)
-#  if !defined (X_OK)
-#    define X_OK 1
-#  endif
-static int stat_char PARAMS((char *));
-#endif
-
-static int path_isdir PARAMS((const char *));
-
-static char *rl_quote_filename PARAMS((char *, int, char *));
-
-static void set_completion_defaults PARAMS((int));
-static int get_y_or_n PARAMS((int));
-static int _rl_internal_pager PARAMS((int));
-static char *printable_part PARAMS((char *));
-static int fnwidth PARAMS((const char *));
-static int fnprint PARAMS((const char *, int));
-static int print_filename PARAMS((char *, char *, int));
-
-static char **gen_completion_matches PARAMS((char *, int, int, rl_compentry_func_t *, int, int));
-
-static char **remove_duplicate_matches PARAMS((char **));
-static void insert_match PARAMS((char *, int, int, char *));
-static int append_to_match PARAMS((char *, int, int, int));
-static void insert_all_matches PARAMS((char **, int, char *));
-static void display_matches PARAMS((char **));
-static int compute_lcd_of_matches PARAMS((char **, int, const char *));
-static int postprocess_matches PARAMS((char ***, int));
-
-static char *make_quoted_replacement PARAMS((char *, int, char *));
-
-/* **************************************************************** */
-/*                                                                 */
-/*     Completion matching, from readline's point of view.         */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Variables known only to the readline library. */
-
-/* If non-zero, non-unique completions always show the list of matches. */
-int _rl_complete_show_all = 0;
-
-/* If non-zero, non-unique completions show the list of matches, unless it
-   is not possible to do partial completion and modify the line. */
-int _rl_complete_show_unmodified = 0;
-
-/* If non-zero, completed directory names have a slash appended. */
-int _rl_complete_mark_directories = 1;
-
-/* If non-zero, the symlinked directory completion behavior introduced in
-   readline-4.2a is disabled, and symlinks that point to directories have
-   a slash appended (subject to the value of _rl_complete_mark_directories).
-   This is user-settable via the mark-symlinked-directories variable. */
-int _rl_complete_mark_symlink_dirs = 0;
-
-/* If non-zero, completions are printed horizontally in alphabetical order,
-   like `ls -x'. */
-int _rl_print_completions_horizontally;
-
-/* Non-zero means that case is not significant in filename completion. */
-#if defined (__MSDOS__) && !defined (__DJGPP__)
-int _rl_completion_case_fold = 1;
-#else
-int _rl_completion_case_fold;
-#endif
-
-/* If non-zero, don't match hidden files (filenames beginning with a `.' on
-   Unix) when doing filename completion. */
-int _rl_match_hidden_files = 1;
-
-/* Length in characters of a common prefix replaced with an ellipsis (`...')
-   when displaying completion matches.  Matches whose printable portion has
-   more than this number of displaying characters in common will have the common
-   display prefix replaced with an ellipsis. */
-int _rl_completion_prefix_display_length = 0;
-
-/* Global variables available to applications using readline. */
-
-#if defined (VISIBLE_STATS)
-/* Non-zero means add an additional character to each filename displayed
-   during listing completion iff rl_filename_completion_desired which helps
-   to indicate the type of file being listed. */
-int rl_visible_stats = 0;
-#endif /* VISIBLE_STATS */
-
-/* If non-zero, then this is the address of a function to call when
-   completing on a directory name.  The function is called with
-   the address of a string (the current directory name) as an arg. */
-rl_icppfunc_t *rl_directory_completion_hook = (rl_icppfunc_t *)NULL;
-
-rl_icppfunc_t *rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL;
-
-/* Non-zero means readline completion functions perform tilde expansion. */
-int rl_complete_with_tilde_expansion = 0;
-
-/* Pointer to the generator function for completion_matches ().
-   NULL means to use rl_filename_completion_function (), the default filename
-   completer. */
-rl_compentry_func_t *rl_completion_entry_function = (rl_compentry_func_t *)NULL;
-
-/* Pointer to generator function for rl_menu_complete ().  NULL means to use
-   *rl_completion_entry_function (see above). */
-rl_compentry_func_t *rl_menu_completion_entry_function = (rl_compentry_func_t *)NULL;
-
-/* Pointer to alternative function to create matches.
-   Function is called with TEXT, START, and END.
-   START and END are indices in RL_LINE_BUFFER saying what the boundaries
-   of TEXT are.
-   If this function exists and returns NULL then call the value of
-   rl_completion_entry_function to try to match, otherwise use the
-   array of strings returned. */
-rl_completion_func_t *rl_attempted_completion_function = (rl_completion_func_t *)NULL;
-
-/* Non-zero means to suppress normal filename completion after the
-   user-specified completion function has been called. */
-int rl_attempted_completion_over = 0;
-
-/* Set to a character indicating the type of completion being performed
-   by rl_complete_internal, available for use by application completion
-   functions. */
-int rl_completion_type = 0;
-
-/* Up to this many items will be displayed in response to a
-   possible-completions call.  After that, we ask the user if
-   she is sure she wants to see them all.  A negative value means
-   don't ask. */
-int rl_completion_query_items = 100;
-
-int _rl_page_completions = 1;
-
-/* The basic list of characters that signal a break between words for the
-   completer routine.  The contents of this variable is what breaks words
-   in the shell, i.e. " \t\n\"\\'`@$><=" */
-const char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{("; /* }) */
-
-/* List of basic quoting characters. */
-const char *rl_basic_quote_characters = "\"'";
-
-/* The list of characters that signal a break between words for
-   rl_complete_internal.  The default list is the contents of
-   rl_basic_word_break_characters.  */
-/*const*/ char *rl_completer_word_break_characters = (/*const*/ char *)NULL;
-
-/* Hook function to allow an application to set the completion word
-   break characters before readline breaks up the line.  Allows
-   position-dependent word break characters. */
-rl_cpvfunc_t *rl_completion_word_break_hook = (rl_cpvfunc_t *)NULL;
-
-/* List of characters which can be used to quote a substring of the line.
-   Completion occurs on the entire substring, and within the substring
-   rl_completer_word_break_characters are treated as any other character,
-   unless they also appear within this list. */
-const char *rl_completer_quote_characters = (const char *)NULL;
-
-/* List of characters that should be quoted in filenames by the completer. */
-const char *rl_filename_quote_characters = (const char *)NULL;
-
-/* List of characters that are word break characters, but should be left
-   in TEXT when it is passed to the completion function.  The shell uses
-   this to help determine what kind of completing to do. */
-const char *rl_special_prefixes = (const char *)NULL;
-
-/* If non-zero, then disallow duplicates in the matches. */
-int rl_ignore_completion_duplicates = 1;
-
-/* Non-zero means that the results of the matches are to be treated
-   as filenames.  This is ALWAYS zero on entry, and can only be changed
-   within a completion entry finder function. */
-int rl_filename_completion_desired = 0;
-
-/* Non-zero means that the results of the matches are to be quoted using
-   double quotes (or an application-specific quoting mechanism) if the
-   filename contains any characters in rl_filename_quote_chars.  This is
-   ALWAYS non-zero on entry, and can only be changed within a completion
-   entry finder function. */
-int rl_filename_quoting_desired = 1;
-
-/* This function, if defined, is called by the completer when real
-   filename completion is done, after all the matching names have been
-   generated. It is passed a (char**) known as matches in the code below.
-   It consists of a NULL-terminated array of pointers to potential
-   matching strings.  The 1st element (matches[0]) is the maximal
-   substring that is common to all matches. This function can re-arrange
-   the list of matches as required, but all elements of the array must be
-   free()'d if they are deleted. The main intent of this function is
-   to implement FIGNORE a la SunOS csh. */
-rl_compignore_func_t *rl_ignore_some_completions_function = (rl_compignore_func_t *)NULL;
-
-/* Set to a function to quote a filename in an application-specific fashion.
-   Called with the text to quote, the type of match found (single or multiple)
-   and a pointer to the quoting character to be used, which the function can
-   reset if desired. */
-rl_quote_func_t *rl_filename_quoting_function = rl_quote_filename;
-         
-/* Function to call to remove quoting characters from a filename.  Called
-   before completion is attempted, so the embedded quotes do not interfere
-   with matching names in the file system.  Readline doesn't do anything
-   with this; it's set only by applications. */
-rl_dequote_func_t *rl_filename_dequoting_function = (rl_dequote_func_t *)NULL;
-
-/* Function to call to decide whether or not a word break character is
-   quoted.  If a character is quoted, it does not break words for the
-   completer. */
-rl_linebuf_func_t *rl_char_is_quoted_p = (rl_linebuf_func_t *)NULL;
-
-/* If non-zero, the completion functions don't append anything except a
-   possible closing quote.  This is set to 0 by rl_complete_internal and
-   may be changed by an application-specific completion function. */
-int rl_completion_suppress_append = 0;
-
-/* Character appended to completed words when at the end of the line.  The
-   default is a space. */
-int rl_completion_append_character = ' ';
-
-/* If non-zero, the completion functions don't append any closing quote.
-   This is set to 0 by rl_complete_internal and may be changed by an
-   application-specific completion function. */
-int rl_completion_suppress_quote = 0;
-
-/* Set to any quote character readline thinks it finds before any application
-   completion function is called. */
-int rl_completion_quote_character;
-
-/* Set to a non-zero value if readline found quoting anywhere in the word to
-   be completed; set before any application completion function is called. */
-int rl_completion_found_quote;
-
-/* If non-zero, a slash will be appended to completed filenames that are
-   symbolic links to directory names, subject to the value of the
-   mark-directories variable (which is user-settable).  This exists so
-   that application completion functions can override the user's preference
-   (set via the mark-symlinked-directories variable) if appropriate.
-   It's set to the value of _rl_complete_mark_symlink_dirs in
-   rl_complete_internal before any application-specific completion
-   function is called, so without that function doing anything, the user's
-   preferences are honored. */
-int rl_completion_mark_symlink_dirs;
-
-/* If non-zero, inhibit completion (temporarily). */
-int rl_inhibit_completion;
-
-/* Set to the last key used to invoke one of the completion functions */
-int rl_completion_invoking_key;
-
-/* If non-zero, sort the completion matches.  On by default. */
-int rl_sort_completion_matches = 1;
-
-/* Variables local to this file. */
-
-/* Local variable states what happened during the last completion attempt. */
-static int completion_changed_buffer;
-
-/* The result of the query to the user about displaying completion matches */
-static int completion_y_or_n;
-
-/*************************************/
-/*                                  */
-/*    Bindable completion functions  */
-/*                                  */
-/*************************************/
-
-/* Complete the word at or before point.  You have supplied the function
-   that does the initial simple matching selection algorithm (see
-   rl_completion_matches ()).  The default is to do filename completion. */
-int
-rl_complete (ignore, invoking_key)
-     int ignore, invoking_key;
-{
-  rl_completion_invoking_key = invoking_key;
-
-  if (rl_inhibit_completion)
-    return (_rl_insert_char (ignore, invoking_key));
-  else if (rl_last_func == rl_complete && !completion_changed_buffer)
-    return (rl_complete_internal ('?'));
-  else if (_rl_complete_show_all)
-    return (rl_complete_internal ('!'));
-  else if (_rl_complete_show_unmodified)
-    return (rl_complete_internal ('@'));
-  else
-    return (rl_complete_internal (TAB));
-}
-
-/* List the possible completions.  See description of rl_complete (). */
-int
-rl_possible_completions (ignore, invoking_key)
-     int ignore, invoking_key;
-{
-  rl_completion_invoking_key = invoking_key;
-  return (rl_complete_internal ('?'));
-}
-
-int
-rl_insert_completions (ignore, invoking_key)
-     int ignore, invoking_key;
-{
-  rl_completion_invoking_key = invoking_key;
-  return (rl_complete_internal ('*'));
-}
-
-/* Return the correct value to pass to rl_complete_internal performing
-   the same tests as rl_complete.  This allows consecutive calls to an
-   application's completion function to list possible completions and for
-   an application-specific completion function to honor the
-   show-all-if-ambiguous readline variable. */
-int
-rl_completion_mode (cfunc)
-     rl_command_func_t *cfunc;
-{
-  if (rl_last_func == cfunc && !completion_changed_buffer)
-    return '?';
-  else if (_rl_complete_show_all)
-    return '!';
-  else if (_rl_complete_show_unmodified)
-    return '@';
-  else
-    return TAB;
-}
-
-/************************************/
-/*                                 */
-/*    Completion utility functions  */
-/*                                 */
-/************************************/
-
-/* Reset readline state on a signal or other event. */
-void
-_rl_reset_completion_state ()
-{
-  rl_completion_found_quote = 0;
-  rl_completion_quote_character = 0;
-}
-
-/* Set default values for readline word completion.  These are the variables
-   that application completion functions can change or inspect. */
-static void
-set_completion_defaults (what_to_do)
-     int what_to_do;
-{
-  /* Only the completion entry function can change these. */
-  rl_filename_completion_desired = 0;
-  rl_filename_quoting_desired = 1;
-  rl_completion_type = what_to_do;
-  rl_completion_suppress_append = rl_completion_suppress_quote = 0;
-  rl_completion_append_character = ' ';
-
-  /* The completion entry function may optionally change this. */
-  rl_completion_mark_symlink_dirs = _rl_complete_mark_symlink_dirs;
-}
-
-/* The user must press "y" or "n". Non-zero return means "y" pressed. */
-static int
-get_y_or_n (for_pager)
-     int for_pager;
-{
-  int c;
-
-  for (;;)
-    {
-      RL_SETSTATE(RL_STATE_MOREINPUT);
-      c = rl_read_key ();
-      RL_UNSETSTATE(RL_STATE_MOREINPUT);
-
-      if (c == 'y' || c == 'Y' || c == ' ')
-       return (1);
-      if (c == 'n' || c == 'N' || c == RUBOUT)
-       return (0);
-      if (c == ABORT_CHAR || c < 0)
-       _rl_abort_internal ();
-      if (for_pager && (c == NEWLINE || c == RETURN))
-       return (2);
-      if (for_pager && (c == 'q' || c == 'Q'))
-       return (0);
-      rl_ding ();
-    }
-}
-
-static int
-_rl_internal_pager (lines)
-     int lines;
-{
-  int i;
-
-  fprintf (rl_outstream, "--More--");
-  fflush (rl_outstream);
-  i = get_y_or_n (1);
-  _rl_erase_entire_line ();
-  if (i == 0)
-    return -1;
-  else if (i == 2)
-    return (lines - 1);
-  else
-    return 0;
-}
-
-static int
-path_isdir (filename)
-     const char *filename;
-{
-  struct stat finfo;
-
-  return (stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode));
-}
-
-#if defined (VISIBLE_STATS)
-/* Return the character which best describes FILENAME.
-     `@' for symbolic links
-     `/' for directories
-     `*' for executables
-     `=' for sockets
-     `|' for FIFOs
-     `%' for character special devices
-     `#' for block special devices */
-static int
-stat_char (filename)
-     char *filename;
-{
-  struct stat finfo;
-  int character, r;
-
-  /* Short-circuit a //server on cygwin, since that will always behave as
-     a directory. */
-#if __CYGWIN__
-  if (filename[0] == '/' && filename[1] == '/' && strchr (filename+2, '/') == 0)
-    return '/';
-#endif
-
-#if defined (HAVE_LSTAT) && defined (S_ISLNK)
-  r = lstat (filename, &finfo);
-#else
-  r = stat (filename, &finfo);
-#endif
-
-  if (r == -1)
-    return (0);
-
-  character = 0;
-  if (S_ISDIR (finfo.st_mode))
-    character = '/';
-#if defined (S_ISCHR)
-  else if (S_ISCHR (finfo.st_mode))
-    character = '%';
-#endif /* S_ISCHR */
-#if defined (S_ISBLK)
-  else if (S_ISBLK (finfo.st_mode))
-    character = '#';
-#endif /* S_ISBLK */
-#if defined (S_ISLNK)
-  else if (S_ISLNK (finfo.st_mode))
-    character = '@';
-#endif /* S_ISLNK */
-#if defined (S_ISSOCK)
-  else if (S_ISSOCK (finfo.st_mode))
-    character = '=';
-#endif /* S_ISSOCK */
-#if defined (S_ISFIFO)
-  else if (S_ISFIFO (finfo.st_mode))
-    character = '|';
-#endif
-  else if (S_ISREG (finfo.st_mode))
-    {
-      if (access (filename, X_OK) == 0)
-       character = '*';
-    }
-  return (character);
-}
-#endif /* VISIBLE_STATS */
-
-/* Return the portion of PATHNAME that should be output when listing
-   possible completions.  If we are hacking filename completion, we
-   are only interested in the basename, the portion following the
-   final slash.  Otherwise, we return what we were passed.  Since
-   printing empty strings is not very informative, if we're doing
-   filename completion, and the basename is the empty string, we look
-   for the previous slash and return the portion following that.  If
-   there's no previous slash, we just return what we were passed. */
-static char *
-printable_part (pathname)
-      char *pathname;
-{
-  char *temp, *x;
-
-  if (rl_filename_completion_desired == 0)     /* don't need to do anything */
-    return (pathname);
-
-  temp = strrchr (pathname, '/');
-#if defined (__MSDOS__)
-  if (temp == 0 && ISALPHA ((unsigned char)pathname[0]) && pathname[1] == ':')
-    temp = pathname + 1;
-#endif
-
-  if (temp == 0 || *temp == '\0')
-    return (pathname);
-  /* If the basename is NULL, we might have a pathname like '/usr/src/'.
-     Look for a previous slash and, if one is found, return the portion
-     following that slash.  If there's no previous slash, just return the
-     pathname we were passed. */
-  else if (temp[1] == '\0')
-    {
-      for (x = temp - 1; x > pathname; x--)
-        if (*x == '/')
-          break;
-      return ((*x == '/') ? x + 1 : pathname);
-    }
-  else
-    return ++temp;
-}
-
-/* Compute width of STRING when displayed on screen by print_filename */
-static int
-fnwidth (string)
-     const char *string;
-{
-  int width, pos;
-#if defined (HANDLE_MULTIBYTE)
-  mbstate_t ps;
-  int left, w;
-  size_t clen;
-  wchar_t wc;
-
-  left = strlen (string) + 1;
-  memset (&ps, 0, sizeof (mbstate_t));
-#endif
-
-  width = pos = 0;
-  while (string[pos])
-    {
-      if (CTRL_CHAR (string[pos]) || string[pos] == RUBOUT)
-       {
-         width += 2;
-         pos++;
-       }
-      else
-       {
-#if defined (HANDLE_MULTIBYTE)
-         clen = mbrtowc (&wc, string + pos, left - pos, &ps);
-         if (MB_INVALIDCH (clen))
-           {
-             width++;
-             pos++;
-             memset (&ps, 0, sizeof (mbstate_t));
-           }
-         else if (MB_NULLWCH (clen))
-           break;
-         else
-           {
-             pos += clen;
-             w = wcwidth (wc);
-             width += (w >= 0) ? w : 1;
-           }
-#else
-         width++;
-         pos++;
-#endif
-       }
-    }
-
-  return width;
-}
-
-#define ELLIPSIS_LEN   3
-
-static int
-fnprint (to_print, prefix_bytes)
-     const char *to_print;
-     int prefix_bytes;
-{
-  int printed_len, w;
-  const char *s;
-#if defined (HANDLE_MULTIBYTE)
-  mbstate_t ps;
-  const char *end;
-  size_t tlen;
-  int width;
-  wchar_t wc;
-
-  end = to_print + strlen (to_print) + 1;
-  memset (&ps, 0, sizeof (mbstate_t));
-#endif
-
-  printed_len = 0;
-
-  /* Don't print only the ellipsis if the common prefix is one of the
-     possible completions */
-  if (to_print[prefix_bytes] == '\0')
-    prefix_bytes = 0;
-
-  if (prefix_bytes)
-    {
-      char ellipsis;
-
-      ellipsis = (to_print[prefix_bytes] == '.') ? '_' : '.';
-      for (w = 0; w < ELLIPSIS_LEN; w++)
-       putc (ellipsis, rl_outstream);
-      printed_len = ELLIPSIS_LEN;
-    }
-
-  s = to_print + prefix_bytes;
-  while (*s)
-    {
-      if (CTRL_CHAR (*s))
-        {
-          putc ('^', rl_outstream);
-          putc (UNCTRL (*s), rl_outstream);
-          printed_len += 2;
-          s++;
-#if defined (HANDLE_MULTIBYTE)
-         memset (&ps, 0, sizeof (mbstate_t));
-#endif
-        }
-      else if (*s == RUBOUT)
-       {
-         putc ('^', rl_outstream);
-         putc ('?', rl_outstream);
-         printed_len += 2;
-         s++;
-#if defined (HANDLE_MULTIBYTE)
-         memset (&ps, 0, sizeof (mbstate_t));
-#endif
-       }
-      else
-       {
-#if defined (HANDLE_MULTIBYTE)
-         tlen = mbrtowc (&wc, s, end - s, &ps);
-         if (MB_INVALIDCH (tlen))
-           {
-             tlen = 1;
-             width = 1;
-             memset (&ps, 0, sizeof (mbstate_t));
-           }
-         else if (MB_NULLWCH (tlen))
-           break;
-         else
-           {
-             w = wcwidth (wc);
-             width = (w >= 0) ? w : 1;
-           }
-         fwrite (s, 1, tlen, rl_outstream);
-         s += tlen;
-         printed_len += width;
-#else
-         putc (*s, rl_outstream);
-         s++;
-         printed_len++;
-#endif
-       }
-    }
-
-  return printed_len;
-}
-
-/* Output TO_PRINT to rl_outstream.  If VISIBLE_STATS is defined and we
-   are using it, check for and output a single character for `special'
-   filenames.  Return the number of characters we output. */
-
-static int
-print_filename (to_print, full_pathname, prefix_bytes)
-     char *to_print, *full_pathname;
-     int prefix_bytes;
-{
-  int printed_len, extension_char, slen, tlen;
-  char *s, c, *new_full_pathname, *dn;
-
-  extension_char = 0;
-  printed_len = fnprint (to_print, prefix_bytes);
-
-#if defined (VISIBLE_STATS)
- if (rl_filename_completion_desired && (rl_visible_stats || _rl_complete_mark_directories))
-#else
- if (rl_filename_completion_desired && _rl_complete_mark_directories)
-#endif
-    {
-      /* If to_print != full_pathname, to_print is the basename of the
-        path passed.  In this case, we try to expand the directory
-        name before checking for the stat character. */
-      if (to_print != full_pathname)
-       {
-         /* Terminate the directory name. */
-         c = to_print[-1];
-         to_print[-1] = '\0';
-
-         /* If setting the last slash in full_pathname to a NUL results in
-            full_pathname being the empty string, we are trying to complete
-            files in the root directory.  If we pass a null string to the
-            bash directory completion hook, for example, it will expand it
-            to the current directory.  We just want the `/'. */
-         if (full_pathname == 0 || *full_pathname == 0)
-           dn = "/";
-         else if (full_pathname[0] != '/')
-           dn = full_pathname;
-         else if (full_pathname[1] == 0)
-           dn = "//";          /* restore trailing slash to `//' */
-         else if (full_pathname[1] == '/' && full_pathname[2] == 0)
-           dn = "/";           /* don't turn /// into // */
-         else
-           dn = full_pathname;
-         s = tilde_expand (dn);
-         if (rl_directory_completion_hook)
-           (*rl_directory_completion_hook) (&s);
-
-         slen = strlen (s);
-         tlen = strlen (to_print);
-         new_full_pathname = (char *)xmalloc (slen + tlen + 2);
-         strcpy (new_full_pathname, s);
-         if (s[slen - 1] == '/')
-           slen--;
-         else
-           new_full_pathname[slen] = '/';
-         new_full_pathname[slen] = '/';
-         strcpy (new_full_pathname + slen + 1, to_print);
-
-#if defined (VISIBLE_STATS)
-         if (rl_visible_stats)
-           extension_char = stat_char (new_full_pathname);
-         else
-#endif
-         if (path_isdir (new_full_pathname))
-           extension_char = '/';
-
-         free (new_full_pathname);
-         to_print[-1] = c;
-       }
-      else
-       {
-         s = tilde_expand (full_pathname);
-#if defined (VISIBLE_STATS)
-         if (rl_visible_stats)
-           extension_char = stat_char (s);
-         else
-#endif
-           if (path_isdir (s))
-             extension_char = '/';
-       }
-
-      free (s);
-      if (extension_char)
-       {
-         putc (extension_char, rl_outstream);
-         printed_len++;
-       }
-    }
-
-  return printed_len;
-}
-
-static char *
-rl_quote_filename (s, rtype, qcp)
-     char *s;
-     int rtype;
-     char *qcp;
-{
-  char *r;
-
-  r = (char *)xmalloc (strlen (s) + 2);
-  *r = *rl_completer_quote_characters;
-  strcpy (r + 1, s);
-  if (qcp)
-    *qcp = *rl_completer_quote_characters;
-  return r;
-}
-
-/* Find the bounds of the current word for completion purposes, and leave
-   rl_point set to the end of the word.  This function skips quoted
-   substrings (characters between matched pairs of characters in
-   rl_completer_quote_characters).  First we try to find an unclosed
-   quoted substring on which to do matching.  If one is not found, we use
-   the word break characters to find the boundaries of the current word.
-   We call an application-specific function to decide whether or not a
-   particular word break character is quoted; if that function returns a
-   non-zero result, the character does not break a word.  This function
-   returns the opening quote character if we found an unclosed quoted
-   substring, '\0' otherwise.  FP, if non-null, is set to a value saying
-   which (shell-like) quote characters we found (single quote, double
-   quote, or backslash) anywhere in the string.  DP, if non-null, is set to
-   the value of the delimiter character that caused a word break. */
-
-char
-_rl_find_completion_word (fp, dp)
-     int *fp, *dp;
-{
-  int scan, end, found_quote, delimiter, pass_next, isbrk;
-  char quote_char, *brkchars;
-
-  end = rl_point;
-  found_quote = delimiter = 0;
-  quote_char = '\0';
-
-  brkchars = 0;
-  if (rl_completion_word_break_hook)
-    brkchars = (*rl_completion_word_break_hook) ();
-  if (brkchars == 0)
-    brkchars = rl_completer_word_break_characters;
-
-  if (rl_completer_quote_characters)
-    {
-      /* We have a list of characters which can be used in pairs to
-        quote substrings for the completer.  Try to find the start
-        of an unclosed quoted substring. */
-      /* FOUND_QUOTE is set so we know what kind of quotes we found. */
-      for (scan = pass_next = 0; scan < end; scan = MB_NEXTCHAR (rl_line_buffer, scan, 1, MB_FIND_ANY))
-       {
-         if (pass_next)
-           {
-             pass_next = 0;
-             continue;
-           }
-
-         /* Shell-like semantics for single quotes -- don't allow backslash
-            to quote anything in single quotes, especially not the closing
-            quote.  If you don't like this, take out the check on the value
-            of quote_char. */
-         if (quote_char != '\'' && rl_line_buffer[scan] == '\\')
-           {
-             pass_next = 1;
-             found_quote |= RL_QF_BACKSLASH;
-             continue;
-           }
-
-         if (quote_char != '\0')
-           {
-             /* Ignore everything until the matching close quote char. */
-             if (rl_line_buffer[scan] == quote_char)
-               {
-                 /* Found matching close.  Abandon this substring. */
-                 quote_char = '\0';
-                 rl_point = end;
-               }
-           }
-         else if (strchr (rl_completer_quote_characters, rl_line_buffer[scan]))
-           {
-             /* Found start of a quoted substring. */
-             quote_char = rl_line_buffer[scan];
-             rl_point = scan + 1;
-             /* Shell-like quoting conventions. */
-             if (quote_char == '\'')
-               found_quote |= RL_QF_SINGLE_QUOTE;
-             else if (quote_char == '"')
-               found_quote |= RL_QF_DOUBLE_QUOTE;
-             else
-               found_quote |= RL_QF_OTHER_QUOTE;      
-           }
-       }
-    }
-
-  if (rl_point == end && quote_char == '\0')
-    {
-      /* We didn't find an unclosed quoted substring upon which to do
-         completion, so use the word break characters to find the
-         substring on which to complete. */
-      while (rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_ANY))
-       {
-         scan = rl_line_buffer[rl_point];
-
-         if (strchr (brkchars, scan) == 0)
-           continue;
-
-         /* Call the application-specific function to tell us whether
-            this word break character is quoted and should be skipped. */
-         if (rl_char_is_quoted_p && found_quote &&
-             (*rl_char_is_quoted_p) (rl_line_buffer, rl_point))
-           continue;
-
-         /* Convoluted code, but it avoids an n^2 algorithm with calls
-            to char_is_quoted. */
-         break;
-       }
-    }
-
-  /* If we are at an unquoted word break, then advance past it. */
-  scan = rl_line_buffer[rl_point];
-
-  /* If there is an application-specific function to say whether or not
-     a character is quoted and we found a quote character, let that
-     function decide whether or not a character is a word break, even
-     if it is found in rl_completer_word_break_characters.  Don't bother
-     if we're at the end of the line, though. */
-  if (scan)
-    {
-      if (rl_char_is_quoted_p)
-       isbrk = (found_quote == 0 ||
-               (*rl_char_is_quoted_p) (rl_line_buffer, rl_point) == 0) &&
-               strchr (brkchars, scan) != 0;
-      else
-       isbrk = strchr (brkchars, scan) != 0;
-
-      if (isbrk)
-       {
-         /* If the character that caused the word break was a quoting
-            character, then remember it as the delimiter. */
-         if (rl_basic_quote_characters &&
-             strchr (rl_basic_quote_characters, scan) &&
-             (end - rl_point) > 1)
-           delimiter = scan;
-
-         /* If the character isn't needed to determine something special
-            about what kind of completion to perform, then advance past it. */
-         if (rl_special_prefixes == 0 || strchr (rl_special_prefixes, scan) == 0)
-           rl_point++;
-       }
-    }
-
-  if (fp)
-    *fp = found_quote;
-  if (dp)
-    *dp = delimiter;
-
-  return (quote_char);
-}
-
-static char **
-gen_completion_matches (text, start, end, our_func, found_quote, quote_char)
-     char *text;
-     int start, end;
-     rl_compentry_func_t *our_func;
-     int found_quote, quote_char;
-{
-  char **matches;
-
-  rl_completion_found_quote = found_quote;
-  rl_completion_quote_character = quote_char;
-
-  /* If the user wants to TRY to complete, but then wants to give
-     up and use the default completion function, they set the
-     variable rl_attempted_completion_function. */
-  if (rl_attempted_completion_function)
-    {
-      _rl_interrupt_immediately++;
-      matches = (*rl_attempted_completion_function) (text, start, end);
-      _rl_interrupt_immediately--;
-
-      if (matches || rl_attempted_completion_over)
-       {
-         rl_attempted_completion_over = 0;
-         return (matches);
-       }
-    }
-
-  /* XXX -- filename dequoting moved into rl_filename_completion_function */
-
-  matches = rl_completion_matches (text, our_func);
-  return matches;  
-}
-
-/* Filter out duplicates in MATCHES.  This frees up the strings in
-   MATCHES. */
-static char **
-remove_duplicate_matches (matches)
-     char **matches;
-{
-  char *lowest_common;
-  int i, j, newlen;
-  char dead_slot;
-  char **temp_array;
-
-  /* Sort the items. */
-  for (i = 0; matches[i]; i++)
-    ;
-
-  /* Sort the array without matches[0], since we need it to
-     stay in place no matter what. */
-  if (i && rl_sort_completion_matches)
-    qsort (matches+1, i-1, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
-
-  /* Remember the lowest common denominator for it may be unique. */
-  lowest_common = savestring (matches[0]);
-
-  for (i = newlen = 0; matches[i + 1]; i++)
-    {
-      if (strcmp (matches[i], matches[i + 1]) == 0)
-       {
-         free (matches[i]);
-         matches[i] = (char *)&dead_slot;
-       }
-      else
-       newlen++;
-    }
-
-  /* We have marked all the dead slots with (char *)&dead_slot.
-     Copy all the non-dead entries into a new array. */
-  temp_array = (char **)xmalloc ((3 + newlen) * sizeof (char *));
-  for (i = j = 1; matches[i]; i++)
-    {
-      if (matches[i] != (char *)&dead_slot)
-       temp_array[j++] = matches[i];
-    }
-  temp_array[j] = (char *)NULL;
-
-  if (matches[0] != (char *)&dead_slot)
-    free (matches[0]);
-
-  /* Place the lowest common denominator back in [0]. */
-  temp_array[0] = lowest_common;
-
-  /* If there is one string left, and it is identical to the
-     lowest common denominator, then the LCD is the string to
-     insert. */
-  if (j == 2 && strcmp (temp_array[0], temp_array[1]) == 0)
-    {
-      free (temp_array[1]);
-      temp_array[1] = (char *)NULL;
-    }
-  return (temp_array);
-}
-
-/* Find the common prefix of the list of matches, and put it into
-   matches[0]. */
-static int
-compute_lcd_of_matches (match_list, matches, text)
-     char **match_list;
-     int matches;
-     const char *text;
-{
-  register int i, c1, c2, si;
-  int low;             /* Count of max-matched characters. */
-  char *dtext;         /* dequoted TEXT, if needed */
-#if defined (HANDLE_MULTIBYTE)
-  int v;
-  mbstate_t ps1, ps2;
-  wchar_t wc1, wc2;
-#endif
-
-  /* If only one match, just use that.  Otherwise, compare each
-     member of the list with the next, finding out where they
-     stop matching. */
-  if (matches == 1)
-    {
-      match_list[0] = match_list[1];
-      match_list[1] = (char *)NULL;
-      return 1;
-    }
-
-  for (i = 1, low = 100000; i < matches; i++)
-    {
-#if defined (HANDLE_MULTIBYTE)
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-       {
-         memset (&ps1, 0, sizeof (mbstate_t));
-         memset (&ps2, 0, sizeof (mbstate_t));
-       }
-#endif
-      if (_rl_completion_case_fold)
-       {
-         for (si = 0;
-              (c1 = _rl_to_lower(match_list[i][si])) &&
-              (c2 = _rl_to_lower(match_list[i + 1][si]));
-              si++)
-#if defined (HANDLE_MULTIBYTE)
-           if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-             {
-               v = mbrtowc (&wc1, match_list[i]+si, strlen (match_list[i]+si), &ps1);
-               mbrtowc (&wc2, match_list[i+1]+si, strlen (match_list[i+1]+si), &ps2);
-               wc1 = towlower (wc1);
-               wc2 = towlower (wc2);
-               if (wc1 != wc2)
-                 break;
-               else if (v > 1)
-                 si += v - 1;
-             }
-           else
-#endif
-           if (c1 != c2)
-             break;
-       }
-      else
-       {
-         for (si = 0;
-              (c1 = match_list[i][si]) &&
-              (c2 = match_list[i + 1][si]);
-              si++)
-#if defined (HANDLE_MULTIBYTE)
-           if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-             {
-               mbstate_t ps_back;
-               ps_back = ps1;
-               if (!_rl_compare_chars (match_list[i], si, &ps1, match_list[i+1], si, &ps2))
-                 break;
-               else if ((v = _rl_get_char_len (&match_list[i][si], &ps_back)) > 1)
-                 si += v - 1;
-             }
-           else
-#endif
-           if (c1 != c2)
-             break;
-       }
-
-      if (low > si)
-       low = si;
-    }
-
-  /* If there were multiple matches, but none matched up to even the
-     first character, and the user typed something, use that as the
-     value of matches[0]. */
-  if (low == 0 && text && *text)
-    {
-      match_list[0] = (char *)xmalloc (strlen (text) + 1);
-      strcpy (match_list[0], text);
-    }
-  else
-    {
-      match_list[0] = (char *)xmalloc (low + 1);
-
-      /* XXX - this might need changes in the presence of multibyte chars */
-
-      /* If we are ignoring case, try to preserve the case of the string
-        the user typed in the face of multiple matches differing in case. */
-      if (_rl_completion_case_fold)
-       {
-         /* We're making an assumption here:
-               IF we're completing filenames AND
-                  the application has defined a filename dequoting function AND
-                  we found a quote character AND
-                  the application has requested filename quoting
-               THEN
-                  we assume that TEXT was dequoted before checking against
-                  the file system and needs to be dequoted here before we
-                  check against the list of matches
-               FI */
-         dtext = (char *)NULL;
-         if (rl_filename_completion_desired &&
-             rl_filename_dequoting_function &&
-             rl_completion_found_quote &&
-             rl_filename_quoting_desired)
-           {
-             dtext = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character);
-             text = dtext;
-           }
-
-         /* sort the list to get consistent answers. */
-         qsort (match_list+1, matches, sizeof(char *), (QSFUNC *)_rl_qsort_string_compare);
-
-         si = strlen (text);
-         if (si <= low)
-           {
-             for (i = 1; i <= matches; i++)
-               if (strncmp (match_list[i], text, si) == 0)
-                 {
-                   strncpy (match_list[0], match_list[i], low);
-                   break;
-                 }
-             /* no casematch, use first entry */
-             if (i > matches)
-               strncpy (match_list[0], match_list[1], low);
-           }
-         else
-           /* otherwise, just use the text the user typed. */
-           strncpy (match_list[0], text, low);
-
-         FREE (dtext);
-       }
-      else
-        strncpy (match_list[0], match_list[1], low);
-
-      match_list[0][low] = '\0';
-    }
-
-  return matches;
-}
-
-static int
-postprocess_matches (matchesp, matching_filenames)
-     char ***matchesp;
-     int matching_filenames;
-{
-  char *t, **matches, **temp_matches;
-  int nmatch, i;
-
-  matches = *matchesp;
-
-  if (matches == 0)
-    return 0;
-
-  /* It seems to me that in all the cases we handle we would like
-     to ignore duplicate possiblilities.  Scan for the text to
-     insert being identical to the other completions. */
-  if (rl_ignore_completion_duplicates)
-    {
-      temp_matches = remove_duplicate_matches (matches);
-      free (matches);
-      matches = temp_matches;
-    }
-
-  /* If we are matching filenames, then here is our chance to
-     do clever processing by re-examining the list.  Call the
-     ignore function with the array as a parameter.  It can
-     munge the array, deleting matches as it desires. */
-  if (rl_ignore_some_completions_function && matching_filenames)
-    {
-      for (nmatch = 1; matches[nmatch]; nmatch++)
-       ;
-      (void)(*rl_ignore_some_completions_function) (matches);
-      if (matches == 0 || matches[0] == 0)
-       {
-         FREE (matches);
-         *matchesp = (char **)0;
-         return 0;
-        }
-      else
-       {
-         /* If we removed some matches, recompute the common prefix. */
-         for (i = 1; matches[i]; i++)
-           ;
-         if (i > 1 && i < nmatch)
-           {
-             t = matches[0];
-             compute_lcd_of_matches (matches, i - 1, t);
-             FREE (t);
-           }
-       }
-    }
-
-  *matchesp = matches;
-  return (1);
-}
-
-/* A convenience function for displaying a list of strings in
-   columnar format on readline's output stream.  MATCHES is the list
-   of strings, in argv format, LEN is the number of strings in MATCHES,
-   and MAX is the length of the longest string in MATCHES. */
-void
-rl_display_match_list (matches, len, max)
-     char **matches;
-     int len, max;
-{
-  int count, limit, printed_len, lines;
-  int i, j, k, l, common_length, sind;
-  char *temp, *t;
-
-  /* Find the length of the prefix common to all items: length as displayed
-     characters (common_length) and as a byte index into the matches (sind) */
-  common_length = sind = 0;
-  if (_rl_completion_prefix_display_length > 0)
-    {
-      t = printable_part (matches[0]);
-      temp = strrchr (t, '/');
-      common_length = temp ? fnwidth (temp) : fnwidth (t);
-      sind = temp ? strlen (temp) : strlen (t);
-
-      if (common_length > _rl_completion_prefix_display_length && common_length > ELLIPSIS_LEN)
-       max -= common_length - ELLIPSIS_LEN;
-      else
-       common_length = sind = 0;
-    }
-
-  /* How many items of MAX length can we fit in the screen window? */
-  max += 2;
-  limit = _rl_screenwidth / max;
-  if (limit != 1 && (limit * max == _rl_screenwidth))
-    limit--;
-
-  /* Avoid a possible floating exception.  If max > _rl_screenwidth,
-     limit will be 0 and a divide-by-zero fault will result. */
-  if (limit == 0)
-    limit = 1;
-
-  /* How many iterations of the printing loop? */
-  count = (len + (limit - 1)) / limit;
-
-  /* Watch out for special case.  If LEN is less than LIMIT, then
-     just do the inner printing loop.
-          0 < len <= limit  implies  count = 1. */
-
-  /* Sort the items if they are not already sorted. */
-  if (rl_ignore_completion_duplicates == 0 && rl_sort_completion_matches)
-    qsort (matches + 1, len, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
-
-  rl_crlf ();
-
-  lines = 0;
-  if (_rl_print_completions_horizontally == 0)
-    {
-      /* Print the sorted items, up-and-down alphabetically, like ls. */
-      for (i = 1; i <= count; i++)
-       {
-         for (j = 0, l = i; j < limit; j++)
-           {
-             if (l > len || matches[l] == 0)
-               break;
-             else
-               {
-                 temp = printable_part (matches[l]);
-                 printed_len = print_filename (temp, matches[l], sind);
-
-                 if (j + 1 < limit)
-                   for (k = 0; k < max - printed_len; k++)
-                     putc (' ', rl_outstream);
-               }
-             l += count;
-           }
-         rl_crlf ();
-         lines++;
-         if (_rl_page_completions && lines >= (_rl_screenheight - 1) && i < count)
-           {
-             lines = _rl_internal_pager (lines);
-             if (lines < 0)
-               return;
-           }
-       }
-    }
-  else
-    {
-      /* Print the sorted items, across alphabetically, like ls -x. */
-      for (i = 1; matches[i]; i++)
-       {
-         temp = printable_part (matches[i]);
-         printed_len = print_filename (temp, matches[i], sind);
-         /* Have we reached the end of this line? */
-         if (matches[i+1])
-           {
-             if (i && (limit > 1) && (i % limit) == 0)
-               {
-                 rl_crlf ();
-                 lines++;
-                 if (_rl_page_completions && lines >= _rl_screenheight - 1)
-                   {
-                     lines = _rl_internal_pager (lines);
-                     if (lines < 0)
-                       return;
-                   }
-               }
-             else
-               for (k = 0; k < max - printed_len; k++)
-                 putc (' ', rl_outstream);
-           }
-       }
-      rl_crlf ();
-    }
-}
-
-/* Display MATCHES, a list of matching filenames in argv format.  This
-   handles the simple case -- a single match -- first.  If there is more
-   than one match, we compute the number of strings in the list and the
-   length of the longest string, which will be needed by the display
-   function.  If the application wants to handle displaying the list of
-   matches itself, it sets RL_COMPLETION_DISPLAY_MATCHES_HOOK to the
-   address of a function, and we just call it.  If we're handling the
-   display ourselves, we just call rl_display_match_list.  We also check
-   that the list of matches doesn't exceed the user-settable threshold,
-   and ask the user if he wants to see the list if there are more matches
-   than RL_COMPLETION_QUERY_ITEMS. */
-static void
-display_matches (matches)
-     char **matches;
-{
-  int len, max, i;
-  char *temp;
-
-  /* Move to the last visible line of a possibly-multiple-line command. */
-  _rl_move_vert (_rl_vis_botlin);
-
-  /* Handle simple case first.  What if there is only one answer? */
-  if (matches[1] == 0)
-    {
-      temp = printable_part (matches[0]);
-      rl_crlf ();
-      print_filename (temp, matches[0], 0);
-      rl_crlf ();
-
-      rl_forced_update_display ();
-      rl_display_fixed = 1;
-
-      return;
-    }
-
-  /* There is more than one answer.  Find out how many there are,
-     and find the maximum printed length of a single entry. */
-  for (max = 0, i = 1; matches[i]; i++)
-    {
-      temp = printable_part (matches[i]);
-      len = fnwidth (temp);
-
-      if (len > max)
-       max = len;
-    }
-
-  len = i - 1;
-
-  /* If the caller has defined a display hook, then call that now. */
-  if (rl_completion_display_matches_hook)
-    {
-      (*rl_completion_display_matches_hook) (matches, len, max);
-      return;
-    }
-       
-  /* If there are many items, then ask the user if she really wants to
-     see them all. */
-  if (rl_completion_query_items > 0 && len >= rl_completion_query_items)
-    {
-      rl_crlf ();
-      fprintf (rl_outstream, "Display all %d possibilities? (y or n)", len);
-      fflush (rl_outstream);
-      if ((completion_y_or_n = get_y_or_n (0)) == 0)
-       {
-         rl_crlf ();
-
-         rl_forced_update_display ();
-         rl_display_fixed = 1;
-
-         return;
-       }
-    }
-
-  rl_display_match_list (matches, len, max);
-
-  rl_forced_update_display ();
-  rl_display_fixed = 1;
-}
-
-static char *
-make_quoted_replacement (match, mtype, qc)
-     char *match;
-     int mtype;
-     char *qc; /* Pointer to quoting character, if any */
-{
-  int should_quote, do_replace;
-  char *replacement;
-
-  /* If we are doing completion on quoted substrings, and any matches
-     contain any of the completer_word_break_characters, then auto-
-     matically prepend the substring with a quote character (just pick
-     the first one from the list of such) if it does not already begin
-     with a quote string.  FIXME: Need to remove any such automatically
-     inserted quote character when it no longer is necessary, such as
-     if we change the string we are completing on and the new set of
-     matches don't require a quoted substring. */
-  replacement = match;
-
-  should_quote = match && rl_completer_quote_characters &&
-                       rl_filename_completion_desired &&
-                       rl_filename_quoting_desired;
-
-  if (should_quote)
-    should_quote = should_quote && (!qc || !*qc ||
-                    (rl_completer_quote_characters && strchr (rl_completer_quote_characters, *qc)));
-
-  if (should_quote)
-    {
-      /* If there is a single match, see if we need to quote it.
-         This also checks whether the common prefix of several
-        matches needs to be quoted. */
-      should_quote = rl_filename_quote_characters
-                       ? (_rl_strpbrk (match, rl_filename_quote_characters) != 0)
-                       : 0;
-
-      do_replace = should_quote ? mtype : NO_MATCH;
-      /* Quote the replacement, since we found an embedded
-        word break character in a potential match. */
-      if (do_replace != NO_MATCH && rl_filename_quoting_function)
-       replacement = (*rl_filename_quoting_function) (match, do_replace, qc);
-    }
-  return (replacement);
-}
-
-static void
-insert_match (match, start, mtype, qc)
-     char *match;
-     int start, mtype;
-     char *qc;
-{
-  char *replacement;
-  char oqc;
-
-  oqc = qc ? *qc : '\0';
-  replacement = make_quoted_replacement (match, mtype, qc);
-
-  /* Now insert the match. */
-  if (replacement)
-    {
-      /* Don't double an opening quote character. */
-      if (qc && *qc && start && rl_line_buffer[start - 1] == *qc &&
-           replacement[0] == *qc)
-       start--;
-      /* If make_quoted_replacement changed the quoting character, remove
-        the opening quote and insert the (fully-quoted) replacement. */
-      else if (qc && (*qc != oqc) && start && rl_line_buffer[start - 1] == oqc &&
-           replacement[0] != oqc)
-       start--;
-      _rl_replace_text (replacement, start, rl_point - 1);
-      if (replacement != match)
-        free (replacement);
-    }
-}
-
-/* Append any necessary closing quote and a separator character to the
-   just-inserted match.  If the user has specified that directories
-   should be marked by a trailing `/', append one of those instead.  The
-   default trailing character is a space.  Returns the number of characters
-   appended.  If NONTRIVIAL_MATCH is set, we test for a symlink (if the OS
-   has them) and don't add a suffix for a symlink to a directory.  A
-   nontrivial match is one that actually adds to the word being completed.
-   The variable rl_completion_mark_symlink_dirs controls this behavior
-   (it's initially set to the what the user has chosen, indicated by the
-   value of _rl_complete_mark_symlink_dirs, but may be modified by an
-   application's completion function). */
-static int
-append_to_match (text, delimiter, quote_char, nontrivial_match)
-     char *text;
-     int delimiter, quote_char, nontrivial_match;
-{
-  char temp_string[4], *filename;
-  int temp_string_index, s;
-  struct stat finfo;
-
-  temp_string_index = 0;
-  if (quote_char && rl_point && rl_completion_suppress_quote == 0 &&
-      rl_line_buffer[rl_point - 1] != quote_char)
-    temp_string[temp_string_index++] = quote_char;
-
-  if (delimiter)
-    temp_string[temp_string_index++] = delimiter;
-  else if (rl_completion_suppress_append == 0 && rl_completion_append_character)
-    temp_string[temp_string_index++] = rl_completion_append_character;
-
-  temp_string[temp_string_index++] = '\0';
-
-  if (rl_filename_completion_desired)
-    {
-      filename = tilde_expand (text);
-      s = (nontrivial_match && rl_completion_mark_symlink_dirs == 0)
-               ? LSTAT (filename, &finfo)
-               : stat (filename, &finfo);
-      if (s == 0 && S_ISDIR (finfo.st_mode))
-       {
-         if (_rl_complete_mark_directories /* && rl_completion_suppress_append == 0 */)
-           {
-             /* This is clumsy.  Avoid putting in a double slash if point
-                is at the end of the line and the previous character is a
-                slash. */
-             if (rl_point && rl_line_buffer[rl_point] == '\0' && rl_line_buffer[rl_point - 1] == '/')
-               ;
-             else if (rl_line_buffer[rl_point] != '/')
-               rl_insert_text ("/");
-           }
-       }
-#ifdef S_ISLNK
-      /* Don't add anything if the filename is a symlink and resolves to a
-        directory. */
-      else if (s == 0 && S_ISLNK (finfo.st_mode) &&
-              stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode))
-       ;
-#endif
-      else
-       {
-         if (rl_point == rl_end && temp_string_index)
-           rl_insert_text (temp_string);
-       }
-      free (filename);
-    }
-  else
-    {
-      if (rl_point == rl_end && temp_string_index)
-       rl_insert_text (temp_string);
-    }
-
-  return (temp_string_index);
-}
-
-static void
-insert_all_matches (matches, point, qc)
-     char **matches;
-     int point;
-     char *qc;
-{
-  int i;
-  char *rp;
-
-  rl_begin_undo_group ();
-  /* remove any opening quote character; make_quoted_replacement will add
-     it back. */
-  if (qc && *qc && point && rl_line_buffer[point - 1] == *qc)
-    point--;
-  rl_delete_text (point, rl_point);
-  rl_point = point;
-
-  if (matches[1])
-    {
-      for (i = 1; matches[i]; i++)
-       {
-         rp = make_quoted_replacement (matches[i], SINGLE_MATCH, qc);
-         rl_insert_text (rp);
-         rl_insert_text (" ");
-         if (rp != matches[i])
-           free (rp);
-       }
-    }
-  else
-    {
-      rp = make_quoted_replacement (matches[0], SINGLE_MATCH, qc);
-      rl_insert_text (rp);
-      rl_insert_text (" ");
-      if (rp != matches[0])
-       free (rp);
-    }
-  rl_end_undo_group ();
-}
-
-void
-_rl_free_match_list (matches)
-     char **matches;
-{
-  register int i;
-
-  if (matches == 0)
-    return;
-
-  for (i = 0; matches[i]; i++)
-    free (matches[i]);
-  free (matches);
-}
-
-/* Complete the word at or before point.
-   WHAT_TO_DO says what to do with the completion.
-   `?' means list the possible completions.
-   TAB means do standard completion.
-   `*' means insert all of the possible completions.
-   `!' means to do standard completion, and list all possible completions if
-   there is more than one.
-   `@' means to do standard completion, and list all possible completions if
-   there is more than one and partial completion is not possible. */
-int
-rl_complete_internal (what_to_do)
-     int what_to_do;
-{
-  char **matches;
-  rl_compentry_func_t *our_func;
-  int start, end, delimiter, found_quote, i, nontrivial_lcd;
-  char *text, *saved_line_buffer;
-  char quote_char;
-
-  RL_SETSTATE(RL_STATE_COMPLETING);
-
-  set_completion_defaults (what_to_do);
-
-  saved_line_buffer = rl_line_buffer ? savestring (rl_line_buffer) : (char *)NULL;
-  our_func = rl_completion_entry_function
-               ? rl_completion_entry_function
-               : rl_filename_completion_function;
-  /* We now look backwards for the start of a filename/variable word. */
-  end = rl_point;
-  found_quote = delimiter = 0;
-  quote_char = '\0';
-
-  if (rl_point)
-    /* This (possibly) changes rl_point.  If it returns a non-zero char,
-       we know we have an open quote. */
-    quote_char = _rl_find_completion_word (&found_quote, &delimiter);
-
-  start = rl_point;
-  rl_point = end;
-
-  text = rl_copy_text (start, end);
-  matches = gen_completion_matches (text, start, end, our_func, found_quote, quote_char);
-  /* nontrivial_lcd is set if the common prefix adds something to the word
-     being completed. */
-  nontrivial_lcd = matches && strcmp (text, matches[0]) != 0;
-  free (text);
-
-  if (matches == 0)
-    {
-      rl_ding ();
-      FREE (saved_line_buffer);
-      completion_changed_buffer = 0;
-      RL_UNSETSTATE(RL_STATE_COMPLETING);
-      _rl_reset_completion_state ();
-      return (0);
-    }
-
-  /* If we are matching filenames, the attempted completion function will
-     have set rl_filename_completion_desired to a non-zero value.  The basic
-     rl_filename_completion_function does this. */
-  i = rl_filename_completion_desired;
-
-  if (postprocess_matches (&matches, i) == 0)
-    {
-      rl_ding ();
-      FREE (saved_line_buffer);
-      completion_changed_buffer = 0;
-      RL_UNSETSTATE(RL_STATE_COMPLETING);
-      _rl_reset_completion_state ();
-      return (0);
-    }
-
-  switch (what_to_do)
-    {
-    case TAB:
-    case '!':
-    case '@':
-      /* Insert the first match with proper quoting. */
-      if (*matches[0])
-       insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
-
-      /* If there are more matches, ring the bell to indicate.
-        If we are in vi mode, Posix.2 says to not ring the bell.
-        If the `show-all-if-ambiguous' variable is set, display
-        all the matches immediately.  Otherwise, if this was the
-        only match, and we are hacking files, check the file to
-        see if it was a directory.  If so, and the `mark-directories'
-        variable is set, add a '/' to the name.  If not, and we
-        are at the end of the line, then add a space.  */
-      if (matches[1])
-       {
-         if (what_to_do == '!')
-           {
-             display_matches (matches);
-             break;
-           }
-         else if (what_to_do == '@')
-           {
-             if (nontrivial_lcd == 0)
-               display_matches (matches);
-             break;
-           }
-         else if (rl_editing_mode != vi_mode)
-           rl_ding (); /* There are other matches remaining. */
-       }
-      else
-       append_to_match (matches[0], delimiter, quote_char, nontrivial_lcd);
-
-      break;
-
-    case '*':
-      insert_all_matches (matches, start, &quote_char);
-      break;
-
-    case '?':
-      display_matches (matches);
-      break;
-
-    default:
-      _rl_ttymsg ("bad value %d for what_to_do in rl_complete", what_to_do);
-      rl_ding ();
-      FREE (saved_line_buffer);
-      RL_UNSETSTATE(RL_STATE_COMPLETING);
-      _rl_reset_completion_state ();
-      return 1;
-    }
-
-  _rl_free_match_list (matches);
-
-  /* Check to see if the line has changed through all of this manipulation. */
-  if (saved_line_buffer)
-    {
-      completion_changed_buffer = strcmp (rl_line_buffer, saved_line_buffer) != 0;
-      free (saved_line_buffer);
-    }
-
-  RL_UNSETSTATE(RL_STATE_COMPLETING);
-  _rl_reset_completion_state ();
-  return 0;
-}
-
-/***************************************************************/
-/*                                                            */
-/*  Application-callable completion match generator functions  */
-/*                                                            */
-/***************************************************************/
-
-/* Return an array of (char *) which is a list of completions for TEXT.
-   If there are no completions, return a NULL pointer.
-   The first entry in the returned array is the substitution for TEXT.
-   The remaining entries are the possible completions.
-   The array is terminated with a NULL pointer.
-
-   ENTRY_FUNCTION is a function of two args, and returns a (char *).
-     The first argument is TEXT.
-     The second is a state argument; it should be zero on the first call, and
-     non-zero on subsequent calls.  It returns a NULL pointer to the caller
-     when there are no more matches.
- */
-char **
-rl_completion_matches (text, entry_function)
-     const char *text;
-     rl_compentry_func_t *entry_function;
-{
-  /* Number of slots in match_list. */
-  int match_list_size;
-
-  /* The list of matches. */
-  char **match_list;
-
-  /* Number of matches actually found. */
-  int matches;
-
-  /* Temporary string binder. */
-  char *string;
-
-  matches = 0;
-  match_list_size = 10;
-  match_list = (char **)xmalloc ((match_list_size + 1) * sizeof (char *));
-  match_list[1] = (char *)NULL;
-
-  _rl_interrupt_immediately++;
-  while (string = (*entry_function) (text, matches))
-    {
-      if (matches + 1 == match_list_size)
-       match_list = (char **)xrealloc
-         (match_list, ((match_list_size += 10) + 1) * sizeof (char *));
-
-      match_list[++matches] = string;
-      match_list[matches + 1] = (char *)NULL;
-    }
-  _rl_interrupt_immediately--;
-
-  /* If there were any matches, then look through them finding out the
-     lowest common denominator.  That then becomes match_list[0]. */
-  if (matches)
-    compute_lcd_of_matches (match_list, matches, text);
-  else                         /* There were no matches. */
-    {
-      free (match_list);
-      match_list = (char **)NULL;
-    }
-  return (match_list);
-}
-
-/* A completion function for usernames.
-   TEXT contains a partial username preceded by a random
-   character (usually `~').  */
-char *
-rl_username_completion_function (text, state)
-     const char *text;
-     int state;
-{
-#if defined (__WIN32__) || defined (__OPENNT)
-  return (char *)NULL;
-#else /* !__WIN32__ && !__OPENNT) */
-  static char *username = (char *)NULL;
-  static struct passwd *entry;
-  static int namelen, first_char, first_char_loc;
-  char *value;
-
-  if (state == 0)
-    {
-      FREE (username);
-
-      first_char = *text;
-      first_char_loc = first_char == '~';
-
-      username = savestring (&text[first_char_loc]);
-      namelen = strlen (username);
-      setpwent ();
-    }
-
-#if defined (HAVE_GETPWENT)
-  while (entry = getpwent ())
-    {
-      /* Null usernames should result in all users as possible completions. */
-      if (namelen == 0 || (STREQN (username, entry->pw_name, namelen)))
-       break;
-    }
-#endif
-
-  if (entry == 0)
-    {
-#if defined (HAVE_GETPWENT)
-      endpwent ();
-#endif
-      return ((char *)NULL);
-    }
-  else
-    {
-      value = (char *)xmalloc (2 + strlen (entry->pw_name));
-
-      *value = *text;
-
-      strcpy (value + first_char_loc, entry->pw_name);
-
-      if (first_char == '~')
-       rl_filename_completion_desired = 1;
-
-      return (value);
-    }
-#endif /* !__WIN32__ && !__OPENNT */
-}
-
-/* Okay, now we write the entry_function for filename completion.  In the
-   general case.  Note that completion in the shell is a little different
-   because of all the pathnames that must be followed when looking up the
-   completion for a command. */
-char *
-rl_filename_completion_function (text, state)
-     const char *text;
-     int state;
-{
-  static DIR *directory = (DIR *)NULL;
-  static char *filename = (char *)NULL;
-  static char *dirname = (char *)NULL;
-  static char *users_dirname = (char *)NULL;
-  static int filename_len;
-  char *temp;
-  int dirlen;
-  struct dirent *entry;
-
-  /* If we don't have any state, then do some initialization. */
-  if (state == 0)
-    {
-      /* If we were interrupted before closing the directory or reading
-        all of its contents, close it. */
-      if (directory)
-       {
-         closedir (directory);
-         directory = (DIR *)NULL;
-       }
-      FREE (dirname);
-      FREE (filename);
-      FREE (users_dirname);
-
-      filename = savestring (text);
-      if (*text == 0)
-       text = ".";
-      dirname = savestring (text);
-
-      temp = strrchr (dirname, '/');
-
-#if defined (__MSDOS__)
-      /* special hack for //X/... */
-      if (dirname[0] == '/' && dirname[1] == '/' && ISALPHA ((unsigned char)dirname[2]) && dirname[3] == '/')
-        temp = strrchr (dirname + 3, '/');
-#endif
-
-      if (temp)
-       {
-         strcpy (filename, ++temp);
-         *temp = '\0';
-       }
-#if defined (__MSDOS__)
-      /* searches from current directory on the drive */
-      else if (ISALPHA ((unsigned char)dirname[0]) && dirname[1] == ':')
-        {
-          strcpy (filename, dirname + 2);
-          dirname[2] = '\0';
-        }
-#endif
-      else
-       {
-         dirname[0] = '.';
-         dirname[1] = '\0';
-       }
-
-      /* We aren't done yet.  We also support the "~user" syntax. */
-
-      /* Save the version of the directory that the user typed. */
-      users_dirname = savestring (dirname);
-
-      if (*dirname == '~')
-       {
-         temp = tilde_expand (dirname);
-         free (dirname);
-         dirname = temp;
-       }
-
-      if (rl_directory_rewrite_hook)
-       (*rl_directory_rewrite_hook) (&dirname);
-
-      /* The directory completion hook should perform any necessary
-        dequoting. */
-      if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&dirname))
-       {
-         free (users_dirname);
-         users_dirname = savestring (dirname);
-       }
-      else if (rl_completion_found_quote && rl_filename_dequoting_function)
-       {
-         /* delete single and double quotes */
-         temp = (*rl_filename_dequoting_function) (users_dirname, rl_completion_quote_character);
-         free (users_dirname);
-         users_dirname = temp;
-       }
-      directory = opendir (dirname);
-
-      /* Now dequote a non-null filename. */
-      if (filename && *filename && rl_completion_found_quote && rl_filename_dequoting_function)
-       {
-         /* delete single and double quotes */
-         temp = (*rl_filename_dequoting_function) (filename, rl_completion_quote_character);
-         free (filename);
-         filename = temp;
-       }
-      filename_len = strlen (filename);
-
-      rl_filename_completion_desired = 1;
-    }
-
-  /* At this point we should entertain the possibility of hacking wildcarded
-     filenames, like /usr/man/man<WILD>/te<TAB>.  If the directory name
-     contains globbing characters, then build an array of directories, and
-     then map over that list while completing. */
-  /* *** UNIMPLEMENTED *** */
-
-  /* Now that we have some state, we can read the directory. */
-
-  entry = (struct dirent *)NULL;
-  while (directory && (entry = readdir (directory)))
-    {
-      /* Special case for no filename.  If the user has disabled the
-         `match-hidden-files' variable, skip filenames beginning with `.'.
-        All other entries except "." and ".." match. */
-      if (filename_len == 0)
-       {
-         if (_rl_match_hidden_files == 0 && HIDDEN_FILE (entry->d_name))
-           continue;
-
-         if (entry->d_name[0] != '.' ||
-              (entry->d_name[1] &&
-                (entry->d_name[1] != '.' || entry->d_name[2])))
-           break;
-       }
-      else
-       {
-         /* Otherwise, if these match up to the length of filename, then
-            it is a match. */
-         if (_rl_completion_case_fold)
-           {
-             if ((_rl_to_lower (entry->d_name[0]) == _rl_to_lower (filename[0])) &&
-                 (((int)D_NAMLEN (entry)) >= filename_len) &&
-                 (_rl_strnicmp (filename, entry->d_name, filename_len) == 0))
-               break;
-           }
-         else
-           {
-             if ((entry->d_name[0] == filename[0]) &&
-                 (((int)D_NAMLEN (entry)) >= filename_len) &&
-                 (strncmp (filename, entry->d_name, filename_len) == 0))
-               break;
-           }
-       }
-    }
-
-  if (entry == 0)
-    {
-      if (directory)
-       {
-         closedir (directory);
-         directory = (DIR *)NULL;
-       }
-      if (dirname)
-       {
-         free (dirname);
-         dirname = (char *)NULL;
-       }
-      if (filename)
-       {
-         free (filename);
-         filename = (char *)NULL;
-       }
-      if (users_dirname)
-       {
-         free (users_dirname);
-         users_dirname = (char *)NULL;
-       }
-
-      return (char *)NULL;
-    }
-  else
-    {
-      /* dirname && (strcmp (dirname, ".") != 0) */
-      if (dirname && (dirname[0] != '.' || dirname[1]))
-       {
-         if (rl_complete_with_tilde_expansion && *users_dirname == '~')
-           {
-             dirlen = strlen (dirname);
-             temp = (char *)xmalloc (2 + dirlen + D_NAMLEN (entry));
-             strcpy (temp, dirname);
-             /* Canonicalization cuts off any final slash present.  We
-                may need to add it back. */
-             if (dirname[dirlen - 1] != '/')
-               {
-                 temp[dirlen++] = '/';
-                 temp[dirlen] = '\0';
-               }
-           }
-         else
-           {
-             dirlen = strlen (users_dirname);
-             temp = (char *)xmalloc (2 + dirlen + D_NAMLEN (entry));
-             strcpy (temp, users_dirname);
-             /* Make sure that temp has a trailing slash here. */
-             if (users_dirname[dirlen - 1] != '/')
-               temp[dirlen++] = '/';
-           }
-
-         strcpy (temp + dirlen, entry->d_name);
-       }
-      else
-       temp = savestring (entry->d_name);
-
-      return (temp);
-    }
-}
-
-/* An initial implementation of a menu completion function a la tcsh.  The
-   first time (if the last readline command was not rl_menu_complete), we
-   generate the list of matches.  This code is very similar to the code in
-   rl_complete_internal -- there should be a way to combine the two.  Then,
-   for each item in the list of matches, we insert the match in an undoable
-   fashion, with the appropriate character appended (this happens on the
-   second and subsequent consecutive calls to rl_menu_complete).  When we
-   hit the end of the match list, we restore the original unmatched text,
-   ring the bell, and reset the counter to zero. */
-int
-rl_old_menu_complete (count, invoking_key)
-     int count, invoking_key;
-{
-  rl_compentry_func_t *our_func;
-  int matching_filenames, found_quote;
-
-  static char *orig_text;
-  static char **matches = (char **)0;
-  static int match_list_index = 0;
-  static int match_list_size = 0;
-  static int orig_start, orig_end;
-  static char quote_char;
-  static int delimiter;
-
-  /* The first time through, we generate the list of matches and set things
-     up to insert them. */
-  if (rl_last_func != rl_menu_complete)
-    {
-      /* Clean up from previous call, if any. */
-      FREE (orig_text);
-      if (matches)
-       _rl_free_match_list (matches);
-
-      match_list_index = match_list_size = 0;
-      matches = (char **)NULL;
-
-      rl_completion_invoking_key = invoking_key;
-
-      /* Only the completion entry function can change these. */
-      set_completion_defaults ('%');
-
-      our_func = rl_menu_completion_entry_function;
-      if (our_func == 0)
-       our_func = rl_completion_entry_function
-                       ? rl_completion_entry_function
-                       : rl_filename_completion_function;
-
-      /* We now look backwards for the start of a filename/variable word. */
-      orig_end = rl_point;
-      found_quote = delimiter = 0;
-      quote_char = '\0';
-
-      if (rl_point)
-       /* This (possibly) changes rl_point.  If it returns a non-zero char,
-          we know we have an open quote. */
-       quote_char = _rl_find_completion_word (&found_quote, &delimiter);
-
-      orig_start = rl_point;
-      rl_point = orig_end;
-
-      orig_text = rl_copy_text (orig_start, orig_end);
-      matches = gen_completion_matches (orig_text, orig_start, orig_end,
-                                       our_func, found_quote, quote_char);
-
-      /* If we are matching filenames, the attempted completion function will
-        have set rl_filename_completion_desired to a non-zero value.  The basic
-        rl_filename_completion_function does this. */
-      matching_filenames = rl_filename_completion_desired;
-
-      if (matches == 0 || postprocess_matches (&matches, matching_filenames) == 0)
-       {
-         rl_ding ();
-         FREE (matches);
-         matches = (char **)0;
-         FREE (orig_text);
-         orig_text = (char *)0;
-         completion_changed_buffer = 0;
-          return (0);
-       }
-
-      for (match_list_size = 0; matches[match_list_size]; match_list_size++)
-        ;
-      /* matches[0] is lcd if match_list_size > 1, but the circular buffer
-        code below should take care of it. */
-
-      if (match_list_size > 1 && _rl_complete_show_all)
-       display_matches (matches);
-    }
-
-  /* Now we have the list of matches.  Replace the text between
-     rl_line_buffer[orig_start] and rl_line_buffer[rl_point] with
-     matches[match_list_index], and add any necessary closing char. */
-
-  if (matches == 0 || match_list_size == 0) 
-    {
-      rl_ding ();
-      FREE (matches);
-      matches = (char **)0;
-      completion_changed_buffer = 0;
-      return (0);
-    }
-
-  match_list_index += count;
-  if (match_list_index < 0)
-    match_list_index += match_list_size;
-  else
-    match_list_index %= match_list_size;
-
-  if (match_list_index == 0 && match_list_size > 1)
-    {
-      rl_ding ();
-      insert_match (orig_text, orig_start, MULT_MATCH, &quote_char);
-    }
-  else
-    {
-      insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, &quote_char);
-      append_to_match (matches[match_list_index], delimiter, quote_char,
-                      strcmp (orig_text, matches[match_list_index]));
-    }
-
-  completion_changed_buffer = 1;
-  return (0);
-}
-
-int
-rl_menu_complete (count, ignore)
-     int count, ignore;
-{
-  rl_compentry_func_t *our_func;
-  int matching_filenames, found_quote;
-
-  static char *orig_text;
-  static char **matches = (char **)0;
-  static int match_list_index = 0;
-  static int match_list_size = 0;
-  static int nontrivial_lcd = 0;
-  static int full_completion = 0;      /* set to 1 if menu completion should reinitialize on next call */
-  static int orig_start, orig_end;
-  static char quote_char;
-  static int delimiter;
-
-  /* The first time through, we generate the list of matches and set things
-     up to insert them. */
-  if (rl_last_func != rl_menu_complete || full_completion)
-    {
-      /* Clean up from previous call, if any. */
-      FREE (orig_text);
-      if (matches)
-       _rl_free_match_list (matches);
-
-      match_list_index = match_list_size = 0;
-      matches = (char **)NULL;
-
-      full_completion = 0;
-
-      /* Only the completion entry function can change these. */
-      set_completion_defaults ('%');
-
-      our_func = rl_menu_completion_entry_function;
-      if (our_func == 0)
-       our_func = rl_completion_entry_function
-                       ? rl_completion_entry_function
-                       : rl_filename_completion_function;
-
-      /* We now look backwards for the start of a filename/variable word. */
-      orig_end = rl_point;
-      found_quote = delimiter = 0;
-      quote_char = '\0';
-
-      if (rl_point)
-       /* This (possibly) changes rl_point.  If it returns a non-zero char,
-          we know we have an open quote. */
-       quote_char = _rl_find_completion_word (&found_quote, &delimiter);
-
-      orig_start = rl_point;
-      rl_point = orig_end;
-
-      orig_text = rl_copy_text (orig_start, orig_end);
-      matches = gen_completion_matches (orig_text, orig_start, orig_end,
-                                       our_func, found_quote, quote_char);
-
-      nontrivial_lcd = matches && strcmp (orig_text, matches[0]) != 0;
-
-      /* If we are matching filenames, the attempted completion function will
-        have set rl_filename_completion_desired to a non-zero value.  The basic
-        rl_filename_completion_function does this. */
-      matching_filenames = rl_filename_completion_desired;
-
-      if (matches == 0 || postprocess_matches (&matches, matching_filenames) == 0)
-       {
-         rl_ding ();
-         FREE (matches);
-         matches = (char **)0;
-         FREE (orig_text);
-         orig_text = (char *)0;
-         completion_changed_buffer = 0;
-          return (0);
-       }
-
-      for (match_list_size = 0; matches[match_list_size]; match_list_size++)
-        ;
-
-      if (match_list_size == 0) 
-       {
-         rl_ding ();
-         FREE (matches);
-         matches = (char **)0;
-         match_list_index = 0;
-         completion_changed_buffer = 0;
-         return (0);
-        }
-
-      /* matches[0] is lcd if match_list_size > 1, but the circular buffer
-        code below should take care of it. */
-      if (*matches[0])
-       {
-         insert_match (matches[0], orig_start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
-         orig_end = orig_start + strlen (matches[0]);
-         completion_changed_buffer = STREQ (orig_text, matches[0]) == 0;
-       }
-
-      if (match_list_size > 1 && _rl_complete_show_all)
-       {
-         display_matches (matches);
-         /* If there are so many matches that the user has to be asked
-            whether or not he wants to see the matches, menu completion
-            is unwieldy. */
-         if (rl_completion_query_items > 0 && match_list_size >= rl_completion_query_items)
-           {
-             rl_ding ();
-             FREE (matches);
-             matches = (char **)0;
-             full_completion = 1;
-             return (0);
-           }
-       }
-      else if (match_list_size <= 1)
-       {
-         append_to_match (matches[0], delimiter, quote_char, nontrivial_lcd);
-         full_completion = 1;
-         return (0);
-       }
-    }
-
-  /* Now we have the list of matches.  Replace the text between
-     rl_line_buffer[orig_start] and rl_line_buffer[rl_point] with
-     matches[match_list_index], and add any necessary closing char. */
-
-  if (matches == 0 || match_list_size == 0) 
-    {
-      rl_ding ();
-      FREE (matches);
-      matches = (char **)0;
-      completion_changed_buffer = 0;
-      return (0);
-    }
-
-  match_list_index += count;
-  if (match_list_index < 0)
-    match_list_index += match_list_size;
-  else
-    match_list_index %= match_list_size;
-
-  if (match_list_index == 0 && match_list_size > 1)
-    {
-      rl_ding ();
-      insert_match (matches[0], orig_start, MULT_MATCH, &quote_char);
-    }
-  else
-    {
-      insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, &quote_char);
-      append_to_match (matches[match_list_index], delimiter, quote_char,
-                      strcmp (orig_text, matches[match_list_index]));
-    }
-
-  completion_changed_buffer = 1;
-  return (0);
-}
diff --git a/lib/readline/complete.c~ b/lib/readline/complete.c~
deleted file mode 100644 (file)
index d9af5cf..0000000
+++ /dev/null
@@ -1,2530 +0,0 @@
-/* complete.c -- filename completion for readline. */
-
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
-
-   This file is part of the GNU Readline Library (Readline), a library
-   for reading lines of text with interactive input and history editing.
-
-   Readline is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   Readline is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#define READLINE_LIBRARY
-
-#if defined (HAVE_CONFIG_H)
-#  include <config.h>
-#endif
-
-#include <sys/types.h>
-#include <fcntl.h>
-#if defined (HAVE_SYS_FILE_H)
-#  include <sys/file.h>
-#endif
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#if defined (HAVE_STDLIB_H)
-#  include <stdlib.h>
-#else
-#  include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#include <stdio.h>
-
-#include <errno.h>
-#if !defined (errno)
-extern int errno;
-#endif /* !errno */
-
-#if defined (HAVE_PWD_H)
-#include <pwd.h>
-#endif
-
-#include "posixdir.h"
-#include "posixstat.h"
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-#include "rlmbutil.h"
-
-/* Some standard library routines. */
-#include "readline.h"
-#include "xmalloc.h"
-#include "rlprivate.h"
-
-#ifdef __STDC__
-typedef int QSFUNC (const void *, const void *);
-#else
-typedef int QSFUNC ();
-#endif
-
-#ifdef HAVE_LSTAT
-#  define LSTAT lstat
-#else
-#  define LSTAT stat
-#endif
-
-/* Unix version of a hidden file.  Could be different on other systems. */
-#define HIDDEN_FILE(fname)     ((fname)[0] == '.')
-
-/* Most systems don't declare getpwent in <pwd.h> if _POSIX_SOURCE is
-   defined. */
-#if defined (HAVE_GETPWENT) && (!defined (HAVE_GETPW_DECLS) || defined (_POSIX_SOURCE))
-extern struct passwd *getpwent PARAMS((void));
-#endif /* HAVE_GETPWENT && (!HAVE_GETPW_DECLS || _POSIX_SOURCE) */
-
-/* If non-zero, then this is the address of a function to call when
-   completing a word would normally display the list of possible matches.
-   This function is called instead of actually doing the display.
-   It takes three arguments: (char **matches, int num_matches, int max_length)
-   where MATCHES is the array of strings that matched, NUM_MATCHES is the
-   number of strings in that array, and MAX_LENGTH is the length of the
-   longest string in that array. */
-rl_compdisp_func_t *rl_completion_display_matches_hook = (rl_compdisp_func_t *)NULL;
-
-#if defined (VISIBLE_STATS)
-#  if !defined (X_OK)
-#    define X_OK 1
-#  endif
-static int stat_char PARAMS((char *));
-#endif
-
-static int path_isdir PARAMS((const char *));
-
-static char *rl_quote_filename PARAMS((char *, int, char *));
-
-static void set_completion_defaults PARAMS((int));
-static int get_y_or_n PARAMS((int));
-static int _rl_internal_pager PARAMS((int));
-static char *printable_part PARAMS((char *));
-static int fnwidth PARAMS((const char *));
-static int fnprint PARAMS((const char *, int));
-static int print_filename PARAMS((char *, char *, int));
-
-static char **gen_completion_matches PARAMS((char *, int, int, rl_compentry_func_t *, int, int));
-
-static char **remove_duplicate_matches PARAMS((char **));
-static void insert_match PARAMS((char *, int, int, char *));
-static int append_to_match PARAMS((char *, int, int, int));
-static void insert_all_matches PARAMS((char **, int, char *));
-static void display_matches PARAMS((char **));
-static int compute_lcd_of_matches PARAMS((char **, int, const char *));
-static int postprocess_matches PARAMS((char ***, int));
-
-static char *make_quoted_replacement PARAMS((char *, int, char *));
-
-/* **************************************************************** */
-/*                                                                 */
-/*     Completion matching, from readline's point of view.         */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Variables known only to the readline library. */
-
-/* If non-zero, non-unique completions always show the list of matches. */
-int _rl_complete_show_all = 0;
-
-/* If non-zero, non-unique completions show the list of matches, unless it
-   is not possible to do partial completion and modify the line. */
-int _rl_complete_show_unmodified = 0;
-
-/* If non-zero, completed directory names have a slash appended. */
-int _rl_complete_mark_directories = 1;
-
-/* If non-zero, the symlinked directory completion behavior introduced in
-   readline-4.2a is disabled, and symlinks that point to directories have
-   a slash appended (subject to the value of _rl_complete_mark_directories).
-   This is user-settable via the mark-symlinked-directories variable. */
-int _rl_complete_mark_symlink_dirs = 0;
-
-/* If non-zero, completions are printed horizontally in alphabetical order,
-   like `ls -x'. */
-int _rl_print_completions_horizontally;
-
-/* Non-zero means that case is not significant in filename completion. */
-#if defined (__MSDOS__) && !defined (__DJGPP__)
-int _rl_completion_case_fold = 1;
-#else
-int _rl_completion_case_fold;
-#endif
-
-/* If non-zero, don't match hidden files (filenames beginning with a `.' on
-   Unix) when doing filename completion. */
-int _rl_match_hidden_files = 1;
-
-/* Length in characters of a common prefix replaced with an ellipsis (`...')
-   when displaying completion matches.  Matches whose printable portion has
-   more than this number of displaying characters in common will have the common
-   display prefix replaced with an ellipsis. */
-int _rl_completion_prefix_display_length = 0;
-
-/* Global variables available to applications using readline. */
-
-#if defined (VISIBLE_STATS)
-/* Non-zero means add an additional character to each filename displayed
-   during listing completion iff rl_filename_completion_desired which helps
-   to indicate the type of file being listed. */
-int rl_visible_stats = 0;
-#endif /* VISIBLE_STATS */
-
-/* If non-zero, when completing in the middle of a word, don't insert
-   characters from the match that match characters following point in
-   the word.  This means, for instance, completing when the cursor is
-   after the `e' in `Makefile' won't result in `Makefilefile'. */
-int _rl_skip_completed_text = 0;
-
-/* If non-zero, then this is the address of a function to call when
-   completing on a directory name.  The function is called with
-   the address of a string (the current directory name) as an arg. */
-rl_icppfunc_t *rl_directory_completion_hook = (rl_icppfunc_t *)NULL;
-
-rl_icppfunc_t *rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL;
-
-/* If non-zero, this is the address of a function to call when reading
-   directory entries from the filesystem for completion and comparing
-   them to the partial word to be completed.  The function should
-   either return its first argument (if no conversion takes place) or
-   newly-allocated memory.  This can, for instance, convert filenames
-   between character sets for comparison against what's typed at the
-   keyboard.  The returned value is what is added to the list of
-   matches.  The second argument is the length of the filename to be
-   converted. */
-rl_dequote_func_t *rl_filename_rewrite_hook = (rl_dequote_func_t *)NULL;
-
-/* Non-zero means readline completion functions perform tilde expansion. */
-int rl_complete_with_tilde_expansion = 0;
-
-/* Pointer to the generator function for completion_matches ().
-   NULL means to use rl_filename_completion_function (), the default filename
-   completer. */
-rl_compentry_func_t *rl_completion_entry_function = (rl_compentry_func_t *)NULL;
-
-/* Pointer to generator function for rl_menu_complete ().  NULL means to use
-   *rl_completion_entry_function (see above). */
-rl_compentry_func_t *rl_menu_completion_entry_function = (rl_compentry_func_t *)NULL;
-
-/* Pointer to alternative function to create matches.
-   Function is called with TEXT, START, and END.
-   START and END are indices in RL_LINE_BUFFER saying what the boundaries
-   of TEXT are.
-   If this function exists and returns NULL then call the value of
-   rl_completion_entry_function to try to match, otherwise use the
-   array of strings returned. */
-rl_completion_func_t *rl_attempted_completion_function = (rl_completion_func_t *)NULL;
-
-/* Non-zero means to suppress normal filename completion after the
-   user-specified completion function has been called. */
-int rl_attempted_completion_over = 0;
-
-/* Set to a character indicating the type of completion being performed
-   by rl_complete_internal, available for use by application completion
-   functions. */
-int rl_completion_type = 0;
-
-/* Up to this many items will be displayed in response to a
-   possible-completions call.  After that, we ask the user if
-   she is sure she wants to see them all.  A negative value means
-   don't ask. */
-int rl_completion_query_items = 100;
-
-int _rl_page_completions = 1;
-
-/* The basic list of characters that signal a break between words for the
-   completer routine.  The contents of this variable is what breaks words
-   in the shell, i.e. " \t\n\"\\'`@$><=" */
-const char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{("; /* }) */
-
-/* List of basic quoting characters. */
-const char *rl_basic_quote_characters = "\"'";
-
-/* The list of characters that signal a break between words for
-   rl_complete_internal.  The default list is the contents of
-   rl_basic_word_break_characters.  */
-/*const*/ char *rl_completer_word_break_characters = (/*const*/ char *)NULL;
-
-/* Hook function to allow an application to set the completion word
-   break characters before readline breaks up the line.  Allows
-   position-dependent word break characters. */
-rl_cpvfunc_t *rl_completion_word_break_hook = (rl_cpvfunc_t *)NULL;
-
-/* List of characters which can be used to quote a substring of the line.
-   Completion occurs on the entire substring, and within the substring
-   rl_completer_word_break_characters are treated as any other character,
-   unless they also appear within this list. */
-const char *rl_completer_quote_characters = (const char *)NULL;
-
-/* List of characters that should be quoted in filenames by the completer. */
-const char *rl_filename_quote_characters = (const char *)NULL;
-
-/* List of characters that are word break characters, but should be left
-   in TEXT when it is passed to the completion function.  The shell uses
-   this to help determine what kind of completing to do. */
-const char *rl_special_prefixes = (const char *)NULL;
-
-/* If non-zero, then disallow duplicates in the matches. */
-int rl_ignore_completion_duplicates = 1;
-
-/* Non-zero means that the results of the matches are to be treated
-   as filenames.  This is ALWAYS zero on entry, and can only be changed
-   within a completion entry finder function. */
-int rl_filename_completion_desired = 0;
-
-/* Non-zero means that the results of the matches are to be quoted using
-   double quotes (or an application-specific quoting mechanism) if the
-   filename contains any characters in rl_filename_quote_chars.  This is
-   ALWAYS non-zero on entry, and can only be changed within a completion
-   entry finder function. */
-int rl_filename_quoting_desired = 1;
-
-/* This function, if defined, is called by the completer when real
-   filename completion is done, after all the matching names have been
-   generated. It is passed a (char**) known as matches in the code below.
-   It consists of a NULL-terminated array of pointers to potential
-   matching strings.  The 1st element (matches[0]) is the maximal
-   substring that is common to all matches. This function can re-arrange
-   the list of matches as required, but all elements of the array must be
-   free()'d if they are deleted. The main intent of this function is
-   to implement FIGNORE a la SunOS csh. */
-rl_compignore_func_t *rl_ignore_some_completions_function = (rl_compignore_func_t *)NULL;
-
-/* Set to a function to quote a filename in an application-specific fashion.
-   Called with the text to quote, the type of match found (single or multiple)
-   and a pointer to the quoting character to be used, which the function can
-   reset if desired. */
-rl_quote_func_t *rl_filename_quoting_function = rl_quote_filename;
-         
-/* Function to call to remove quoting characters from a filename.  Called
-   before completion is attempted, so the embedded quotes do not interfere
-   with matching names in the file system.  Readline doesn't do anything
-   with this; it's set only by applications. */
-rl_dequote_func_t *rl_filename_dequoting_function = (rl_dequote_func_t *)NULL;
-
-/* Function to call to decide whether or not a word break character is
-   quoted.  If a character is quoted, it does not break words for the
-   completer. */
-rl_linebuf_func_t *rl_char_is_quoted_p = (rl_linebuf_func_t *)NULL;
-
-/* If non-zero, the completion functions don't append anything except a
-   possible closing quote.  This is set to 0 by rl_complete_internal and
-   may be changed by an application-specific completion function. */
-int rl_completion_suppress_append = 0;
-
-/* Character appended to completed words when at the end of the line.  The
-   default is a space. */
-int rl_completion_append_character = ' ';
-
-/* If non-zero, the completion functions don't append any closing quote.
-   This is set to 0 by rl_complete_internal and may be changed by an
-   application-specific completion function. */
-int rl_completion_suppress_quote = 0;
-
-/* Set to any quote character readline thinks it finds before any application
-   completion function is called. */
-int rl_completion_quote_character;
-
-/* Set to a non-zero value if readline found quoting anywhere in the word to
-   be completed; set before any application completion function is called. */
-int rl_completion_found_quote;
-
-/* If non-zero, a slash will be appended to completed filenames that are
-   symbolic links to directory names, subject to the value of the
-   mark-directories variable (which is user-settable).  This exists so
-   that application completion functions can override the user's preference
-   (set via the mark-symlinked-directories variable) if appropriate.
-   It's set to the value of _rl_complete_mark_symlink_dirs in
-   rl_complete_internal before any application-specific completion
-   function is called, so without that function doing anything, the user's
-   preferences are honored. */
-int rl_completion_mark_symlink_dirs;
-
-/* If non-zero, inhibit completion (temporarily). */
-int rl_inhibit_completion;
-
-/* Set to the last key used to invoke one of the completion functions */
-int rl_completion_invoking_key;
-
-/* If non-zero, sort the completion matches.  On by default. */
-int rl_sort_completion_matches = 1;
-
-/* Variables local to this file. */
-
-/* Local variable states what happened during the last completion attempt. */
-static int completion_changed_buffer;
-
-/* The result of the query to the user about displaying completion matches */
-static int completion_y_or_n;
-
-/*************************************/
-/*                                  */
-/*    Bindable completion functions  */
-/*                                  */
-/*************************************/
-
-/* Complete the word at or before point.  You have supplied the function
-   that does the initial simple matching selection algorithm (see
-   rl_completion_matches ()).  The default is to do filename completion. */
-int
-rl_complete (ignore, invoking_key)
-     int ignore, invoking_key;
-{
-  rl_completion_invoking_key = invoking_key;
-
-  if (rl_inhibit_completion)
-    return (_rl_insert_char (ignore, invoking_key));
-  else if (rl_last_func == rl_complete && !completion_changed_buffer)
-    return (rl_complete_internal ('?'));
-  else if (_rl_complete_show_all)
-    return (rl_complete_internal ('!'));
-  else if (_rl_complete_show_unmodified)
-    return (rl_complete_internal ('@'));
-  else
-    return (rl_complete_internal (TAB));
-}
-
-/* List the possible completions.  See description of rl_complete (). */
-int
-rl_possible_completions (ignore, invoking_key)
-     int ignore, invoking_key;
-{
-  rl_completion_invoking_key = invoking_key;
-  return (rl_complete_internal ('?'));
-}
-
-int
-rl_insert_completions (ignore, invoking_key)
-     int ignore, invoking_key;
-{
-  rl_completion_invoking_key = invoking_key;
-  return (rl_complete_internal ('*'));
-}
-
-/* Return the correct value to pass to rl_complete_internal performing
-   the same tests as rl_complete.  This allows consecutive calls to an
-   application's completion function to list possible completions and for
-   an application-specific completion function to honor the
-   show-all-if-ambiguous readline variable. */
-int
-rl_completion_mode (cfunc)
-     rl_command_func_t *cfunc;
-{
-  if (rl_last_func == cfunc && !completion_changed_buffer)
-    return '?';
-  else if (_rl_complete_show_all)
-    return '!';
-  else if (_rl_complete_show_unmodified)
-    return '@';
-  else
-    return TAB;
-}
-
-/************************************/
-/*                                 */
-/*    Completion utility functions  */
-/*                                 */
-/************************************/
-
-/* Reset readline state on a signal or other event. */
-void
-_rl_reset_completion_state ()
-{
-  rl_completion_found_quote = 0;
-  rl_completion_quote_character = 0;
-}
-
-/* Set default values for readline word completion.  These are the variables
-   that application completion functions can change or inspect. */
-static void
-set_completion_defaults (what_to_do)
-     int what_to_do;
-{
-  /* Only the completion entry function can change these. */
-  rl_filename_completion_desired = 0;
-  rl_filename_quoting_desired = 1;
-  rl_completion_type = what_to_do;
-  rl_completion_suppress_append = rl_completion_suppress_quote = 0;
-  rl_completion_append_character = ' ';
-
-  /* The completion entry function may optionally change this. */
-  rl_completion_mark_symlink_dirs = _rl_complete_mark_symlink_dirs;
-}
-
-/* The user must press "y" or "n". Non-zero return means "y" pressed. */
-static int
-get_y_or_n (for_pager)
-     int for_pager;
-{
-  int c;
-
-  for (;;)
-    {
-      RL_SETSTATE(RL_STATE_MOREINPUT);
-      c = rl_read_key ();
-      RL_UNSETSTATE(RL_STATE_MOREINPUT);
-
-      if (c == 'y' || c == 'Y' || c == ' ')
-       return (1);
-      if (c == 'n' || c == 'N' || c == RUBOUT)
-       return (0);
-      if (c == ABORT_CHAR || c < 0)
-       _rl_abort_internal ();
-      if (for_pager && (c == NEWLINE || c == RETURN))
-       return (2);
-      if (for_pager && (c == 'q' || c == 'Q'))
-       return (0);
-      rl_ding ();
-    }
-}
-
-static int
-_rl_internal_pager (lines)
-     int lines;
-{
-  int i;
-
-  fprintf (rl_outstream, "--More--");
-  fflush (rl_outstream);
-  i = get_y_or_n (1);
-  _rl_erase_entire_line ();
-  if (i == 0)
-    return -1;
-  else if (i == 2)
-    return (lines - 1);
-  else
-    return 0;
-}
-
-static int
-path_isdir (filename)
-     const char *filename;
-{
-  struct stat finfo;
-
-  return (stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode));
-}
-
-#if defined (VISIBLE_STATS)
-/* Return the character which best describes FILENAME.
-     `@' for symbolic links
-     `/' for directories
-     `*' for executables
-     `=' for sockets
-     `|' for FIFOs
-     `%' for character special devices
-     `#' for block special devices */
-static int
-stat_char (filename)
-     char *filename;
-{
-  struct stat finfo;
-  int character, r;
-
-  /* Short-circuit a //server on cygwin, since that will always behave as
-     a directory. */
-#if __CYGWIN__
-  if (filename[0] == '/' && filename[1] == '/' && strchr (filename+2, '/') == 0)
-    return '/';
-#endif
-
-#if defined (HAVE_LSTAT) && defined (S_ISLNK)
-  r = lstat (filename, &finfo);
-#else
-  r = stat (filename, &finfo);
-#endif
-
-  if (r == -1)
-    return (0);
-
-  character = 0;
-  if (S_ISDIR (finfo.st_mode))
-    character = '/';
-#if defined (S_ISCHR)
-  else if (S_ISCHR (finfo.st_mode))
-    character = '%';
-#endif /* S_ISCHR */
-#if defined (S_ISBLK)
-  else if (S_ISBLK (finfo.st_mode))
-    character = '#';
-#endif /* S_ISBLK */
-#if defined (S_ISLNK)
-  else if (S_ISLNK (finfo.st_mode))
-    character = '@';
-#endif /* S_ISLNK */
-#if defined (S_ISSOCK)
-  else if (S_ISSOCK (finfo.st_mode))
-    character = '=';
-#endif /* S_ISSOCK */
-#if defined (S_ISFIFO)
-  else if (S_ISFIFO (finfo.st_mode))
-    character = '|';
-#endif
-  else if (S_ISREG (finfo.st_mode))
-    {
-      if (access (filename, X_OK) == 0)
-       character = '*';
-    }
-  return (character);
-}
-#endif /* VISIBLE_STATS */
-
-/* Return the portion of PATHNAME that should be output when listing
-   possible completions.  If we are hacking filename completion, we
-   are only interested in the basename, the portion following the
-   final slash.  Otherwise, we return what we were passed.  Since
-   printing empty strings is not very informative, if we're doing
-   filename completion, and the basename is the empty string, we look
-   for the previous slash and return the portion following that.  If
-   there's no previous slash, we just return what we were passed. */
-static char *
-printable_part (pathname)
-      char *pathname;
-{
-  char *temp, *x;
-
-  if (rl_filename_completion_desired == 0)     /* don't need to do anything */
-    return (pathname);
-
-  temp = strrchr (pathname, '/');
-#if defined (__MSDOS__)
-  if (temp == 0 && ISALPHA ((unsigned char)pathname[0]) && pathname[1] == ':')
-    temp = pathname + 1;
-#endif
-
-  if (temp == 0 || *temp == '\0')
-    return (pathname);
-  /* If the basename is NULL, we might have a pathname like '/usr/src/'.
-     Look for a previous slash and, if one is found, return the portion
-     following that slash.  If there's no previous slash, just return the
-     pathname we were passed. */
-  else if (temp[1] == '\0')
-    {
-      for (x = temp - 1; x > pathname; x--)
-        if (*x == '/')
-          break;
-      return ((*x == '/') ? x + 1 : pathname);
-    }
-  else
-    return ++temp;
-}
-
-/* Compute width of STRING when displayed on screen by print_filename */
-static int
-fnwidth (string)
-     const char *string;
-{
-  int width, pos;
-#if defined (HANDLE_MULTIBYTE)
-  mbstate_t ps;
-  int left, w;
-  size_t clen;
-  wchar_t wc;
-
-  left = strlen (string) + 1;
-  memset (&ps, 0, sizeof (mbstate_t));
-#endif
-
-  width = pos = 0;
-  while (string[pos])
-    {
-      if (CTRL_CHAR (string[pos]) || string[pos] == RUBOUT)
-       {
-         width += 2;
-         pos++;
-       }
-      else
-       {
-#if defined (HANDLE_MULTIBYTE)
-         clen = mbrtowc (&wc, string + pos, left - pos, &ps);
-         if (MB_INVALIDCH (clen))
-           {
-             width++;
-             pos++;
-             memset (&ps, 0, sizeof (mbstate_t));
-           }
-         else if (MB_NULLWCH (clen))
-           break;
-         else
-           {
-             pos += clen;
-             w = wcwidth (wc);
-             width += (w >= 0) ? w : 1;
-           }
-#else
-         width++;
-         pos++;
-#endif
-       }
-    }
-
-  return width;
-}
-
-#define ELLIPSIS_LEN   3
-
-static int
-fnprint (to_print, prefix_bytes)
-     const char *to_print;
-     int prefix_bytes;
-{
-  int printed_len, w;
-  const char *s;
-#if defined (HANDLE_MULTIBYTE)
-  mbstate_t ps;
-  const char *end;
-  size_t tlen;
-  int width;
-  wchar_t wc;
-
-  end = to_print + strlen (to_print) + 1;
-  memset (&ps, 0, sizeof (mbstate_t));
-#endif
-
-  printed_len = 0;
-
-  /* Don't print only the ellipsis if the common prefix is one of the
-     possible completions */
-  if (to_print[prefix_bytes] == '\0')
-    prefix_bytes = 0;
-
-  if (prefix_bytes)
-    {
-      char ellipsis;
-
-      ellipsis = (to_print[prefix_bytes] == '.') ? '_' : '.';
-      for (w = 0; w < ELLIPSIS_LEN; w++)
-       putc (ellipsis, rl_outstream);
-      printed_len = ELLIPSIS_LEN;
-    }
-
-  s = to_print + prefix_bytes;
-  while (*s)
-    {
-      if (CTRL_CHAR (*s))
-        {
-          putc ('^', rl_outstream);
-          putc (UNCTRL (*s), rl_outstream);
-          printed_len += 2;
-          s++;
-#if defined (HANDLE_MULTIBYTE)
-         memset (&ps, 0, sizeof (mbstate_t));
-#endif
-        }
-      else if (*s == RUBOUT)
-       {
-         putc ('^', rl_outstream);
-         putc ('?', rl_outstream);
-         printed_len += 2;
-         s++;
-#if defined (HANDLE_MULTIBYTE)
-         memset (&ps, 0, sizeof (mbstate_t));
-#endif
-       }
-      else
-       {
-#if defined (HANDLE_MULTIBYTE)
-         tlen = mbrtowc (&wc, s, end - s, &ps);
-         if (MB_INVALIDCH (tlen))
-           {
-             tlen = 1;
-             width = 1;
-             memset (&ps, 0, sizeof (mbstate_t));
-           }
-         else if (MB_NULLWCH (tlen))
-           break;
-         else
-           {
-             w = wcwidth (wc);
-             width = (w >= 0) ? w : 1;
-           }
-         fwrite (s, 1, tlen, rl_outstream);
-         s += tlen;
-         printed_len += width;
-#else
-         putc (*s, rl_outstream);
-         s++;
-         printed_len++;
-#endif
-       }
-    }
-
-  return printed_len;
-}
-
-/* Output TO_PRINT to rl_outstream.  If VISIBLE_STATS is defined and we
-   are using it, check for and output a single character for `special'
-   filenames.  Return the number of characters we output. */
-
-static int
-print_filename (to_print, full_pathname, prefix_bytes)
-     char *to_print, *full_pathname;
-     int prefix_bytes;
-{
-  int printed_len, extension_char, slen, tlen;
-  char *s, c, *new_full_pathname, *dn;
-
-  extension_char = 0;
-  printed_len = fnprint (to_print, prefix_bytes);
-
-#if defined (VISIBLE_STATS)
- if (rl_filename_completion_desired && (rl_visible_stats || _rl_complete_mark_directories))
-#else
- if (rl_filename_completion_desired && _rl_complete_mark_directories)
-#endif
-    {
-      /* If to_print != full_pathname, to_print is the basename of the
-        path passed.  In this case, we try to expand the directory
-        name before checking for the stat character. */
-      if (to_print != full_pathname)
-       {
-         /* Terminate the directory name. */
-         c = to_print[-1];
-         to_print[-1] = '\0';
-
-         /* If setting the last slash in full_pathname to a NUL results in
-            full_pathname being the empty string, we are trying to complete
-            files in the root directory.  If we pass a null string to the
-            bash directory completion hook, for example, it will expand it
-            to the current directory.  We just want the `/'. */
-         if (full_pathname == 0 || *full_pathname == 0)
-           dn = "/";
-         else if (full_pathname[0] != '/')
-           dn = full_pathname;
-         else if (full_pathname[1] == 0)
-           dn = "//";          /* restore trailing slash to `//' */
-         else if (full_pathname[1] == '/' && full_pathname[2] == 0)
-           dn = "/";           /* don't turn /// into // */
-         else
-           dn = full_pathname;
-         s = tilde_expand (dn);
-         if (rl_directory_completion_hook)
-           (*rl_directory_completion_hook) (&s);
-
-         slen = strlen (s);
-         tlen = strlen (to_print);
-         new_full_pathname = (char *)xmalloc (slen + tlen + 2);
-         strcpy (new_full_pathname, s);
-         if (s[slen - 1] == '/')
-           slen--;
-         else
-           new_full_pathname[slen] = '/';
-         new_full_pathname[slen] = '/';
-         strcpy (new_full_pathname + slen + 1, to_print);
-
-#if defined (VISIBLE_STATS)
-         if (rl_visible_stats)
-           extension_char = stat_char (new_full_pathname);
-         else
-#endif
-         if (path_isdir (new_full_pathname))
-           extension_char = '/';
-
-         free (new_full_pathname);
-         to_print[-1] = c;
-       }
-      else
-       {
-         s = tilde_expand (full_pathname);
-#if defined (VISIBLE_STATS)
-         if (rl_visible_stats)
-           extension_char = stat_char (s);
-         else
-#endif
-           if (path_isdir (s))
-             extension_char = '/';
-       }
-
-      free (s);
-      if (extension_char)
-       {
-         putc (extension_char, rl_outstream);
-         printed_len++;
-       }
-    }
-
-  return printed_len;
-}
-
-static char *
-rl_quote_filename (s, rtype, qcp)
-     char *s;
-     int rtype;
-     char *qcp;
-{
-  char *r;
-
-  r = (char *)xmalloc (strlen (s) + 2);
-  *r = *rl_completer_quote_characters;
-  strcpy (r + 1, s);
-  if (qcp)
-    *qcp = *rl_completer_quote_characters;
-  return r;
-}
-
-/* Find the bounds of the current word for completion purposes, and leave
-   rl_point set to the end of the word.  This function skips quoted
-   substrings (characters between matched pairs of characters in
-   rl_completer_quote_characters).  First we try to find an unclosed
-   quoted substring on which to do matching.  If one is not found, we use
-   the word break characters to find the boundaries of the current word.
-   We call an application-specific function to decide whether or not a
-   particular word break character is quoted; if that function returns a
-   non-zero result, the character does not break a word.  This function
-   returns the opening quote character if we found an unclosed quoted
-   substring, '\0' otherwise.  FP, if non-null, is set to a value saying
-   which (shell-like) quote characters we found (single quote, double
-   quote, or backslash) anywhere in the string.  DP, if non-null, is set to
-   the value of the delimiter character that caused a word break. */
-
-char
-_rl_find_completion_word (fp, dp)
-     int *fp, *dp;
-{
-  int scan, end, found_quote, delimiter, pass_next, isbrk;
-  char quote_char, *brkchars;
-
-  end = rl_point;
-  found_quote = delimiter = 0;
-  quote_char = '\0';
-
-  brkchars = 0;
-  if (rl_completion_word_break_hook)
-    brkchars = (*rl_completion_word_break_hook) ();
-  if (brkchars == 0)
-    brkchars = rl_completer_word_break_characters;
-
-  if (rl_completer_quote_characters)
-    {
-      /* We have a list of characters which can be used in pairs to
-        quote substrings for the completer.  Try to find the start
-        of an unclosed quoted substring. */
-      /* FOUND_QUOTE is set so we know what kind of quotes we found. */
-      for (scan = pass_next = 0; scan < end; scan = MB_NEXTCHAR (rl_line_buffer, scan, 1, MB_FIND_ANY))
-       {
-         if (pass_next)
-           {
-             pass_next = 0;
-             continue;
-           }
-
-         /* Shell-like semantics for single quotes -- don't allow backslash
-            to quote anything in single quotes, especially not the closing
-            quote.  If you don't like this, take out the check on the value
-            of quote_char. */
-         if (quote_char != '\'' && rl_line_buffer[scan] == '\\')
-           {
-             pass_next = 1;
-             found_quote |= RL_QF_BACKSLASH;
-             continue;
-           }
-
-         if (quote_char != '\0')
-           {
-             /* Ignore everything until the matching close quote char. */
-             if (rl_line_buffer[scan] == quote_char)
-               {
-                 /* Found matching close.  Abandon this substring. */
-                 quote_char = '\0';
-                 rl_point = end;
-               }
-           }
-         else if (strchr (rl_completer_quote_characters, rl_line_buffer[scan]))
-           {
-             /* Found start of a quoted substring. */
-             quote_char = rl_line_buffer[scan];
-             rl_point = scan + 1;
-             /* Shell-like quoting conventions. */
-             if (quote_char == '\'')
-               found_quote |= RL_QF_SINGLE_QUOTE;
-             else if (quote_char == '"')
-               found_quote |= RL_QF_DOUBLE_QUOTE;
-             else
-               found_quote |= RL_QF_OTHER_QUOTE;      
-           }
-       }
-    }
-
-  if (rl_point == end && quote_char == '\0')
-    {
-      /* We didn't find an unclosed quoted substring upon which to do
-         completion, so use the word break characters to find the
-         substring on which to complete. */
-      while (rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_ANY))
-       {
-         scan = rl_line_buffer[rl_point];
-
-         if (strchr (brkchars, scan) == 0)
-           continue;
-
-         /* Call the application-specific function to tell us whether
-            this word break character is quoted and should be skipped. */
-         if (rl_char_is_quoted_p && found_quote &&
-             (*rl_char_is_quoted_p) (rl_line_buffer, rl_point))
-           continue;
-
-         /* Convoluted code, but it avoids an n^2 algorithm with calls
-            to char_is_quoted. */
-         break;
-       }
-    }
-
-  /* If we are at an unquoted word break, then advance past it. */
-  scan = rl_line_buffer[rl_point];
-
-  /* If there is an application-specific function to say whether or not
-     a character is quoted and we found a quote character, let that
-     function decide whether or not a character is a word break, even
-     if it is found in rl_completer_word_break_characters.  Don't bother
-     if we're at the end of the line, though. */
-  if (scan)
-    {
-      if (rl_char_is_quoted_p)
-       isbrk = (found_quote == 0 ||
-               (*rl_char_is_quoted_p) (rl_line_buffer, rl_point) == 0) &&
-               strchr (brkchars, scan) != 0;
-      else
-       isbrk = strchr (brkchars, scan) != 0;
-
-      if (isbrk)
-       {
-         /* If the character that caused the word break was a quoting
-            character, then remember it as the delimiter. */
-         if (rl_basic_quote_characters &&
-             strchr (rl_basic_quote_characters, scan) &&
-             (end - rl_point) > 1)
-           delimiter = scan;
-
-         /* If the character isn't needed to determine something special
-            about what kind of completion to perform, then advance past it. */
-         if (rl_special_prefixes == 0 || strchr (rl_special_prefixes, scan) == 0)
-           rl_point++;
-       }
-    }
-
-  if (fp)
-    *fp = found_quote;
-  if (dp)
-    *dp = delimiter;
-
-  return (quote_char);
-}
-
-static char **
-gen_completion_matches (text, start, end, our_func, found_quote, quote_char)
-     char *text;
-     int start, end;
-     rl_compentry_func_t *our_func;
-     int found_quote, quote_char;
-{
-  char **matches;
-
-  rl_completion_found_quote = found_quote;
-  rl_completion_quote_character = quote_char;
-
-  /* If the user wants to TRY to complete, but then wants to give
-     up and use the default completion function, they set the
-     variable rl_attempted_completion_function. */
-  if (rl_attempted_completion_function)
-    {
-      _rl_interrupt_immediately++;
-      matches = (*rl_attempted_completion_function) (text, start, end);
-      if (_rl_interrupt_immediately)
-       _rl_interrupt_immediately--;
-
-      if (matches || rl_attempted_completion_over)
-       {
-         rl_attempted_completion_over = 0;
-         return (matches);
-       }
-    }
-
-  /* XXX -- filename dequoting moved into rl_filename_completion_function */
-
-  matches = rl_completion_matches (text, our_func);
-  return matches;  
-}
-
-/* Filter out duplicates in MATCHES.  This frees up the strings in
-   MATCHES. */
-static char **
-remove_duplicate_matches (matches)
-     char **matches;
-{
-  char *lowest_common;
-  int i, j, newlen;
-  char dead_slot;
-  char **temp_array;
-
-  /* Sort the items. */
-  for (i = 0; matches[i]; i++)
-    ;
-
-  /* Sort the array without matches[0], since we need it to
-     stay in place no matter what. */
-  if (i && rl_sort_completion_matches)
-    qsort (matches+1, i-1, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
-
-  /* Remember the lowest common denominator for it may be unique. */
-  lowest_common = savestring (matches[0]);
-
-  for (i = newlen = 0; matches[i + 1]; i++)
-    {
-      if (strcmp (matches[i], matches[i + 1]) == 0)
-       {
-         free (matches[i]);
-         matches[i] = (char *)&dead_slot;
-       }
-      else
-       newlen++;
-    }
-
-  /* We have marked all the dead slots with (char *)&dead_slot.
-     Copy all the non-dead entries into a new array. */
-  temp_array = (char **)xmalloc ((3 + newlen) * sizeof (char *));
-  for (i = j = 1; matches[i]; i++)
-    {
-      if (matches[i] != (char *)&dead_slot)
-       temp_array[j++] = matches[i];
-    }
-  temp_array[j] = (char *)NULL;
-
-  if (matches[0] != (char *)&dead_slot)
-    free (matches[0]);
-
-  /* Place the lowest common denominator back in [0]. */
-  temp_array[0] = lowest_common;
-
-  /* If there is one string left, and it is identical to the
-     lowest common denominator, then the LCD is the string to
-     insert. */
-  if (j == 2 && strcmp (temp_array[0], temp_array[1]) == 0)
-    {
-      free (temp_array[1]);
-      temp_array[1] = (char *)NULL;
-    }
-  return (temp_array);
-}
-
-/* Find the common prefix of the list of matches, and put it into
-   matches[0]. */
-static int
-compute_lcd_of_matches (match_list, matches, text)
-     char **match_list;
-     int matches;
-     const char *text;
-{
-  register int i, c1, c2, si;
-  int low;             /* Count of max-matched characters. */
-  char *dtext;         /* dequoted TEXT, if needed */
-#if defined (HANDLE_MULTIBYTE)
-  int v;
-  mbstate_t ps1, ps2;
-  wchar_t wc1, wc2;
-#endif
-
-  /* If only one match, just use that.  Otherwise, compare each
-     member of the list with the next, finding out where they
-     stop matching. */
-  if (matches == 1)
-    {
-      match_list[0] = match_list[1];
-      match_list[1] = (char *)NULL;
-      return 1;
-    }
-
-  for (i = 1, low = 100000; i < matches; i++)
-    {
-#if defined (HANDLE_MULTIBYTE)
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-       {
-         memset (&ps1, 0, sizeof (mbstate_t));
-         memset (&ps2, 0, sizeof (mbstate_t));
-       }
-#endif
-      if (_rl_completion_case_fold)
-       {
-         for (si = 0;
-              (c1 = _rl_to_lower(match_list[i][si])) &&
-              (c2 = _rl_to_lower(match_list[i + 1][si]));
-              si++)
-#if defined (HANDLE_MULTIBYTE)
-           if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-             {
-               v = mbrtowc (&wc1, match_list[i]+si, strlen (match_list[i]+si), &ps1);
-               mbrtowc (&wc2, match_list[i+1]+si, strlen (match_list[i+1]+si), &ps2);
-               wc1 = towlower (wc1);
-               wc2 = towlower (wc2);
-               if (wc1 != wc2)
-                 break;
-               else if (v > 1)
-                 si += v - 1;
-             }
-           else
-#endif
-           if (c1 != c2)
-             break;
-       }
-      else
-       {
-         for (si = 0;
-              (c1 = match_list[i][si]) &&
-              (c2 = match_list[i + 1][si]);
-              si++)
-#if defined (HANDLE_MULTIBYTE)
-           if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-             {
-               mbstate_t ps_back;
-               ps_back = ps1;
-               if (!_rl_compare_chars (match_list[i], si, &ps1, match_list[i+1], si, &ps2))
-                 break;
-               else if ((v = _rl_get_char_len (&match_list[i][si], &ps_back)) > 1)
-                 si += v - 1;
-             }
-           else
-#endif
-           if (c1 != c2)
-             break;
-       }
-
-      if (low > si)
-       low = si;
-    }
-
-  /* If there were multiple matches, but none matched up to even the
-     first character, and the user typed something, use that as the
-     value of matches[0]. */
-  if (low == 0 && text && *text)
-    {
-      match_list[0] = (char *)xmalloc (strlen (text) + 1);
-      strcpy (match_list[0], text);
-    }
-  else
-    {
-      match_list[0] = (char *)xmalloc (low + 1);
-
-      /* XXX - this might need changes in the presence of multibyte chars */
-
-      /* If we are ignoring case, try to preserve the case of the string
-        the user typed in the face of multiple matches differing in case. */
-      if (_rl_completion_case_fold)
-       {
-         /* We're making an assumption here:
-               IF we're completing filenames AND
-                  the application has defined a filename dequoting function AND
-                  we found a quote character AND
-                  the application has requested filename quoting
-               THEN
-                  we assume that TEXT was dequoted before checking against
-                  the file system and needs to be dequoted here before we
-                  check against the list of matches
-               FI */
-         dtext = (char *)NULL;
-         if (rl_filename_completion_desired &&
-             rl_filename_dequoting_function &&
-             rl_completion_found_quote &&
-             rl_filename_quoting_desired)
-           {
-             dtext = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character);
-             text = dtext;
-           }
-
-         /* sort the list to get consistent answers. */
-         qsort (match_list+1, matches, sizeof(char *), (QSFUNC *)_rl_qsort_string_compare);
-
-         si = strlen (text);
-         if (si <= low)
-           {
-             for (i = 1; i <= matches; i++)
-               if (strncmp (match_list[i], text, si) == 0)
-                 {
-                   strncpy (match_list[0], match_list[i], low);
-                   break;
-                 }
-             /* no casematch, use first entry */
-             if (i > matches)
-               strncpy (match_list[0], match_list[1], low);
-           }
-         else
-           /* otherwise, just use the text the user typed. */
-           strncpy (match_list[0], text, low);
-
-         FREE (dtext);
-       }
-      else
-        strncpy (match_list[0], match_list[1], low);
-
-      match_list[0][low] = '\0';
-    }
-
-  return matches;
-}
-
-static int
-postprocess_matches (matchesp, matching_filenames)
-     char ***matchesp;
-     int matching_filenames;
-{
-  char *t, **matches, **temp_matches;
-  int nmatch, i;
-
-  matches = *matchesp;
-
-  if (matches == 0)
-    return 0;
-
-  /* It seems to me that in all the cases we handle we would like
-     to ignore duplicate possiblilities.  Scan for the text to
-     insert being identical to the other completions. */
-  if (rl_ignore_completion_duplicates)
-    {
-      temp_matches = remove_duplicate_matches (matches);
-      free (matches);
-      matches = temp_matches;
-    }
-
-  /* If we are matching filenames, then here is our chance to
-     do clever processing by re-examining the list.  Call the
-     ignore function with the array as a parameter.  It can
-     munge the array, deleting matches as it desires. */
-  if (rl_ignore_some_completions_function && matching_filenames)
-    {
-      for (nmatch = 1; matches[nmatch]; nmatch++)
-       ;
-      (void)(*rl_ignore_some_completions_function) (matches);
-      if (matches == 0 || matches[0] == 0)
-       {
-         FREE (matches);
-         *matchesp = (char **)0;
-         return 0;
-        }
-      else
-       {
-         /* If we removed some matches, recompute the common prefix. */
-         for (i = 1; matches[i]; i++)
-           ;
-         if (i > 1 && i < nmatch)
-           {
-             t = matches[0];
-             compute_lcd_of_matches (matches, i - 1, t);
-             FREE (t);
-           }
-       }
-    }
-
-  *matchesp = matches;
-  return (1);
-}
-
-/* A convenience function for displaying a list of strings in
-   columnar format on readline's output stream.  MATCHES is the list
-   of strings, in argv format, LEN is the number of strings in MATCHES,
-   and MAX is the length of the longest string in MATCHES. */
-void
-rl_display_match_list (matches, len, max)
-     char **matches;
-     int len, max;
-{
-  int count, limit, printed_len, lines;
-  int i, j, k, l, common_length, sind;
-  char *temp, *t;
-
-  /* Find the length of the prefix common to all items: length as displayed
-     characters (common_length) and as a byte index into the matches (sind) */
-  common_length = sind = 0;
-  if (_rl_completion_prefix_display_length > 0)
-    {
-      t = printable_part (matches[0]);
-      temp = strrchr (t, '/');
-      common_length = temp ? fnwidth (temp) : fnwidth (t);
-      sind = temp ? strlen (temp) : strlen (t);
-
-      if (common_length > _rl_completion_prefix_display_length && common_length > ELLIPSIS_LEN)
-       max -= common_length - ELLIPSIS_LEN;
-      else
-       common_length = sind = 0;
-    }
-
-  /* How many items of MAX length can we fit in the screen window? */
-  max += 2;
-  limit = _rl_screenwidth / max;
-  if (limit != 1 && (limit * max == _rl_screenwidth))
-    limit--;
-
-  /* Avoid a possible floating exception.  If max > _rl_screenwidth,
-     limit will be 0 and a divide-by-zero fault will result. */
-  if (limit == 0)
-    limit = 1;
-
-  /* How many iterations of the printing loop? */
-  count = (len + (limit - 1)) / limit;
-
-  /* Watch out for special case.  If LEN is less than LIMIT, then
-     just do the inner printing loop.
-          0 < len <= limit  implies  count = 1. */
-
-  /* Sort the items if they are not already sorted. */
-  if (rl_ignore_completion_duplicates == 0 && rl_sort_completion_matches)
-    qsort (matches + 1, len, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
-
-  rl_crlf ();
-
-  lines = 0;
-  if (_rl_print_completions_horizontally == 0)
-    {
-      /* Print the sorted items, up-and-down alphabetically, like ls. */
-      for (i = 1; i <= count; i++)
-       {
-         for (j = 0, l = i; j < limit; j++)
-           {
-             if (l > len || matches[l] == 0)
-               break;
-             else
-               {
-                 temp = printable_part (matches[l]);
-                 printed_len = print_filename (temp, matches[l], sind);
-
-                 if (j + 1 < limit)
-                   for (k = 0; k < max - printed_len; k++)
-                     putc (' ', rl_outstream);
-               }
-             l += count;
-           }
-         rl_crlf ();
-         lines++;
-         if (_rl_page_completions && lines >= (_rl_screenheight - 1) && i < count)
-           {
-             lines = _rl_internal_pager (lines);
-             if (lines < 0)
-               return;
-           }
-       }
-    }
-  else
-    {
-      /* Print the sorted items, across alphabetically, like ls -x. */
-      for (i = 1; matches[i]; i++)
-       {
-         temp = printable_part (matches[i]);
-         printed_len = print_filename (temp, matches[i], sind);
-         /* Have we reached the end of this line? */
-         if (matches[i+1])
-           {
-             if (i && (limit > 1) && (i % limit) == 0)
-               {
-                 rl_crlf ();
-                 lines++;
-                 if (_rl_page_completions && lines >= _rl_screenheight - 1)
-                   {
-                     lines = _rl_internal_pager (lines);
-                     if (lines < 0)
-                       return;
-                   }
-               }
-             else
-               for (k = 0; k < max - printed_len; k++)
-                 putc (' ', rl_outstream);
-           }
-       }
-      rl_crlf ();
-    }
-}
-
-/* Display MATCHES, a list of matching filenames in argv format.  This
-   handles the simple case -- a single match -- first.  If there is more
-   than one match, we compute the number of strings in the list and the
-   length of the longest string, which will be needed by the display
-   function.  If the application wants to handle displaying the list of
-   matches itself, it sets RL_COMPLETION_DISPLAY_MATCHES_HOOK to the
-   address of a function, and we just call it.  If we're handling the
-   display ourselves, we just call rl_display_match_list.  We also check
-   that the list of matches doesn't exceed the user-settable threshold,
-   and ask the user if he wants to see the list if there are more matches
-   than RL_COMPLETION_QUERY_ITEMS. */
-static void
-display_matches (matches)
-     char **matches;
-{
-  int len, max, i;
-  char *temp;
-
-  /* Move to the last visible line of a possibly-multiple-line command. */
-  _rl_move_vert (_rl_vis_botlin);
-
-  /* Handle simple case first.  What if there is only one answer? */
-  if (matches[1] == 0)
-    {
-      temp = printable_part (matches[0]);
-      rl_crlf ();
-      print_filename (temp, matches[0], 0);
-      rl_crlf ();
-
-      rl_forced_update_display ();
-      rl_display_fixed = 1;
-
-      return;
-    }
-
-  /* There is more than one answer.  Find out how many there are,
-     and find the maximum printed length of a single entry. */
-  for (max = 0, i = 1; matches[i]; i++)
-    {
-      temp = printable_part (matches[i]);
-      len = fnwidth (temp);
-
-      if (len > max)
-       max = len;
-    }
-
-  len = i - 1;
-
-  /* If the caller has defined a display hook, then call that now. */
-  if (rl_completion_display_matches_hook)
-    {
-      (*rl_completion_display_matches_hook) (matches, len, max);
-      return;
-    }
-       
-  /* If there are many items, then ask the user if she really wants to
-     see them all. */
-  if (rl_completion_query_items > 0 && len >= rl_completion_query_items)
-    {
-      rl_crlf ();
-      fprintf (rl_outstream, "Display all %d possibilities? (y or n)", len);
-      fflush (rl_outstream);
-      if ((completion_y_or_n = get_y_or_n (0)) == 0)
-       {
-         rl_crlf ();
-
-         rl_forced_update_display ();
-         rl_display_fixed = 1;
-
-         return;
-       }
-    }
-
-  rl_display_match_list (matches, len, max);
-
-  rl_forced_update_display ();
-  rl_display_fixed = 1;
-}
-
-static char *
-make_quoted_replacement (match, mtype, qc)
-     char *match;
-     int mtype;
-     char *qc; /* Pointer to quoting character, if any */
-{
-  int should_quote, do_replace;
-  char *replacement;
-
-  /* If we are doing completion on quoted substrings, and any matches
-     contain any of the completer_word_break_characters, then auto-
-     matically prepend the substring with a quote character (just pick
-     the first one from the list of such) if it does not already begin
-     with a quote string.  FIXME: Need to remove any such automatically
-     inserted quote character when it no longer is necessary, such as
-     if we change the string we are completing on and the new set of
-     matches don't require a quoted substring. */
-  replacement = match;
-
-  should_quote = match && rl_completer_quote_characters &&
-                       rl_filename_completion_desired &&
-                       rl_filename_quoting_desired;
-
-  if (should_quote)
-    should_quote = should_quote && (!qc || !*qc ||
-                    (rl_completer_quote_characters && strchr (rl_completer_quote_characters, *qc)));
-
-  if (should_quote)
-    {
-      /* If there is a single match, see if we need to quote it.
-         This also checks whether the common prefix of several
-        matches needs to be quoted. */
-      should_quote = rl_filename_quote_characters
-                       ? (_rl_strpbrk (match, rl_filename_quote_characters) != 0)
-                       : 0;
-
-      do_replace = should_quote ? mtype : NO_MATCH;
-      /* Quote the replacement, since we found an embedded
-        word break character in a potential match. */
-      if (do_replace != NO_MATCH && rl_filename_quoting_function)
-       replacement = (*rl_filename_quoting_function) (match, do_replace, qc);
-    }
-  return (replacement);
-}
-
-static void
-insert_match (match, start, mtype, qc)
-     char *match;
-     int start, mtype;
-     char *qc;
-{
-  char *replacement, *r;
-  char oqc;
-  int end, rlen;
-
-  oqc = qc ? *qc : '\0';
-  replacement = make_quoted_replacement (match, mtype, qc);
-
-  /* Now insert the match. */
-  if (replacement)
-    {
-      rlen = strlen (replacement);
-      /* Don't double an opening quote character. */
-      if (qc && *qc && start && rl_line_buffer[start - 1] == *qc &&
-           replacement[0] == *qc)
-       start--;
-      /* If make_quoted_replacement changed the quoting character, remove
-        the opening quote and insert the (fully-quoted) replacement. */
-      else if (qc && (*qc != oqc) && start && rl_line_buffer[start - 1] == oqc &&
-           replacement[0] != oqc)
-       start--;
-      end = rl_point - 1;
-      /* Don't double a closing quote character */
-      if (qc && *qc && end && rl_line_buffer[rl_point] == *qc && replacement[rlen - 1] == *qc)
-        end++;
-      if (_rl_skip_completed_text)
-       {
-         r = replacement;
-         while (start < rl_end && *r && rl_line_buffer[start] == *r)
-           {
-             start++;
-             r++;
-           }
-         if (start <= end || *r)
-           _rl_replace_text (r, start, end);
-         rl_point = start + strlen (r);
-       }
-      else
-       _rl_replace_text (replacement, start, end);
-      if (replacement != match)
-        free (replacement);
-    }
-}
-
-/* Append any necessary closing quote and a separator character to the
-   just-inserted match.  If the user has specified that directories
-   should be marked by a trailing `/', append one of those instead.  The
-   default trailing character is a space.  Returns the number of characters
-   appended.  If NONTRIVIAL_MATCH is set, we test for a symlink (if the OS
-   has them) and don't add a suffix for a symlink to a directory.  A
-   nontrivial match is one that actually adds to the word being completed.
-   The variable rl_completion_mark_symlink_dirs controls this behavior
-   (it's initially set to the what the user has chosen, indicated by the
-   value of _rl_complete_mark_symlink_dirs, but may be modified by an
-   application's completion function). */
-static int
-append_to_match (text, delimiter, quote_char, nontrivial_match)
-     char *text;
-     int delimiter, quote_char, nontrivial_match;
-{
-  char temp_string[4], *filename;
-  int temp_string_index, s;
-  struct stat finfo;
-
-  temp_string_index = 0;
-  if (quote_char && rl_point && rl_completion_suppress_quote == 0 &&
-      rl_line_buffer[rl_point - 1] != quote_char)
-    temp_string[temp_string_index++] = quote_char;
-
-  if (delimiter)
-    temp_string[temp_string_index++] = delimiter;
-  else if (rl_completion_suppress_append == 0 && rl_completion_append_character)
-    temp_string[temp_string_index++] = rl_completion_append_character;
-
-  temp_string[temp_string_index++] = '\0';
-
-  if (rl_filename_completion_desired)
-    {
-      filename = tilde_expand (text);
-      s = (nontrivial_match && rl_completion_mark_symlink_dirs == 0)
-               ? LSTAT (filename, &finfo)
-               : stat (filename, &finfo);
-      if (s == 0 && S_ISDIR (finfo.st_mode))
-       {
-         if (_rl_complete_mark_directories /* && rl_completion_suppress_append == 0 */)
-           {
-             /* This is clumsy.  Avoid putting in a double slash if point
-                is at the end of the line and the previous character is a
-                slash. */
-             if (rl_point && rl_line_buffer[rl_point] == '\0' && rl_line_buffer[rl_point - 1] == '/')
-               ;
-             else if (rl_line_buffer[rl_point] != '/')
-               rl_insert_text ("/");
-           }
-       }
-#ifdef S_ISLNK
-      /* Don't add anything if the filename is a symlink and resolves to a
-        directory. */
-      else if (s == 0 && S_ISLNK (finfo.st_mode) &&
-              stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode))
-       ;
-#endif
-      else
-       {
-         if (rl_point == rl_end && temp_string_index)
-           rl_insert_text (temp_string);
-       }
-      free (filename);
-    }
-  else
-    {
-      if (rl_point == rl_end && temp_string_index)
-       rl_insert_text (temp_string);
-    }
-
-  return (temp_string_index);
-}
-
-static void
-insert_all_matches (matches, point, qc)
-     char **matches;
-     int point;
-     char *qc;
-{
-  int i;
-  char *rp;
-
-  rl_begin_undo_group ();
-  /* remove any opening quote character; make_quoted_replacement will add
-     it back. */
-  if (qc && *qc && point && rl_line_buffer[point - 1] == *qc)
-    point--;
-  rl_delete_text (point, rl_point);
-  rl_point = point;
-
-  if (matches[1])
-    {
-      for (i = 1; matches[i]; i++)
-       {
-         rp = make_quoted_replacement (matches[i], SINGLE_MATCH, qc);
-         rl_insert_text (rp);
-         rl_insert_text (" ");
-         if (rp != matches[i])
-           free (rp);
-       }
-    }
-  else
-    {
-      rp = make_quoted_replacement (matches[0], SINGLE_MATCH, qc);
-      rl_insert_text (rp);
-      rl_insert_text (" ");
-      if (rp != matches[0])
-       free (rp);
-    }
-  rl_end_undo_group ();
-}
-
-void
-_rl_free_match_list (matches)
-     char **matches;
-{
-  register int i;
-
-  if (matches == 0)
-    return;
-
-  for (i = 0; matches[i]; i++)
-    free (matches[i]);
-  free (matches);
-}
-
-/* Complete the word at or before point.
-   WHAT_TO_DO says what to do with the completion.
-   `?' means list the possible completions.
-   TAB means do standard completion.
-   `*' means insert all of the possible completions.
-   `!' means to do standard completion, and list all possible completions if
-   there is more than one.
-   `@' means to do standard completion, and list all possible completions if
-   there is more than one and partial completion is not possible. */
-int
-rl_complete_internal (what_to_do)
-     int what_to_do;
-{
-  char **matches;
-  rl_compentry_func_t *our_func;
-  int start, end, delimiter, found_quote, i, nontrivial_lcd;
-  char *text, *saved_line_buffer;
-  char quote_char;
-
-  RL_SETSTATE(RL_STATE_COMPLETING);
-
-  set_completion_defaults (what_to_do);
-
-  saved_line_buffer = rl_line_buffer ? savestring (rl_line_buffer) : (char *)NULL;
-  our_func = rl_completion_entry_function
-               ? rl_completion_entry_function
-               : rl_filename_completion_function;
-  /* We now look backwards for the start of a filename/variable word. */
-  end = rl_point;
-  found_quote = delimiter = 0;
-  quote_char = '\0';
-
-  if (rl_point)
-    /* This (possibly) changes rl_point.  If it returns a non-zero char,
-       we know we have an open quote. */
-    quote_char = _rl_find_completion_word (&found_quote, &delimiter);
-
-  start = rl_point;
-  rl_point = end;
-
-  text = rl_copy_text (start, end);
-  matches = gen_completion_matches (text, start, end, our_func, found_quote, quote_char);
-  /* nontrivial_lcd is set if the common prefix adds something to the word
-     being completed. */
-  nontrivial_lcd = matches && strcmp (text, matches[0]) != 0;
-  free (text);
-
-  if (matches == 0)
-    {
-      rl_ding ();
-      FREE (saved_line_buffer);
-      completion_changed_buffer = 0;
-      RL_UNSETSTATE(RL_STATE_COMPLETING);
-      _rl_reset_completion_state ();
-      return (0);
-    }
-
-  /* If we are matching filenames, the attempted completion function will
-     have set rl_filename_completion_desired to a non-zero value.  The basic
-     rl_filename_completion_function does this. */
-  i = rl_filename_completion_desired;
-
-  if (postprocess_matches (&matches, i) == 0)
-    {
-      rl_ding ();
-      FREE (saved_line_buffer);
-      completion_changed_buffer = 0;
-      RL_UNSETSTATE(RL_STATE_COMPLETING);
-      _rl_reset_completion_state ();
-      return (0);
-    }
-
-  switch (what_to_do)
-    {
-    case TAB:
-    case '!':
-    case '@':
-      /* Insert the first match with proper quoting. */
-      if (*matches[0])
-       insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
-
-      /* If there are more matches, ring the bell to indicate.
-        If we are in vi mode, Posix.2 says to not ring the bell.
-        If the `show-all-if-ambiguous' variable is set, display
-        all the matches immediately.  Otherwise, if this was the
-        only match, and we are hacking files, check the file to
-        see if it was a directory.  If so, and the `mark-directories'
-        variable is set, add a '/' to the name.  If not, and we
-        are at the end of the line, then add a space.  */
-      if (matches[1])
-       {
-         if (what_to_do == '!')
-           {
-             display_matches (matches);
-             break;
-           }
-         else if (what_to_do == '@')
-           {
-             if (nontrivial_lcd == 0)
-               display_matches (matches);
-             break;
-           }
-         else if (rl_editing_mode != vi_mode)
-           rl_ding (); /* There are other matches remaining. */
-       }
-      else
-       append_to_match (matches[0], delimiter, quote_char, nontrivial_lcd);
-
-      break;
-
-    case '*':
-      insert_all_matches (matches, start, &quote_char);
-      break;
-
-    case '?':
-      display_matches (matches);
-      break;
-
-    default:
-      _rl_ttymsg ("bad value %d for what_to_do in rl_complete", what_to_do);
-      rl_ding ();
-      FREE (saved_line_buffer);
-      RL_UNSETSTATE(RL_STATE_COMPLETING);
-      _rl_reset_completion_state ();
-      return 1;
-    }
-
-  _rl_free_match_list (matches);
-
-  /* Check to see if the line has changed through all of this manipulation. */
-  if (saved_line_buffer)
-    {
-      completion_changed_buffer = strcmp (rl_line_buffer, saved_line_buffer) != 0;
-      free (saved_line_buffer);
-    }
-
-  RL_UNSETSTATE(RL_STATE_COMPLETING);
-  _rl_reset_completion_state ();
-  return 0;
-}
-
-/***************************************************************/
-/*                                                            */
-/*  Application-callable completion match generator functions  */
-/*                                                            */
-/***************************************************************/
-
-/* Return an array of (char *) which is a list of completions for TEXT.
-   If there are no completions, return a NULL pointer.
-   The first entry in the returned array is the substitution for TEXT.
-   The remaining entries are the possible completions.
-   The array is terminated with a NULL pointer.
-
-   ENTRY_FUNCTION is a function of two args, and returns a (char *).
-     The first argument is TEXT.
-     The second is a state argument; it should be zero on the first call, and
-     non-zero on subsequent calls.  It returns a NULL pointer to the caller
-     when there are no more matches.
- */
-char **
-rl_completion_matches (text, entry_function)
-     const char *text;
-     rl_compentry_func_t *entry_function;
-{
-  /* Number of slots in match_list. */
-  int match_list_size;
-
-  /* The list of matches. */
-  char **match_list;
-
-  /* Number of matches actually found. */
-  int matches;
-
-  /* Temporary string binder. */
-  char *string;
-
-  matches = 0;
-  match_list_size = 10;
-  match_list = (char **)xmalloc ((match_list_size + 1) * sizeof (char *));
-  match_list[1] = (char *)NULL;
-
-  _rl_interrupt_immediately++;
-  while (string = (*entry_function) (text, matches))
-    {
-      if (matches + 1 == match_list_size)
-       match_list = (char **)xrealloc
-         (match_list, ((match_list_size += 10) + 1) * sizeof (char *));
-
-      match_list[++matches] = string;
-      match_list[matches + 1] = (char *)NULL;
-    }
-  if (_rl_interrupt_immediately)
-    _rl_interrupt_immediately--;
-
-  /* If there were any matches, then look through them finding out the
-     lowest common denominator.  That then becomes match_list[0]. */
-  if (matches)
-    compute_lcd_of_matches (match_list, matches, text);
-  else                         /* There were no matches. */
-    {
-      free (match_list);
-      match_list = (char **)NULL;
-    }
-  return (match_list);
-}
-
-/* A completion function for usernames.
-   TEXT contains a partial username preceded by a random
-   character (usually `~').  */
-char *
-rl_username_completion_function (text, state)
-     const char *text;
-     int state;
-{
-#if defined (__WIN32__) || defined (__OPENNT)
-  return (char *)NULL;
-#else /* !__WIN32__ && !__OPENNT) */
-  static char *username = (char *)NULL;
-  static struct passwd *entry;
-  static int namelen, first_char, first_char_loc;
-  char *value;
-
-  if (state == 0)
-    {
-      FREE (username);
-
-      first_char = *text;
-      first_char_loc = first_char == '~';
-
-      username = savestring (&text[first_char_loc]);
-      namelen = strlen (username);
-      setpwent ();
-    }
-
-#if defined (HAVE_GETPWENT)
-  while (entry = getpwent ())
-    {
-      /* Null usernames should result in all users as possible completions. */
-      if (namelen == 0 || (STREQN (username, entry->pw_name, namelen)))
-       break;
-    }
-#endif
-
-  if (entry == 0)
-    {
-#if defined (HAVE_GETPWENT)
-      endpwent ();
-#endif
-      return ((char *)NULL);
-    }
-  else
-    {
-      value = (char *)xmalloc (2 + strlen (entry->pw_name));
-
-      *value = *text;
-
-      strcpy (value + first_char_loc, entry->pw_name);
-
-      if (first_char == '~')
-       rl_filename_completion_desired = 1;
-
-      return (value);
-    }
-#endif /* !__WIN32__ && !__OPENNT */
-}
-
-/* Okay, now we write the entry_function for filename completion.  In the
-   general case.  Note that completion in the shell is a little different
-   because of all the pathnames that must be followed when looking up the
-   completion for a command. */
-char *
-rl_filename_completion_function (text, state)
-     const char *text;
-     int state;
-{
-  static DIR *directory = (DIR *)NULL;
-  static char *filename = (char *)NULL;
-  static char *dirname = (char *)NULL;
-  static char *users_dirname = (char *)NULL;
-  static int filename_len;
-  char *temp, *dentry, *convfn;
-  int dirlen, dentlen, convlen;
-  struct dirent *entry;
-
-  /* If we don't have any state, then do some initialization. */
-  if (state == 0)
-    {
-      /* If we were interrupted before closing the directory or reading
-        all of its contents, close it. */
-      if (directory)
-       {
-         closedir (directory);
-         directory = (DIR *)NULL;
-       }
-      FREE (dirname);
-      FREE (filename);
-      FREE (users_dirname);
-
-      filename = savestring (text);
-      if (*text == 0)
-       text = ".";
-      dirname = savestring (text);
-
-      temp = strrchr (dirname, '/');
-
-#if defined (__MSDOS__)
-      /* special hack for //X/... */
-      if (dirname[0] == '/' && dirname[1] == '/' && ISALPHA ((unsigned char)dirname[2]) && dirname[3] == '/')
-        temp = strrchr (dirname + 3, '/');
-#endif
-
-      if (temp)
-       {
-         strcpy (filename, ++temp);
-         *temp = '\0';
-       }
-#if defined (__MSDOS__)
-      /* searches from current directory on the drive */
-      else if (ISALPHA ((unsigned char)dirname[0]) && dirname[1] == ':')
-        {
-          strcpy (filename, dirname + 2);
-          dirname[2] = '\0';
-        }
-#endif
-      else
-       {
-         dirname[0] = '.';
-         dirname[1] = '\0';
-       }
-
-      /* We aren't done yet.  We also support the "~user" syntax. */
-
-      /* Save the version of the directory that the user typed. */
-      users_dirname = savestring (dirname);
-
-      if (*dirname == '~')
-       {
-         temp = tilde_expand (dirname);
-         free (dirname);
-         dirname = temp;
-       }
-
-      if (rl_directory_rewrite_hook)
-       (*rl_directory_rewrite_hook) (&dirname);
-
-      /* The directory completion hook should perform any necessary
-        dequoting. */
-      if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&dirname))
-       {
-         free (users_dirname);
-         users_dirname = savestring (dirname);
-       }
-      else if (rl_completion_found_quote && rl_filename_dequoting_function)
-       {
-         /* delete single and double quotes */
-         temp = (*rl_filename_dequoting_function) (users_dirname, rl_completion_quote_character);
-         free (users_dirname);
-         users_dirname = temp;
-       }
-      directory = opendir (dirname);
-
-      /* Now dequote a non-null filename. */
-      if (filename && *filename && rl_completion_found_quote && rl_filename_dequoting_function)
-       {
-         /* delete single and double quotes */
-         temp = (*rl_filename_dequoting_function) (filename, rl_completion_quote_character);
-         free (filename);
-         filename = temp;
-       }
-      filename_len = strlen (filename);
-
-      rl_filename_completion_desired = 1;
-    }
-
-  /* At this point we should entertain the possibility of hacking wildcarded
-     filenames, like /usr/man/man<WILD>/te<TAB>.  If the directory name
-     contains globbing characters, then build an array of directories, and
-     then map over that list while completing. */
-  /* *** UNIMPLEMENTED *** */
-
-  /* Now that we have some state, we can read the directory. */
-
-  entry = (struct dirent *)NULL;
-  while (directory && (entry = readdir (directory)))
-    {
-      convfn = dentry = entry->d_name;
-      convlen = dentlen = D_NAMLEN (entry);
-
-      if (rl_filename_rewrite_hook)
-       {
-         convfn = (*rl_filename_rewrite_hook) (dentry, dentlen);
-         convlen = (convfn == dentry) ? dentlen : strlen (convfn);
-       }
-
-      /* Special case for no filename.  If the user has disabled the
-         `match-hidden-files' variable, skip filenames beginning with `.'.
-        All other entries except "." and ".." match. */
-      if (filename_len == 0)
-       {
-         if (_rl_match_hidden_files == 0 && HIDDEN_FILE (entry->d_name))
-           continue;
-
-         if (convfn[0] != '.' ||
-              (convfn[1] && (convfn[1] != '.' || convfn[2])))
-           break;
-       }
-      else
-       {
-         /* Otherwise, if these match up to the length of filename, then
-            it is a match. */
-         if (_rl_completion_case_fold)
-           {
-             if ((_rl_to_lower (convfn[0]) == _rl_to_lower (filename[0])) &&
-                 (convlen >= filename_len) &&
-                 (_rl_strnicmp (filename, convfn, filename_len) == 0))
-               break;
-           }
-         else
-           {
-             if ((convfn[0] == filename[0]) &&
-                 (convlen >= filename_len) &&
-                 (strncmp (filename, convfn, filename_len) == 0))
-               break;
-           }
-       }
-    }
-
-  if (entry == 0)
-    {
-      if (directory)
-       {
-         closedir (directory);
-         directory = (DIR *)NULL;
-       }
-      if (dirname)
-       {
-         free (dirname);
-         dirname = (char *)NULL;
-       }
-      if (filename)
-       {
-         free (filename);
-         filename = (char *)NULL;
-       }
-      if (users_dirname)
-       {
-         free (users_dirname);
-         users_dirname = (char *)NULL;
-       }
-
-      return (char *)NULL;
-    }
-  else
-    {
-      /* dirname && (strcmp (dirname, ".") != 0) */
-      if (dirname && (dirname[0] != '.' || dirname[1]))
-       {
-         if (rl_complete_with_tilde_expansion && *users_dirname == '~')
-           {
-             dirlen = strlen (dirname);
-             temp = (char *)xmalloc (2 + dirlen + D_NAMLEN (entry));
-             strcpy (temp, dirname);
-             /* Canonicalization cuts off any final slash present.  We
-                may need to add it back. */
-             if (dirname[dirlen - 1] != '/')
-               {
-                 temp[dirlen++] = '/';
-                 temp[dirlen] = '\0';
-               }
-           }
-         else
-           {
-             dirlen = strlen (users_dirname);
-             temp = (char *)xmalloc (2 + dirlen + D_NAMLEN (entry));
-             strcpy (temp, users_dirname);
-             /* Make sure that temp has a trailing slash here. */
-             if (users_dirname[dirlen - 1] != '/')
-               temp[dirlen++] = '/';
-           }
-
-         strcpy (temp + dirlen, entry->d_name);
-       }
-      else
-       temp = savestring (convfn);
-
-      if (convfn != dentry)
-       free (convfn);
-
-      return (temp);
-    }
-}
-
-/* An initial implementation of a menu completion function a la tcsh.  The
-   first time (if the last readline command was not rl_old_menu_complete), we
-   generate the list of matches.  This code is very similar to the code in
-   rl_complete_internal -- there should be a way to combine the two.  Then,
-   for each item in the list of matches, we insert the match in an undoable
-   fashion, with the appropriate character appended (this happens on the
-   second and subsequent consecutive calls to rl_old_menu_complete).  When we
-   hit the end of the match list, we restore the original unmatched text,
-   ring the bell, and reset the counter to zero. */
-int
-rl_old_menu_complete (count, invoking_key)
-     int count, invoking_key;
-{
-  rl_compentry_func_t *our_func;
-  int matching_filenames, found_quote;
-
-  static char *orig_text;
-  static char **matches = (char **)0;
-  static int match_list_index = 0;
-  static int match_list_size = 0;
-  static int orig_start, orig_end;
-  static char quote_char;
-  static int delimiter;
-
-  /* The first time through, we generate the list of matches and set things
-     up to insert them. */
-  if (rl_last_func != rl_old_menu_complete)
-    {
-      /* Clean up from previous call, if any. */
-      FREE (orig_text);
-      if (matches)
-       _rl_free_match_list (matches);
-
-      match_list_index = match_list_size = 0;
-      matches = (char **)NULL;
-
-      rl_completion_invoking_key = invoking_key;
-
-      RL_SETSTATE(RL_STATE_COMPLETING);
-
-      /* Only the completion entry function can change these. */
-      set_completion_defaults ('%');
-
-      our_func = rl_menu_completion_entry_function;
-      if (our_func == 0)
-       our_func = rl_completion_entry_function
-                       ? rl_completion_entry_function
-                       : rl_filename_completion_function;
-
-      /* We now look backwards for the start of a filename/variable word. */
-      orig_end = rl_point;
-      found_quote = delimiter = 0;
-      quote_char = '\0';
-
-      if (rl_point)
-       /* This (possibly) changes rl_point.  If it returns a non-zero char,
-          we know we have an open quote. */
-       quote_char = _rl_find_completion_word (&found_quote, &delimiter);
-
-      orig_start = rl_point;
-      rl_point = orig_end;
-
-      orig_text = rl_copy_text (orig_start, orig_end);
-      matches = gen_completion_matches (orig_text, orig_start, orig_end,
-                                       our_func, found_quote, quote_char);
-
-      /* If we are matching filenames, the attempted completion function will
-        have set rl_filename_completion_desired to a non-zero value.  The basic
-        rl_filename_completion_function does this. */
-      matching_filenames = rl_filename_completion_desired;
-
-      if (matches == 0 || postprocess_matches (&matches, matching_filenames) == 0)
-       {
-         rl_ding ();
-         FREE (matches);
-         matches = (char **)0;
-         FREE (orig_text);
-         orig_text = (char *)0;
-         completion_changed_buffer = 0;
-         RL_UNSETSTATE(RL_STATE_COMPLETING);
-          return (0);
-       }
-
-      RL_UNSETSTATE(RL_STATE_COMPLETING);
-
-      for (match_list_size = 0; matches[match_list_size]; match_list_size++)
-        ;
-      /* matches[0] is lcd if match_list_size > 1, but the circular buffer
-        code below should take care of it. */
-
-      if (match_list_size > 1 && _rl_complete_show_all)
-       display_matches (matches);
-    }
-
-  /* Now we have the list of matches.  Replace the text between
-     rl_line_buffer[orig_start] and rl_line_buffer[rl_point] with
-     matches[match_list_index], and add any necessary closing char. */
-
-  if (matches == 0 || match_list_size == 0) 
-    {
-      rl_ding ();
-      FREE (matches);
-      matches = (char **)0;
-      completion_changed_buffer = 0;
-      return (0);
-    }
-
-  match_list_index += count;
-  if (match_list_index < 0)
-    match_list_index += match_list_size;
-  else
-    match_list_index %= match_list_size;
-
-  if (match_list_index == 0 && match_list_size > 1)
-    {
-      rl_ding ();
-      insert_match (orig_text, orig_start, MULT_MATCH, &quote_char);
-    }
-  else
-    {
-      insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, &quote_char);
-      append_to_match (matches[match_list_index], delimiter, quote_char,
-                      strcmp (orig_text, matches[match_list_index]));
-    }
-
-  completion_changed_buffer = 1;
-  return (0);
-}
-
-int
-rl_menu_complete (count, ignore)
-     int count, ignore;
-{
-  rl_compentry_func_t *our_func;
-  int matching_filenames, found_quote;
-
-  static char *orig_text;
-  static char **matches = (char **)0;
-  static int match_list_index = 0;
-  static int match_list_size = 0;
-  static int nontrivial_lcd = 0;
-  static int full_completion = 0;      /* set to 1 if menu completion should reinitialize on next call */
-  static int orig_start, orig_end;
-  static char quote_char;
-  static int delimiter;
-
-  /* The first time through, we generate the list of matches and set things
-     up to insert them. */
-  if ((rl_last_func != rl_menu_complete && rl_last_func != rl_backward_menu_complete) || full_completion)
-    {
-      /* Clean up from previous call, if any. */
-      FREE (orig_text);
-      if (matches)
-       _rl_free_match_list (matches);
-
-      match_list_index = match_list_size = 0;
-      matches = (char **)NULL;
-
-      full_completion = 0;
-
-      RL_SETSTATE(RL_STATE_COMPLETING);
-
-      /* Only the completion entry function can change these. */
-      set_completion_defaults ('%');
-
-      our_func = rl_menu_completion_entry_function;
-      if (our_func == 0)
-       our_func = rl_completion_entry_function
-                       ? rl_completion_entry_function
-                       : rl_filename_completion_function;
-
-      /* We now look backwards for the start of a filename/variable word. */
-      orig_end = rl_point;
-      found_quote = delimiter = 0;
-      quote_char = '\0';
-
-      if (rl_point)
-       /* This (possibly) changes rl_point.  If it returns a non-zero char,
-          we know we have an open quote. */
-       quote_char = _rl_find_completion_word (&found_quote, &delimiter);
-
-      orig_start = rl_point;
-      rl_point = orig_end;
-
-      orig_text = rl_copy_text (orig_start, orig_end);
-      matches = gen_completion_matches (orig_text, orig_start, orig_end,
-                                       our_func, found_quote, quote_char);
-
-      nontrivial_lcd = matches && strcmp (orig_text, matches[0]) != 0;
-
-      /* If we are matching filenames, the attempted completion function will
-        have set rl_filename_completion_desired to a non-zero value.  The basic
-        rl_filename_completion_function does this. */
-      matching_filenames = rl_filename_completion_desired;
-
-      if (matches == 0 || postprocess_matches (&matches, matching_filenames) == 0)
-       {
-         rl_ding ();
-         FREE (matches);
-         matches = (char **)0;
-         FREE (orig_text);
-         orig_text = (char *)0;
-         completion_changed_buffer = 0;
-         RL_UNSETSTATE(RL_STATE_COMPLETING);
-          return (0);
-       }
-
-      RL_UNSETSTATE(RL_STATE_COMPLETING);
-
-      for (match_list_size = 0; matches[match_list_size]; match_list_size++)
-        ;
-
-      if (match_list_size == 0) 
-       {
-         rl_ding ();
-         FREE (matches);
-         matches = (char **)0;
-         match_list_index = 0;
-         completion_changed_buffer = 0;
-         return (0);
-        }
-
-      /* matches[0] is lcd if match_list_size > 1, but the circular buffer
-        code below should take care of it. */
-      if (*matches[0])
-       {
-         insert_match (matches[0], orig_start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
-         orig_end = orig_start + strlen (matches[0]);
-         completion_changed_buffer = STREQ (orig_text, matches[0]) == 0;
-       }
-
-      if (match_list_size > 1 && _rl_complete_show_all)
-       {
-         display_matches (matches);
-         /* If there are so many matches that the user has to be asked
-            whether or not he wants to see the matches, menu completion
-            is unwieldy. */
-         if (rl_completion_query_items > 0 && match_list_size >= rl_completion_query_items)
-           {
-             rl_ding ();
-             FREE (matches);
-             matches = (char **)0;
-             full_completion = 1;
-             return (0);
-           }
-       }
-      else if (match_list_size <= 1)
-       {
-         append_to_match (matches[0], delimiter, quote_char, nontrivial_lcd);
-         full_completion = 1;
-         return (0);
-       }
-    }
-
-  /* Now we have the list of matches.  Replace the text between
-     rl_line_buffer[orig_start] and rl_line_buffer[rl_point] with
-     matches[match_list_index], and add any necessary closing char. */
-
-  if (matches == 0 || match_list_size == 0) 
-    {
-      rl_ding ();
-      FREE (matches);
-      matches = (char **)0;
-      completion_changed_buffer = 0;
-      return (0);
-    }
-
-  match_list_index += count;
-  if (match_list_index < 0)
-    match_list_index += match_list_size;
-  else
-    match_list_index %= match_list_size;
-
-  if (match_list_index == 0 && match_list_size > 1)
-    {
-      rl_ding ();
-      insert_match (matches[0], orig_start, MULT_MATCH, &quote_char);
-    }
-  else
-    {
-      insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, &quote_char);
-      append_to_match (matches[match_list_index], delimiter, quote_char,
-                      strcmp (orig_text, matches[match_list_index]));
-    }
-
-  completion_changed_buffer = 1;
-  return (0);
-}
-
-int
-rl_backward_menu_complete (count, key)
-     int count, key;
-{
-  /* Positive arguments to backward-menu-complete translate into negative
-     arguments for menu-complete, and vice versa. */
-  return (rl_menu_complete (-count, key));
-}
diff --git a/lib/readline/display.c.save b/lib/readline/display.c.save
deleted file mode 100644 (file)
index 742e4e6..0000000
+++ /dev/null
@@ -1,2689 +0,0 @@
-/* display.c -- readline redisplay facility. */
-
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
-
-   This file is part of the GNU Readline Library (Readline), a library    
-   for reading lines of text with interactive input and history editing.
-
-   Readline is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   Readline is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#define READLINE_LIBRARY
-
-#if defined (HAVE_CONFIG_H)
-#  include <config.h>
-#endif
-
-#include <sys/types.h>
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#include "posixstat.h"
-
-#if defined (HAVE_STDLIB_H)
-#  include <stdlib.h>
-#else
-#  include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#include <stdio.h>
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-#include "rlmbutil.h"
-
-/* Termcap library stuff. */
-#include "tcap.h"
-
-/* Some standard library routines. */
-#include "readline.h"
-#include "history.h"
-
-#include "rlprivate.h"
-#include "xmalloc.h"
-
-#if !defined (strchr) && !defined (__STDC__)
-extern char *strchr (), *strrchr ();
-#endif /* !strchr && !__STDC__ */
-
-static void update_line PARAMS((char *, char *, int, int, int, int));
-static void space_to_eol PARAMS((int));
-static void delete_chars PARAMS((int));
-static void insert_some_chars PARAMS((char *, int, int));
-static void cr PARAMS((void));
-
-/* State of visible and invisible lines. */
-struct line_state
-  {
-    char *line;
-    int *lbreaks;
-    int lbsize;
-#if defined (HANDLE_MULTIBYTE)
-    int *wrapped_line;
-    int wbsize;
-#endif
-  };
-
-/* The line display buffers.  One is the line currently displayed on
-   the screen.  The other is the line about to be displayed. */
-static struct line_state line_state_array[2];
-static struct line_state *line_state_visible = &line_state_array[0];
-static struct line_state *line_state_invisible = &line_state_array[1];
-static int line_structures_initialized = 0;
-
-/* Backwards-compatible names. */
-#define inv_lbreaks    (line_state_invisible->lbreaks)
-#define inv_lbsize     (line_state_invisible->lbsize)
-#define vis_lbreaks    (line_state_visible->lbreaks)
-#define vis_lbsize     (line_state_visible->lbsize)
-
-#define visible_line   (line_state_visible->line)
-#define invisible_line (line_state_invisible->line)
-
-#if defined (HANDLE_MULTIBYTE)
-static int _rl_col_width PARAMS((const char *, int, int));
-#else
-#  define _rl_col_width(l, s, e)       (((e) <= (s)) ? 0 : (e) - (s))
-#endif
-
-/* Heuristic used to decide whether it is faster to move from CUR to NEW
-   by backing up or outputting a carriage return and moving forward.  CUR
-   and NEW are either both buffer positions or absolute screen positions. */
-#define CR_FASTER(new, cur) (((new) + 1) < ((cur) - (new)))
-
-/* _rl_last_c_pos is an absolute cursor position in multibyte locales and a
-   buffer index in others.  This macro is used when deciding whether the
-   current cursor position is in the middle of a prompt string containing
-   invisible characters.  XXX - might need to take `modmark' into account. */
-#define PROMPT_ENDING_INDEX \
-  ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) ? prompt_physical_chars : prompt_last_invisible+1)
-  
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Display stuff                               */
-/*                                                                 */
-/* **************************************************************** */
-
-/* This is the stuff that is hard for me.  I never seem to write good
-   display routines in C.  Let's see how I do this time. */
-
-/* (PWP) Well... Good for a simple line updater, but totally ignores
-   the problems of input lines longer than the screen width.
-
-   update_line and the code that calls it makes a multiple line,
-   automatically wrapping line update.  Careful attention needs
-   to be paid to the vertical position variables. */
-
-/* Keep two buffers; one which reflects the current contents of the
-   screen, and the other to draw what we think the new contents should
-   be.  Then compare the buffers, and make whatever changes to the
-   screen itself that we should.  Finally, make the buffer that we
-   just drew into be the one which reflects the current contents of the
-   screen, and place the cursor where it belongs.
-
-   Commands that want to can fix the display themselves, and then let
-   this function know that the display has been fixed by setting the
-   RL_DISPLAY_FIXED variable.  This is good for efficiency. */
-
-/* Application-specific redisplay function. */
-rl_voidfunc_t *rl_redisplay_function = rl_redisplay;
-
-/* Global variables declared here. */
-/* What YOU turn on when you have handled all redisplay yourself. */
-int rl_display_fixed = 0;
-
-int _rl_suppress_redisplay = 0;
-int _rl_want_redisplay = 0;
-
-/* The stuff that gets printed out before the actual text of the line.
-   This is usually pointing to rl_prompt. */
-char *rl_display_prompt = (char *)NULL;
-
-/* Pseudo-global variables declared here. */
-
-/* The visible cursor position.  If you print some text, adjust this. */
-/* NOTE: _rl_last_c_pos is used as a buffer index when not in a locale
-   supporting multibyte characters, and an absolute cursor position when
-   in such a locale.  This is an artifact of the donated multibyte support.
-   Care must be taken when modifying its value. */
-int _rl_last_c_pos = 0;
-int _rl_last_v_pos = 0;
-
-static int cpos_adjusted;
-static int cpos_buffer_position;
-static int prompt_multibyte_chars;
-
-/* Number of lines currently on screen minus 1. */
-int _rl_vis_botlin = 0;
-
-/* Variables used only in this file. */
-/* The last left edge of text that was displayed.  This is used when
-   doing horizontal scrolling.  It shifts in thirds of a screenwidth. */
-static int last_lmargin;
-
-/* A buffer for `modeline' messages. */
-static char msg_buf[128];
-
-/* Non-zero forces the redisplay even if we thought it was unnecessary. */
-static int forced_display;
-
-/* Default and initial buffer size.  Can grow. */
-static int line_size = 1024;
-
-/* Variables to keep track of the expanded prompt string, which may
-   include invisible characters. */
-
-static char *local_prompt, *local_prompt_prefix;
-static int local_prompt_len;
-static int prompt_visible_length, prompt_prefix_length;
-
-/* The number of invisible characters in the line currently being
-   displayed on the screen. */
-static int visible_wrap_offset;
-
-/* The number of invisible characters in the prompt string.  Static so it
-   can be shared between rl_redisplay and update_line */
-static int wrap_offset;
-
-/* The index of the last invisible character in the prompt string. */
-static int prompt_last_invisible;
-
-/* The length (buffer offset) of the first line of the last (possibly
-   multi-line) buffer displayed on the screen. */
-static int visible_first_line_len;
-
-/* Number of invisible characters on the first physical line of the prompt.
-   Only valid when the number of physical characters in the prompt exceeds
-   (or is equal to) _rl_screenwidth. */
-static int prompt_invis_chars_first_line;
-
-static int prompt_last_screen_line;
-
-static int prompt_physical_chars;
-
-/* set to a non-zero value by rl_redisplay if we are marking modified history
-   lines and the current line is so marked. */
-static int modmark;
-
-/* Variables to save and restore prompt and display information. */
-
-/* These are getting numerous enough that it's time to create a struct. */
-
-static char *saved_local_prompt;
-static char *saved_local_prefix;
-static int saved_last_invisible;
-static int saved_visible_length;
-static int saved_prefix_length;
-static int saved_local_length;
-static int saved_invis_chars_first_line;
-static int saved_physical_chars;
-
-/* Expand the prompt string S and return the number of visible
-   characters in *LP, if LP is not null.  This is currently more-or-less
-   a placeholder for expansion.  LIP, if non-null is a place to store the
-   index of the last invisible character in the returned string. NIFLP,
-   if non-zero, is a place to store the number of invisible characters in
-   the first prompt line.  The previous are used as byte counts -- indexes
-   into a character buffer. */
-
-/* Current implementation:
-       \001 (^A) start non-visible characters
-       \002 (^B) end non-visible characters
-   all characters except \001 and \002 (following a \001) are copied to
-   the returned string; all characters except those between \001 and
-   \002 are assumed to be `visible'. */        
-
-static char *
-expand_prompt (pmt, lp, lip, niflp, vlp)
-     char *pmt;
-     int *lp, *lip, *niflp, *vlp;
-{
-  char *r, *ret, *p, *igstart;
-  int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars;
-
-  /* Short-circuit if we can. */
-  if ((MB_CUR_MAX <= 1 || rl_byte_oriented) && strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
-    {
-      r = savestring (pmt);
-      if (lp)
-       *lp = strlen (r);
-      if (lip)
-       *lip = 0;
-      if (niflp)
-       *niflp = 0;
-      if (vlp)
-       *vlp = lp ? *lp : strlen (r);
-      return r;
-    }
-
-  l = strlen (pmt);
-  r = ret = (char *)xmalloc (l + 1);
-
-  invfl = 0;   /* invisible chars in first line of prompt */
-  invflset = 0;        /* we only want to set invfl once */
-
-  igstart = 0;
-  for (rl = ignoring = last = ninvis = physchars = 0, p = pmt; p && *p; p++)
-    {
-      /* This code strips the invisible character string markers
-        RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
-      if (ignoring == 0 && *p == RL_PROMPT_START_IGNORE)               /* XXX - check ignoring? */
-       {
-         ignoring = 1;
-         igstart = p;
-         continue;
-       }
-      else if (ignoring && *p == RL_PROMPT_END_IGNORE)
-       {
-         ignoring = 0;
-         if (p != (igstart + 1))
-           last = r - ret - 1;
-         continue;
-       }
-      else
-       {
-#if defined (HANDLE_MULTIBYTE)
-         if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-           {
-             pind = p - pmt;
-             ind = _rl_find_next_mbchar (pmt, pind, 1, MB_FIND_NONZERO);
-             l = ind - pind;
-             while (l--)
-               *r++ = *p++;
-             if (!ignoring)
-               {
-                 /* rl ends up being assigned to prompt_visible_length,
-                    which is the number of characters in the buffer that
-                    contribute to characters on the screen, which might
-                    not be the same as the number of physical characters
-                    on the screen in the presence of multibyte characters */
-                 rl += ind - pind;
-                 physchars += _rl_col_width (pmt, pind, ind);
-               }
-             else
-               ninvis += ind - pind;
-             p--;                      /* compensate for later increment */
-           }
-         else
-#endif
-           {
-             *r++ = *p;
-             if (!ignoring)
-               {
-                 rl++;                 /* visible length byte counter */
-                 physchars++;
-               }
-             else
-               ninvis++;               /* invisible chars byte counter */
-           }
-
-         if (invflset == 0 && rl >= _rl_screenwidth)
-           {
-             invfl = ninvis;
-             invflset = 1;
-           }
-       }
-    }
-
-  if (rl < _rl_screenwidth)
-    invfl = ninvis;
-
-  *r = '\0';
-  if (lp)
-    *lp = rl;
-  if (lip)
-    *lip = last;
-  if (niflp)
-    *niflp = invfl;
-  if  (vlp)
-    *vlp = physchars;
-  return ret;
-}
-
-/* Just strip out RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE from
-   PMT and return the rest of PMT. */
-char *
-_rl_strip_prompt (pmt)
-     char *pmt;
-{
-  char *ret;
-
-  ret = expand_prompt (pmt, (int *)NULL, (int *)NULL, (int *)NULL, (int *)NULL);
-  return ret;
-}
-
-/*
- * Expand the prompt string into the various display components, if
- * necessary.
- *
- * local_prompt = expanded last line of string in rl_display_prompt
- *               (portion after the final newline)
- * local_prompt_prefix = portion before last newline of rl_display_prompt,
- *                      expanded via expand_prompt
- * prompt_visible_length = number of visible characters in local_prompt
- * prompt_prefix_length = number of visible characters in local_prompt_prefix
- *
- * This function is called once per call to readline().  It may also be
- * called arbitrarily to expand the primary prompt.
- *
- * The return value is the number of visible characters on the last line
- * of the (possibly multi-line) prompt.
- */
-int
-rl_expand_prompt (prompt)
-     char *prompt;
-{
-  char *p, *t;
-  int c;
-
-  /* Clear out any saved values. */
-  FREE (local_prompt);
-  FREE (local_prompt_prefix);
-
-  local_prompt = local_prompt_prefix = (char *)0;
-  local_prompt_len = 0;
-  prompt_last_invisible = prompt_invis_chars_first_line = 0;
-  prompt_visible_length = prompt_physical_chars = 0;
-
-  if (prompt == 0 || *prompt == 0)
-    return (0);
-
-  p = strrchr (prompt, '\n');
-  if (!p)
-    {
-      /* The prompt is only one logical line, though it might wrap. */
-      local_prompt = expand_prompt (prompt, &prompt_visible_length,
-                                           &prompt_last_invisible,
-                                           &prompt_invis_chars_first_line,
-                                           &prompt_physical_chars);
-      local_prompt_prefix = (char *)0;
-      local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
-      return (prompt_visible_length);
-    }
-  else
-    {
-      /* The prompt spans multiple lines. */
-      t = ++p;
-      local_prompt = expand_prompt (p, &prompt_visible_length,
-                                      &prompt_last_invisible,
-                                      &prompt_invis_chars_first_line,
-                                      &prompt_physical_chars);
-      c = *t; *t = '\0';
-      /* The portion of the prompt string up to and including the
-        final newline is now null-terminated. */
-      local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length,
-                                                  (int *)NULL,
-                                                  (int *)NULL,
-                                                  (int *)NULL);
-      *t = c;
-      local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
-      return (prompt_prefix_length);
-    }
-}
-
-/* Initialize the VISIBLE_LINE and INVISIBLE_LINE arrays, and their associated
-   arrays of line break markers.  MINSIZE is the minimum size of VISIBLE_LINE
-   and INVISIBLE_LINE; if it is greater than LINE_SIZE, LINE_SIZE is
-   increased.  If the lines have already been allocated, this ensures that
-   they can hold at least MINSIZE characters. */
-static void
-init_line_structures (minsize)
-      int minsize;
-{
-  register int n;
-
-  if (invisible_line == 0)     /* initialize it */
-    {
-      if (line_size < minsize)
-       line_size = minsize;
-      visible_line = (char *)xmalloc (line_size);
-      invisible_line = (char *)xmalloc (line_size);
-    }
-  else if (line_size < minsize)        /* ensure it can hold MINSIZE chars */
-    {
-      line_size *= 2;
-      if (line_size < minsize)
-       line_size = minsize;
-      visible_line = (char *)xrealloc (visible_line, line_size);
-      invisible_line = (char *)xrealloc (invisible_line, line_size);
-    }
-
-  for (n = minsize; n < line_size; n++)
-    {
-      visible_line[n] = 0;
-      invisible_line[n] = 1;
-    }
-
-  if (vis_lbreaks == 0)
-    {
-      /* should be enough. */
-      inv_lbsize = vis_lbsize = 256;
-
-#if defined (HANDLE_MULTIBYTE)
-      line_state_visible->wbsize = vis_lbsize;
-      line_state_visible->wrapped_line = (int *)xmalloc (line_state_visible->wbsize * sizeof (int));
-
-      line_state_invisible->wbsize = inv_lbsize;
-      line_state_invisible->wrapped_line = (int *)xmalloc (line_state_invisible->wbsize * sizeof (int));
-#endif
-
-      inv_lbreaks = (int *)xmalloc (inv_lbsize * sizeof (int));
-      vis_lbreaks = (int *)xmalloc (vis_lbsize * sizeof (int));
-      inv_lbreaks[0] = vis_lbreaks[0] = 0;
-    }
-
-  line_structures_initialized = 1;
-}
-  
-/* Basic redisplay algorithm. */
-void
-rl_redisplay ()
-{
-  register int in, out, c, linenum, cursor_linenum;
-  register char *line;
-  int inv_botlin, lb_botlin, lb_linenum, o_cpos;
-  int newlines, lpos, temp, n0, num, prompt_lines_estimate;
-  char *prompt_this_line;
-#if defined (HANDLE_MULTIBYTE)
-  wchar_t wc;
-  size_t wc_bytes;
-  int wc_width;
-  mbstate_t ps;
-  int _rl_wrapped_multicolumn = 0;
-#endif
-
-  if (_rl_echoing_p == 0)
-    return;
-
-  /* Block keyboard interrupts because this function manipulates global
-     data structures. */
-  _rl_block_sigint ();  
-  RL_SETSTATE (RL_STATE_REDISPLAYING);
-
-  if (!rl_display_prompt)
-    rl_display_prompt = "";
-
-  if (line_structures_initialized == 0)
-    {
-      init_line_structures (0);
-      rl_on_new_line ();
-    }
-
-  /* Draw the line into the buffer. */
-  cpos_buffer_position = -1;
-
-  prompt_multibyte_chars = prompt_visible_length - prompt_physical_chars;
-
-  line = invisible_line;
-  out = inv_botlin = 0;
-
-  /* Mark the line as modified or not.  We only do this for history
-     lines. */
-  modmark = 0;
-  if (_rl_mark_modified_lines && current_history () && rl_undo_list)
-    {
-      line[out++] = '*';
-      line[out] = '\0';
-      modmark = 1;
-    }
-
-  /* If someone thought that the redisplay was handled, but the currently
-     visible line has a different modification state than the one about
-     to become visible, then correct the caller's misconception. */
-  if (visible_line[0] != invisible_line[0])
-    rl_display_fixed = 0;
-
-  /* If the prompt to be displayed is the `primary' readline prompt (the
-     one passed to readline()), use the values we have already expanded.
-     If not, use what's already in rl_display_prompt.  WRAP_OFFSET is the
-     number of non-visible characters in the prompt string. */
-  if (rl_display_prompt == rl_prompt || local_prompt)
-    {
-      if (local_prompt_prefix && forced_display)
-       _rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix));
-
-      if (local_prompt_len > 0)
-       {
-         temp = local_prompt_len + out + 2;
-         if (temp >= line_size)
-           {
-             line_size = (temp + 1024) - (temp % 1024);
-             visible_line = (char *)xrealloc (visible_line, line_size);
-             line = invisible_line = (char *)xrealloc (invisible_line, line_size);
-           }
-         strncpy (line + out, local_prompt, local_prompt_len);
-         out += local_prompt_len;
-       }
-      line[out] = '\0';
-      wrap_offset = local_prompt_len - prompt_visible_length;
-    }
-  else
-    {
-      int pmtlen;
-      prompt_this_line = strrchr (rl_display_prompt, '\n');
-      if (!prompt_this_line)
-       prompt_this_line = rl_display_prompt;
-      else
-       {
-         prompt_this_line++;
-         pmtlen = prompt_this_line - rl_display_prompt;        /* temp var */
-         if (forced_display)
-           {
-             _rl_output_some_chars (rl_display_prompt, pmtlen);
-             /* Make sure we are at column zero even after a newline,
-                regardless of the state of terminal output processing. */
-             if (pmtlen < 2 || prompt_this_line[-2] != '\r')
-               cr ();
-           }
-       }
-
-      prompt_physical_chars = pmtlen = strlen (prompt_this_line);
-      temp = pmtlen + out + 2;
-      if (temp >= line_size)
-       {
-         line_size = (temp + 1024) - (temp % 1024);
-         visible_line = (char *)xrealloc (visible_line, line_size);
-         line = invisible_line = (char *)xrealloc (invisible_line, line_size);
-       }
-      strncpy (line + out,  prompt_this_line, pmtlen);
-      out += pmtlen;
-      line[out] = '\0';
-      wrap_offset = prompt_invis_chars_first_line = 0;
-    }
-
-#define CHECK_INV_LBREAKS() \
-      do { \
-       if (newlines >= (inv_lbsize - 2)) \
-         { \
-           inv_lbsize *= 2; \
-           inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
-         } \
-      } while (0)
-
-#if defined (HANDLE_MULTIBYTE)   
-#define CHECK_LPOS() \
-      do { \
-       lpos++; \
-       if (lpos >= _rl_screenwidth) \
-         { \
-           if (newlines >= (inv_lbsize - 2)) \
-             { \
-               inv_lbsize *= 2; \
-               inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
-             } \
-           inv_lbreaks[++newlines] = out; \
-           if (newlines >= (line_state_invisible->wbsize - 1)) \
-             { \
-               line_state_invisible->wbsize *= 2; \
-               line_state_invisible->wrapped_line = (int *)xrealloc (line_state_invisible->wrapped_line, line_state_invisible->wbsize * sizeof(int)); \
-             } \
-           line_state_invisible->wrapped_line[newlines] = _rl_wrapped_multicolumn; \
-           lpos = 0; \
-         } \
-      } while (0)
-#else
-#define CHECK_LPOS() \
-      do { \
-       lpos++; \
-       if (lpos >= _rl_screenwidth) \
-         { \
-           if (newlines >= (inv_lbsize - 2)) \
-             { \
-               inv_lbsize *= 2; \
-               inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
-             } \
-           inv_lbreaks[++newlines] = out; \
-           lpos = 0; \
-         } \
-      } while (0)
-#endif
-
-  /* inv_lbreaks[i] is where line i starts in the buffer. */
-  inv_lbreaks[newlines = 0] = 0;
-  lpos = prompt_physical_chars + modmark;
-
-#if defined (HANDLE_MULTIBYTE)
-  memset (line_state_invisible->wrapped_line, 0, line_state_invisible->wbsize * sizeof (int));
-  num = 0;
-#endif
-
-  /* prompt_invis_chars_first_line is the number of invisible characters in
-     the first physical line of the prompt.
-     wrap_offset - prompt_invis_chars_first_line is the number of invis
-     chars on the second (or, more generally, last) line. */
-
-  /* This is zero-based, used to set the newlines */
-  prompt_lines_estimate = lpos / _rl_screenwidth;
-
-  /* what if lpos is already >= _rl_screenwidth before we start drawing the
-     contents of the command line? */
-  while (lpos >= _rl_screenwidth)
-    {
-      int z;
-      /* fix from Darin Johnson <darin@acuson.com> for prompt string with
-         invisible characters that is longer than the screen width.  The
-         prompt_invis_chars_first_line variable could be made into an array
-         saying how many invisible characters there are per line, but that's
-         probably too much work for the benefit gained.  How many people have
-         prompts that exceed two physical lines?
-         Additional logic fix from Edward Catmur <ed@catmur.co.uk> */
-#if defined (HANDLE_MULTIBYTE)
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0)
-       {
-         n0 = num;
-          temp = local_prompt_len;
-          while (num < temp)
-           {
-             z = _rl_col_width  (local_prompt, n0, num);
-             if (z > _rl_screenwidth)
-               {
-                 num = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY);
-                 break;
-               }
-             else if (z == _rl_screenwidth)
-               break;
-             num++;
-           }
-          temp = num;
-       }
-      else
-#endif /* !HANDLE_MULTIBYTE */
-       temp = ((newlines + 1) * _rl_screenwidth);
-
-      /* Now account for invisible characters in the current line. */
-      /* XXX - this assumes that the invisible characters may be split, but only
-        between the first and the last lines. */
-      temp += ((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line
-                                                            : ((newlines == prompt_lines_estimate) ? wrap_offset : prompt_invis_chars_first_line))
-                                         : ((newlines == 0) ? wrap_offset : 0));
-             
-      inv_lbreaks[++newlines] = temp;
-#if defined (HANDLE_MULTIBYTE)
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0)
-       lpos -= _rl_col_width (local_prompt, n0, num);
-      else
-#endif
-       lpos -= _rl_screenwidth;
-    }
-
-  prompt_last_screen_line = newlines;
-
-  /* Draw the rest of the line (after the prompt) into invisible_line, keeping
-     track of where the cursor is (cpos_buffer_position), the number of the line containing
-     the cursor (lb_linenum), the last line number (lb_botlin and inv_botlin).
-     It maintains an array of line breaks for display (inv_lbreaks).
-     This handles expanding tabs for display and displaying meta characters. */
-  lb_linenum = 0;
-#if defined (HANDLE_MULTIBYTE)
-  in = 0;
-  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-    {
-      memset (&ps, 0, sizeof (mbstate_t));
-      /* XXX - what if wc_bytes ends up <= 0? check for MB_INVALIDCH */
-      wc_bytes = mbrtowc (&wc, rl_line_buffer, rl_end, &ps);
-    }
-  else
-    wc_bytes = 1;
-  while (in < rl_end)
-#else
-  for (in = 0; in < rl_end; in++)
-#endif
-    {
-      c = (unsigned char)rl_line_buffer[in];
-
-#if defined (HANDLE_MULTIBYTE)
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-       {
-         if (MB_INVALIDCH (wc_bytes))
-           {
-             /* Byte sequence is invalid or shortened.  Assume that the
-                first byte represents a character. */
-             wc_bytes = 1;
-             /* Assume that a character occupies a single column. */
-             wc_width = 1;
-             memset (&ps, 0, sizeof (mbstate_t));
-           }
-         else if (MB_NULLWCH (wc_bytes))
-           break;                      /* Found '\0' */
-         else
-           {
-             temp = wcwidth (wc);
-             wc_width = (temp >= 0) ? temp : 1;
-           }
-       }
-#endif
-
-      if (out + 8 >= line_size)                /* XXX - 8 for \t */
-       {
-         line_size *= 2;
-         visible_line = (char *)xrealloc (visible_line, line_size);
-         invisible_line = (char *)xrealloc (invisible_line, line_size);
-         line = invisible_line;
-       }
-
-      if (in == rl_point)
-       {
-         cpos_buffer_position = out;
-         lb_linenum = newlines;
-       }
-
-#if defined (HANDLE_MULTIBYTE)
-      if (META_CHAR (c) && _rl_output_meta_chars == 0) /* XXX - clean up */
-#else
-      if (META_CHAR (c))
-#endif
-       {
-         if (_rl_output_meta_chars == 0)
-           {
-             sprintf (line + out, "\\%o", c);
-
-             if (lpos + 4 >= _rl_screenwidth)
-               {
-                 temp = _rl_screenwidth - lpos;
-                 CHECK_INV_LBREAKS ();
-                 inv_lbreaks[++newlines] = out + temp;
-                 lpos = 4 - temp;
-               }
-             else
-               lpos += 4;
-
-             out += 4;
-           }
-         else
-           {
-             line[out++] = c;
-             CHECK_LPOS();
-           }
-       }
-#if defined (DISPLAY_TABS)
-      else if (c == '\t')
-       {
-         register int newout;
-
-#if 0
-         newout = (out | (int)7) + 1;
-#else
-         newout = out + 8 - lpos % 8;
-#endif
-         temp = newout - out;
-         if (lpos + temp >= _rl_screenwidth)
-           {
-             register int temp2;
-             temp2 = _rl_screenwidth - lpos;
-             CHECK_INV_LBREAKS ();
-             inv_lbreaks[++newlines] = out + temp2;
-             lpos = temp - temp2;
-             while (out < newout)
-               line[out++] = ' ';
-           }
-         else
-           {
-             while (out < newout)
-               line[out++] = ' ';
-             lpos += temp;
-           }
-       }
-#endif
-      else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
-       {
-         line[out++] = '\0';   /* XXX - sentinel */
-         CHECK_INV_LBREAKS ();
-         inv_lbreaks[++newlines] = out;
-         lpos = 0;
-       }
-      else if (CTRL_CHAR (c) || c == RUBOUT)
-       {
-         line[out++] = '^';
-         CHECK_LPOS();
-         line[out++] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
-         CHECK_LPOS();
-       }
-      else
-       {
-#if defined (HANDLE_MULTIBYTE)
-         if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-           {
-             register int i;
-
-             _rl_wrapped_multicolumn = 0;
-
-             if (_rl_screenwidth < lpos + wc_width)
-               for (i = lpos; i < _rl_screenwidth; i++)
-                 {
-                   /* The space will be removed in update_line() */
-                   line[out++] = ' ';
-                   _rl_wrapped_multicolumn++;
-                   CHECK_LPOS();
-                 }
-             if (in == rl_point)
-               {
-                 cpos_buffer_position = out;
-                 lb_linenum = newlines;
-               }
-             for (i = in; i < in+wc_bytes; i++)
-               line[out++] = rl_line_buffer[i];
-             for (i = 0; i < wc_width; i++)
-               CHECK_LPOS();
-           }
-         else
-           {
-             line[out++] = c;
-             CHECK_LPOS();
-           }
-#else
-         line[out++] = c;
-         CHECK_LPOS();
-#endif
-       }
-
-#if defined (HANDLE_MULTIBYTE)
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-       {
-         in += wc_bytes;
-         /* XXX - what if wc_bytes ends up <= 0? check for MB_INVALIDCH */
-         wc_bytes = mbrtowc (&wc, rl_line_buffer + in, rl_end - in, &ps);
-       }
-      else
-        in++;
-#endif
-
-    }
-  line[out] = '\0';
-  if (cpos_buffer_position < 0)
-    {
-      cpos_buffer_position = out;
-      lb_linenum = newlines;
-    }
-
-  inv_botlin = lb_botlin = newlines;
-  CHECK_INV_LBREAKS ();
-  inv_lbreaks[newlines+1] = out;
-  cursor_linenum = lb_linenum;
-
-  /* CPOS_BUFFER_POSITION == position in buffer where cursor should be placed.
-     CURSOR_LINENUM == line number where the cursor should be placed. */
-
-  /* PWP: now is when things get a bit hairy.  The visible and invisible
-     line buffers are really multiple lines, which would wrap every
-     (screenwidth - 1) characters.  Go through each in turn, finding
-     the changed region and updating it.  The line order is top to bottom. */
-
-  /* If we can move the cursor up and down, then use multiple lines,
-     otherwise, let long lines display in a single terminal line, and
-     horizontally scroll it. */
-
-  if (_rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
-    {
-      int nleft, pos, changed_screen_line, tx;
-
-      if (!rl_display_fixed || forced_display)
-       {
-         forced_display = 0;
-
-         /* If we have more than a screenful of material to display, then
-            only display a screenful.  We should display the last screen,
-            not the first.  */
-         if (out >= _rl_screenchars)
-           {
-             if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-               out = _rl_find_prev_mbchar (line, _rl_screenchars, MB_FIND_ANY);
-             else
-               out = _rl_screenchars - 1;
-           }
-
-         /* The first line is at character position 0 in the buffer.  The
-            second and subsequent lines start at inv_lbreaks[N], offset by
-            OFFSET (which has already been calculated above).  */
-
-#define INVIS_FIRST()  (prompt_physical_chars > _rl_screenwidth ? prompt_invis_chars_first_line : wrap_offset)
-#define WRAP_OFFSET(line, offset)  ((line == 0) \
-                                       ? (offset ? INVIS_FIRST() : 0) \
-                                       : ((line == prompt_last_screen_line) ? wrap_offset-prompt_invis_chars_first_line : 0))
-#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
-#define VIS_LLEN(l)    ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
-#define INV_LLEN(l)    (inv_lbreaks[l+1] - inv_lbreaks[l])
-#define VIS_CHARS(line) (visible_line + vis_lbreaks[line])
-#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
-#define INV_LINE(line) (invisible_line + inv_lbreaks[line])
-
-#define OLD_CPOS_IN_PROMPT() (cpos_adjusted == 0 && \
-                       _rl_last_c_pos != o_cpos && \
-                       _rl_last_c_pos > wrap_offset && \
-                       o_cpos < prompt_last_invisible)
-
-         /* For each line in the buffer, do the updating display. */
-         for (linenum = 0; linenum <= inv_botlin; linenum++)
-           {
-             /* This can lead us astray if we execute a program that changes
-                the locale from a non-multibyte to a multibyte one. */
-             o_cpos = _rl_last_c_pos;
-             cpos_adjusted = 0;
-             update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum,
-                          VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin);
-
-             /* update_line potentially changes _rl_last_c_pos, but doesn't
-                take invisible characters into account, since _rl_last_c_pos
-                is an absolute cursor position in a multibyte locale.  See
-                if compensating here is the right thing, or if we have to
-                change update_line itself.  There are several cases in which
-                update_line adjusts _rl_last_c_pos itself (so it can pass
-                _rl_move_cursor_relative accurate values); it communicates
-                this back by setting cpos_adjusted.  If we assume that
-                _rl_last_c_pos is correct (an absolute cursor position) each
-                time update_line is called, then we can assume in our
-                calculations that o_cpos does not need to be adjusted by
-                wrap_offset. */
-             if (linenum == 0 && (MB_CUR_MAX > 1 && rl_byte_oriented == 0) && OLD_CPOS_IN_PROMPT())
-               _rl_last_c_pos -= prompt_invis_chars_first_line;        /* XXX - was wrap_offset */
-             else if (linenum == prompt_last_screen_line && prompt_physical_chars > _rl_screenwidth &&
-                       (MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
-                       cpos_adjusted == 0 &&
-                       _rl_last_c_pos != o_cpos &&
-                       _rl_last_c_pos > (prompt_last_invisible - _rl_screenwidth - prompt_invis_chars_first_line))
-               _rl_last_c_pos -= (wrap_offset-prompt_invis_chars_first_line);
-                 
-             /* If this is the line with the prompt, we might need to
-                compensate for invisible characters in the new line. Do
-                this only if there is not more than one new line (which
-                implies that we completely overwrite the old visible line)
-                and the new line is shorter than the old.  Make sure we are
-                at the end of the new line before clearing. */
-             if (linenum == 0 &&
-                 inv_botlin == 0 && _rl_last_c_pos == out &&
-                 (wrap_offset > visible_wrap_offset) &&
-                 (_rl_last_c_pos < visible_first_line_len))
-               {
-                 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-                   nleft = _rl_screenwidth - _rl_last_c_pos;
-                 else
-                   nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos;
-                 if (nleft)
-                   _rl_clear_to_eol (nleft);
-               }
-#if 0
-             /* This segment is intended to handle the case where the prompt
-                has invisible characters on the second line and the new line
-                to be displayed needs to clear the rest of the old characters
-                out (e.g., when printing the i-search prompt).  In general,
-                the case of the new line being shorter than the old.
-                Incomplete */
-             else if (linenum == prompt_last_screen_line &&
-                      prompt_physical_chars > _rl_screenwidth &&
-                      wrap_offset != prompt_invis_chars_first_line &&
-                      _rl_last_c_pos == out &&
-#endif
-
-
-             /* Since the new first line is now visible, save its length. */
-             if (linenum == 0)
-               visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset;
-           }
-
-         /* We may have deleted some lines.  If so, clear the left over
-            blank ones at the bottom out. */
-         if (_rl_vis_botlin > inv_botlin)
-           {
-             char *tt;
-             for (; linenum <= _rl_vis_botlin; linenum++)
-               {
-                 tt = VIS_CHARS (linenum);
-                 _rl_move_vert (linenum);
-                 _rl_move_cursor_relative (0, tt);
-                 _rl_clear_to_eol
-                   ((linenum == _rl_vis_botlin) ? strlen (tt) : _rl_screenwidth);
-               }
-           }
-         _rl_vis_botlin = inv_botlin;
-
-         /* CHANGED_SCREEN_LINE is set to 1 if we have moved to a
-            different screen line during this redisplay. */
-         changed_screen_line = _rl_last_v_pos != cursor_linenum;
-         if (changed_screen_line)
-           {
-             _rl_move_vert (cursor_linenum);
-             /* If we moved up to the line with the prompt using _rl_term_up,
-                the physical cursor position on the screen stays the same,
-                but the buffer position needs to be adjusted to account
-                for invisible characters. */
-             if ((MB_CUR_MAX == 1 || rl_byte_oriented) && cursor_linenum == 0 && wrap_offset)
-               _rl_last_c_pos += wrap_offset;
-           }
-
-         /* We have to reprint the prompt if it contains invisible
-            characters, since it's not generally OK to just reprint
-            the characters from the current cursor position.  But we
-            only need to reprint it if the cursor is before the last
-            invisible character in the prompt string. */
-         nleft = prompt_visible_length + wrap_offset;
-         if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&
-#if 0
-             _rl_last_c_pos <= PROMPT_ENDING_INDEX && local_prompt)
-#else
-             _rl_last_c_pos < PROMPT_ENDING_INDEX && local_prompt)
-#endif
-           {
-#if defined (__MSDOS__)
-             putc ('\r', rl_outstream);
-#else
-             if (_rl_term_cr)
-               tputs (_rl_term_cr, 1, _rl_output_character_function);
-#endif
-             if (modmark)
-               _rl_output_some_chars ("*", 1);
-
-             _rl_output_some_chars (local_prompt, nleft);
-             if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-               _rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft) - wrap_offset + modmark;
-             else
-               _rl_last_c_pos = nleft + modmark;
-           }
-
-         /* Where on that line?  And where does that line start
-            in the buffer? */
-         pos = inv_lbreaks[cursor_linenum];
-         /* nleft == number of characters in the line buffer between the
-            start of the line and the desired cursor position. */
-         nleft = cpos_buffer_position - pos;
-
-         /* NLEFT is now a number of characters in a buffer.  When in a
-            multibyte locale, however, _rl_last_c_pos is an absolute cursor
-            position that doesn't take invisible characters in the prompt
-            into account.  We use a fudge factor to compensate. */
-
-         /* Since _rl_backspace() doesn't know about invisible characters in the
-            prompt, and there's no good way to tell it, we compensate for
-            those characters here and call _rl_backspace() directly. */
-         if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
-           {
-             /* TX == new physical cursor position in multibyte locale. */
-             if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-               tx = _rl_col_width (&visible_line[pos], 0, nleft) - visible_wrap_offset;
-             else
-               tx = nleft;
-             if (tx >= 0 && _rl_last_c_pos > tx)
-               {
-                 _rl_backspace (_rl_last_c_pos - tx);  /* XXX */
-                 _rl_last_c_pos = tx;
-               }
-           }
-
-         /* We need to note that in a multibyte locale we are dealing with
-            _rl_last_c_pos as an absolute cursor position, but moving to a
-            point specified by a buffer position (NLEFT) that doesn't take
-            invisible characters into account. */
-         if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-           _rl_move_cursor_relative (nleft, &invisible_line[pos]);
-         else if (nleft != _rl_last_c_pos)
-           _rl_move_cursor_relative (nleft, &invisible_line[pos]);
-       }
-    }
-  else                         /* Do horizontal scrolling. */
-    {
-#define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0)
-      int lmargin, ndisp, nleft, phys_c_pos, t;
-
-      /* Always at top line. */
-      _rl_last_v_pos = 0;
-
-      /* Compute where in the buffer the displayed line should start.  This
-        will be LMARGIN. */
-
-      /* The number of characters that will be displayed before the cursor. */
-      ndisp = cpos_buffer_position - wrap_offset;
-      nleft  = prompt_visible_length + wrap_offset;
-      /* Where the new cursor position will be on the screen.  This can be
-        longer than SCREENWIDTH; if it is, lmargin will be adjusted. */
-      phys_c_pos = cpos_buffer_position - (last_lmargin ? last_lmargin : wrap_offset);
-      t = _rl_screenwidth / 3;
-
-      /* If the number of characters had already exceeded the screenwidth,
-        last_lmargin will be > 0. */
-
-      /* If the number of characters to be displayed is more than the screen
-        width, compute the starting offset so that the cursor is about
-        two-thirds of the way across the screen. */
-      if (phys_c_pos > _rl_screenwidth - 2)
-       {
-         lmargin = cpos_buffer_position - (2 * t);
-         if (lmargin < 0)
-           lmargin = 0;
-         /* If the left margin would be in the middle of a prompt with
-            invisible characters, don't display the prompt at all. */
-         if (wrap_offset && lmargin > 0 && lmargin < nleft)
-           lmargin = nleft;
-       }
-      else if (ndisp < _rl_screenwidth - 2)            /* XXX - was -1 */
-       lmargin = 0;
-      else if (phys_c_pos < 1)
-       {
-         /* If we are moving back towards the beginning of the line and
-            the last margin is no longer correct, compute a new one. */
-         lmargin = ((cpos_buffer_position - 1) / t) * t;       /* XXX */
-         if (wrap_offset && lmargin > 0 && lmargin < nleft)
-           lmargin = nleft;
-       }
-      else
-       lmargin = last_lmargin;
-
-      /* If the first character on the screen isn't the first character
-        in the display line, indicate this with a special character. */
-      if (lmargin > 0)
-       line[lmargin] = '<';
-
-      /* If SCREENWIDTH characters starting at LMARGIN do not encompass
-        the whole line, indicate that with a special character at the
-        right edge of the screen.  If LMARGIN is 0, we need to take the
-        wrap offset into account. */
-      t = lmargin + M_OFFSET (lmargin, wrap_offset) + _rl_screenwidth;
-      if (t < out)
-       line[t - 1] = '>';
-
-      if (rl_display_fixed == 0 || forced_display || lmargin != last_lmargin)
-       {
-         forced_display = 0;
-         o_cpos = _rl_last_c_pos;
-         cpos_adjusted = 0;
-         update_line (&visible_line[last_lmargin],
-                      &invisible_line[lmargin],
-                      0,
-                      _rl_screenwidth + visible_wrap_offset,
-                      _rl_screenwidth + (lmargin ? 0 : wrap_offset),
-                      0);
-
-         if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && OLD_CPOS_IN_PROMPT())
-           _rl_last_c_pos -= prompt_invis_chars_first_line;    /* XXX - was wrap_offset */
-
-         /* If the visible new line is shorter than the old, but the number
-            of invisible characters is greater, and we are at the end of
-            the new line, we need to clear to eol. */
-         t = _rl_last_c_pos - M_OFFSET (lmargin, wrap_offset);
-         if ((M_OFFSET (lmargin, wrap_offset) > visible_wrap_offset) &&
-             (_rl_last_c_pos == out) &&
-             t < visible_first_line_len)
-           {
-             nleft = _rl_screenwidth - t;
-             _rl_clear_to_eol (nleft);
-           }
-         visible_first_line_len = out - lmargin - M_OFFSET (lmargin, wrap_offset);
-         if (visible_first_line_len > _rl_screenwidth)
-           visible_first_line_len = _rl_screenwidth;
-
-         _rl_move_cursor_relative (cpos_buffer_position - lmargin, &invisible_line[lmargin]);
-         last_lmargin = lmargin;
-       }
-    }
-  fflush (rl_outstream);
-
-  /* Swap visible and non-visible lines. */
-  {
-    struct line_state *vtemp = line_state_visible;
-
-    line_state_visible = line_state_invisible;
-    line_state_invisible = vtemp;
-
-    rl_display_fixed = 0;
-    /* If we are displaying on a single line, and last_lmargin is > 0, we
-       are not displaying any invisible characters, so set visible_wrap_offset
-       to 0. */
-    if (_rl_horizontal_scroll_mode && last_lmargin)
-      visible_wrap_offset = 0;
-    else
-      visible_wrap_offset = wrap_offset;
-  }
-
-  RL_UNSETSTATE (RL_STATE_REDISPLAYING);
-  _rl_release_sigint ();
-}
-
-/* PWP: update_line() is based on finding the middle difference of each
-   line on the screen; vis:
-
-                            /old first difference
-       /beginning of line   |        /old last same       /old EOL
-       v                    v        v             v
-old:   eddie> Oh, my little gruntle-buggy is to me, as lurgid as
-new:   eddie> Oh, my little buggy says to me, as lurgid as
-       ^                    ^  ^                          ^
-       \beginning of line   |  \new last same     \new end of line
-                            \new first difference
-
-   All are character pointers for the sake of speed.  Special cases for
-   no differences, as well as for end of line additions must be handled.
-
-   Could be made even smarter, but this works well enough */
-static void
-update_line (old, new, current_line, omax, nmax, inv_botlin)
-     register char *old, *new;
-     int current_line, omax, nmax, inv_botlin;
-{
-  register char *ofd, *ols, *oe, *nfd, *nls, *ne;
-  int temp, lendiff, wsatend, od, nd, twidth, o_cpos;
-  int current_invis_chars;
-  int col_lendiff, col_temp;
-#if defined (HANDLE_MULTIBYTE)
-  mbstate_t ps_new, ps_old;
-  int new_offset, old_offset;
-#endif
-
-  /* If we're at the right edge of a terminal that supports xn, we're
-     ready to wrap around, so do so.  This fixes problems with knowing
-     the exact cursor position and cut-and-paste with certain terminal
-     emulators.  In this calculation, TEMP is the physical screen
-     position of the cursor. */
-  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-    temp = _rl_last_c_pos;
-  else
-    temp = _rl_last_c_pos - WRAP_OFFSET (_rl_last_v_pos, visible_wrap_offset);
-  if (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode
-       && _rl_last_v_pos == current_line - 1)
-    {
-#if defined (HANDLE_MULTIBYTE)
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-       {
-         wchar_t wc;
-         mbstate_t ps;
-         int tempwidth, bytes;
-         size_t ret;
-
-         /* This fixes only double-column characters, but if the wrapped
-            character comsumes more than three columns, spaces will be
-            inserted in the string buffer. */
-         if (current_line < line_state_visible->wbsize && line_state_visible->wrapped_line[current_line] > 0)
-           _rl_clear_to_eol (line_state_visible->wrapped_line[current_line]);
-
-         memset (&ps, 0, sizeof (mbstate_t));
-         ret = mbrtowc (&wc, new, MB_CUR_MAX, &ps);
-         if (MB_INVALIDCH (ret))
-           {
-             tempwidth = 1;
-             ret = 1;
-           }
-         else if (MB_NULLWCH (ret))
-           tempwidth = 0;
-         else
-           tempwidth = wcwidth (wc);
-
-         if (tempwidth > 0)
-           {
-             int count, i;
-             bytes = ret;
-             for (count = 0; count < bytes; count++)
-               putc (new[count], rl_outstream);
-             _rl_last_c_pos = tempwidth;
-             _rl_last_v_pos++;
-             memset (&ps, 0, sizeof (mbstate_t));
-             ret = mbrtowc (&wc, old, MB_CUR_MAX, &ps);
-             if (ret != 0 && bytes != 0)
-               {
-                 if (MB_INVALIDCH (ret))
-                   ret = 1;
-                 memmove (old+bytes, old+ret, strlen (old+ret));
-                 memcpy (old, new, bytes);
-                 /* Fix up indices if we copy data from one line to another */
-                 omax += bytes - ret;
-                 for (i = current_line+1; i < inv_botlin+1; i++)
-                   vis_lbreaks[i] += bytes - ret;
-               }
-           }
-         else
-           {
-             putc (' ', rl_outstream);
-             _rl_last_c_pos = 1;
-             _rl_last_v_pos++;
-             if (old[0] && new[0])
-               old[0] = new[0];
-           }
-       }
-      else
-#endif
-       {
-         if (new[0])
-           putc (new[0], rl_outstream);
-         else
-           putc (' ', rl_outstream);
-         _rl_last_c_pos = 1;
-         _rl_last_v_pos++;
-         if (old[0] && new[0])
-           old[0] = new[0];
-       }
-    }
-
-      
-  /* Find first difference. */
-#if defined (HANDLE_MULTIBYTE)
-  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-    {
-      /* See if the old line is a subset of the new line, so that the
-        only change is adding characters. */
-      temp = (omax < nmax) ? omax : nmax;
-      if (memcmp (old, new, temp) == 0)                /* adding at the end */
-       {
-         ofd = old + temp;
-         nfd = new + temp;
-       }
-      else
-       {      
-         memset (&ps_new, 0, sizeof(mbstate_t));
-         memset (&ps_old, 0, sizeof(mbstate_t));
-
-         if (omax == nmax && STREQN (new, old, omax))
-           {
-             ofd = old + omax;
-             nfd = new + nmax;
-           }
-         else
-           {
-             new_offset = old_offset = 0;
-             for (ofd = old, nfd = new;
-                   (ofd - old < omax) && *ofd &&
-                   _rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new); )
-               {
-                 old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY);
-                 new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY);
-                 ofd = old + old_offset;
-                 nfd = new + new_offset;
-               }
-           }
-       }
-    }
-  else
-#endif
-  for (ofd = old, nfd = new;
-       (ofd - old < omax) && *ofd && (*ofd == *nfd);
-       ofd++, nfd++)
-    ;
-
-  /* Move to the end of the screen line.  ND and OD are used to keep track
-     of the distance between ne and new and oe and old, respectively, to
-     move a subtraction out of each loop. */
-  for (od = ofd - old, oe = ofd; od < omax && *oe; oe++, od++);
-  for (nd = nfd - new, ne = nfd; nd < nmax && *ne; ne++, nd++);
-
-  /* If no difference, continue to next line. */
-  if (ofd == oe && nfd == ne)
-    return;
-
-  wsatend = 1;                 /* flag for trailing whitespace */
-
-#if defined (HANDLE_MULTIBYTE)
-  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-    {
-      ols = old + _rl_find_prev_mbchar (old, oe - old, MB_FIND_ANY);
-      nls = new + _rl_find_prev_mbchar (new, ne - new, MB_FIND_ANY);
-      while ((ols > ofd) && (nls > nfd))
-       {
-         memset (&ps_old, 0, sizeof (mbstate_t));
-         memset (&ps_new, 0, sizeof (mbstate_t));
-
-#if 0
-         /* On advice from jir@yamato.ibm.com */
-         _rl_adjust_point (old, ols - old, &ps_old);
-         _rl_adjust_point (new, nls - new, &ps_new);
-#endif
-
-         if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0)
-           break;
-
-         if (*ols == ' ')
-           wsatend = 0;
-
-         ols = old + _rl_find_prev_mbchar (old, ols - old, MB_FIND_ANY);
-         nls = new + _rl_find_prev_mbchar (new, nls - new, MB_FIND_ANY);
-       }
-    }
-  else
-    {
-#endif /* HANDLE_MULTIBYTE */
-  ols = oe - 1;                        /* find last same */
-  nls = ne - 1;
-  while ((ols > ofd) && (nls > nfd) && (*ols == *nls))
-    {
-      if (*ols != ' ')
-       wsatend = 0;
-      ols--;
-      nls--;
-    }
-#if defined (HANDLE_MULTIBYTE)
-    }
-#endif
-
-  if (wsatend)
-    {
-      ols = oe;
-      nls = ne;
-    }
-#if defined (HANDLE_MULTIBYTE)
-  /* This may not work for stateful encoding, but who cares?  To handle
-     stateful encoding properly, we have to scan each string from the
-     beginning and compare. */
-  else if (_rl_compare_chars (ols, 0, NULL, nls, 0, NULL) == 0)
-#else
-  else if (*ols != *nls)
-#endif
-    {
-      if (*ols)                        /* don't step past the NUL */
-       {
-         if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-           ols = old + _rl_find_next_mbchar (old, ols - old, 1, MB_FIND_ANY);
-         else
-           ols++;
-       }
-      if (*nls)
-       {
-         if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-           nls = new + _rl_find_next_mbchar (new, nls - new, 1, MB_FIND_ANY);
-         else
-           nls++;
-       }
-    }
-
-  /* count of invisible characters in the current invisible line. */
-  current_invis_chars = W_OFFSET (current_line, wrap_offset);
-  if (_rl_last_v_pos != current_line)
-    {
-      _rl_move_vert (current_line);
-      if ((MB_CUR_MAX == 1 || rl_byte_oriented) && current_line == 0 && visible_wrap_offset)
-       _rl_last_c_pos += visible_wrap_offset;
-    }
-
-  /* If this is the first line and there are invisible characters in the
-     prompt string, and the prompt string has not changed, and the current
-     cursor position is before the last invisible character in the prompt,
-     and the index of the character to move to is past the end of the prompt
-     string, then redraw the entire prompt string.  We can only do this
-     reliably if the terminal supports a `cr' capability.
-
-     This is not an efficiency hack -- there is a problem with redrawing
-     portions of the prompt string if they contain terminal escape
-     sequences (like drawing the `unbold' sequence without a corresponding
-     `bold') that manifests itself on certain terminals. */
-
-  lendiff = local_prompt_len;
-  od = ofd - old;      /* index of first difference in visible line */
-  if (current_line == 0 && !_rl_horizontal_scroll_mode &&
-      _rl_term_cr && lendiff > prompt_visible_length && _rl_last_c_pos > 0 &&
-      od >= lendiff && _rl_last_c_pos < PROMPT_ENDING_INDEX)
-    {
-#if defined (__MSDOS__)
-      putc ('\r', rl_outstream);
-#else
-      tputs (_rl_term_cr, 1, _rl_output_character_function);
-#endif
-      if (modmark)
-       _rl_output_some_chars ("*", 1);
-      _rl_output_some_chars (local_prompt, lendiff);
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-       {
-         /* We take wrap_offset into account here so we can pass correct
-            information to _rl_move_cursor_relative. */
-         _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff) - wrap_offset + modmark;
-         cpos_adjusted = 1;
-       }
-      else
-       _rl_last_c_pos = lendiff + modmark;
-    }
-
-  o_cpos = _rl_last_c_pos;
-
-  /* When this function returns, _rl_last_c_pos is correct, and an absolute
-     cursor postion in multibyte mode, but a buffer index when not in a
-     multibyte locale. */
-  _rl_move_cursor_relative (od, old);
-#if 1
-#if defined (HANDLE_MULTIBYTE)
-  /* We need to indicate that the cursor position is correct in the presence of
-     invisible characters in the prompt string.  Let's see if setting this when
-     we make sure we're at the end of the drawn prompt string works. */
-  if (current_line == 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0 &&
-      (_rl_last_c_pos > 0 || o_cpos > 0) &&
-      _rl_last_c_pos == prompt_physical_chars)
-    cpos_adjusted = 1;
-#endif
-#endif
-
-  /* if (len (new) > len (old))
-     lendiff == difference in buffer
-     col_lendiff == difference on screen
-     When not using multibyte characters, these are equal */
-  lendiff = (nls - nfd) - (ols - ofd);
-  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-    col_lendiff = _rl_col_width (new, nfd - new, nls - new) - _rl_col_width (old, ofd - old, ols - old);
-  else
-    col_lendiff = lendiff;
-
-  /* If we are changing the number of invisible characters in a line, and
-     the spot of first difference is before the end of the invisible chars,
-     lendiff needs to be adjusted. */
-  if (current_line == 0 && !_rl_horizontal_scroll_mode &&
-      current_invis_chars != visible_wrap_offset)
-    {
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-       {
-         lendiff += visible_wrap_offset - current_invis_chars;
-         col_lendiff += visible_wrap_offset - current_invis_chars;
-       }
-      else
-       {
-         lendiff += visible_wrap_offset - current_invis_chars;
-         col_lendiff = lendiff;
-       }
-    }
-
-  /* Insert (diff (len (old), len (new)) ch. */
-  temp = ne - nfd;
-  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-    col_temp = _rl_col_width (new, nfd - new, ne - new);
-  else
-    col_temp = temp;
-
-  if (col_lendiff > 0) /* XXX - was lendiff */
-    {
-      /* Non-zero if we're increasing the number of lines. */
-      int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
-      /* If col_lendiff is > 0, implying that the new string takes up more
-        screen real estate than the old, but lendiff is < 0, meaning that it
-        takes fewer bytes, we need to just output the characters starting
-        from the first difference.  These will overwrite what is on the
-        display, so there's no reason to do a smart update.  This can really
-        only happen in a multibyte environment. */
-      if (lendiff < 0)
-       {
-         _rl_output_some_chars (nfd, temp);
-         _rl_last_c_pos += _rl_col_width (nfd, 0, temp);
-         /* If nfd begins before any invisible characters in the prompt,
-            adjust _rl_last_c_pos to account for wrap_offset and set
-            cpos_adjusted to let the caller know. */
-         if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
-           {
-             _rl_last_c_pos -= wrap_offset;
-             cpos_adjusted = 1;
-           }
-         return;
-       }
-      /* Sometimes it is cheaper to print the characters rather than
-        use the terminal's capabilities.  If we're growing the number
-        of lines, make sure we actually cause the new line to wrap
-        around on auto-wrapping terminals. */
-      else if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
-       {
-         /* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and
-            _rl_horizontal_scroll_mode == 1, inserting the characters with
-            _rl_term_IC or _rl_term_ic will screw up the screen because of the
-            invisible characters.  We need to just draw them. */
-         /* The same thing happens if we're trying to draw before the last
-            invisible character in the prompt string or we're increasing the
-            number of invisible characters in the line and we're not drawing
-            the entire prompt string. */
-         if (*ols && ((_rl_horizontal_scroll_mode &&
-                       _rl_last_c_pos == 0 &&
-                       lendiff > prompt_visible_length &&
-                       current_invis_chars > 0) == 0) &&
-                     (((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
-                       current_line == 0 && wrap_offset &&
-                       ((nfd - new) <= prompt_last_invisible) &&
-                       (col_lendiff < prompt_visible_length)) == 0) &&
-                     (visible_wrap_offset >= current_invis_chars))
-           {
-             insert_some_chars (nfd, lendiff, col_lendiff);
-             _rl_last_c_pos += col_lendiff;
-           }
-#if 0          /* XXX - for now */
-         else if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && _rl_last_c_pos == 0 && wrap_offset && (nfd-new) <= prompt_last_invisible && col_lendiff < prompt_visible_length && visible_wrap_offset >= current_invis_chars)
-           {
-             _rl_output_some_chars (nfd, lendiff);
-             _rl_last_c_pos += col_lendiff;
-           }
-#endif
-         else if ((MB_CUR_MAX == 1 || rl_byte_oriented != 0) && *ols == 0 && lendiff > 0)
-           {
-             /* At the end of a line the characters do not have to
-                be "inserted".  They can just be placed on the screen. */
-             /* However, this screws up the rest of this block, which
-                assumes you've done the insert because you can. */
-             _rl_output_some_chars (nfd, lendiff);
-             _rl_last_c_pos += col_lendiff;
-           }
-         else
-           {
-             _rl_output_some_chars (nfd, temp);
-             _rl_last_c_pos += col_temp;
-             /* If nfd begins before the last invisible character in the
-                prompt, adjust _rl_last_c_pos to account for wrap_offset
-                and set cpos_adjusted to let the caller know. */
-             if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
-               {
-                 _rl_last_c_pos -= wrap_offset;
-                 cpos_adjusted = 1;
-               }
-             return;
-           }
-         /* Copy (new) chars to screen from first diff to last match. */
-         temp = nls - nfd;
-         if ((temp - lendiff) > 0)
-           {
-             _rl_output_some_chars (nfd + lendiff, temp - lendiff);
-            /* XXX -- this bears closer inspection.  Fixes a redisplay bug
-               reported against bash-3.0-alpha by Andreas Schwab involving
-               multibyte characters and prompt strings with invisible
-               characters, but was previously disabled. */
-             if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-               twidth = _rl_col_width (nfd+lendiff, 0, temp-col_lendiff);
-             else
-               twidth = temp - lendiff;
-             _rl_last_c_pos += twidth;
-             /* If nfd begins before the last invisible character in the
-                prompt, adjust _rl_last_c_pos to account for wrap_offset
-                and set cpos_adjusted to let the caller know. */
-             if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
-               {
-                 _rl_last_c_pos -= wrap_offset;
-                 cpos_adjusted = 1;
-               }
-           }
-       }
-      else
-       {
-         /* cannot insert chars, write to EOL */
-         _rl_output_some_chars (nfd, temp);
-         _rl_last_c_pos += col_temp;
-         /* If we're in a multibyte locale and were before the last invisible
-            char in the current line (which implies we just output some invisible
-            characters) we need to adjust _rl_last_c_pos, since it represents
-            a physical character position. */
-         if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
-               current_line == prompt_last_screen_line && wrap_offset &&
-               wrap_offset != prompt_invis_chars_first_line &&
-               ((nfd-new) < (prompt_last_invisible-(current_line*_rl_screenwidth))))
-           {
-             _rl_last_c_pos -= wrap_offset - prompt_invis_chars_first_line;
-             cpos_adjusted = 1;
-           }
-       }
-    }
-  else                         /* Delete characters from line. */
-    {
-      /* If possible and inexpensive to use terminal deletion, then do so. */
-      if (_rl_term_dc && (2 * col_temp) >= -col_lendiff)
-       {
-         /* If all we're doing is erasing the invisible characters in the
-            prompt string, don't bother.  It screws up the assumptions
-            about what's on the screen. */
-         if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 &&
-             -lendiff == visible_wrap_offset)
-           col_lendiff = 0;
-
-         if (col_lendiff)
-           delete_chars (-col_lendiff); /* delete (diff) characters */
-
-         /* Copy (new) chars to screen from first diff to last match */
-         temp = nls - nfd;
-         if (temp > 0)
-           {
-             /* If nfd begins at the prompt, or before the invisible
-                characters in the prompt, we need to adjust _rl_last_c_pos
-                in a multibyte locale to account for the wrap offset and
-                set cpos_adjusted accordingly. */
-             _rl_output_some_chars (nfd, temp);
-             if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-               {
-                 _rl_last_c_pos += _rl_col_width (nfd, 0, temp);
-                 if (current_line == 0 && wrap_offset &&  ((nfd - new) <= prompt_last_invisible))
-                   {
-                     _rl_last_c_pos -= wrap_offset;
-                     cpos_adjusted = 1;
-                   }
-               }
-             else
-               _rl_last_c_pos += temp;
-           }
-       }
-      /* Otherwise, print over the existing material. */
-      else
-       {
-         if (temp > 0)
-           {
-             /* If nfd begins at the prompt, or before the invisible
-                characters in the prompt, we need to adjust _rl_last_c_pos
-                in a multibyte locale to account for the wrap offset and
-                set cpos_adjusted accordingly. */
-             _rl_output_some_chars (nfd, temp);
-             _rl_last_c_pos += col_temp;               /* XXX */
-             if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-               {
-                 if (current_line == 0 && wrap_offset &&  ((nfd - new) <= prompt_last_invisible))
-                   {
-                     _rl_last_c_pos -= wrap_offset;
-                     cpos_adjusted = 1;
-                   }
-               }
-           }
-         lendiff = (oe - old) - (ne - new);
-         if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-           col_lendiff = _rl_col_width (old, 0, oe - old) - _rl_col_width (new, 0, ne - new);
-         else
-           col_lendiff = lendiff;
-
-#if 0
-         if (col_lendiff)
-#else
-         /* If we've already printed over the entire width of the screen,
-            including the old material, then col_lendiff doesn't matter and
-            space_to_eol will insert too many spaces.  XXX - maybe we should
-            adjust col_lendiff based on the difference between _rl_last_c_pos
-            and _rl_screenwidth */
-         if (col_lendiff && ((MB_CUR_MAX == 1 || rl_byte_oriented) || (_rl_last_c_pos < _rl_screenwidth)))
-#endif
-           {     
-             if (_rl_term_autowrap && current_line < inv_botlin)
-               space_to_eol (col_lendiff);
-             else
-               _rl_clear_to_eol (col_lendiff);
-           }
-       }
-    }
-}
-
-/* Tell the update routines that we have moved onto a new (empty) line. */
-int
-rl_on_new_line ()
-{
-  if (visible_line)
-    visible_line[0] = '\0';
-
-  _rl_last_c_pos = _rl_last_v_pos = 0;
-  _rl_vis_botlin = last_lmargin = 0;
-  if (vis_lbreaks)
-    vis_lbreaks[0] = vis_lbreaks[1] = 0;
-  visible_wrap_offset = 0;
-  return 0;
-}
-
-/* Tell the update routines that we have moved onto a new line with the
-   prompt already displayed.  Code originally from the version of readline
-   distributed with CLISP.  rl_expand_prompt must have already been called
-   (explicitly or implicitly).  This still doesn't work exactly right. */
-int
-rl_on_new_line_with_prompt ()
-{
-  int prompt_size, i, l, real_screenwidth, newlines;
-  char *prompt_last_line, *lprompt;
-
-  /* Initialize visible_line and invisible_line to ensure that they can hold
-     the already-displayed prompt. */
-  prompt_size = strlen (rl_prompt) + 1;
-  init_line_structures (prompt_size);
-
-  /* Make sure the line structures hold the already-displayed prompt for
-     redisplay. */
-  lprompt = local_prompt ? local_prompt : rl_prompt;
-  strcpy (visible_line, lprompt);
-  strcpy (invisible_line, lprompt);
-
-  /* If the prompt contains newlines, take the last tail. */
-  prompt_last_line = strrchr (rl_prompt, '\n');
-  if (!prompt_last_line)
-    prompt_last_line = rl_prompt;
-
-  l = strlen (prompt_last_line);
-  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-    _rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l);   /* XXX */
-  else
-    _rl_last_c_pos = l;
-
-  /* Dissect prompt_last_line into screen lines. Note that here we have
-     to use the real screenwidth. Readline's notion of screenwidth might be
-     one less, see terminal.c. */
-  real_screenwidth = _rl_screenwidth + (_rl_term_autowrap ? 0 : 1);
-  _rl_last_v_pos = l / real_screenwidth;
-  /* If the prompt length is a multiple of real_screenwidth, we don't know
-     whether the cursor is at the end of the last line, or already at the
-     beginning of the next line. Output a newline just to be safe. */
-  if (l > 0 && (l % real_screenwidth) == 0)
-    _rl_output_some_chars ("\n", 1);
-  last_lmargin = 0;
-
-  newlines = 0; i = 0;
-  while (i <= l)
-    {
-      _rl_vis_botlin = newlines;
-      vis_lbreaks[newlines++] = i;
-      i += real_screenwidth;
-    }
-  vis_lbreaks[newlines] = l;
-  visible_wrap_offset = 0;
-
-  rl_display_prompt = rl_prompt;       /* XXX - make sure it's set */
-
-  return 0;
-}
-
-/* Actually update the display, period. */
-int
-rl_forced_update_display ()
-{
-  register char *temp;
-
-  if (visible_line)
-    {
-      temp = visible_line;
-      while (*temp)
-       *temp++ = '\0';
-    }
-  rl_on_new_line ();
-  forced_display++;
-  (*rl_redisplay_function) ();
-  return 0;
-}
-
-/* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices.
-   (Well, when we don't have multibyte characters, _rl_last_c_pos is a
-   buffer index.)
-   DATA is the contents of the screen line of interest; i.e., where
-   the movement is being done. */
-void
-_rl_move_cursor_relative (new, data)
-     int new;
-     const char *data;
-{
-  register int i;
-  int woff;                    /* number of invisible chars on current line */
-  int cpos, dpos;              /* current and desired cursor positions */
-  int adjust;
-
-  woff = WRAP_OFFSET (_rl_last_v_pos, wrap_offset);
-  cpos = _rl_last_c_pos;
-
-  if (cpos == 0 && cpos == new)
-    return;
-
-#if defined (HANDLE_MULTIBYTE)
-  /* If we have multibyte characters, NEW is indexed by the buffer point in
-     a multibyte string, but _rl_last_c_pos is the display position.  In
-     this case, NEW's display position is not obvious and must be
-     calculated.  We need to account for invisible characters in this line,
-     as long as we are past them and they are counted by _rl_col_width. */
-  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-    {
-      adjust = 1;
-      /* Try to short-circuit common cases and eliminate a bunch of multibyte
-        character function calls. */
-      /* 1.  prompt string */
-      if (new == local_prompt_len && memcmp (data, local_prompt, new) == 0)
-       {
-         dpos = prompt_visible_length;
-         cpos_adjusted = 1;
-         adjust = 0;
-       }
-      /* 2.  prompt_string + line contents */
-      else if (new > local_prompt_len && local_prompt && memcmp (data, local_prompt, local_prompt_len) == 0)
-       {
-         dpos = prompt_visible_length + _rl_col_width (data, local_prompt_len, new);
-         cpos_adjusted = 1;
-         adjust = 0;
-       }
-      else
-        dpos = _rl_col_width (data, 0, new);
-
-      /* Use NEW when comparing against the last invisible character in the
-        prompt string, since they're both buffer indices and DPOS is a
-        desired display position. */
-      if (adjust && ((new > prompt_last_invisible) ||          /* XXX - don't use woff here */
-         (prompt_physical_chars >= _rl_screenwidth &&
-          _rl_last_v_pos == prompt_last_screen_line &&
-          wrap_offset >= woff && dpos >= woff &&
-          new > (prompt_last_invisible-(_rl_screenwidth*_rl_last_v_pos)-wrap_offset))))
-          /* XXX last comparison might need to be >= */
-       {
-         dpos -= woff;
-         /* Since this will be assigned to _rl_last_c_pos at the end (more
-            precisely, _rl_last_c_pos == dpos when this function returns),
-            let the caller know. */
-         cpos_adjusted = 1;
-       }
-    }
-  else
-#endif
-    dpos = new;
-
-  /* If we don't have to do anything, then return. */
-  if (cpos == dpos)
-    return;
-
-  /* It may be faster to output a CR, and then move forwards instead
-     of moving backwards. */
-  /* i == current physical cursor position. */
-#if defined (HANDLE_MULTIBYTE)
-  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-    i = _rl_last_c_pos;
-  else
-#endif
-  i = _rl_last_c_pos - woff;
-  if (dpos == 0 || CR_FASTER (dpos, _rl_last_c_pos) ||
-      (_rl_term_autowrap && i == _rl_screenwidth))
-    {
-#if defined (__MSDOS__)
-      putc ('\r', rl_outstream);
-#else
-      tputs (_rl_term_cr, 1, _rl_output_character_function);
-#endif /* !__MSDOS__ */
-      cpos = _rl_last_c_pos = 0;
-    }
-
-  if (cpos < dpos)
-    {
-      /* Move the cursor forward.  We do it by printing the command
-        to move the cursor forward if there is one, else print that
-        portion of the output buffer again.  Which is cheaper? */
-
-      /* The above comment is left here for posterity.  It is faster
-        to print one character (non-control) than to print a control
-        sequence telling the terminal to move forward one character.
-        That kind of control is for people who don't know what the
-        data is underneath the cursor. */
-
-      /* However, we need a handle on where the current display position is
-        in the buffer for the immediately preceding comment to be true.
-        In multibyte locales, we don't currently have that info available.
-        Without it, we don't know where the data we have to display begins
-        in the buffer and we have to go back to the beginning of the screen
-        line.  In this case, we can use the terminal sequence to move forward
-        if it's available. */
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-       {
-         if (_rl_term_forward_char)
-           {
-             for (i = cpos; i < dpos; i++)
-               tputs (_rl_term_forward_char, 1, _rl_output_character_function);
-           }
-         else
-           {
-             tputs (_rl_term_cr, 1, _rl_output_character_function);
-             for (i = 0; i < new; i++)
-               putc (data[i], rl_outstream);
-           }
-       }
-      else
-       for (i = cpos; i < new; i++)
-         putc (data[i], rl_outstream);
-    }
-
-#if defined (HANDLE_MULTIBYTE)
-  /* NEW points to the buffer point, but _rl_last_c_pos is the display point.
-     The byte length of the string is probably bigger than the column width
-     of the string, which means that if NEW == _rl_last_c_pos, then NEW's
-     display point is less than _rl_last_c_pos. */
-#endif
-  else if (cpos > dpos)
-    _rl_backspace (cpos - dpos);
-
-  _rl_last_c_pos = dpos;
-}
-
-/* PWP: move the cursor up or down. */
-void
-_rl_move_vert (to)
-     int to;
-{
-  register int delta, i;
-
-  if (_rl_last_v_pos == to || to > _rl_screenheight)
-    return;
-
-  if ((delta = to - _rl_last_v_pos) > 0)
-    {
-      for (i = 0; i < delta; i++)
-       putc ('\n', rl_outstream);
-#if defined (__MSDOS__)
-      putc ('\r', rl_outstream);
-#else
-      tputs (_rl_term_cr, 1, _rl_output_character_function);
-#endif
-      _rl_last_c_pos = 0;
-    }
-  else
-    {                  /* delta < 0 */
-      if (_rl_term_up && *_rl_term_up)
-       for (i = 0; i < -delta; i++)
-         tputs (_rl_term_up, 1, _rl_output_character_function);
-    }
-
-  _rl_last_v_pos = to;         /* Now TO is here */
-}
-
-/* Physically print C on rl_outstream.  This is for functions which know
-   how to optimize the display.  Return the number of characters output. */
-int
-rl_show_char (c)
-     int c;
-{
-  int n = 1;
-  if (META_CHAR (c) && (_rl_output_meta_chars == 0))
-    {
-      fprintf (rl_outstream, "M-");
-      n += 2;
-      c = UNMETA (c);
-    }
-
-#if defined (DISPLAY_TABS)
-  if ((CTRL_CHAR (c) && c != '\t') || c == RUBOUT)
-#else
-  if (CTRL_CHAR (c) || c == RUBOUT)
-#endif /* !DISPLAY_TABS */
-    {
-      fprintf (rl_outstream, "C-");
-      n += 2;
-      c = CTRL_CHAR (c) ? UNCTRL (c) : '?';
-    }
-
-  putc (c, rl_outstream);
-  fflush (rl_outstream);
-  return n;
-}
-
-int
-rl_character_len (c, pos)
-     register int c, pos;
-{
-  unsigned char uc;
-
-  uc = (unsigned char)c;
-
-  if (META_CHAR (uc))
-    return ((_rl_output_meta_chars == 0) ? 4 : 1);
-
-  if (uc == '\t')
-    {
-#if defined (DISPLAY_TABS)
-      return (((pos | 7) + 1) - pos);
-#else
-      return (2);
-#endif /* !DISPLAY_TABS */
-    }
-
-  if (CTRL_CHAR (c) || c == RUBOUT)
-    return (2);
-
-  return ((ISPRINT (uc)) ? 1 : 2);
-}
-/* How to print things in the "echo-area".  The prompt is treated as a
-   mini-modeline. */
-static int msg_saved_prompt = 0;
-
-#if defined (USE_VARARGS)
-int
-#if defined (PREFER_STDARG)
-rl_message (const char *format, ...)
-#else
-rl_message (va_alist)
-     va_dcl
-#endif
-{
-  va_list args;
-#if defined (PREFER_VARARGS)
-  char *format;
-#endif
-
-#if defined (PREFER_STDARG)
-  va_start (args, format);
-#else
-  va_start (args);
-  format = va_arg (args, char *);
-#endif
-
-#if defined (HAVE_VSNPRINTF)
-  vsnprintf (msg_buf, sizeof (msg_buf) - 1, format, args);
-#else
-  vsprintf (msg_buf, format, args);
-  msg_buf[sizeof(msg_buf) - 1] = '\0'; /* overflow? */
-#endif
-  va_end (args);
-
-  if (saved_local_prompt == 0)
-    {
-      rl_save_prompt ();
-      msg_saved_prompt = 1;
-    }
-  rl_display_prompt = msg_buf;
-  local_prompt = expand_prompt (msg_buf, &prompt_visible_length,
-                                        &prompt_last_invisible,
-                                        &prompt_invis_chars_first_line,
-                                        &prompt_physical_chars);
-  local_prompt_prefix = (char *)NULL;
-  local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
-  (*rl_redisplay_function) ();
-
-  return 0;
-}
-#else /* !USE_VARARGS */
-int
-rl_message (format, arg1, arg2)
-     char *format;
-{
-  sprintf (msg_buf, format, arg1, arg2);
-  msg_buf[sizeof(msg_buf) - 1] = '\0'; /* overflow? */
-
-  rl_display_prompt = msg_buf;
-  if (saved_local_prompt == 0)
-    {
-      rl_save_prompt ();
-      msg_saved_prompt = 1;
-    }
-  local_prompt = expand_prompt (msg_buf, &prompt_visible_length,
-                                        &prompt_last_invisible,
-                                        &prompt_invis_chars_first_line,
-                                        &prompt_physical_chars);
-  local_prompt_prefix = (char *)NULL;
-  local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
-  (*rl_redisplay_function) ();
-      
-  return 0;
-}
-#endif /* !USE_VARARGS */
-
-/* How to clear things from the "echo-area". */
-int
-rl_clear_message ()
-{
-  rl_display_prompt = rl_prompt;
-  if (msg_saved_prompt)
-    {
-      rl_restore_prompt ();
-      msg_saved_prompt = 0;
-    }
-  (*rl_redisplay_function) ();
-  return 0;
-}
-
-int
-rl_reset_line_state ()
-{
-  rl_on_new_line ();
-
-  rl_display_prompt = rl_prompt ? rl_prompt : "";
-  forced_display = 1;
-  return 0;
-}
-
-void
-rl_save_prompt ()
-{
-  saved_local_prompt = local_prompt;
-  saved_local_prefix = local_prompt_prefix;
-  saved_prefix_length = prompt_prefix_length;
-  saved_local_length = local_prompt_len;
-  saved_last_invisible = prompt_last_invisible;
-  saved_visible_length = prompt_visible_length;
-  saved_invis_chars_first_line = prompt_invis_chars_first_line;
-  saved_physical_chars = prompt_physical_chars;
-
-  local_prompt = local_prompt_prefix = (char *)0;
-  local_prompt_len = 0;
-  prompt_last_invisible = prompt_visible_length = prompt_prefix_length = 0;
-  prompt_invis_chars_first_line = prompt_physical_chars = 0;
-}
-
-void
-rl_restore_prompt ()
-{
-  FREE (local_prompt);
-  FREE (local_prompt_prefix);
-
-  local_prompt = saved_local_prompt;
-  local_prompt_prefix = saved_local_prefix;
-  local_prompt_len = saved_local_length;
-  prompt_prefix_length = saved_prefix_length;
-  prompt_last_invisible = saved_last_invisible;
-  prompt_visible_length = saved_visible_length;
-  prompt_invis_chars_first_line = saved_invis_chars_first_line;
-  prompt_physical_chars = saved_physical_chars;
-
-  /* can test saved_local_prompt to see if prompt info has been saved. */
-  saved_local_prompt = saved_local_prefix = (char *)0;
-  saved_local_length = 0;
-  saved_last_invisible = saved_visible_length = saved_prefix_length = 0;
-  saved_invis_chars_first_line = saved_physical_chars = 0;
-}
-
-char *
-_rl_make_prompt_for_search (pchar)
-     int pchar;
-{
-  int len;
-  char *pmt, *p;
-
-  rl_save_prompt ();
-
-  /* We've saved the prompt, and can do anything with the various prompt
-     strings we need before they're restored.  We want the unexpanded
-     portion of the prompt string after any final newline. */
-  p = rl_prompt ? strrchr (rl_prompt, '\n') : 0;
-  if (p == 0)
-    {
-      len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
-      pmt = (char *)xmalloc (len + 2);
-      if (len)
-       strcpy (pmt, rl_prompt);
-      pmt[len] = pchar;
-      pmt[len+1] = '\0';
-    }
-  else
-    {
-      p++;
-      len = strlen (p);
-      pmt = (char *)xmalloc (len + 2);
-      if (len)
-       strcpy (pmt, p);
-      pmt[len] = pchar;
-      pmt[len+1] = '\0';
-    }  
-
-  /* will be overwritten by expand_prompt, called from rl_message */
-  prompt_physical_chars = saved_physical_chars + 1;
-  return pmt;
-}
-
-/* Quick redisplay hack when erasing characters at the end of the line. */
-void
-_rl_erase_at_end_of_line (l)
-     int l;
-{
-  register int i;
-
-  _rl_backspace (l);
-  for (i = 0; i < l; i++)
-    putc (' ', rl_outstream);
-  _rl_backspace (l);
-  for (i = 0; i < l; i++)
-    visible_line[--_rl_last_c_pos] = '\0';
-  rl_display_fixed++;
-}
-
-/* Clear to the end of the line.  COUNT is the minimum
-   number of character spaces to clear, */
-void
-_rl_clear_to_eol (count)
-     int count;
-{
-  if (_rl_term_clreol)
-    tputs (_rl_term_clreol, 1, _rl_output_character_function);
-  else if (count)
-    space_to_eol (count);
-}
-
-/* Clear to the end of the line using spaces.  COUNT is the minimum
-   number of character spaces to clear, */
-static void
-space_to_eol (count)
-     int count;
-{
-  register int i;
-
-  for (i = 0; i < count; i++)
-   putc (' ', rl_outstream);
-
-  _rl_last_c_pos += count;
-}
-
-void
-_rl_clear_screen ()
-{
-  if (_rl_term_clrpag)
-    tputs (_rl_term_clrpag, 1, _rl_output_character_function);
-  else
-    rl_crlf ();
-}
-
-/* Insert COUNT characters from STRING to the output stream at column COL. */
-static void
-insert_some_chars (string, count, col)
-     char *string;
-     int count, col;
-{
-#if defined (__MSDOS__) || defined (__MINGW32__)
-  _rl_output_some_chars (string, count);
-#else
-  /* DEBUGGING */
-  if (MB_CUR_MAX == 1 || rl_byte_oriented)
-    if (count != col)
-      _rl_ttymsg ("debug: insert_some_chars: count (%d) != col (%d)", count, col);
-
-  /* If IC is defined, then we do not have to "enter" insert mode. */
-  if (_rl_term_IC)
-    {
-      char *buffer;
-
-      buffer = tgoto (_rl_term_IC, 0, col);
-      tputs (buffer, 1, _rl_output_character_function);
-      _rl_output_some_chars (string, count);
-    }
-  else
-    {
-      register int i;
-
-      /* If we have to turn on insert-mode, then do so. */
-      if (_rl_term_im && *_rl_term_im)
-       tputs (_rl_term_im, 1, _rl_output_character_function);
-
-      /* If there is a special command for inserting characters, then
-        use that first to open up the space. */
-      if (_rl_term_ic && *_rl_term_ic)
-       {
-         for (i = col; i--; )
-           tputs (_rl_term_ic, 1, _rl_output_character_function);
-       }
-
-      /* Print the text. */
-      _rl_output_some_chars (string, count);
-
-      /* If there is a string to turn off insert mode, we had best use
-        it now. */
-      if (_rl_term_ei && *_rl_term_ei)
-       tputs (_rl_term_ei, 1, _rl_output_character_function);
-    }
-#endif /* __MSDOS__ || __MINGW32__ */
-}
-
-/* Delete COUNT characters from the display line. */
-static void
-delete_chars (count)
-     int count;
-{
-  if (count > _rl_screenwidth) /* XXX */
-    return;
-
-#if !defined (__MSDOS__) && !defined (__MINGW32__)
-  if (_rl_term_DC && *_rl_term_DC)
-    {
-      char *buffer;
-      buffer = tgoto (_rl_term_DC, count, count);
-      tputs (buffer, count, _rl_output_character_function);
-    }
-  else
-    {
-      if (_rl_term_dc && *_rl_term_dc)
-       while (count--)
-         tputs (_rl_term_dc, 1, _rl_output_character_function);
-    }
-#endif /* !__MSDOS__ && !__MINGW32__ */
-}
-
-void
-_rl_update_final ()
-{
-  int full_lines;
-
-  full_lines = 0;
-  /* If the cursor is the only thing on an otherwise-blank last line,
-     compensate so we don't print an extra CRLF. */
-  if (_rl_vis_botlin && _rl_last_c_pos == 0 &&
-       visible_line[vis_lbreaks[_rl_vis_botlin]] == 0)
-    {
-      _rl_vis_botlin--;
-      full_lines = 1;
-    }
-  _rl_move_vert (_rl_vis_botlin);
-  /* If we've wrapped lines, remove the final xterm line-wrap flag. */
-  if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == _rl_screenwidth))
-    {
-      char *last_line;
-
-      last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]];
-      cpos_buffer_position = -1;       /* don't know where we are in buffer */
-      _rl_move_cursor_relative (_rl_screenwidth - 1, last_line);       /* XXX */
-      _rl_clear_to_eol (0);
-      putc (last_line[_rl_screenwidth - 1], rl_outstream);
-    }
-  _rl_vis_botlin = 0;
-  rl_crlf ();
-  fflush (rl_outstream);
-  rl_display_fixed++;
-}
-
-/* Move to the start of the current line. */
-static void
-cr ()
-{
-  if (_rl_term_cr)
-    {
-#if defined (__MSDOS__)
-      putc ('\r', rl_outstream);
-#else
-      tputs (_rl_term_cr, 1, _rl_output_character_function);
-#endif
-      _rl_last_c_pos = 0;
-    }
-}
-
-/* Redraw the last line of a multi-line prompt that may possibly contain
-   terminal escape sequences.  Called with the cursor at column 0 of the
-   line to draw the prompt on. */
-static void
-redraw_prompt (t)
-     char *t;
-{
-  char *oldp;
-
-  oldp = rl_display_prompt;
-  rl_save_prompt ();
-
-  rl_display_prompt = t;
-  local_prompt = expand_prompt (t, &prompt_visible_length,
-                                  &prompt_last_invisible,
-                                  &prompt_invis_chars_first_line,
-                                  &prompt_physical_chars);
-  local_prompt_prefix = (char *)NULL;
-  local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
-
-  rl_forced_update_display ();
-
-  rl_display_prompt = oldp;
-  rl_restore_prompt();
-}
-      
-/* Redisplay the current line after a SIGWINCH is received. */
-void
-_rl_redisplay_after_sigwinch ()
-{
-  char *t;
-
-  /* Clear the last line (assuming that the screen size change will result in
-     either more or fewer characters on that line only) and put the cursor at
-     column 0.  Make sure the right thing happens if we have wrapped to a new
-     screen line. */
-  if (_rl_term_cr)
-    {
-      _rl_move_vert (_rl_vis_botlin);
-
-#if defined (__MSDOS__)
-      putc ('\r', rl_outstream);
-#else
-      tputs (_rl_term_cr, 1, _rl_output_character_function);
-#endif
-      _rl_last_c_pos = 0;
-#if defined (__MSDOS__)
-      space_to_eol (_rl_screenwidth);
-      putc ('\r', rl_outstream);
-#else
-      if (_rl_term_clreol)
-       tputs (_rl_term_clreol, 1, _rl_output_character_function);
-      else
-       {
-         space_to_eol (_rl_screenwidth);
-         tputs (_rl_term_cr, 1, _rl_output_character_function);
-       }
-#endif
-      if (_rl_last_v_pos > 0)
-       _rl_move_vert (0);
-    }
-  else
-    rl_crlf ();
-
-  /* Redraw only the last line of a multi-line prompt. */
-  t = strrchr (rl_display_prompt, '\n');
-  if (t)
-    redraw_prompt (++t);
-  else
-    rl_forced_update_display ();
-}
-
-void
-_rl_clean_up_for_exit ()
-{
-  if (_rl_echoing_p)
-    {
-      _rl_move_vert (_rl_vis_botlin);
-      _rl_vis_botlin = 0;
-      fflush (rl_outstream);
-      rl_restart_output (1, 0);
-    }
-}
-
-void
-_rl_erase_entire_line ()
-{
-  cr ();
-  _rl_clear_to_eol (0);
-  cr ();
-  fflush (rl_outstream);
-}
-
-/* return the `current display line' of the cursor -- the number of lines to
-   move up to get to the first screen line of the current readline line. */
-int
-_rl_current_display_line ()
-{
-  int ret, nleft;
-
-  /* Find out whether or not there might be invisible characters in the
-     editing buffer. */
-  if (rl_display_prompt == rl_prompt)
-    nleft = _rl_last_c_pos - _rl_screenwidth - rl_visible_prompt_length;
-  else
-    nleft = _rl_last_c_pos - _rl_screenwidth;
-
-  if (nleft > 0)
-    ret = 1 + nleft / _rl_screenwidth;
-  else
-    ret = 0;
-
-  return ret;
-}
-
-#if defined (HANDLE_MULTIBYTE)
-/* Calculate the number of screen columns occupied by STR from START to END.
-   In the case of multibyte characters with stateful encoding, we have to
-   scan from the beginning of the string to take the state into account. */
-static int
-_rl_col_width (str, start, end)
-     const char *str;
-     int start, end;
-{
-  wchar_t wc;
-  mbstate_t ps;
-  int tmp, point, width, max;
-
-  if (end <= start)
-    return 0;
-  if (MB_CUR_MAX == 1 || rl_byte_oriented)
-{
-_rl_ttymsg ("_rl_col_width: called with MB_CUR_MAX == 1");
-    return (end - start);
-}
-
-  memset (&ps, 0, sizeof (mbstate_t));
-
-  point = 0;
-  max = end;
-
-  /* Try to short-circuit common cases.  The adjustment to remove wrap_offset
-     is done by the caller. */
-  /* 1.  prompt string */
-  if (start == 0 && end == local_prompt_len && memcmp (str, local_prompt, local_prompt_len) == 0)
-    return (prompt_visible_length + wrap_offset);
-  /* 2.  prompt string + line contents */
-  else if (start == 0 && end > local_prompt_len && local_prompt && memcmp (str, local_prompt, local_prompt_len) == 0)
-    {
-      tmp = prompt_visible_length + wrap_offset;
-      /* XXX - try to call ourselves recursively with non-prompt portion */
-      if (local_prompt_len > start)
-       tmp += _rl_col_width (str, local_prompt_len, end);
-      return (tmp);
-    }
-
-  while (point < start)
-    {
-      tmp = mbrlen (str + point, max, &ps);
-      if (MB_INVALIDCH ((size_t)tmp))
-       {
-         /* In this case, the bytes are invalid or too short to compose a
-            multibyte character, so we assume that the first byte represents
-            a single character. */
-         point++;
-         max--;
-
-         /* Clear the state of the byte sequence, because in this case the
-            effect of mbstate is undefined. */
-         memset (&ps, 0, sizeof (mbstate_t));
-       }
-      else if (MB_NULLWCH (tmp))
-       break;          /* Found '\0' */
-      else
-       {
-         point += tmp;
-         max -= tmp;
-       }
-    }
-
-  /* If START is not a byte that starts a character, then POINT will be
-     greater than START.  In this case, assume that (POINT - START) gives
-     a byte count that is the number of columns of difference. */
-  width = point - start;
-
-  while (point < end)
-    {
-      tmp = mbrtowc (&wc, str + point, max, &ps);
-      if (MB_INVALIDCH ((size_t)tmp))
-       {
-         /* In this case, the bytes are invalid or too short to compose a
-            multibyte character, so we assume that the first byte represents
-            a single character. */
-         point++;
-         max--;
-
-         /* and assume that the byte occupies a single column. */
-         width++;
-
-         /* Clear the state of the byte sequence, because in this case the
-            effect of mbstate is undefined. */
-         memset (&ps, 0, sizeof (mbstate_t));
-       }
-      else if (MB_NULLWCH (tmp))
-       break;                  /* Found '\0' */
-      else
-       {
-         point += tmp;
-         max -= tmp;
-         tmp = wcwidth(wc);
-         width += (tmp >= 0) ? tmp : 1;
-       }
-    }
-
-  width += point - end;
-
-  return width;
-}
-#endif /* HANDLE_MULTIBYTE */
diff --git a/lib/readline/display.c~ b/lib/readline/display.c~
deleted file mode 100644 (file)
index 12575f3..0000000
+++ /dev/null
@@ -1,2688 +0,0 @@
-/* display.c -- readline redisplay facility. */
-
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
-
-   This file is part of the GNU Readline Library (Readline), a library    
-   for reading lines of text with interactive input and history editing.
-
-   Readline is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   Readline is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#define READLINE_LIBRARY
-
-#if defined (HAVE_CONFIG_H)
-#  include <config.h>
-#endif
-
-#include <sys/types.h>
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#include "posixstat.h"
-
-#if defined (HAVE_STDLIB_H)
-#  include <stdlib.h>
-#else
-#  include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#include <stdio.h>
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-#include "rlmbutil.h"
-
-/* Termcap library stuff. */
-#include "tcap.h"
-
-/* Some standard library routines. */
-#include "readline.h"
-#include "history.h"
-
-#include "rlprivate.h"
-#include "xmalloc.h"
-
-#if !defined (strchr) && !defined (__STDC__)
-extern char *strchr (), *strrchr ();
-#endif /* !strchr && !__STDC__ */
-
-static void update_line PARAMS((char *, char *, int, int, int, int));
-static void space_to_eol PARAMS((int));
-static void delete_chars PARAMS((int));
-static void insert_some_chars PARAMS((char *, int, int));
-static void cr PARAMS((void));
-
-/* State of visible and invisible lines. */
-struct line_state
-  {
-    char *line;
-    int *lbreaks;
-    int lbsize;
-#if defined (HANDLE_MULTIBYTE)
-    int *wrapped_line;
-    int wbsize;
-#endif
-  };
-
-/* The line display buffers.  One is the line currently displayed on
-   the screen.  The other is the line about to be displayed. */
-static struct line_state line_state_array[2];
-static struct line_state *line_state_visible = &line_state_array[0];
-static struct line_state *line_state_invisible = &line_state_array[1];
-static int line_structures_initialized = 0;
-
-/* Backwards-compatible names. */
-#define inv_lbreaks    (line_state_invisible->lbreaks)
-#define inv_lbsize     (line_state_invisible->lbsize)
-#define vis_lbreaks    (line_state_visible->lbreaks)
-#define vis_lbsize     (line_state_visible->lbsize)
-
-#define visible_line   (line_state_visible->line)
-#define invisible_line (line_state_invisible->line)
-
-#if defined (HANDLE_MULTIBYTE)
-static int _rl_col_width PARAMS((const char *, int, int, int));
-#else
-#  define _rl_col_width(l, s, e, f)    (((e) <= (s)) ? 0 : (e) - (s))
-#endif
-
-/* Heuristic used to decide whether it is faster to move from CUR to NEW
-   by backing up or outputting a carriage return and moving forward.  CUR
-   and NEW are either both buffer positions or absolute screen positions. */
-#define CR_FASTER(new, cur) (((new) + 1) < ((cur) - (new)))
-
-/* _rl_last_c_pos is an absolute cursor position in multibyte locales and a
-   buffer index in others.  This macro is used when deciding whether the
-   current cursor position is in the middle of a prompt string containing
-   invisible characters.  XXX - might need to take `modmark' into account. */
-#define PROMPT_ENDING_INDEX \
-  ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) ? prompt_physical_chars : prompt_last_invisible+1)
-  
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Display stuff                               */
-/*                                                                 */
-/* **************************************************************** */
-
-/* This is the stuff that is hard for me.  I never seem to write good
-   display routines in C.  Let's see how I do this time. */
-
-/* (PWP) Well... Good for a simple line updater, but totally ignores
-   the problems of input lines longer than the screen width.
-
-   update_line and the code that calls it makes a multiple line,
-   automatically wrapping line update.  Careful attention needs
-   to be paid to the vertical position variables. */
-
-/* Keep two buffers; one which reflects the current contents of the
-   screen, and the other to draw what we think the new contents should
-   be.  Then compare the buffers, and make whatever changes to the
-   screen itself that we should.  Finally, make the buffer that we
-   just drew into be the one which reflects the current contents of the
-   screen, and place the cursor where it belongs.
-
-   Commands that want to can fix the display themselves, and then let
-   this function know that the display has been fixed by setting the
-   RL_DISPLAY_FIXED variable.  This is good for efficiency. */
-
-/* Application-specific redisplay function. */
-rl_voidfunc_t *rl_redisplay_function = rl_redisplay;
-
-/* Global variables declared here. */
-/* What YOU turn on when you have handled all redisplay yourself. */
-int rl_display_fixed = 0;
-
-int _rl_suppress_redisplay = 0;
-int _rl_want_redisplay = 0;
-
-/* The stuff that gets printed out before the actual text of the line.
-   This is usually pointing to rl_prompt. */
-char *rl_display_prompt = (char *)NULL;
-
-/* Pseudo-global variables declared here. */
-
-/* The visible cursor position.  If you print some text, adjust this. */
-/* NOTE: _rl_last_c_pos is used as a buffer index when not in a locale
-   supporting multibyte characters, and an absolute cursor position when
-   in such a locale.  This is an artifact of the donated multibyte support.
-   Care must be taken when modifying its value. */
-int _rl_last_c_pos = 0;
-int _rl_last_v_pos = 0;
-
-static int cpos_adjusted;
-static int cpos_buffer_position;
-static int prompt_multibyte_chars;
-
-/* Number of lines currently on screen minus 1. */
-int _rl_vis_botlin = 0;
-
-/* Variables used only in this file. */
-/* The last left edge of text that was displayed.  This is used when
-   doing horizontal scrolling.  It shifts in thirds of a screenwidth. */
-static int last_lmargin;
-
-/* A buffer for `modeline' messages. */
-static char msg_buf[128];
-
-/* Non-zero forces the redisplay even if we thought it was unnecessary. */
-static int forced_display;
-
-/* Default and initial buffer size.  Can grow. */
-static int line_size = 1024;
-
-/* Variables to keep track of the expanded prompt string, which may
-   include invisible characters. */
-
-static char *local_prompt, *local_prompt_prefix;
-static int local_prompt_len;
-static int prompt_visible_length, prompt_prefix_length;
-
-/* The number of invisible characters in the line currently being
-   displayed on the screen. */
-static int visible_wrap_offset;
-
-/* The number of invisible characters in the prompt string.  Static so it
-   can be shared between rl_redisplay and update_line */
-static int wrap_offset;
-
-/* The index of the last invisible character in the prompt string. */
-static int prompt_last_invisible;
-
-/* The length (buffer offset) of the first line of the last (possibly
-   multi-line) buffer displayed on the screen. */
-static int visible_first_line_len;
-
-/* Number of invisible characters on the first physical line of the prompt.
-   Only valid when the number of physical characters in the prompt exceeds
-   (or is equal to) _rl_screenwidth. */
-static int prompt_invis_chars_first_line;
-
-static int prompt_last_screen_line;
-
-static int prompt_physical_chars;
-
-/* set to a non-zero value by rl_redisplay if we are marking modified history
-   lines and the current line is so marked. */
-static int modmark;
-
-/* Variables to save and restore prompt and display information. */
-
-/* These are getting numerous enough that it's time to create a struct. */
-
-static char *saved_local_prompt;
-static char *saved_local_prefix;
-static int saved_last_invisible;
-static int saved_visible_length;
-static int saved_prefix_length;
-static int saved_local_length;
-static int saved_invis_chars_first_line;
-static int saved_physical_chars;
-
-/* Expand the prompt string S and return the number of visible
-   characters in *LP, if LP is not null.  This is currently more-or-less
-   a placeholder for expansion.  LIP, if non-null is a place to store the
-   index of the last invisible character in the returned string. NIFLP,
-   if non-zero, is a place to store the number of invisible characters in
-   the first prompt line.  The previous are used as byte counts -- indexes
-   into a character buffer. */
-
-/* Current implementation:
-       \001 (^A) start non-visible characters
-       \002 (^B) end non-visible characters
-   all characters except \001 and \002 (following a \001) are copied to
-   the returned string; all characters except those between \001 and
-   \002 are assumed to be `visible'. */        
-
-static char *
-expand_prompt (pmt, lp, lip, niflp, vlp)
-     char *pmt;
-     int *lp, *lip, *niflp, *vlp;
-{
-  char *r, *ret, *p, *igstart;
-  int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars;
-
-  /* Short-circuit if we can. */
-  if ((MB_CUR_MAX <= 1 || rl_byte_oriented) && strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
-    {
-      r = savestring (pmt);
-      if (lp)
-       *lp = strlen (r);
-      if (lip)
-       *lip = 0;
-      if (niflp)
-       *niflp = 0;
-      if (vlp)
-       *vlp = lp ? *lp : strlen (r);
-      return r;
-    }
-
-  l = strlen (pmt);
-  r = ret = (char *)xmalloc (l + 1);
-
-  invfl = 0;   /* invisible chars in first line of prompt */
-  invflset = 0;        /* we only want to set invfl once */
-
-  igstart = 0;
-  for (rl = ignoring = last = ninvis = physchars = 0, p = pmt; p && *p; p++)
-    {
-      /* This code strips the invisible character string markers
-        RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
-      if (ignoring == 0 && *p == RL_PROMPT_START_IGNORE)               /* XXX - check ignoring? */
-       {
-         ignoring = 1;
-         igstart = p;
-         continue;
-       }
-      else if (ignoring && *p == RL_PROMPT_END_IGNORE)
-       {
-         ignoring = 0;
-         if (p != (igstart + 1))
-           last = r - ret - 1;
-         continue;
-       }
-      else
-       {
-#if defined (HANDLE_MULTIBYTE)
-         if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-           {
-             pind = p - pmt;
-             ind = _rl_find_next_mbchar (pmt, pind, 1, MB_FIND_NONZERO);
-             l = ind - pind;
-             while (l--)
-               *r++ = *p++;
-             if (!ignoring)
-               {
-                 /* rl ends up being assigned to prompt_visible_length,
-                    which is the number of characters in the buffer that
-                    contribute to characters on the screen, which might
-                    not be the same as the number of physical characters
-                    on the screen in the presence of multibyte characters */
-                 rl += ind - pind;
-                 physchars += _rl_col_width (pmt, pind, ind, 0);
-               }
-             else
-               ninvis += ind - pind;
-             p--;                      /* compensate for later increment */
-           }
-         else
-#endif
-           {
-             *r++ = *p;
-             if (!ignoring)
-               {
-                 rl++;                 /* visible length byte counter */
-                 physchars++;
-               }
-             else
-               ninvis++;               /* invisible chars byte counter */
-           }
-
-         if (invflset == 0 && rl >= _rl_screenwidth)
-           {
-             invfl = ninvis;
-             invflset = 1;
-           }
-       }
-    }
-
-  if (rl < _rl_screenwidth)
-    invfl = ninvis;
-
-  *r = '\0';
-  if (lp)
-    *lp = rl;
-  if (lip)
-    *lip = last;
-  if (niflp)
-    *niflp = invfl;
-  if  (vlp)
-    *vlp = physchars;
-  return ret;
-}
-
-/* Just strip out RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE from
-   PMT and return the rest of PMT. */
-char *
-_rl_strip_prompt (pmt)
-     char *pmt;
-{
-  char *ret;
-
-  ret = expand_prompt (pmt, (int *)NULL, (int *)NULL, (int *)NULL, (int *)NULL);
-  return ret;
-}
-
-/*
- * Expand the prompt string into the various display components, if
- * necessary.
- *
- * local_prompt = expanded last line of string in rl_display_prompt
- *               (portion after the final newline)
- * local_prompt_prefix = portion before last newline of rl_display_prompt,
- *                      expanded via expand_prompt
- * prompt_visible_length = number of visible characters in local_prompt
- * prompt_prefix_length = number of visible characters in local_prompt_prefix
- *
- * This function is called once per call to readline().  It may also be
- * called arbitrarily to expand the primary prompt.
- *
- * The return value is the number of visible characters on the last line
- * of the (possibly multi-line) prompt.
- */
-int
-rl_expand_prompt (prompt)
-     char *prompt;
-{
-  char *p, *t;
-  int c;
-
-  /* Clear out any saved values. */
-  FREE (local_prompt);
-  FREE (local_prompt_prefix);
-
-  local_prompt = local_prompt_prefix = (char *)0;
-  local_prompt_len = 0;
-  prompt_last_invisible = prompt_invis_chars_first_line = 0;
-  prompt_visible_length = prompt_physical_chars = 0;
-
-  if (prompt == 0 || *prompt == 0)
-    return (0);
-
-  p = strrchr (prompt, '\n');
-  if (!p)
-    {
-      /* The prompt is only one logical line, though it might wrap. */
-      local_prompt = expand_prompt (prompt, &prompt_visible_length,
-                                           &prompt_last_invisible,
-                                           &prompt_invis_chars_first_line,
-                                           &prompt_physical_chars);
-      local_prompt_prefix = (char *)0;
-      local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
-      return (prompt_visible_length);
-    }
-  else
-    {
-      /* The prompt spans multiple lines. */
-      t = ++p;
-      local_prompt = expand_prompt (p, &prompt_visible_length,
-                                      &prompt_last_invisible,
-                                      &prompt_invis_chars_first_line,
-                                      &prompt_physical_chars);
-      c = *t; *t = '\0';
-      /* The portion of the prompt string up to and including the
-        final newline is now null-terminated. */
-      local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length,
-                                                  (int *)NULL,
-                                                  (int *)NULL,
-                                                  (int *)NULL);
-      *t = c;
-      local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
-      return (prompt_prefix_length);
-    }
-}
-
-/* Initialize the VISIBLE_LINE and INVISIBLE_LINE arrays, and their associated
-   arrays of line break markers.  MINSIZE is the minimum size of VISIBLE_LINE
-   and INVISIBLE_LINE; if it is greater than LINE_SIZE, LINE_SIZE is
-   increased.  If the lines have already been allocated, this ensures that
-   they can hold at least MINSIZE characters. */
-static void
-init_line_structures (minsize)
-      int minsize;
-{
-  register int n;
-
-  if (invisible_line == 0)     /* initialize it */
-    {
-      if (line_size < minsize)
-       line_size = minsize;
-      visible_line = (char *)xmalloc (line_size);
-      invisible_line = (char *)xmalloc (line_size);
-    }
-  else if (line_size < minsize)        /* ensure it can hold MINSIZE chars */
-    {
-      line_size *= 2;
-      if (line_size < minsize)
-       line_size = minsize;
-      visible_line = (char *)xrealloc (visible_line, line_size);
-      invisible_line = (char *)xrealloc (invisible_line, line_size);
-    }
-
-  for (n = minsize; n < line_size; n++)
-    {
-      visible_line[n] = 0;
-      invisible_line[n] = 1;
-    }
-
-  if (vis_lbreaks == 0)
-    {
-      /* should be enough. */
-      inv_lbsize = vis_lbsize = 256;
-
-#if defined (HANDLE_MULTIBYTE)
-      line_state_visible->wbsize = vis_lbsize;
-      line_state_visible->wrapped_line = (int *)xmalloc (line_state_visible->wbsize * sizeof (int));
-
-      line_state_invisible->wbsize = inv_lbsize;
-      line_state_invisible->wrapped_line = (int *)xmalloc (line_state_invisible->wbsize * sizeof (int));
-#endif
-
-      inv_lbreaks = (int *)xmalloc (inv_lbsize * sizeof (int));
-      vis_lbreaks = (int *)xmalloc (vis_lbsize * sizeof (int));
-      inv_lbreaks[0] = vis_lbreaks[0] = 0;
-    }
-
-  line_structures_initialized = 1;
-}
-  
-/* Basic redisplay algorithm. */
-void
-rl_redisplay ()
-{
-  register int in, out, c, linenum, cursor_linenum;
-  register char *line;
-  int inv_botlin, lb_botlin, lb_linenum, o_cpos;
-  int newlines, lpos, temp, n0, num, prompt_lines_estimate;
-  char *prompt_this_line;
-#if defined (HANDLE_MULTIBYTE)
-  wchar_t wc;
-  size_t wc_bytes;
-  int wc_width;
-  mbstate_t ps;
-  int _rl_wrapped_multicolumn = 0;
-#endif
-
-  if (_rl_echoing_p == 0)
-    return;
-
-  /* Block keyboard interrupts because this function manipulates global
-     data structures. */
-  _rl_block_sigint ();  
-  RL_SETSTATE (RL_STATE_REDISPLAYING);
-
-  if (!rl_display_prompt)
-    rl_display_prompt = "";
-
-  if (line_structures_initialized == 0)
-    {
-      init_line_structures (0);
-      rl_on_new_line ();
-    }
-
-  /* Draw the line into the buffer. */
-  cpos_buffer_position = -1;
-
-  prompt_multibyte_chars = prompt_visible_length - prompt_physical_chars;
-
-  line = invisible_line;
-  out = inv_botlin = 0;
-
-  /* Mark the line as modified or not.  We only do this for history
-     lines. */
-  modmark = 0;
-  if (_rl_mark_modified_lines && current_history () && rl_undo_list)
-    {
-      line[out++] = '*';
-      line[out] = '\0';
-      modmark = 1;
-    }
-
-  /* If someone thought that the redisplay was handled, but the currently
-     visible line has a different modification state than the one about
-     to become visible, then correct the caller's misconception. */
-  if (visible_line[0] != invisible_line[0])
-    rl_display_fixed = 0;
-
-  /* If the prompt to be displayed is the `primary' readline prompt (the
-     one passed to readline()), use the values we have already expanded.
-     If not, use what's already in rl_display_prompt.  WRAP_OFFSET is the
-     number of non-visible characters in the prompt string. */
-  if (rl_display_prompt == rl_prompt || local_prompt)
-    {
-      if (local_prompt_prefix && forced_display)
-       _rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix));
-
-      if (local_prompt_len > 0)
-       {
-         temp = local_prompt_len + out + 2;
-         if (temp >= line_size)
-           {
-             line_size = (temp + 1024) - (temp % 1024);
-             visible_line = (char *)xrealloc (visible_line, line_size);
-             line = invisible_line = (char *)xrealloc (invisible_line, line_size);
-           }
-         strncpy (line + out, local_prompt, local_prompt_len);
-         out += local_prompt_len;
-       }
-      line[out] = '\0';
-      wrap_offset = local_prompt_len - prompt_visible_length;
-    }
-  else
-    {
-      int pmtlen;
-      prompt_this_line = strrchr (rl_display_prompt, '\n');
-      if (!prompt_this_line)
-       prompt_this_line = rl_display_prompt;
-      else
-       {
-         prompt_this_line++;
-         pmtlen = prompt_this_line - rl_display_prompt;        /* temp var */
-         if (forced_display)
-           {
-             _rl_output_some_chars (rl_display_prompt, pmtlen);
-             /* Make sure we are at column zero even after a newline,
-                regardless of the state of terminal output processing. */
-             if (pmtlen < 2 || prompt_this_line[-2] != '\r')
-               cr ();
-           }
-       }
-
-      prompt_physical_chars = pmtlen = strlen (prompt_this_line);
-      temp = pmtlen + out + 2;
-      if (temp >= line_size)
-       {
-         line_size = (temp + 1024) - (temp % 1024);
-         visible_line = (char *)xrealloc (visible_line, line_size);
-         line = invisible_line = (char *)xrealloc (invisible_line, line_size);
-       }
-      strncpy (line + out,  prompt_this_line, pmtlen);
-      out += pmtlen;
-      line[out] = '\0';
-      wrap_offset = prompt_invis_chars_first_line = 0;
-    }
-
-#define CHECK_INV_LBREAKS() \
-      do { \
-       if (newlines >= (inv_lbsize - 2)) \
-         { \
-           inv_lbsize *= 2; \
-           inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
-         } \
-      } while (0)
-
-#if defined (HANDLE_MULTIBYTE)   
-#define CHECK_LPOS() \
-      do { \
-       lpos++; \
-       if (lpos >= _rl_screenwidth) \
-         { \
-           if (newlines >= (inv_lbsize - 2)) \
-             { \
-               inv_lbsize *= 2; \
-               inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
-             } \
-           inv_lbreaks[++newlines] = out; \
-           if (newlines >= (line_state_invisible->wbsize - 1)) \
-             { \
-               line_state_invisible->wbsize *= 2; \
-               line_state_invisible->wrapped_line = (int *)xrealloc (line_state_invisible->wrapped_line, line_state_invisible->wbsize * sizeof(int)); \
-             } \
-           line_state_invisible->wrapped_line[newlines] = _rl_wrapped_multicolumn; \
-           lpos = 0; \
-         } \
-      } while (0)
-#else
-#define CHECK_LPOS() \
-      do { \
-       lpos++; \
-       if (lpos >= _rl_screenwidth) \
-         { \
-           if (newlines >= (inv_lbsize - 2)) \
-             { \
-               inv_lbsize *= 2; \
-               inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
-             } \
-           inv_lbreaks[++newlines] = out; \
-           lpos = 0; \
-         } \
-      } while (0)
-#endif
-
-  /* inv_lbreaks[i] is where line i starts in the buffer. */
-  inv_lbreaks[newlines = 0] = 0;
-  lpos = prompt_physical_chars + modmark;
-
-#if defined (HANDLE_MULTIBYTE)
-  memset (line_state_invisible->wrapped_line, 0, line_state_invisible->wbsize * sizeof (int));
-  num = 0;
-#endif
-
-  /* prompt_invis_chars_first_line is the number of invisible characters in
-     the first physical line of the prompt.
-     wrap_offset - prompt_invis_chars_first_line is the number of invis
-     chars on the second (or, more generally, last) line. */
-
-  /* This is zero-based, used to set the newlines */
-  prompt_lines_estimate = lpos / _rl_screenwidth;
-
-  /* what if lpos is already >= _rl_screenwidth before we start drawing the
-     contents of the command line? */
-  while (lpos >= _rl_screenwidth)
-    {
-      int z;
-      /* fix from Darin Johnson <darin@acuson.com> for prompt string with
-         invisible characters that is longer than the screen width.  The
-         prompt_invis_chars_first_line variable could be made into an array
-         saying how many invisible characters there are per line, but that's
-         probably too much work for the benefit gained.  How many people have
-         prompts that exceed two physical lines?
-         Additional logic fix from Edward Catmur <ed@catmur.co.uk> */
-#if defined (HANDLE_MULTIBYTE)
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0)
-       {
-         n0 = num;
-          temp = local_prompt_len;
-          while (num < temp)
-           {
-             z = _rl_col_width  (local_prompt, n0, num, 1);
-             if (z > _rl_screenwidth)
-               {
-                 num = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY);
-                 break;
-               }
-             else if (z == _rl_screenwidth)
-               break;
-             num++;
-           }
-          temp = num;
-       }
-      else
-#endif /* !HANDLE_MULTIBYTE */
-       temp = ((newlines + 1) * _rl_screenwidth);
-
-      /* Now account for invisible characters in the current line. */
-      /* XXX - this assumes that the invisible characters may be split, but only
-        between the first and the last lines. */
-      temp += ((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line
-                                                            : ((newlines == prompt_lines_estimate) ? wrap_offset : prompt_invis_chars_first_line))
-                                         : ((newlines == 0) ? wrap_offset : 0));
-             
-      inv_lbreaks[++newlines] = temp;
-#if defined (HANDLE_MULTIBYTE)
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0)
-       lpos -= _rl_col_width (local_prompt, n0, num, 1);
-      else
-#endif
-       lpos -= _rl_screenwidth;
-    }
-
-  prompt_last_screen_line = newlines;
-
-  /* Draw the rest of the line (after the prompt) into invisible_line, keeping
-     track of where the cursor is (cpos_buffer_position), the number of the line containing
-     the cursor (lb_linenum), the last line number (lb_botlin and inv_botlin).
-     It maintains an array of line breaks for display (inv_lbreaks).
-     This handles expanding tabs for display and displaying meta characters. */
-  lb_linenum = 0;
-#if defined (HANDLE_MULTIBYTE)
-  in = 0;
-  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-    {
-      memset (&ps, 0, sizeof (mbstate_t));
-      /* XXX - what if wc_bytes ends up <= 0? check for MB_INVALIDCH */
-      wc_bytes = mbrtowc (&wc, rl_line_buffer, rl_end, &ps);
-    }
-  else
-    wc_bytes = 1;
-  while (in < rl_end)
-#else
-  for (in = 0; in < rl_end; in++)
-#endif
-    {
-      c = (unsigned char)rl_line_buffer[in];
-
-#if defined (HANDLE_MULTIBYTE)
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-       {
-         if (MB_INVALIDCH (wc_bytes))
-           {
-             /* Byte sequence is invalid or shortened.  Assume that the
-                first byte represents a character. */
-             wc_bytes = 1;
-             /* Assume that a character occupies a single column. */
-             wc_width = 1;
-             memset (&ps, 0, sizeof (mbstate_t));
-           }
-         else if (MB_NULLWCH (wc_bytes))
-           break;                      /* Found '\0' */
-         else
-           {
-             temp = wcwidth (wc);
-             wc_width = (temp >= 0) ? temp : 1;
-           }
-       }
-#endif
-
-      if (out + 8 >= line_size)                /* XXX - 8 for \t */
-       {
-         line_size *= 2;
-         visible_line = (char *)xrealloc (visible_line, line_size);
-         invisible_line = (char *)xrealloc (invisible_line, line_size);
-         line = invisible_line;
-       }
-
-      if (in == rl_point)
-       {
-         cpos_buffer_position = out;
-         lb_linenum = newlines;
-       }
-
-#if defined (HANDLE_MULTIBYTE)
-      if (META_CHAR (c) && _rl_output_meta_chars == 0) /* XXX - clean up */
-#else
-      if (META_CHAR (c))
-#endif
-       {
-         if (_rl_output_meta_chars == 0)
-           {
-             sprintf (line + out, "\\%o", c);
-
-             if (lpos + 4 >= _rl_screenwidth)
-               {
-                 temp = _rl_screenwidth - lpos;
-                 CHECK_INV_LBREAKS ();
-                 inv_lbreaks[++newlines] = out + temp;
-                 lpos = 4 - temp;
-               }
-             else
-               lpos += 4;
-
-             out += 4;
-           }
-         else
-           {
-             line[out++] = c;
-             CHECK_LPOS();
-           }
-       }
-#if defined (DISPLAY_TABS)
-      else if (c == '\t')
-       {
-         register int newout;
-
-#if 0
-         newout = (out | (int)7) + 1;
-#else
-         newout = out + 8 - lpos % 8;
-#endif
-         temp = newout - out;
-         if (lpos + temp >= _rl_screenwidth)
-           {
-             register int temp2;
-             temp2 = _rl_screenwidth - lpos;
-             CHECK_INV_LBREAKS ();
-             inv_lbreaks[++newlines] = out + temp2;
-             lpos = temp - temp2;
-             while (out < newout)
-               line[out++] = ' ';
-           }
-         else
-           {
-             while (out < newout)
-               line[out++] = ' ';
-             lpos += temp;
-           }
-       }
-#endif
-      else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
-       {
-         line[out++] = '\0';   /* XXX - sentinel */
-         CHECK_INV_LBREAKS ();
-         inv_lbreaks[++newlines] = out;
-         lpos = 0;
-       }
-      else if (CTRL_CHAR (c) || c == RUBOUT)
-       {
-         line[out++] = '^';
-         CHECK_LPOS();
-         line[out++] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
-         CHECK_LPOS();
-       }
-      else
-       {
-#if defined (HANDLE_MULTIBYTE)
-         if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-           {
-             register int i;
-
-             _rl_wrapped_multicolumn = 0;
-
-             if (_rl_screenwidth < lpos + wc_width)
-               for (i = lpos; i < _rl_screenwidth; i++)
-                 {
-                   /* The space will be removed in update_line() */
-                   line[out++] = ' ';
-                   _rl_wrapped_multicolumn++;
-                   CHECK_LPOS();
-                 }
-             if (in == rl_point)
-               {
-                 cpos_buffer_position = out;
-                 lb_linenum = newlines;
-               }
-             for (i = in; i < in+wc_bytes; i++)
-               line[out++] = rl_line_buffer[i];
-             for (i = 0; i < wc_width; i++)
-               CHECK_LPOS();
-           }
-         else
-           {
-             line[out++] = c;
-             CHECK_LPOS();
-           }
-#else
-         line[out++] = c;
-         CHECK_LPOS();
-#endif
-       }
-
-#if defined (HANDLE_MULTIBYTE)
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-       {
-         in += wc_bytes;
-         /* XXX - what if wc_bytes ends up <= 0? check for MB_INVALIDCH */
-         wc_bytes = mbrtowc (&wc, rl_line_buffer + in, rl_end - in, &ps);
-       }
-      else
-        in++;
-#endif
-
-    }
-  line[out] = '\0';
-  if (cpos_buffer_position < 0)
-    {
-      cpos_buffer_position = out;
-      lb_linenum = newlines;
-    }
-
-  inv_botlin = lb_botlin = newlines;
-  CHECK_INV_LBREAKS ();
-  inv_lbreaks[newlines+1] = out;
-  cursor_linenum = lb_linenum;
-
-  /* CPOS_BUFFER_POSITION == position in buffer where cursor should be placed.
-     CURSOR_LINENUM == line number where the cursor should be placed. */
-
-  /* PWP: now is when things get a bit hairy.  The visible and invisible
-     line buffers are really multiple lines, which would wrap every
-     (screenwidth - 1) characters.  Go through each in turn, finding
-     the changed region and updating it.  The line order is top to bottom. */
-
-  /* If we can move the cursor up and down, then use multiple lines,
-     otherwise, let long lines display in a single terminal line, and
-     horizontally scroll it. */
-
-  if (_rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
-    {
-      int nleft, pos, changed_screen_line, tx;
-
-      if (!rl_display_fixed || forced_display)
-       {
-         forced_display = 0;
-
-         /* If we have more than a screenful of material to display, then
-            only display a screenful.  We should display the last screen,
-            not the first.  */
-         if (out >= _rl_screenchars)
-           {
-             if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-               out = _rl_find_prev_mbchar (line, _rl_screenchars, MB_FIND_ANY);
-             else
-               out = _rl_screenchars - 1;
-           }
-
-         /* The first line is at character position 0 in the buffer.  The
-            second and subsequent lines start at inv_lbreaks[N], offset by
-            OFFSET (which has already been calculated above).  */
-
-#define INVIS_FIRST()  (prompt_physical_chars > _rl_screenwidth ? prompt_invis_chars_first_line : wrap_offset)
-#define WRAP_OFFSET(line, offset)  ((line == 0) \
-                                       ? (offset ? INVIS_FIRST() : 0) \
-                                       : ((line == prompt_last_screen_line) ? wrap_offset-prompt_invis_chars_first_line : 0))
-#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
-#define VIS_LLEN(l)    ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
-#define INV_LLEN(l)    (inv_lbreaks[l+1] - inv_lbreaks[l])
-#define VIS_CHARS(line) (visible_line + vis_lbreaks[line])
-#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
-#define INV_LINE(line) (invisible_line + inv_lbreaks[line])
-
-#define OLD_CPOS_IN_PROMPT() (cpos_adjusted == 0 && \
-                       _rl_last_c_pos != o_cpos && \
-                       _rl_last_c_pos > wrap_offset && \
-                       o_cpos < prompt_last_invisible)
-
-         /* For each line in the buffer, do the updating display. */
-         for (linenum = 0; linenum <= inv_botlin; linenum++)
-           {
-             /* This can lead us astray if we execute a program that changes
-                the locale from a non-multibyte to a multibyte one. */
-             o_cpos = _rl_last_c_pos;
-             cpos_adjusted = 0;
-             update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum,
-                          VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin);
-
-             /* update_line potentially changes _rl_last_c_pos, but doesn't
-                take invisible characters into account, since _rl_last_c_pos
-                is an absolute cursor position in a multibyte locale.  See
-                if compensating here is the right thing, or if we have to
-                change update_line itself.  There are several cases in which
-                update_line adjusts _rl_last_c_pos itself (so it can pass
-                _rl_move_cursor_relative accurate values); it communicates
-                this back by setting cpos_adjusted.  If we assume that
-                _rl_last_c_pos is correct (an absolute cursor position) each
-                time update_line is called, then we can assume in our
-                calculations that o_cpos does not need to be adjusted by
-                wrap_offset. */
-             if (linenum == 0 && (MB_CUR_MAX > 1 && rl_byte_oriented == 0) && OLD_CPOS_IN_PROMPT())
-               _rl_last_c_pos -= prompt_invis_chars_first_line;        /* XXX - was wrap_offset */
-             else if (linenum == prompt_last_screen_line && prompt_physical_chars > _rl_screenwidth &&
-                       (MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
-                       cpos_adjusted == 0 &&
-                       _rl_last_c_pos != o_cpos &&
-                       _rl_last_c_pos > (prompt_last_invisible - _rl_screenwidth - prompt_invis_chars_first_line))
-               _rl_last_c_pos -= (wrap_offset-prompt_invis_chars_first_line);
-                 
-             /* If this is the line with the prompt, we might need to
-                compensate for invisible characters in the new line. Do
-                this only if there is not more than one new line (which
-                implies that we completely overwrite the old visible line)
-                and the new line is shorter than the old.  Make sure we are
-                at the end of the new line before clearing. */
-             if (linenum == 0 &&
-                 inv_botlin == 0 && _rl_last_c_pos == out &&
-                 (wrap_offset > visible_wrap_offset) &&
-                 (_rl_last_c_pos < visible_first_line_len))
-               {
-                 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-                   nleft = _rl_screenwidth - _rl_last_c_pos;
-                 else
-                   nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos;
-                 if (nleft)
-                   _rl_clear_to_eol (nleft);
-               }
-#if 0
-             /* This segment is intended to handle the case where the prompt
-                has invisible characters on the second line and the new line
-                to be displayed needs to clear the rest of the old characters
-                out (e.g., when printing the i-search prompt).  In general,
-                the case of the new line being shorter than the old.
-                Incomplete */
-             else if (linenum == prompt_last_screen_line &&
-                      prompt_physical_chars > _rl_screenwidth &&
-                      wrap_offset != prompt_invis_chars_first_line &&
-                      _rl_last_c_pos == out &&
-#endif
-
-
-             /* Since the new first line is now visible, save its length. */
-             if (linenum == 0)
-               visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset;
-           }
-
-         /* We may have deleted some lines.  If so, clear the left over
-            blank ones at the bottom out. */
-         if (_rl_vis_botlin > inv_botlin)
-           {
-             char *tt;
-             for (; linenum <= _rl_vis_botlin; linenum++)
-               {
-                 tt = VIS_CHARS (linenum);
-                 _rl_move_vert (linenum);
-                 _rl_move_cursor_relative (0, tt);
-                 _rl_clear_to_eol
-                   ((linenum == _rl_vis_botlin) ? strlen (tt) : _rl_screenwidth);
-               }
-           }
-         _rl_vis_botlin = inv_botlin;
-
-         /* CHANGED_SCREEN_LINE is set to 1 if we have moved to a
-            different screen line during this redisplay. */
-         changed_screen_line = _rl_last_v_pos != cursor_linenum;
-         if (changed_screen_line)
-           {
-             _rl_move_vert (cursor_linenum);
-             /* If we moved up to the line with the prompt using _rl_term_up,
-                the physical cursor position on the screen stays the same,
-                but the buffer position needs to be adjusted to account
-                for invisible characters. */
-             if ((MB_CUR_MAX == 1 || rl_byte_oriented) && cursor_linenum == 0 && wrap_offset)
-               _rl_last_c_pos += wrap_offset;
-           }
-
-         /* We have to reprint the prompt if it contains invisible
-            characters, since it's not generally OK to just reprint
-            the characters from the current cursor position.  But we
-            only need to reprint it if the cursor is before the last
-            invisible character in the prompt string. */
-         nleft = prompt_visible_length + wrap_offset;
-         if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&
-#if 0
-             _rl_last_c_pos <= PROMPT_ENDING_INDEX && local_prompt)
-#else
-             _rl_last_c_pos < PROMPT_ENDING_INDEX && local_prompt)
-#endif
-           {
-#if defined (__MSDOS__)
-             putc ('\r', rl_outstream);
-#else
-             if (_rl_term_cr)
-               tputs (_rl_term_cr, 1, _rl_output_character_function);
-#endif
-             if (modmark)
-               _rl_output_some_chars ("*", 1);
-
-             _rl_output_some_chars (local_prompt, nleft);
-             if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-               _rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft, 1) - wrap_offset + modmark;
-             else
-               _rl_last_c_pos = nleft + modmark;
-           }
-
-         /* Where on that line?  And where does that line start
-            in the buffer? */
-         pos = inv_lbreaks[cursor_linenum];
-         /* nleft == number of characters in the line buffer between the
-            start of the line and the desired cursor position. */
-         nleft = cpos_buffer_position - pos;
-
-         /* NLEFT is now a number of characters in a buffer.  When in a
-            multibyte locale, however, _rl_last_c_pos is an absolute cursor
-            position that doesn't take invisible characters in the prompt
-            into account.  We use a fudge factor to compensate. */
-
-         /* Since _rl_backspace() doesn't know about invisible characters in the
-            prompt, and there's no good way to tell it, we compensate for
-            those characters here and call _rl_backspace() directly. */
-         if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
-           {
-             /* TX == new physical cursor position in multibyte locale. */
-             if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-               tx = _rl_col_width (&visible_line[pos], 0, nleft, 1) - visible_wrap_offset;
-             else
-               tx = nleft;
-             if (tx >= 0 && _rl_last_c_pos > tx)
-               {
-                 _rl_backspace (_rl_last_c_pos - tx);  /* XXX */
-                 _rl_last_c_pos = tx;
-               }
-           }
-
-         /* We need to note that in a multibyte locale we are dealing with
-            _rl_last_c_pos as an absolute cursor position, but moving to a
-            point specified by a buffer position (NLEFT) that doesn't take
-            invisible characters into account. */
-         if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-           _rl_move_cursor_relative (nleft, &invisible_line[pos]);
-         else if (nleft != _rl_last_c_pos)
-           _rl_move_cursor_relative (nleft, &invisible_line[pos]);
-       }
-    }
-  else                         /* Do horizontal scrolling. */
-    {
-#define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0)
-      int lmargin, ndisp, nleft, phys_c_pos, t;
-
-      /* Always at top line. */
-      _rl_last_v_pos = 0;
-
-      /* Compute where in the buffer the displayed line should start.  This
-        will be LMARGIN. */
-
-      /* The number of characters that will be displayed before the cursor. */
-      ndisp = cpos_buffer_position - wrap_offset;
-      nleft  = prompt_visible_length + wrap_offset;
-      /* Where the new cursor position will be on the screen.  This can be
-        longer than SCREENWIDTH; if it is, lmargin will be adjusted. */
-      phys_c_pos = cpos_buffer_position - (last_lmargin ? last_lmargin : wrap_offset);
-      t = _rl_screenwidth / 3;
-
-      /* If the number of characters had already exceeded the screenwidth,
-        last_lmargin will be > 0. */
-
-      /* If the number of characters to be displayed is more than the screen
-        width, compute the starting offset so that the cursor is about
-        two-thirds of the way across the screen. */
-      if (phys_c_pos > _rl_screenwidth - 2)
-       {
-         lmargin = cpos_buffer_position - (2 * t);
-         if (lmargin < 0)
-           lmargin = 0;
-         /* If the left margin would be in the middle of a prompt with
-            invisible characters, don't display the prompt at all. */
-         if (wrap_offset && lmargin > 0 && lmargin < nleft)
-           lmargin = nleft;
-       }
-      else if (ndisp < _rl_screenwidth - 2)            /* XXX - was -1 */
-       lmargin = 0;
-      else if (phys_c_pos < 1)
-       {
-         /* If we are moving back towards the beginning of the line and
-            the last margin is no longer correct, compute a new one. */
-         lmargin = ((cpos_buffer_position - 1) / t) * t;       /* XXX */
-         if (wrap_offset && lmargin > 0 && lmargin < nleft)
-           lmargin = nleft;
-       }
-      else
-       lmargin = last_lmargin;
-
-      /* If the first character on the screen isn't the first character
-        in the display line, indicate this with a special character. */
-      if (lmargin > 0)
-       line[lmargin] = '<';
-
-      /* If SCREENWIDTH characters starting at LMARGIN do not encompass
-        the whole line, indicate that with a special character at the
-        right edge of the screen.  If LMARGIN is 0, we need to take the
-        wrap offset into account. */
-      t = lmargin + M_OFFSET (lmargin, wrap_offset) + _rl_screenwidth;
-      if (t < out)
-       line[t - 1] = '>';
-
-      if (rl_display_fixed == 0 || forced_display || lmargin != last_lmargin)
-       {
-         forced_display = 0;
-         o_cpos = _rl_last_c_pos;
-         cpos_adjusted = 0;
-         update_line (&visible_line[last_lmargin],
-                      &invisible_line[lmargin],
-                      0,
-                      _rl_screenwidth + visible_wrap_offset,
-                      _rl_screenwidth + (lmargin ? 0 : wrap_offset),
-                      0);
-
-         if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && OLD_CPOS_IN_PROMPT())
-           _rl_last_c_pos -= prompt_invis_chars_first_line;    /* XXX - was wrap_offset */
-
-         /* If the visible new line is shorter than the old, but the number
-            of invisible characters is greater, and we are at the end of
-            the new line, we need to clear to eol. */
-         t = _rl_last_c_pos - M_OFFSET (lmargin, wrap_offset);
-         if ((M_OFFSET (lmargin, wrap_offset) > visible_wrap_offset) &&
-             (_rl_last_c_pos == out) &&
-             t < visible_first_line_len)
-           {
-             nleft = _rl_screenwidth - t;
-             _rl_clear_to_eol (nleft);
-           }
-         visible_first_line_len = out - lmargin - M_OFFSET (lmargin, wrap_offset);
-         if (visible_first_line_len > _rl_screenwidth)
-           visible_first_line_len = _rl_screenwidth;
-
-         _rl_move_cursor_relative (cpos_buffer_position - lmargin, &invisible_line[lmargin]);
-         last_lmargin = lmargin;
-       }
-    }
-  fflush (rl_outstream);
-
-  /* Swap visible and non-visible lines. */
-  {
-    struct line_state *vtemp = line_state_visible;
-
-    line_state_visible = line_state_invisible;
-    line_state_invisible = vtemp;
-
-    rl_display_fixed = 0;
-    /* If we are displaying on a single line, and last_lmargin is > 0, we
-       are not displaying any invisible characters, so set visible_wrap_offset
-       to 0. */
-    if (_rl_horizontal_scroll_mode && last_lmargin)
-      visible_wrap_offset = 0;
-    else
-      visible_wrap_offset = wrap_offset;
-  }
-
-  RL_UNSETSTATE (RL_STATE_REDISPLAYING);
-  _rl_release_sigint ();
-}
-
-/* PWP: update_line() is based on finding the middle difference of each
-   line on the screen; vis:
-
-                            /old first difference
-       /beginning of line   |        /old last same       /old EOL
-       v                    v        v             v
-old:   eddie> Oh, my little gruntle-buggy is to me, as lurgid as
-new:   eddie> Oh, my little buggy says to me, as lurgid as
-       ^                    ^  ^                          ^
-       \beginning of line   |  \new last same     \new end of line
-                            \new first difference
-
-   All are character pointers for the sake of speed.  Special cases for
-   no differences, as well as for end of line additions must be handled.
-
-   Could be made even smarter, but this works well enough */
-static void
-update_line (old, new, current_line, omax, nmax, inv_botlin)
-     register char *old, *new;
-     int current_line, omax, nmax, inv_botlin;
-{
-  register char *ofd, *ols, *oe, *nfd, *nls, *ne;
-  int temp, lendiff, wsatend, od, nd, twidth, o_cpos;
-  int current_invis_chars;
-  int col_lendiff, col_temp;
-#if defined (HANDLE_MULTIBYTE)
-  mbstate_t ps_new, ps_old;
-  int new_offset, old_offset;
-#endif
-
-  /* If we're at the right edge of a terminal that supports xn, we're
-     ready to wrap around, so do so.  This fixes problems with knowing
-     the exact cursor position and cut-and-paste with certain terminal
-     emulators.  In this calculation, TEMP is the physical screen
-     position of the cursor. */
-  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-    temp = _rl_last_c_pos;
-  else
-    temp = _rl_last_c_pos - WRAP_OFFSET (_rl_last_v_pos, visible_wrap_offset);
-  if (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode
-       && _rl_last_v_pos == current_line - 1)
-    {
-#if defined (HANDLE_MULTIBYTE)
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-       {
-         wchar_t wc;
-         mbstate_t ps;
-         int tempwidth, bytes;
-         size_t ret;
-
-         /* This fixes only double-column characters, but if the wrapped
-            character comsumes more than three columns, spaces will be
-            inserted in the string buffer. */
-         if (current_line < line_state_visible->wbsize && line_state_visible->wrapped_line[current_line] > 0)
-           _rl_clear_to_eol (line_state_visible->wrapped_line[current_line]);
-
-         memset (&ps, 0, sizeof (mbstate_t));
-         ret = mbrtowc (&wc, new, MB_CUR_MAX, &ps);
-         if (MB_INVALIDCH (ret))
-           {
-             tempwidth = 1;
-             ret = 1;
-           }
-         else if (MB_NULLWCH (ret))
-           tempwidth = 0;
-         else
-           tempwidth = wcwidth (wc);
-
-         if (tempwidth > 0)
-           {
-             int count, i;
-             bytes = ret;
-             for (count = 0; count < bytes; count++)
-               putc (new[count], rl_outstream);
-             _rl_last_c_pos = tempwidth;
-             _rl_last_v_pos++;
-             memset (&ps, 0, sizeof (mbstate_t));
-             ret = mbrtowc (&wc, old, MB_CUR_MAX, &ps);
-             if (ret != 0 && bytes != 0)
-               {
-                 if (MB_INVALIDCH (ret))
-                   ret = 1;
-                 memmove (old+bytes, old+ret, strlen (old+ret));
-                 memcpy (old, new, bytes);
-                 /* Fix up indices if we copy data from one line to another */
-                 omax += bytes - ret;
-                 for (i = current_line+1; i < inv_botlin+1; i++)
-                   vis_lbreaks[i] += bytes - ret;
-               }
-           }
-         else
-           {
-             putc (' ', rl_outstream);
-             _rl_last_c_pos = 1;
-             _rl_last_v_pos++;
-             if (old[0] && new[0])
-               old[0] = new[0];
-           }
-       }
-      else
-#endif
-       {
-         if (new[0])
-           putc (new[0], rl_outstream);
-         else
-           putc (' ', rl_outstream);
-         _rl_last_c_pos = 1;
-         _rl_last_v_pos++;
-         if (old[0] && new[0])
-           old[0] = new[0];
-       }
-    }
-
-      
-  /* Find first difference. */
-#if defined (HANDLE_MULTIBYTE)
-  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-    {
-      /* See if the old line is a subset of the new line, so that the
-        only change is adding characters. */
-      temp = (omax < nmax) ? omax : nmax;
-      if (memcmp (old, new, temp) == 0)                /* adding at the end */
-       {
-         ofd = old + temp;
-         nfd = new + temp;
-       }
-      else
-       {      
-         memset (&ps_new, 0, sizeof(mbstate_t));
-         memset (&ps_old, 0, sizeof(mbstate_t));
-
-         if (omax == nmax && STREQN (new, old, omax))
-           {
-             ofd = old + omax;
-             nfd = new + nmax;
-           }
-         else
-           {
-             new_offset = old_offset = 0;
-             for (ofd = old, nfd = new;
-                   (ofd - old < omax) && *ofd &&
-                   _rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new); )
-               {
-                 old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY);
-                 new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY);
-                 ofd = old + old_offset;
-                 nfd = new + new_offset;
-               }
-           }
-       }
-    }
-  else
-#endif
-  for (ofd = old, nfd = new;
-       (ofd - old < omax) && *ofd && (*ofd == *nfd);
-       ofd++, nfd++)
-    ;
-
-  /* Move to the end of the screen line.  ND and OD are used to keep track
-     of the distance between ne and new and oe and old, respectively, to
-     move a subtraction out of each loop. */
-  for (od = ofd - old, oe = ofd; od < omax && *oe; oe++, od++);
-  for (nd = nfd - new, ne = nfd; nd < nmax && *ne; ne++, nd++);
-
-  /* If no difference, continue to next line. */
-  if (ofd == oe && nfd == ne)
-    return;
-
-  wsatend = 1;                 /* flag for trailing whitespace */
-
-#if defined (HANDLE_MULTIBYTE)
-  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-    {
-      ols = old + _rl_find_prev_mbchar (old, oe - old, MB_FIND_ANY);
-      nls = new + _rl_find_prev_mbchar (new, ne - new, MB_FIND_ANY);
-      while ((ols > ofd) && (nls > nfd))
-       {
-         memset (&ps_old, 0, sizeof (mbstate_t));
-         memset (&ps_new, 0, sizeof (mbstate_t));
-
-#if 0
-         /* On advice from jir@yamato.ibm.com */
-         _rl_adjust_point (old, ols - old, &ps_old);
-         _rl_adjust_point (new, nls - new, &ps_new);
-#endif
-
-         if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0)
-           break;
-
-         if (*ols == ' ')
-           wsatend = 0;
-
-         ols = old + _rl_find_prev_mbchar (old, ols - old, MB_FIND_ANY);
-         nls = new + _rl_find_prev_mbchar (new, nls - new, MB_FIND_ANY);
-       }
-    }
-  else
-    {
-#endif /* HANDLE_MULTIBYTE */
-  ols = oe - 1;                        /* find last same */
-  nls = ne - 1;
-  while ((ols > ofd) && (nls > nfd) && (*ols == *nls))
-    {
-      if (*ols != ' ')
-       wsatend = 0;
-      ols--;
-      nls--;
-    }
-#if defined (HANDLE_MULTIBYTE)
-    }
-#endif
-
-  if (wsatend)
-    {
-      ols = oe;
-      nls = ne;
-    }
-#if defined (HANDLE_MULTIBYTE)
-  /* This may not work for stateful encoding, but who cares?  To handle
-     stateful encoding properly, we have to scan each string from the
-     beginning and compare. */
-  else if (_rl_compare_chars (ols, 0, NULL, nls, 0, NULL) == 0)
-#else
-  else if (*ols != *nls)
-#endif
-    {
-      if (*ols)                        /* don't step past the NUL */
-       {
-         if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-           ols = old + _rl_find_next_mbchar (old, ols - old, 1, MB_FIND_ANY);
-         else
-           ols++;
-       }
-      if (*nls)
-       {
-         if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-           nls = new + _rl_find_next_mbchar (new, nls - new, 1, MB_FIND_ANY);
-         else
-           nls++;
-       }
-    }
-
-  /* count of invisible characters in the current invisible line. */
-  current_invis_chars = W_OFFSET (current_line, wrap_offset);
-  if (_rl_last_v_pos != current_line)
-    {
-      _rl_move_vert (current_line);
-      if ((MB_CUR_MAX == 1 || rl_byte_oriented) && current_line == 0 && visible_wrap_offset)
-       _rl_last_c_pos += visible_wrap_offset;
-    }
-
-  /* If this is the first line and there are invisible characters in the
-     prompt string, and the prompt string has not changed, and the current
-     cursor position is before the last invisible character in the prompt,
-     and the index of the character to move to is past the end of the prompt
-     string, then redraw the entire prompt string.  We can only do this
-     reliably if the terminal supports a `cr' capability.
-
-     This is not an efficiency hack -- there is a problem with redrawing
-     portions of the prompt string if they contain terminal escape
-     sequences (like drawing the `unbold' sequence without a corresponding
-     `bold') that manifests itself on certain terminals. */
-
-  lendiff = local_prompt_len;
-  od = ofd - old;      /* index of first difference in visible line */
-  if (current_line == 0 && !_rl_horizontal_scroll_mode &&
-      _rl_term_cr && lendiff > prompt_visible_length && _rl_last_c_pos > 0 &&
-      od >= lendiff && _rl_last_c_pos < PROMPT_ENDING_INDEX)
-    {
-#if defined (__MSDOS__)
-      putc ('\r', rl_outstream);
-#else
-      tputs (_rl_term_cr, 1, _rl_output_character_function);
-#endif
-      if (modmark)
-       _rl_output_some_chars ("*", 1);
-      _rl_output_some_chars (local_prompt, lendiff);
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-       {
-         /* We take wrap_offset into account here so we can pass correct
-            information to _rl_move_cursor_relative. */
-         _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff, 1) - wrap_offset + modmark;
-         cpos_adjusted = 1;
-       }
-      else
-       _rl_last_c_pos = lendiff + modmark;
-    }
-
-  o_cpos = _rl_last_c_pos;
-
-  /* When this function returns, _rl_last_c_pos is correct, and an absolute
-     cursor postion in multibyte mode, but a buffer index when not in a
-     multibyte locale. */
-  _rl_move_cursor_relative (od, old);
-#if 1
-#if defined (HANDLE_MULTIBYTE)
-  /* We need to indicate that the cursor position is correct in the presence of
-     invisible characters in the prompt string.  Let's see if setting this when
-     we make sure we're at the end of the drawn prompt string works. */
-  if (current_line == 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0 &&
-      (_rl_last_c_pos > 0 || o_cpos > 0) &&
-      _rl_last_c_pos == prompt_physical_chars)
-    cpos_adjusted = 1;
-#endif
-#endif
-
-  /* if (len (new) > len (old))
-     lendiff == difference in buffer
-     col_lendiff == difference on screen
-     When not using multibyte characters, these are equal */
-  lendiff = (nls - nfd) - (ols - ofd);
-  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-    col_lendiff = _rl_col_width (new, nfd - new, nls - new, 1) - _rl_col_width (old, ofd - old, ols - old, 1);
-  else
-    col_lendiff = lendiff;
-
-  /* If we are changing the number of invisible characters in a line, and
-     the spot of first difference is before the end of the invisible chars,
-     lendiff needs to be adjusted. */
-  if (current_line == 0 && !_rl_horizontal_scroll_mode &&
-      current_invis_chars != visible_wrap_offset)
-    {
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-       {
-         lendiff += visible_wrap_offset - current_invis_chars;
-         col_lendiff += visible_wrap_offset - current_invis_chars;
-       }
-      else
-       {
-         lendiff += visible_wrap_offset - current_invis_chars;
-         col_lendiff = lendiff;
-       }
-    }
-
-  /* Insert (diff (len (old), len (new)) ch. */
-  temp = ne - nfd;
-  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-    col_temp = _rl_col_width (new, nfd - new, ne - new, 1);
-  else
-    col_temp = temp;
-
-  if (col_lendiff > 0) /* XXX - was lendiff */
-    {
-      /* Non-zero if we're increasing the number of lines. */
-      int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
-      /* If col_lendiff is > 0, implying that the new string takes up more
-        screen real estate than the old, but lendiff is < 0, meaning that it
-        takes fewer bytes, we need to just output the characters starting
-        from the first difference.  These will overwrite what is on the
-        display, so there's no reason to do a smart update.  This can really
-        only happen in a multibyte environment. */
-      if (lendiff < 0)
-       {
-         _rl_output_some_chars (nfd, temp);
-         _rl_last_c_pos += _rl_col_width (nfd, 0, temp, 1);
-         /* If nfd begins before any invisible characters in the prompt,
-            adjust _rl_last_c_pos to account for wrap_offset and set
-            cpos_adjusted to let the caller know. */
-         if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
-           {
-             _rl_last_c_pos -= wrap_offset;
-             cpos_adjusted = 1;
-           }
-         return;
-       }
-      /* Sometimes it is cheaper to print the characters rather than
-        use the terminal's capabilities.  If we're growing the number
-        of lines, make sure we actually cause the new line to wrap
-        around on auto-wrapping terminals. */
-      else if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
-       {
-         /* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and
-            _rl_horizontal_scroll_mode == 1, inserting the characters with
-            _rl_term_IC or _rl_term_ic will screw up the screen because of the
-            invisible characters.  We need to just draw them. */
-         /* The same thing happens if we're trying to draw before the last
-            invisible character in the prompt string or we're increasing the
-            number of invisible characters in the line and we're not drawing
-            the entire prompt string. */
-         if (*ols && ((_rl_horizontal_scroll_mode &&
-                       _rl_last_c_pos == 0 &&
-                       lendiff > prompt_visible_length &&
-                       current_invis_chars > 0) == 0) &&
-                     (((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
-                       current_line == 0 && wrap_offset &&
-                       ((nfd - new) <= prompt_last_invisible) &&
-                       (col_lendiff < prompt_visible_length)) == 0) &&
-                     (visible_wrap_offset >= current_invis_chars))
-           {
-             insert_some_chars (nfd, lendiff, col_lendiff);
-             _rl_last_c_pos += col_lendiff;
-           }
-#if 0          /* XXX - for now */
-         else if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && _rl_last_c_pos == 0 && wrap_offset && (nfd-new) <= prompt_last_invisible && col_lendiff < prompt_visible_length && visible_wrap_offset >= current_invis_chars)
-           {
-             _rl_output_some_chars (nfd, lendiff);
-             _rl_last_c_pos += col_lendiff;
-           }
-#endif
-         else if ((MB_CUR_MAX == 1 || rl_byte_oriented != 0) && *ols == 0 && lendiff > 0)
-           {
-             /* At the end of a line the characters do not have to
-                be "inserted".  They can just be placed on the screen. */
-             /* However, this screws up the rest of this block, which
-                assumes you've done the insert because you can. */
-             _rl_output_some_chars (nfd, lendiff);
-             _rl_last_c_pos += col_lendiff;
-           }
-         else
-           {
-             _rl_output_some_chars (nfd, temp);
-             _rl_last_c_pos += col_temp;
-             /* If nfd begins before the last invisible character in the
-                prompt, adjust _rl_last_c_pos to account for wrap_offset
-                and set cpos_adjusted to let the caller know. */
-             if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
-               {
-                 _rl_last_c_pos -= wrap_offset;
-                 cpos_adjusted = 1;
-               }
-             return;
-           }
-         /* Copy (new) chars to screen from first diff to last match. */
-         temp = nls - nfd;
-         if ((temp - lendiff) > 0)
-           {
-             _rl_output_some_chars (nfd + lendiff, temp - lendiff);
-            /* XXX -- this bears closer inspection.  Fixes a redisplay bug
-               reported against bash-3.0-alpha by Andreas Schwab involving
-               multibyte characters and prompt strings with invisible
-               characters, but was previously disabled. */
-             if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-               twidth = _rl_col_width (nfd+lendiff, 0, temp-col_lendiff, 1);
-             else
-               twidth = temp - lendiff;
-             _rl_last_c_pos += twidth;
-             /* If nfd begins before the last invisible character in the
-                prompt, adjust _rl_last_c_pos to account for wrap_offset
-                and set cpos_adjusted to let the caller know. */
-             if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
-               {
-                 _rl_last_c_pos -= wrap_offset;
-                 cpos_adjusted = 1;
-               }
-           }
-       }
-      else
-       {
-         /* cannot insert chars, write to EOL */
-         _rl_output_some_chars (nfd, temp);
-         _rl_last_c_pos += col_temp;
-         /* If we're in a multibyte locale and were before the last invisible
-            char in the current line (which implies we just output some invisible
-            characters) we need to adjust _rl_last_c_pos, since it represents
-            a physical character position. */
-         if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
-               current_line == prompt_last_screen_line && wrap_offset &&
-               wrap_offset != prompt_invis_chars_first_line &&
-               ((nfd-new) < (prompt_last_invisible-(current_line*_rl_screenwidth))))
-           {
-             _rl_last_c_pos -= wrap_offset - prompt_invis_chars_first_line;
-             cpos_adjusted = 1;
-           }
-       }
-    }
-  else                         /* Delete characters from line. */
-    {
-      /* If possible and inexpensive to use terminal deletion, then do so. */
-      if (_rl_term_dc && (2 * col_temp) >= -col_lendiff)
-       {
-         /* If all we're doing is erasing the invisible characters in the
-            prompt string, don't bother.  It screws up the assumptions
-            about what's on the screen. */
-         if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 &&
-             -lendiff == visible_wrap_offset)
-           col_lendiff = 0;
-
-         if (col_lendiff)
-           delete_chars (-col_lendiff); /* delete (diff) characters */
-
-         /* Copy (new) chars to screen from first diff to last match */
-         temp = nls - nfd;
-         if (temp > 0)
-           {
-             /* If nfd begins at the prompt, or before the invisible
-                characters in the prompt, we need to adjust _rl_last_c_pos
-                in a multibyte locale to account for the wrap offset and
-                set cpos_adjusted accordingly. */
-             _rl_output_some_chars (nfd, temp);
-             if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-               {
-                 _rl_last_c_pos += _rl_col_width (nfd, 0, temp, 1);
-                 if (current_line == 0 && wrap_offset &&  ((nfd - new) <= prompt_last_invisible))
-                   {
-                     _rl_last_c_pos -= wrap_offset;
-                     cpos_adjusted = 1;
-                   }
-               }
-             else
-               _rl_last_c_pos += temp;
-           }
-       }
-      /* Otherwise, print over the existing material. */
-      else
-       {
-         if (temp > 0)
-           {
-             /* If nfd begins at the prompt, or before the invisible
-                characters in the prompt, we need to adjust _rl_last_c_pos
-                in a multibyte locale to account for the wrap offset and
-                set cpos_adjusted accordingly. */
-             _rl_output_some_chars (nfd, temp);
-             _rl_last_c_pos += col_temp;               /* XXX */
-             if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-               {
-                 if (current_line == 0 && wrap_offset &&  ((nfd - new) <= prompt_last_invisible))
-                   {
-                     _rl_last_c_pos -= wrap_offset;
-                     cpos_adjusted = 1;
-                   }
-               }
-           }
-         lendiff = (oe - old) - (ne - new);
-         if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-           col_lendiff = _rl_col_width (old, 0, oe - old, 1) - _rl_col_width (new, 0, ne - new, 1);
-         else
-           col_lendiff = lendiff;
-
-#if 0
-         if (col_lendiff)
-#else
-         /* If we've already printed over the entire width of the screen,
-            including the old material, then col_lendiff doesn't matter and
-            space_to_eol will insert too many spaces.  XXX - maybe we should
-            adjust col_lendiff based on the difference between _rl_last_c_pos
-            and _rl_screenwidth */
-         if (col_lendiff && ((MB_CUR_MAX == 1 || rl_byte_oriented) || (_rl_last_c_pos < _rl_screenwidth)))
-#endif
-           {     
-             if (_rl_term_autowrap && current_line < inv_botlin)
-               space_to_eol (col_lendiff);
-             else
-               _rl_clear_to_eol (col_lendiff);
-           }
-       }
-    }
-}
-
-/* Tell the update routines that we have moved onto a new (empty) line. */
-int
-rl_on_new_line ()
-{
-  if (visible_line)
-    visible_line[0] = '\0';
-
-  _rl_last_c_pos = _rl_last_v_pos = 0;
-  _rl_vis_botlin = last_lmargin = 0;
-  if (vis_lbreaks)
-    vis_lbreaks[0] = vis_lbreaks[1] = 0;
-  visible_wrap_offset = 0;
-  return 0;
-}
-
-/* Tell the update routines that we have moved onto a new line with the
-   prompt already displayed.  Code originally from the version of readline
-   distributed with CLISP.  rl_expand_prompt must have already been called
-   (explicitly or implicitly).  This still doesn't work exactly right. */
-int
-rl_on_new_line_with_prompt ()
-{
-  int prompt_size, i, l, real_screenwidth, newlines;
-  char *prompt_last_line, *lprompt;
-
-  /* Initialize visible_line and invisible_line to ensure that they can hold
-     the already-displayed prompt. */
-  prompt_size = strlen (rl_prompt) + 1;
-  init_line_structures (prompt_size);
-
-  /* Make sure the line structures hold the already-displayed prompt for
-     redisplay. */
-  lprompt = local_prompt ? local_prompt : rl_prompt;
-  strcpy (visible_line, lprompt);
-  strcpy (invisible_line, lprompt);
-
-  /* If the prompt contains newlines, take the last tail. */
-  prompt_last_line = strrchr (rl_prompt, '\n');
-  if (!prompt_last_line)
-    prompt_last_line = rl_prompt;
-
-  l = strlen (prompt_last_line);
-  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-    _rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l, 1);        /* XXX */
-  else
-    _rl_last_c_pos = l;
-
-  /* Dissect prompt_last_line into screen lines. Note that here we have
-     to use the real screenwidth. Readline's notion of screenwidth might be
-     one less, see terminal.c. */
-  real_screenwidth = _rl_screenwidth + (_rl_term_autowrap ? 0 : 1);
-  _rl_last_v_pos = l / real_screenwidth;
-  /* If the prompt length is a multiple of real_screenwidth, we don't know
-     whether the cursor is at the end of the last line, or already at the
-     beginning of the next line. Output a newline just to be safe. */
-  if (l > 0 && (l % real_screenwidth) == 0)
-    _rl_output_some_chars ("\n", 1);
-  last_lmargin = 0;
-
-  newlines = 0; i = 0;
-  while (i <= l)
-    {
-      _rl_vis_botlin = newlines;
-      vis_lbreaks[newlines++] = i;
-      i += real_screenwidth;
-    }
-  vis_lbreaks[newlines] = l;
-  visible_wrap_offset = 0;
-
-  rl_display_prompt = rl_prompt;       /* XXX - make sure it's set */
-
-  return 0;
-}
-
-/* Actually update the display, period. */
-int
-rl_forced_update_display ()
-{
-  register char *temp;
-
-  if (visible_line)
-    {
-      temp = visible_line;
-      while (*temp)
-       *temp++ = '\0';
-    }
-  rl_on_new_line ();
-  forced_display++;
-  (*rl_redisplay_function) ();
-  return 0;
-}
-
-/* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices.
-   (Well, when we don't have multibyte characters, _rl_last_c_pos is a
-   buffer index.)
-   DATA is the contents of the screen line of interest; i.e., where
-   the movement is being done. */
-void
-_rl_move_cursor_relative (new, data)
-     int new;
-     const char *data;
-{
-  register int i;
-  int woff;                    /* number of invisible chars on current line */
-  int cpos, dpos;              /* current and desired cursor positions */
-  int adjust;
-
-  woff = WRAP_OFFSET (_rl_last_v_pos, wrap_offset);
-  cpos = _rl_last_c_pos;
-
-  if (cpos == 0 && cpos == new)
-    return;
-
-#if defined (HANDLE_MULTIBYTE)
-  /* If we have multibyte characters, NEW is indexed by the buffer point in
-     a multibyte string, but _rl_last_c_pos is the display position.  In
-     this case, NEW's display position is not obvious and must be
-     calculated.  We need to account for invisible characters in this line,
-     as long as we are past them and they are counted by _rl_col_width. */
-  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-    {
-      adjust = 1;
-      /* Try to short-circuit common cases and eliminate a bunch of multibyte
-        character function calls. */
-      /* 1.  prompt string */
-      if (new == local_prompt_len && memcmp (data, local_prompt, new) == 0)
-       {
-         dpos = prompt_visible_length;
-         cpos_adjusted = 1;
-         adjust = 0;
-       }
-      /* 2.  prompt_string + line contents */
-      else if (new > local_prompt_len && local_prompt && memcmp (data, local_prompt, local_prompt_len) == 0)
-       {
-         dpos = prompt_visible_length + _rl_col_width (data, local_prompt_len, new, 1);
-         cpos_adjusted = 1;
-         adjust = 0;
-       }
-      else
-        dpos = _rl_col_width (data, 0, new, 1);
-
-      /* Use NEW when comparing against the last invisible character in the
-        prompt string, since they're both buffer indices and DPOS is a
-        desired display position. */
-      if (adjust && ((new > prompt_last_invisible) ||          /* XXX - don't use woff here */
-         (prompt_physical_chars >= _rl_screenwidth &&
-          _rl_last_v_pos == prompt_last_screen_line &&
-          wrap_offset >= woff && dpos >= woff &&
-          new > (prompt_last_invisible-(_rl_screenwidth*_rl_last_v_pos)-wrap_offset))))
-          /* XXX last comparison might need to be >= */
-       {
-         dpos -= woff;
-         /* Since this will be assigned to _rl_last_c_pos at the end (more
-            precisely, _rl_last_c_pos == dpos when this function returns),
-            let the caller know. */
-         cpos_adjusted = 1;
-       }
-    }
-  else
-#endif
-    dpos = new;
-
-  /* If we don't have to do anything, then return. */
-  if (cpos == dpos)
-    return;
-
-  /* It may be faster to output a CR, and then move forwards instead
-     of moving backwards. */
-  /* i == current physical cursor position. */
-#if defined (HANDLE_MULTIBYTE)
-  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-    i = _rl_last_c_pos;
-  else
-#endif
-  i = _rl_last_c_pos - woff;
-  if (dpos == 0 || CR_FASTER (dpos, _rl_last_c_pos) ||
-      (_rl_term_autowrap && i == _rl_screenwidth))
-    {
-#if defined (__MSDOS__)
-      putc ('\r', rl_outstream);
-#else
-      tputs (_rl_term_cr, 1, _rl_output_character_function);
-#endif /* !__MSDOS__ */
-      cpos = _rl_last_c_pos = 0;
-    }
-
-  if (cpos < dpos)
-    {
-      /* Move the cursor forward.  We do it by printing the command
-        to move the cursor forward if there is one, else print that
-        portion of the output buffer again.  Which is cheaper? */
-
-      /* The above comment is left here for posterity.  It is faster
-        to print one character (non-control) than to print a control
-        sequence telling the terminal to move forward one character.
-        That kind of control is for people who don't know what the
-        data is underneath the cursor. */
-
-      /* However, we need a handle on where the current display position is
-        in the buffer for the immediately preceding comment to be true.
-        In multibyte locales, we don't currently have that info available.
-        Without it, we don't know where the data we have to display begins
-        in the buffer and we have to go back to the beginning of the screen
-        line.  In this case, we can use the terminal sequence to move forward
-        if it's available. */
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-       {
-         if (_rl_term_forward_char)
-           {
-             for (i = cpos; i < dpos; i++)
-               tputs (_rl_term_forward_char, 1, _rl_output_character_function);
-           }
-         else
-           {
-             tputs (_rl_term_cr, 1, _rl_output_character_function);
-             for (i = 0; i < new; i++)
-               putc (data[i], rl_outstream);
-           }
-       }
-      else
-       for (i = cpos; i < new; i++)
-         putc (data[i], rl_outstream);
-    }
-
-#if defined (HANDLE_MULTIBYTE)
-  /* NEW points to the buffer point, but _rl_last_c_pos is the display point.
-     The byte length of the string is probably bigger than the column width
-     of the string, which means that if NEW == _rl_last_c_pos, then NEW's
-     display point is less than _rl_last_c_pos. */
-#endif
-  else if (cpos > dpos)
-    _rl_backspace (cpos - dpos);
-
-  _rl_last_c_pos = dpos;
-}
-
-/* PWP: move the cursor up or down. */
-void
-_rl_move_vert (to)
-     int to;
-{
-  register int delta, i;
-
-  if (_rl_last_v_pos == to || to > _rl_screenheight)
-    return;
-
-  if ((delta = to - _rl_last_v_pos) > 0)
-    {
-      for (i = 0; i < delta; i++)
-       putc ('\n', rl_outstream);
-#if defined (__MSDOS__)
-      putc ('\r', rl_outstream);
-#else
-      tputs (_rl_term_cr, 1, _rl_output_character_function);
-#endif
-      _rl_last_c_pos = 0;
-    }
-  else
-    {                  /* delta < 0 */
-      if (_rl_term_up && *_rl_term_up)
-       for (i = 0; i < -delta; i++)
-         tputs (_rl_term_up, 1, _rl_output_character_function);
-    }
-
-  _rl_last_v_pos = to;         /* Now TO is here */
-}
-
-/* Physically print C on rl_outstream.  This is for functions which know
-   how to optimize the display.  Return the number of characters output. */
-int
-rl_show_char (c)
-     int c;
-{
-  int n = 1;
-  if (META_CHAR (c) && (_rl_output_meta_chars == 0))
-    {
-      fprintf (rl_outstream, "M-");
-      n += 2;
-      c = UNMETA (c);
-    }
-
-#if defined (DISPLAY_TABS)
-  if ((CTRL_CHAR (c) && c != '\t') || c == RUBOUT)
-#else
-  if (CTRL_CHAR (c) || c == RUBOUT)
-#endif /* !DISPLAY_TABS */
-    {
-      fprintf (rl_outstream, "C-");
-      n += 2;
-      c = CTRL_CHAR (c) ? UNCTRL (c) : '?';
-    }
-
-  putc (c, rl_outstream);
-  fflush (rl_outstream);
-  return n;
-}
-
-int
-rl_character_len (c, pos)
-     register int c, pos;
-{
-  unsigned char uc;
-
-  uc = (unsigned char)c;
-
-  if (META_CHAR (uc))
-    return ((_rl_output_meta_chars == 0) ? 4 : 1);
-
-  if (uc == '\t')
-    {
-#if defined (DISPLAY_TABS)
-      return (((pos | 7) + 1) - pos);
-#else
-      return (2);
-#endif /* !DISPLAY_TABS */
-    }
-
-  if (CTRL_CHAR (c) || c == RUBOUT)
-    return (2);
-
-  return ((ISPRINT (uc)) ? 1 : 2);
-}
-/* How to print things in the "echo-area".  The prompt is treated as a
-   mini-modeline. */
-static int msg_saved_prompt = 0;
-
-#if defined (USE_VARARGS)
-int
-#if defined (PREFER_STDARG)
-rl_message (const char *format, ...)
-#else
-rl_message (va_alist)
-     va_dcl
-#endif
-{
-  va_list args;
-#if defined (PREFER_VARARGS)
-  char *format;
-#endif
-
-#if defined (PREFER_STDARG)
-  va_start (args, format);
-#else
-  va_start (args);
-  format = va_arg (args, char *);
-#endif
-
-#if defined (HAVE_VSNPRINTF)
-  vsnprintf (msg_buf, sizeof (msg_buf) - 1, format, args);
-#else
-  vsprintf (msg_buf, format, args);
-  msg_buf[sizeof(msg_buf) - 1] = '\0'; /* overflow? */
-#endif
-  va_end (args);
-
-  if (saved_local_prompt == 0)
-    {
-      rl_save_prompt ();
-      msg_saved_prompt = 1;
-    }
-  rl_display_prompt = msg_buf;
-  local_prompt = expand_prompt (msg_buf, &prompt_visible_length,
-                                        &prompt_last_invisible,
-                                        &prompt_invis_chars_first_line,
-                                        &prompt_physical_chars);
-  local_prompt_prefix = (char *)NULL;
-  local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
-  (*rl_redisplay_function) ();
-
-  return 0;
-}
-#else /* !USE_VARARGS */
-int
-rl_message (format, arg1, arg2)
-     char *format;
-{
-  sprintf (msg_buf, format, arg1, arg2);
-  msg_buf[sizeof(msg_buf) - 1] = '\0'; /* overflow? */
-
-  rl_display_prompt = msg_buf;
-  if (saved_local_prompt == 0)
-    {
-      rl_save_prompt ();
-      msg_saved_prompt = 1;
-    }
-  local_prompt = expand_prompt (msg_buf, &prompt_visible_length,
-                                        &prompt_last_invisible,
-                                        &prompt_invis_chars_first_line,
-                                        &prompt_physical_chars);
-  local_prompt_prefix = (char *)NULL;
-  local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
-  (*rl_redisplay_function) ();
-      
-  return 0;
-}
-#endif /* !USE_VARARGS */
-
-/* How to clear things from the "echo-area". */
-int
-rl_clear_message ()
-{
-  rl_display_prompt = rl_prompt;
-  if (msg_saved_prompt)
-    {
-      rl_restore_prompt ();
-      msg_saved_prompt = 0;
-    }
-  (*rl_redisplay_function) ();
-  return 0;
-}
-
-int
-rl_reset_line_state ()
-{
-  rl_on_new_line ();
-
-  rl_display_prompt = rl_prompt ? rl_prompt : "";
-  forced_display = 1;
-  return 0;
-}
-
-void
-rl_save_prompt ()
-{
-  saved_local_prompt = local_prompt;
-  saved_local_prefix = local_prompt_prefix;
-  saved_prefix_length = prompt_prefix_length;
-  saved_local_length = local_prompt_len;
-  saved_last_invisible = prompt_last_invisible;
-  saved_visible_length = prompt_visible_length;
-  saved_invis_chars_first_line = prompt_invis_chars_first_line;
-  saved_physical_chars = prompt_physical_chars;
-
-  local_prompt = local_prompt_prefix = (char *)0;
-  local_prompt_len = 0;
-  prompt_last_invisible = prompt_visible_length = prompt_prefix_length = 0;
-  prompt_invis_chars_first_line = prompt_physical_chars = 0;
-}
-
-void
-rl_restore_prompt ()
-{
-  FREE (local_prompt);
-  FREE (local_prompt_prefix);
-
-  local_prompt = saved_local_prompt;
-  local_prompt_prefix = saved_local_prefix;
-  local_prompt_len = saved_local_length;
-  prompt_prefix_length = saved_prefix_length;
-  prompt_last_invisible = saved_last_invisible;
-  prompt_visible_length = saved_visible_length;
-  prompt_invis_chars_first_line = saved_invis_chars_first_line;
-  prompt_physical_chars = saved_physical_chars;
-
-  /* can test saved_local_prompt to see if prompt info has been saved. */
-  saved_local_prompt = saved_local_prefix = (char *)0;
-  saved_local_length = 0;
-  saved_last_invisible = saved_visible_length = saved_prefix_length = 0;
-  saved_invis_chars_first_line = saved_physical_chars = 0;
-}
-
-char *
-_rl_make_prompt_for_search (pchar)
-     int pchar;
-{
-  int len;
-  char *pmt, *p;
-
-  rl_save_prompt ();
-
-  /* We've saved the prompt, and can do anything with the various prompt
-     strings we need before they're restored.  We want the unexpanded
-     portion of the prompt string after any final newline. */
-  p = rl_prompt ? strrchr (rl_prompt, '\n') : 0;
-  if (p == 0)
-    {
-      len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
-      pmt = (char *)xmalloc (len + 2);
-      if (len)
-       strcpy (pmt, rl_prompt);
-      pmt[len] = pchar;
-      pmt[len+1] = '\0';
-    }
-  else
-    {
-      p++;
-      len = strlen (p);
-      pmt = (char *)xmalloc (len + 2);
-      if (len)
-       strcpy (pmt, p);
-      pmt[len] = pchar;
-      pmt[len+1] = '\0';
-    }  
-
-  /* will be overwritten by expand_prompt, called from rl_message */
-  prompt_physical_chars = saved_physical_chars + 1;
-  return pmt;
-}
-
-/* Quick redisplay hack when erasing characters at the end of the line. */
-void
-_rl_erase_at_end_of_line (l)
-     int l;
-{
-  register int i;
-
-  _rl_backspace (l);
-  for (i = 0; i < l; i++)
-    putc (' ', rl_outstream);
-  _rl_backspace (l);
-  for (i = 0; i < l; i++)
-    visible_line[--_rl_last_c_pos] = '\0';
-  rl_display_fixed++;
-}
-
-/* Clear to the end of the line.  COUNT is the minimum
-   number of character spaces to clear, */
-void
-_rl_clear_to_eol (count)
-     int count;
-{
-  if (_rl_term_clreol)
-    tputs (_rl_term_clreol, 1, _rl_output_character_function);
-  else if (count)
-    space_to_eol (count);
-}
-
-/* Clear to the end of the line using spaces.  COUNT is the minimum
-   number of character spaces to clear, */
-static void
-space_to_eol (count)
-     int count;
-{
-  register int i;
-
-  for (i = 0; i < count; i++)
-   putc (' ', rl_outstream);
-
-  _rl_last_c_pos += count;
-}
-
-void
-_rl_clear_screen ()
-{
-  if (_rl_term_clrpag)
-    tputs (_rl_term_clrpag, 1, _rl_output_character_function);
-  else
-    rl_crlf ();
-}
-
-/* Insert COUNT characters from STRING to the output stream at column COL. */
-static void
-insert_some_chars (string, count, col)
-     char *string;
-     int count, col;
-{
-#if defined (__MSDOS__) || defined (__MINGW32__)
-  _rl_output_some_chars (string, count);
-#else
-  /* DEBUGGING */
-  if (MB_CUR_MAX == 1 || rl_byte_oriented)
-    if (count != col)
-      _rl_ttymsg ("debug: insert_some_chars: count (%d) != col (%d)", count, col);
-
-  /* If IC is defined, then we do not have to "enter" insert mode. */
-  if (_rl_term_IC)
-    {
-      char *buffer;
-
-      buffer = tgoto (_rl_term_IC, 0, col);
-      tputs (buffer, 1, _rl_output_character_function);
-      _rl_output_some_chars (string, count);
-    }
-  else
-    {
-      register int i;
-
-      /* If we have to turn on insert-mode, then do so. */
-      if (_rl_term_im && *_rl_term_im)
-       tputs (_rl_term_im, 1, _rl_output_character_function);
-
-      /* If there is a special command for inserting characters, then
-        use that first to open up the space. */
-      if (_rl_term_ic && *_rl_term_ic)
-       {
-         for (i = col; i--; )
-           tputs (_rl_term_ic, 1, _rl_output_character_function);
-       }
-
-      /* Print the text. */
-      _rl_output_some_chars (string, count);
-
-      /* If there is a string to turn off insert mode, we had best use
-        it now. */
-      if (_rl_term_ei && *_rl_term_ei)
-       tputs (_rl_term_ei, 1, _rl_output_character_function);
-    }
-#endif /* __MSDOS__ || __MINGW32__ */
-}
-
-/* Delete COUNT characters from the display line. */
-static void
-delete_chars (count)
-     int count;
-{
-  if (count > _rl_screenwidth) /* XXX */
-    return;
-
-#if !defined (__MSDOS__) && !defined (__MINGW32__)
-  if (_rl_term_DC && *_rl_term_DC)
-    {
-      char *buffer;
-      buffer = tgoto (_rl_term_DC, count, count);
-      tputs (buffer, count, _rl_output_character_function);
-    }
-  else
-    {
-      if (_rl_term_dc && *_rl_term_dc)
-       while (count--)
-         tputs (_rl_term_dc, 1, _rl_output_character_function);
-    }
-#endif /* !__MSDOS__ && !__MINGW32__ */
-}
-
-void
-_rl_update_final ()
-{
-  int full_lines;
-
-  full_lines = 0;
-  /* If the cursor is the only thing on an otherwise-blank last line,
-     compensate so we don't print an extra CRLF. */
-  if (_rl_vis_botlin && _rl_last_c_pos == 0 &&
-       visible_line[vis_lbreaks[_rl_vis_botlin]] == 0)
-    {
-      _rl_vis_botlin--;
-      full_lines = 1;
-    }
-  _rl_move_vert (_rl_vis_botlin);
-  /* If we've wrapped lines, remove the final xterm line-wrap flag. */
-  if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == _rl_screenwidth))
-    {
-      char *last_line;
-
-      last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]];
-      cpos_buffer_position = -1;       /* don't know where we are in buffer */
-      _rl_move_cursor_relative (_rl_screenwidth - 1, last_line);       /* XXX */
-      _rl_clear_to_eol (0);
-      putc (last_line[_rl_screenwidth - 1], rl_outstream);
-    }
-  _rl_vis_botlin = 0;
-  rl_crlf ();
-  fflush (rl_outstream);
-  rl_display_fixed++;
-}
-
-/* Move to the start of the current line. */
-static void
-cr ()
-{
-  if (_rl_term_cr)
-    {
-#if defined (__MSDOS__)
-      putc ('\r', rl_outstream);
-#else
-      tputs (_rl_term_cr, 1, _rl_output_character_function);
-#endif
-      _rl_last_c_pos = 0;
-    }
-}
-
-/* Redraw the last line of a multi-line prompt that may possibly contain
-   terminal escape sequences.  Called with the cursor at column 0 of the
-   line to draw the prompt on. */
-static void
-redraw_prompt (t)
-     char *t;
-{
-  char *oldp;
-
-  oldp = rl_display_prompt;
-  rl_save_prompt ();
-
-  rl_display_prompt = t;
-  local_prompt = expand_prompt (t, &prompt_visible_length,
-                                  &prompt_last_invisible,
-                                  &prompt_invis_chars_first_line,
-                                  &prompt_physical_chars);
-  local_prompt_prefix = (char *)NULL;
-  local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
-
-  rl_forced_update_display ();
-
-  rl_display_prompt = oldp;
-  rl_restore_prompt();
-}
-      
-/* Redisplay the current line after a SIGWINCH is received. */
-void
-_rl_redisplay_after_sigwinch ()
-{
-  char *t;
-
-  /* Clear the last line (assuming that the screen size change will result in
-     either more or fewer characters on that line only) and put the cursor at
-     column 0.  Make sure the right thing happens if we have wrapped to a new
-     screen line. */
-  if (_rl_term_cr)
-    {
-      _rl_move_vert (_rl_vis_botlin);
-
-#if defined (__MSDOS__)
-      putc ('\r', rl_outstream);
-#else
-      tputs (_rl_term_cr, 1, _rl_output_character_function);
-#endif
-      _rl_last_c_pos = 0;
-#if defined (__MSDOS__)
-      space_to_eol (_rl_screenwidth);
-      putc ('\r', rl_outstream);
-#else
-      if (_rl_term_clreol)
-       tputs (_rl_term_clreol, 1, _rl_output_character_function);
-      else
-       {
-         space_to_eol (_rl_screenwidth);
-         tputs (_rl_term_cr, 1, _rl_output_character_function);
-       }
-#endif
-      if (_rl_last_v_pos > 0)
-       _rl_move_vert (0);
-    }
-  else
-    rl_crlf ();
-
-  /* Redraw only the last line of a multi-line prompt. */
-  t = strrchr (rl_display_prompt, '\n');
-  if (t)
-    redraw_prompt (++t);
-  else
-    rl_forced_update_display ();
-}
-
-void
-_rl_clean_up_for_exit ()
-{
-  if (_rl_echoing_p)
-    {
-      _rl_move_vert (_rl_vis_botlin);
-      _rl_vis_botlin = 0;
-      fflush (rl_outstream);
-      rl_restart_output (1, 0);
-    }
-}
-
-void
-_rl_erase_entire_line ()
-{
-  cr ();
-  _rl_clear_to_eol (0);
-  cr ();
-  fflush (rl_outstream);
-}
-
-/* return the `current display line' of the cursor -- the number of lines to
-   move up to get to the first screen line of the current readline line. */
-int
-_rl_current_display_line ()
-{
-  int ret, nleft;
-
-  /* Find out whether or not there might be invisible characters in the
-     editing buffer. */
-  if (rl_display_prompt == rl_prompt)
-    nleft = _rl_last_c_pos - _rl_screenwidth - rl_visible_prompt_length;
-  else
-    nleft = _rl_last_c_pos - _rl_screenwidth;
-
-  if (nleft > 0)
-    ret = 1 + nleft / _rl_screenwidth;
-  else
-    ret = 0;
-
-  return ret;
-}
-
-#if defined (HANDLE_MULTIBYTE)
-/* Calculate the number of screen columns occupied by STR from START to END.
-   In the case of multibyte characters with stateful encoding, we have to
-   scan from the beginning of the string to take the state into account. */
-static int
-_rl_col_width (str, start, end, flags)
-     const char *str;
-     int start, end, flags;
-{
-  wchar_t wc;
-  mbstate_t ps;
-  int tmp, point, width, max;
-
-  if (end <= start)
-    return 0;
-  if (MB_CUR_MAX == 1 || rl_byte_oriented)
-{
-_rl_ttymsg ("_rl_col_width: called with MB_CUR_MAX == 1");
-    return (end - start);
-}
-
-  memset (&ps, 0, sizeof (mbstate_t));
-
-  point = 0;
-  max = end;
-
-  /* Try to short-circuit common cases.  The adjustment to remove wrap_offset
-     is done by the caller. */
-  /* 1.  prompt string */
-  if (flags && start == 0 && end == local_prompt_len && memcmp (str, local_prompt, local_prompt_len) == 0)
-    return (prompt_visible_length + wrap_offset);
-  /* 2.  prompt string + line contents */
-  else if (flags && start == 0 && local_prompt_len > 0 && end > local_prompt_len && local_prompt && memcmp (str, local_prompt, local_prompt_len) == 0)
-    {
-      tmp = prompt_visible_length + wrap_offset;
-      /* XXX - try to call ourselves recursively with non-prompt portion */
-      tmp += _rl_col_width (str, local_prompt_len, end, flags);
-      return (tmp);
-    }
-
-  while (point < start)
-    {
-      tmp = mbrlen (str + point, max, &ps);
-      if (MB_INVALIDCH ((size_t)tmp))
-       {
-         /* In this case, the bytes are invalid or too short to compose a
-            multibyte character, so we assume that the first byte represents
-            a single character. */
-         point++;
-         max--;
-
-         /* Clear the state of the byte sequence, because in this case the
-            effect of mbstate is undefined. */
-         memset (&ps, 0, sizeof (mbstate_t));
-       }
-      else if (MB_NULLWCH (tmp))
-       break;          /* Found '\0' */
-      else
-       {
-         point += tmp;
-         max -= tmp;
-       }
-    }
-
-  /* If START is not a byte that starts a character, then POINT will be
-     greater than START.  In this case, assume that (POINT - START) gives
-     a byte count that is the number of columns of difference. */
-  width = point - start;
-
-  while (point < end)
-    {
-      tmp = mbrtowc (&wc, str + point, max, &ps);
-      if (MB_INVALIDCH ((size_t)tmp))
-       {
-         /* In this case, the bytes are invalid or too short to compose a
-            multibyte character, so we assume that the first byte represents
-            a single character. */
-         point++;
-         max--;
-
-         /* and assume that the byte occupies a single column. */
-         width++;
-
-         /* Clear the state of the byte sequence, because in this case the
-            effect of mbstate is undefined. */
-         memset (&ps, 0, sizeof (mbstate_t));
-       }
-      else if (MB_NULLWCH (tmp))
-       break;                  /* Found '\0' */
-      else
-       {
-         point += tmp;
-         max -= tmp;
-         tmp = wcwidth(wc);
-         width += (tmp >= 0) ? tmp : 1;
-       }
-    }
-
-  width += point - end;
-
-  return width;
-}
-#endif /* HANDLE_MULTIBYTE */
diff --git a/lib/readline/doc/Makefile.old b/lib/readline/doc/Makefile.old
deleted file mode 100644 (file)
index 58d4dd7..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-# 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
diff --git a/lib/readline/doc/readline.3~ b/lib/readline/doc/readline.3~
deleted file mode 100644 (file)
index 6bdca19..0000000
+++ /dev/null
@@ -1,1347 +0,0 @@
-.\"
-.\" MAN PAGE COMMENTS to
-.\"
-.\"    Chet Ramey
-.\"    Information Network Services
-.\"    Case Western Reserve University
-.\"    chet@ins.CWRU.Edu
-.\"
-.\"    Last Change: Sat Aug 22 12:03:05 EDT 2009
-.\"
-.TH READLINE 3 "2009 August 22" "GNU Readline 6.0"
-.\"
-.\" 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
-readline \- get a line from a user with editing
-.SH SYNOPSIS
-.LP
-.nf
-.ft B
-#include <stdio.h>
-#include <readline/readline.h>
-#include <readline/history.h>
-.ft
-.fi
-.LP
-.nf
-\fIchar *\fP
-.br
-\fBreadline\fP (\fIconst char *prompt\fP);
-.fi
-.SH COPYRIGHT
-.if n Readline is Copyright (C) 1989\-2009 Free Software Foundation,  Inc.
-.if t Readline is Copyright \(co 1989\-2009 Free Software Foundation, Inc.
-.SH DESCRIPTION
-.LP
-.B readline
-will read a line from the terminal
-and return it, using
-.B prompt
-as a prompt.  If 
-.B prompt
-is \fBNULL\fP or the empty string, no prompt is issued.
-The line returned is allocated with
-.IR malloc (3);
-the caller must free it when finished.  The line returned
-has the final newline removed, so only the text of the line
-remains.
-.LP
-.B readline
-offers editing capabilities while the user is entering the
-line.
-By default, the line editing commands
-are similar to those of emacs.
-A vi\-style line editing interface is also available.
-.LP
-This manual page describes only the most basic use of \fBreadline\fP.
-Much more functionality is available; see
-\fIThe GNU Readline Library\fP and \fIThe GNU History Library\fP
-for additional information.
-.SH RETURN VALUE
-.LP
-.B readline
-returns the text of the line read.  A blank line
-returns the empty string.  If
-.B EOF
-is encountered while reading a line, and the line is empty,
-.B NULL
-is returned.  If an
-.B EOF
-is read with a non\-empty line, it is
-treated as a newline.
-.SH NOTATION
-.LP
-An 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.
-.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.
-.SH INITIALIZATION FILE
-.LP
-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
-.B INPUTRC
-environment variable.  If that variable is unset, the default is
-.IR ~/.inputrc .
-If that file  does not exist or cannot be read, the ultimate default is
-.IR /etc/inputrc .
-When a program which uses the readline library starts up, the
-init file is read, and the key bindings and variables are set.
-There are only a few basic constructs allowed in the
-readline init 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.
-Each program using this library may add its own commands
-and bindings.
-.PP
-For example, placing
-.RS
-.PP
-M\-Control\-u: universal\-argument
-.RE
-or
-.RS
-C\-Meta\-u: universal\-argument
-.RE
-.sp
-into the 
-.I inputrc
-would make M\-C\-u execute the readline command
-.IR universal\-argument .
-.PP
-The following symbolic character names are recognized while
-processing key bindings:
-.IR DEL ,
-.IR ESC ,
-.IR ESCAPE ,
-.IR LFD ,
-.IR NEWLINE ,
-.IR RET ,
-.IR RETURN ,
-.IR RUBOUT ,
-.IR SPACE ,
-.IR SPC ,
-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).
-.PP
-.SS 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.
-The name and key sequence are separated by a colon.  There can be no
-whitespace between the name and the colon.
-.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 available when specifying
-key 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 ", a double quote
-.TP
-.B \e'
-literal ', a single quote
-.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 should
-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 '.
-.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.  Other programs using this library provide
-similar mechanisms.  The
-.I inputrc
-file may be edited and re-read if a program does not provide
-any other means to incorporate new bindings.
-.SS 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 comment\-begin (``#'')
-The string that is inserted in \fBvi\fP mode when the
-.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.  A negative value causes readline to never ask.
-.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 it with 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 emacs or vi.
-.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 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, the number of entries in the history list 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 clear the eighth bit in 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 legal keymap names is
-\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.  The default value is
-.IR emacs .
-The value of
-.B editing\-mode
-also affects the default keymap.
-.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, unless the leading `.' is     
-supplied by the user in the filename to be completed.
-.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 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 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 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 Bash:
-.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
-.SH SEARCHING
-.PP
-Readline provides commands for searching through the command history
-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.
-To search backward in the history for a particular string, type
-\fBC\-r\fP.  Typing \fBC\-s\fP searches forward through the history.
-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 \fIEscape\fP and
-\fBC\-J\fP characters will terminate an incremental search.
-\fBC\-G\fP 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 \fBC\-s\fP or
-\fBC\-r\fP as appropriate.
-This will search backward or forward in the history for the next
-line 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 newline will terminate the search and accept
-the line, thereby executing the command from the history list.
-A movement command will terminate the search, make the last line found
-the current line, and begin editing.
-.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.
-.SH EDITING COMMANDS
-.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.
-.PP
-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 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, it may be added to the history list for future recall with
-\fBadd_history()\fP.
-If the line is a modified history line, the history line is restored 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 current cursor
-position (the \fIpoint\fP).
-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 an argument,
-behave exactly like \fByank\-nth\-arg\fP.
-Successive calls to \fByank\-last\-arg\fP move back through the history
-list, inserting the last argument of each line in turn.
-The history expansion facilities are used to extract the last argument,
-as if the "!$" history expansion had been specified.
-.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 that you type to the line verbatim.  This is
-how to insert characters like \fBC\-q\fP, for example.
-.TP
-.B tab\-insert (M-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 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 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 between the point and \fImark\fP (saved cursor position).
-This text is referred to as the \fIregion\fP.
-.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.
-The actual completion performed is application-specific.
-.BR Bash ,
-for instance, 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.
-.BR Gdb ,
-on the other hand,
-allows completion of program functions and variables, and
-only attempts filename completion under certain circumstances.
-.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.
-.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.
-.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
-.B comment\-begin
-makes 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 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 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 emacs\-editing\-mode (C\-e)
-When in
-.B vi
-command mode, this causes a switch to
-.B emacs
-editing mode.
-.TP
-.B vi\-editing\-mode (M\-C\-j)
-When in
-.B emacs
-editing mode, this causes a switch to
-.B vi
-editing mode.
-.PD
-.SH DEFAULT KEY BINDINGS
-.LP
-The following is a list of the default emacs and vi bindings.
-Characters with the eighth bit set are written as M\-<character>, and
-are referred to as
-.I metafied
-characters.
-The printable ASCII characters not mentioned in the list of emacs
-standard bindings are bound to the
-.B self\-insert
-function, which just inserts the given character into the input line.
-In vi insertion mode, all characters not specifically mentioned are
-bound to
-.BR self\-insert .
-Characters assigned to signal generation by
-.IR stty (1)
-or the terminal driver, such as C-Z or C-C,
-retain that function.
-Upper and lower case metafied characters are bound to the same function in
-the emacs mode meta keymap.
-The remaining characters are unbound, which causes readline
-to ring the bell (subject to the setting of the
-.B bell\-style
-variable).
-.SS Emacs Mode
-.RS +.6i
-.nf
-.ta 2.5i
-.sp
-Emacs Standard bindings
-.sp
-"C-@"  set-mark
-"C-A"  beginning-of-line
-"C-B"  backward-char
-"C-D"  delete-char
-"C-E"  end-of-line
-"C-F"  forward-char
-"C-G"  abort
-"C-H"  backward-delete-char
-"C-I"  complete
-"C-J"  accept-line
-"C-K"  kill-line
-"C-L"  clear-screen
-"C-M"  accept-line
-"C-N"  next-history
-"C-P"  previous-history
-"C-Q"  quoted-insert
-"C-R"  reverse-search-history
-"C-S"  forward-search-history
-"C-T"  transpose-chars
-"C-U"  unix-line-discard
-"C-V"  quoted-insert
-"C-W"  unix-word-rubout
-"C-Y"  yank
-"C-]"  character-search
-"C-_"  undo
-"\^ " to "/"  self-insert
-"0"  to "9"  self-insert
-":"  to "~"  self-insert
-"C-?"  backward-delete-char
-.PP
-Emacs Meta bindings
-.sp
-"M-C-G"  abort
-"M-C-H"  backward-kill-word
-"M-C-I"  tab-insert
-"M-C-J"  vi-editing-mode
-"M-C-M"  vi-editing-mode
-"M-C-R"  revert-line
-"M-C-Y"  yank-nth-arg
-"M-C-["  complete
-"M-C-]"  character-search-backward
-"M-space"  set-mark
-"M-#"  insert-comment
-"M-&"  tilde-expand
-"M-*"  insert-completions
-"M--"  digit-argument
-"M-."  yank-last-arg
-"M-0"  digit-argument
-"M-1"  digit-argument
-"M-2"  digit-argument
-"M-3"  digit-argument
-"M-4"  digit-argument
-"M-5"  digit-argument
-"M-6"  digit-argument
-"M-7"  digit-argument
-"M-8"  digit-argument
-"M-9"  digit-argument
-"M-<"  beginning-of-history
-"M-="  possible-completions
-"M->"  end-of-history
-"M-?"  possible-completions
-"M-B"  backward-word
-"M-C"  capitalize-word
-"M-D"  kill-word
-"M-F"  forward-word
-"M-L"  downcase-word
-"M-N"  non-incremental-forward-search-history
-"M-P"  non-incremental-reverse-search-history
-"M-R"  revert-line
-"M-T"  transpose-words
-"M-U"  upcase-word
-"M-Y"  yank-pop
-"M-\e"  delete-horizontal-space
-"M-~"  tilde-expand
-"M-C-?"  backward-kill-word
-"M-_"  yank-last-arg
-.PP
-Emacs Control-X bindings
-.sp
-"C-XC-G"  abort
-"C-XC-R"  re-read-init-file
-"C-XC-U"  undo
-"C-XC-X"  exchange-point-and-mark
-"C-X("  start-kbd-macro
-"C-X)"  end-kbd-macro
-"C-XE"  call-last-kbd-macro
-"C-XC-?"  backward-kill-line
-.sp
-.RE
-.SS VI Mode bindings
-.RS +.6i
-.nf
-.ta 2.5i
-.sp
-.PP
-VI Insert Mode functions
-.sp
-"C-D"  vi-eof-maybe
-"C-H"  backward-delete-char
-"C-I"  complete
-"C-J"  accept-line
-"C-M"  accept-line
-"C-R"  reverse-search-history
-"C-S"  forward-search-history
-"C-T"  transpose-chars
-"C-U"  unix-line-discard
-"C-V"  quoted-insert
-"C-W"  unix-word-rubout
-"C-Y"  yank
-"C-["  vi-movement-mode
-"C-_"  undo
-"\^ " to "~"  self-insert
-"C-?"  backward-delete-char
-.PP
-VI Command Mode functions
-.sp
-"C-D"  vi-eof-maybe
-"C-E"  emacs-editing-mode
-"C-G"  abort
-"C-H"  backward-char
-"C-J"  accept-line
-"C-K"  kill-line
-"C-L"  clear-screen
-"C-M"  accept-line
-"C-N"  next-history
-"C-P"  previous-history
-"C-Q"  quoted-insert
-"C-R"  reverse-search-history
-"C-S"  forward-search-history
-"C-T"  transpose-chars
-"C-U"  unix-line-discard
-"C-V"  quoted-insert
-"C-W"  unix-word-rubout
-"C-Y"  yank
-"C-_"  vi-undo
-"\^ "  forward-char
-"#"  insert-comment
-"$"  end-of-line
-"%"  vi-match
-"&"  vi-tilde-expand
-"*"  vi-complete
-"+"  next-history
-","  vi-char-search
-"-"  previous-history
-"."  vi-redo
-"/"  vi-search
-"0"  beginning-of-line
-"1" to "9"  vi-arg-digit
-";"  vi-char-search
-"="  vi-complete
-"?"  vi-search
-"A"  vi-append-eol
-"B"  vi-prev-word
-"C"  vi-change-to
-"D"  vi-delete-to
-"E"  vi-end-word
-"F"  vi-char-search
-"G"  vi-fetch-history
-"I"  vi-insert-beg
-"N"  vi-search-again
-"P"  vi-put
-"R"  vi-replace
-"S"  vi-subst
-"T"  vi-char-search
-"U"  revert-line
-"W"  vi-next-word
-"X"  backward-delete-char
-"Y"  vi-yank-to
-"\e"  vi-complete
-"^"  vi-first-print
-"_"  vi-yank-arg
-"`"  vi-goto-mark
-"a"  vi-append-mode
-"b"  vi-prev-word
-"c"  vi-change-to
-"d"  vi-delete-to
-"e"  vi-end-word
-"f"  vi-char-search
-"h"  backward-char
-"i"  vi-insertion-mode
-"j"  next-history
-"k"  prev-history
-"l"  forward-char
-"m"  vi-set-mark
-"n"  vi-search-again
-"p"  vi-put
-"r"  vi-change-char
-"s"  vi-subst
-"t"  vi-char-search
-"u"  vi-undo
-"w"  vi-next-word
-"x"  vi-delete
-"y"  vi-yank-to
-"|"  vi-column
-"~"  vi-change-case
-.RE
-.SH "SEE ALSO"
-.PD 0
-.TP
-\fIThe Gnu Readline Library\fP, Brian Fox and Chet Ramey
-.TP
-\fIThe Gnu History Library\fP, Brian Fox and Chet Ramey
-.TP
-\fIbash\fP(1)
-.PD
-.SH FILES
-.PD 0
-.TP
-.FN ~/.inputrc
-Individual \fBreadline\fP initialization file
-.PD
-.SH AUTHORS
-Brian Fox, Free Software Foundation
-.br
-bfox@gnu.org
-.PP
-Chet Ramey, Case Western Reserve University
-.br
-chet@ins.CWRU.Edu
-.SH BUG REPORTS
-If you find a bug in
-.B readline,
-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 the
-.B readline
-library that you have.
-.PP
-Once you have determined that a bug actually exists, mail a
-bug report to \fIbug\-readline\fP@\fIgnu.org\fP.
-If you have a fix, you are welcome to mail that
-as well!  Suggestions and `philosophical' bug reports may be mailed
-to \fPbug-readline\fP@\fIgnu.org\fP or posted to the Usenet
-newsgroup
-.BR gnu.bash.bug .
-.PP
-Comments and bug reports concerning
-this manual page should be directed to
-.IR chet@ins.CWRU.Edu .
-.SH BUGS
-.PP
-It's too big and too slow.
diff --git a/lib/readline/doc/rltech.texi~ b/lib/readline/doc/rltech.texi~
deleted file mode 100644 (file)
index 845f277..0000000
+++ /dev/null
@@ -1,2386 +0,0 @@
-@comment %**start of header (This is for running Texinfo on a region.)
-@setfilename rltech.info
-@comment %**end of header (This is for running Texinfo on a region.)
-
-@ifinfo
-This document describes the GNU Readline Library, a utility for aiding
-in the consistency of user interface across discrete programs that need
-to provide a command line interface.
-
-Copyright (C) 1988-2007 Free Software Foundation, Inc.
-
-Permission is granted to make and distribute verbatim copies of
-this manual provided the copyright notice and this permission notice
-pare preserved on all copies.
-
-@ignore
-Permission is granted to process this file through TeX and print the
-results, provided the printed document carries copying permission
-notice identical to this one except for the removal of this paragraph
-(this paragraph not being relevant to the printed manual).
-@end ignore
-
-Permission is granted to copy and distribute modified versions of this
-manual under the conditions for verbatim copying, provided that the entire
-resulting derived work is distributed under the terms of a permission
-notice identical to this one.
-
-Permission is granted to copy and distribute translations of this manual
-into another language, under the above conditions for modified versions,
-except that this permission notice may be stated in a translation approved
-by the Foundation.
-@end ifinfo
-
-@node Programming with GNU Readline
-@chapter Programming with GNU Readline
-
-This chapter describes the interface between the @sc{gnu} Readline Library and
-other programs.  If you are a programmer, and you wish to include the
-features found in @sc{gnu} Readline
-such as completion, line editing, and interactive history manipulation
-in your own programs, this section is for you.
-
-@menu
-* Basic Behavior::     Using the default behavior of Readline.
-* Custom Functions::   Adding your own functions to Readline.
-* Readline Variables::                 Variables accessible to custom
-                                       functions.
-* Readline Convenience Functions::     Functions which Readline supplies to
-                                       aid in writing your own custom
-                                       functions.
-* Readline Signal Handling::   How Readline behaves when it receives signals.
-* Custom Completers::  Supplanting or supplementing Readline's
-                       completion functions.
-@end menu
-
-@node Basic Behavior
-@section Basic Behavior
-
-Many programs provide a command line interface, such as @code{mail},
-@code{ftp}, and @code{sh}.  For such programs, the default behaviour of
-Readline is sufficient.  This section describes how to use Readline in
-the simplest way possible, perhaps to replace calls in your code to
-@code{gets()} or @code{fgets()}.
-
-@findex readline
-@cindex readline, function
-
-The function @code{readline()} prints a prompt @var{prompt}
-and then reads and returns a single line of text from the user.
-If @var{prompt} is @code{NULL} or the empty string, no prompt is displayed.
-The line @code{readline} returns is allocated with @code{malloc()};
-the caller should @code{free()} the line when it has finished with it.
-The declaration for @code{readline} in ANSI C is
-
-@example
-@code{char *readline (const char *@var{prompt});}
-@end example
-
-@noindent
-So, one might say
-@example
-@code{char *line = readline ("Enter a line: ");}
-@end example
-@noindent
-in order to read a line of text from the user.
-The line returned has the final newline removed, so only the
-text remains.
-
-If @code{readline} encounters an @code{EOF} while reading the line, and the
-line is empty at that point, then @code{(char *)NULL} is returned.
-Otherwise, the line is ended just as if a newline had been typed.
-
-If you want the user to be able to get at the line later, (with
-@key{C-p} for example), you must call @code{add_history()} to save the
-line away in a @dfn{history} list of such lines.
-
-@example
-@code{add_history (line)};
-@end example
-
-@noindent
-For full details on the GNU History Library, see the associated manual.
-
-It is preferable to avoid saving empty lines on the history list, since
-users rarely have a burning need to reuse a blank line.  Here is
-a function which usefully replaces the standard @code{gets()} library
-function, and has the advantage of no static buffer to overflow:
-
-@example
-/* A static variable for holding the line. */
-static char *line_read = (char *)NULL;
-
-/* Read a string, and return a pointer to it.
-   Returns NULL on EOF. */
-char *
-rl_gets ()
-@{
-  /* If the buffer has already been allocated,
-     return the memory to the free pool. */
-  if (line_read)
-    @{
-      free (line_read);
-      line_read = (char *)NULL;
-    @}
-
-  /* Get a line from the user. */
-  line_read = readline ("");
-
-  /* If the line has any text in it,
-     save it on the history. */
-  if (line_read && *line_read)
-    add_history (line_read);
-
-  return (line_read);
-@}
-@end example
-
-This function gives the user the default behaviour of @key{TAB}
-completion: completion on file names.  If you do not want Readline to
-complete on filenames, you can change the binding of the @key{TAB} key
-with @code{rl_bind_key()}.
-
-@example
-@code{int rl_bind_key (int @var{key}, rl_command_func_t *@var{function});}
-@end example
-
-@code{rl_bind_key()} takes two arguments: @var{key} is the character that
-you want to bind, and @var{function} is the address of the function to
-call when @var{key} is pressed.  Binding @key{TAB} to @code{rl_insert()}
-makes @key{TAB} insert itself.
-@code{rl_bind_key()} returns non-zero if @var{key} is not a valid
-ASCII character code (between 0 and 255).
-
-Thus, to disable the default @key{TAB} behavior, the following suffices:
-@example
-@code{rl_bind_key ('\t', rl_insert);}
-@end example
-
-This code should be executed once at the start of your program; you
-might write a function called @code{initialize_readline()} which
-performs this and other desired initializations, such as installing
-custom completers (@pxref{Custom Completers}).
-
-@node Custom Functions
-@section Custom Functions
-
-Readline provides many functions for manipulating the text of
-the line, but it isn't possible to anticipate the needs of all
-programs.  This section describes the various functions and variables
-defined within the Readline library which allow a user program to add
-customized functionality to Readline.
-
-Before declaring any functions that customize Readline's behavior, or
-using any functionality Readline provides in other code, an
-application writer should include the file @code{<readline/readline.h>}
-in any file that uses Readline's features.  Since some of the definitions
-in @code{readline.h} use the @code{stdio} library, the file
-@code{<stdio.h>} should be included before @code{readline.h}.
-
-@code{readline.h} defines a C preprocessor variable that should
-be treated as an integer, @code{RL_READLINE_VERSION}, which may
-be used to conditionally compile application code depending on
-the installed Readline version.  The value is a hexadecimal
-encoding of the major and minor version numbers of the library,
-of the form 0x@var{MMmm}.  @var{MM} is the two-digit major
-version number; @var{mm} is the two-digit minor version number. 
-For Readline 4.2, for example, the value of
-@code{RL_READLINE_VERSION} would be @code{0x0402}. 
-
-@menu
-* Readline Typedefs::  C declarations to make code readable.
-* Function Writing::   Variables and calling conventions.
-@end menu
-
-@node Readline Typedefs
-@subsection Readline Typedefs
-
-For readabilty, we declare a number of new object types, all pointers
-to functions.
-
-The reason for declaring these new types is to make it easier to write
-code describing pointers to C functions with appropriately prototyped
-arguments and return values.
-
-For instance, say we want to declare a variable @var{func} as a pointer
-to a function which takes two @code{int} arguments and returns an
-@code{int} (this is the type of all of the Readline bindable functions).
-Instead of the classic C declaration
-
-@code{int (*func)();}
-
-@noindent
-or the ANSI-C style declaration
-
-@code{int (*func)(int, int);}
-
-@noindent
-we may write
-
-@code{rl_command_func_t *func;}
-
-The full list of function pointer types available is
-
-@table @code
-@item typedef int rl_command_func_t (int, int);
-
-@item typedef char *rl_compentry_func_t (const char *, int);
-
-@item typedef char **rl_completion_func_t (const char *, int, int);
-
-@item typedef char *rl_quote_func_t (char *, int, char *);
-
-@item typedef char *rl_dequote_func_t (char *, int);
-
-@item typedef int rl_compignore_func_t (char **);
-
-@item typedef void rl_compdisp_func_t (char **, int, int);
-
-@item typedef int rl_hook_func_t (void);
-
-@item typedef int rl_getc_func_t (FILE *);
-
-@item typedef int rl_linebuf_func_t (char *, int);
-
-@item typedef int rl_intfunc_t (int);
-@item #define rl_ivoidfunc_t rl_hook_func_t
-@item typedef int rl_icpfunc_t (char *);
-@item typedef int rl_icppfunc_t (char **);
-
-@item typedef void rl_voidfunc_t (void);
-@item typedef void rl_vintfunc_t (int);
-@item typedef void rl_vcpfunc_t (char *);
-@item typedef void rl_vcppfunc_t (char **);
-
-@end table
-
-@node Function Writing
-@subsection Writing a New Function
-
-In order to write new functions for Readline, you need to know the
-calling conventions for keyboard-invoked functions, and the names of the
-variables that describe the current state of the line read so far.
-
-The calling sequence for a command @code{foo} looks like
-
-@example
-@code{int foo (int count, int key)}
-@end example
-
-@noindent
-where @var{count} is the numeric argument (or 1 if defaulted) and
-@var{key} is the key that invoked this function.
-
-It is completely up to the function as to what should be done with the
-numeric argument.  Some functions use it as a repeat count, some
-as a flag, and others to choose alternate behavior (refreshing the current
-line as opposed to refreshing the screen, for example).  Some choose to
-ignore it.  In general, if a
-function uses the numeric argument as a repeat count, it should be able
-to do something useful with both negative and positive arguments.
-At the very least, it should be aware that it can be passed a
-negative argument.
-
-A command function should return 0 if its action completes successfully,
-and a non-zero value if some error occurs.
-This is the convention obeyed by all of the builtin Readline bindable
-command functions.
-
-@node Readline Variables
-@section Readline Variables
-
-These variables are available to function writers.
-
-@deftypevar {char *} rl_line_buffer
-This is the line gathered so far.  You are welcome to modify the
-contents of the line, but see @ref{Allowing Undoing}.  The
-function @code{rl_extend_line_buffer} is available to increase
-the memory allocated to @code{rl_line_buffer}.
-@end deftypevar
-
-@deftypevar int rl_point
-The offset of the current cursor position in @code{rl_line_buffer}
-(the @emph{point}).
-@end deftypevar
-
-@deftypevar int rl_end
-The number of characters present in @code{rl_line_buffer}.  When
-@code{rl_point} is at the end of the line, @code{rl_point} and
-@code{rl_end} are equal.
-@end deftypevar
-
-@deftypevar int rl_mark
-The @var{mark} (saved position) in the current line.  If set, the mark
-and point define a @emph{region}.
-@end deftypevar
-
-@deftypevar int rl_done
-Setting this to a non-zero value causes Readline to return the current
-line immediately.
-@end deftypevar
-
-@deftypevar int rl_num_chars_to_read
-Setting this to a positive value before calling @code{readline()} causes
-Readline to return after accepting that many characters, rather
-than reading up to a character bound to @code{accept-line}.
-@end deftypevar
-
-@deftypevar int rl_pending_input
-Setting this to a value makes it the next keystroke read.  This is a
-way to stuff a single character into the input stream.
-@end deftypevar
-
-@deftypevar int rl_dispatching
-Set to a non-zero value if a function is being called from a key binding;
-zero otherwise.  Application functions can test this to discover whether
-they were called directly or by Readline's dispatching mechanism.
-@end deftypevar
-
-@deftypevar int rl_erase_empty_line
-Setting this to a non-zero value causes Readline to completely erase
-the current line, including any prompt, any time a newline is typed as
-the only character on an otherwise-empty line.  The cursor is moved to
-the beginning of the newly-blank line.
-@end deftypevar
-
-@deftypevar {char *} rl_prompt
-The prompt Readline uses.  This is set from the argument to
-@code{readline()}, and should not be assigned to directly.
-The @code{rl_set_prompt()} function (@pxref{Redisplay}) may
-be used to modify the prompt string after calling @code{readline()}.
-@end deftypevar
-
-@deftypevar {char *} rl_display_prompt
-The string displayed as the prompt.  This is usually identical to
-@var{rl_prompt}, but may be changed temporarily by functions that
-use the prompt string as a message area, such as incremental search.
-@end deftypevar
-
-@deftypevar int rl_already_prompted
-If an application wishes to display the prompt itself, rather than have
-Readline do it the first time @code{readline()} is called, it should set
-this variable to a non-zero value after displaying the prompt.
-The prompt must also be passed as the argument to @code{readline()} so
-the redisplay functions can update the display properly.
-The calling application is responsible for managing the value; Readline
-never sets it.
-@end deftypevar
-
-@deftypevar {const char *} rl_library_version
-The version number of this revision of the library.
-@end deftypevar
-
-@deftypevar int rl_readline_version
-An integer encoding the current version of the library.  The encoding is
-of the form 0x@var{MMmm}, where @var{MM} is the two-digit major version
-number, and @var{mm} is the two-digit minor version number.
-For example, for Readline-4.2, @code{rl_readline_version} would have the
-value 0x0402.
-@end deftypevar
-
-@deftypevar {int} rl_gnu_readline_p
-Always set to 1, denoting that this is @sc{gnu} readline rather than some
-emulation.
-@end deftypevar
-
-@deftypevar {const char *} rl_terminal_name
-The terminal type, used for initialization.  If not set by the application,
-Readline sets this to the value of the @env{TERM} environment variable
-the first time it is called.
-@end deftypevar
-
-@deftypevar {const char *} rl_readline_name
-This variable is set to a unique name by each application using Readline.
-The value allows conditional parsing of the inputrc file
-(@pxref{Conditional Init Constructs}).
-@end deftypevar
-
-@deftypevar {FILE *} rl_instream
-The stdio stream from which Readline reads input.
-If @code{NULL}, Readline defaults to @var{stdin}.
-@end deftypevar
-
-@deftypevar {FILE *} rl_outstream
-The stdio stream to which Readline performs output.
-If @code{NULL}, Readline defaults to @var{stdout}.
-@end deftypevar
-
-@deftypevar int rl_prefer_env_winsize
-If non-zero, Readline gives values found in the @env{LINES} and
-@env{COLUMNS} environment variables greater precedence than values fetched
-from the kernel when computing the screen dimensions.
-@end deftypevar
-
-@deftypevar {rl_command_func_t *} rl_last_func
-The address of the last command function Readline executed.  May be used to
-test whether or not a function is being executed twice in succession, for
-example.
-@end deftypevar
-
-@deftypevar {rl_hook_func_t *} rl_startup_hook
-If non-zero, this is the address of a function to call just
-before @code{readline} prints the first prompt.
-@end deftypevar
-
-@deftypevar {rl_hook_func_t *} rl_pre_input_hook
-If non-zero, this is the address of a function to call after
-the first prompt has been printed and just before @code{readline}
-starts reading input characters.
-@end deftypevar
-
-@deftypevar {rl_hook_func_t *} rl_event_hook
-If non-zero, this is the address of a function to call periodically
-when Readline is waiting for terminal input.
-By default, this will be called at most ten times a second if there
-is no keyboard input.
-@end deftypevar
-
-@deftypevar {rl_getc_func_t *} rl_getc_function
-If non-zero, Readline will call indirectly through this pointer
-to get a character from the input stream.  By default, it is set to
-@code{rl_getc}, the default Readline character input function
-(@pxref{Character Input}).
-@end deftypevar
-
-@deftypevar {rl_voidfunc_t *} rl_redisplay_function
-If non-zero, Readline will call indirectly through this pointer
-to update the display with the current contents of the editing buffer.
-By default, it is set to @code{rl_redisplay}, the default Readline
-redisplay function (@pxref{Redisplay}).
-@end deftypevar
-
-@deftypevar {rl_vintfunc_t *} rl_prep_term_function
-If non-zero, Readline will call indirectly through this pointer
-to initialize the terminal.  The function takes a single argument, an
-@code{int} flag that says whether or not to use eight-bit characters.
-By default, this is set to @code{rl_prep_terminal}
-(@pxref{Terminal Management}).
-@end deftypevar
-
-@deftypevar {rl_voidfunc_t *} rl_deprep_term_function
-If non-zero, Readline will call indirectly through this pointer
-to reset the terminal.  This function should undo the effects of
-@code{rl_prep_term_function}.
-By default, this is set to @code{rl_deprep_terminal}
-(@pxref{Terminal Management}).
-@end deftypevar
-
-@deftypevar {Keymap} rl_executing_keymap
-This variable is set to the keymap (@pxref{Keymaps}) in which the
-currently executing readline function was found.
-@end deftypevar 
-
-@deftypevar {Keymap} rl_binding_keymap
-This variable is set to the keymap (@pxref{Keymaps}) in which the
-last key binding occurred.
-@end deftypevar 
-
-@deftypevar {char *} rl_executing_macro
-This variable is set to the text of any currently-executing macro.
-@end deftypevar
-
-@deftypevar {int} rl_readline_state
-A variable with bit values that encapsulate the current Readline state.
-A bit is set with the @code{RL_SETSTATE} macro, and unset with the
-@code{RL_UNSETSTATE} macro.  Use the @code{RL_ISSTATE} macro to test
-whether a particular state bit is set.  Current state bits include:
-
-@table @code
-@item RL_STATE_NONE
-Readline has not yet been called, nor has it begun to intialize.
-@item RL_STATE_INITIALIZING
-Readline is initializing its internal data structures.
-@item RL_STATE_INITIALIZED
-Readline has completed its initialization.
-@item RL_STATE_TERMPREPPED
-Readline has modified the terminal modes to do its own input and redisplay.
-@item RL_STATE_READCMD
-Readline is reading a command from the keyboard.
-@item RL_STATE_METANEXT
-Readline is reading more input after reading the meta-prefix character.
-@item RL_STATE_DISPATCHING
-Readline is dispatching to a command.
-@item RL_STATE_MOREINPUT
-Readline is reading more input while executing an editing command.
-@item RL_STATE_ISEARCH
-Readline is performing an incremental history search.
-@item RL_STATE_NSEARCH
-Readline is performing a non-incremental history search.
-@item RL_STATE_SEARCH
-Readline is searching backward or forward through the history for a string.
-@item RL_STATE_NUMERICARG
-Readline is reading a numeric argument.
-@item RL_STATE_MACROINPUT
-Readline is currently getting its input from a previously-defined keyboard
-macro.
-@item RL_STATE_MACRODEF
-Readline is currently reading characters defining a keyboard macro.
-@item RL_STATE_OVERWRITE
-Readline is in overwrite mode.
-@item RL_STATE_COMPLETING
-Readline is performing word completion.
-@item RL_STATE_SIGHANDLER
-Readline is currently executing the readline signal handler.
-@item RL_STATE_UNDOING
-Readline is performing an undo.
-@item RL_STATE_INPUTPENDING
-Readline has input pending due to a call to @code{rl_execute_next()}.
-@item RL_STATE_TTYCSAVED
-Readline has saved the values of the terminal's special characters.
-@item RL_STATE_CALLBACK
-Readline is currently using the alternate (callback) interface
-(@pxref{Alternate Interface}).
-@item RL_STATE_VIMOTION
-Readline is reading the argument to a vi-mode "motion" command.
-@item RL_STATE_MULTIKEY
-Readline is reading a multiple-keystroke command.
-@item RL_STATE_VICMDONCE
-Readline has entered vi command (movement) mode at least one time during
-the current call to @code{readline()}.
-@item RL_STATE_DONE
-Readline has read a key sequence bound to @code{accept-line}
-and is about to return the line to the caller.
-@end table
-
-@end deftypevar
-
-@deftypevar {int} rl_explicit_arg
-Set to a non-zero value if an explicit numeric argument was specified by
-the user.  Only valid in a bindable command function.
-@end deftypevar
-
-@deftypevar {int} rl_numeric_arg
-Set to the value of any numeric argument explicitly specified by the user
-before executing the current Readline function.  Only valid in a bindable
-command function.
-@end deftypevar
-
-@deftypevar {int} rl_editing_mode
-Set to a value denoting Readline's current editing mode.  A value of
-@var{1} means Readline is currently in emacs mode; @var{0}
-means that vi mode is active.
-@end deftypevar
-
-
-@node Readline Convenience Functions
-@section Readline Convenience Functions
-
-@menu
-* Function Naming::    How to give a function you write a name.
-* Keymaps::            Making keymaps.
-* Binding Keys::       Changing Keymaps.
-* Associating Function Names and Bindings::    Translate function names to
-                                               key sequences.
-* Allowing Undoing::   How to make your functions undoable.
-* Redisplay::          Functions to control line display.
-* Modifying Text::     Functions to modify @code{rl_line_buffer}.
-* Character Input::    Functions to read keyboard input.
-* Terminal Management::        Functions to manage terminal settings.
-* Utility Functions::  Generally useful functions and hooks.
-* Miscellaneous Functions::    Functions that don't fall into any category.
-* Alternate Interface::        Using Readline in a `callback' fashion.
-* A Readline Example::         An example Readline function.
-@end menu
-
-@node Function Naming
-@subsection Naming a Function
-
-The user can dynamically change the bindings of keys while using
-Readline.  This is done by representing the function with a descriptive
-name.  The user is able to type the descriptive name when referring to
-the function.  Thus, in an init file, one might find
-
-@example
-Meta-Rubout:   backward-kill-word
-@end example
-
-This binds the keystroke @key{Meta-Rubout} to the function
-@emph{descriptively} named @code{backward-kill-word}.  You, as the
-programmer, should bind the functions you write to descriptive names as
-well.  Readline provides a function for doing that:
-
-@deftypefun int rl_add_defun (const char *name, rl_command_func_t *function, int key)
-Add @var{name} to the list of named functions.  Make @var{function} be
-the function that gets called.  If @var{key} is not -1, then bind it to
-@var{function} using @code{rl_bind_key()}.
-@end deftypefun
-
-Using this function alone is sufficient for most applications.
-It is the recommended way to add a few functions to the default
-functions that Readline has built in.
-If you need to do something other than adding a function to Readline,
-you may need to use the underlying functions described below.
-
-@node Keymaps
-@subsection Selecting a Keymap
-
-Key bindings take place on a @dfn{keymap}.  The keymap is the
-association between the keys that the user types and the functions that
-get run.  You can make your own keymaps, copy existing keymaps, and tell
-Readline which keymap to use.
-
-@deftypefun Keymap rl_make_bare_keymap (void)
-Returns a new, empty keymap.  The space for the keymap is allocated with
-@code{malloc()}; the caller should free it by calling
-@code{rl_free_keymap()} when done.
-@end deftypefun
-
-@deftypefun Keymap rl_copy_keymap (Keymap map)
-Return a new keymap which is a copy of @var{map}.
-@end deftypefun
-
-@deftypefun Keymap rl_make_keymap (void)
-Return a new keymap with the printing characters bound to rl_insert,
-the lowercase Meta characters bound to run their equivalents, and
-the Meta digits bound to produce numeric arguments.
-@end deftypefun
-
-@deftypefun void rl_discard_keymap (Keymap keymap)
-Free the storage associated with the data in @var{keymap}.
-The caller should free @var{keymap}.
-@end deftypefun
-
-@deftypefun void rl_free_keymap (Keymap keymap)
-Free all storage associated with @var{keymap}.  This calls
-@code{rl_discard_keymap} to free subordindate keymaps and macros.
-@end deftypefun
-
-Readline has several internal keymaps.  These functions allow you to
-change which keymap is active.
-
-@deftypefun Keymap rl_get_keymap (void)
-Returns the currently active keymap.
-@end deftypefun
-
-@deftypefun void rl_set_keymap (Keymap keymap)
-Makes @var{keymap} the currently active keymap.
-@end deftypefun
-
-@deftypefun Keymap rl_get_keymap_by_name (const char *name)
-Return the keymap matching @var{name}.  @var{name} is one which would
-be supplied in a @code{set keymap} inputrc line (@pxref{Readline Init File}).
-@end deftypefun
-
-@deftypefun {char *} rl_get_keymap_name (Keymap keymap)
-Return the name matching @var{keymap}.  @var{name} is one which would
-be supplied in a @code{set keymap} inputrc line (@pxref{Readline Init File}).
-@end deftypefun
-
-@node Binding Keys
-@subsection Binding Keys
-
-Key sequences are associate with functions through the keymap.
-Readline has several internal keymaps: @code{emacs_standard_keymap},
-@code{emacs_meta_keymap}, @code{emacs_ctlx_keymap},
-@code{vi_movement_keymap}, and @code{vi_insertion_keymap}.
-@code{emacs_standard_keymap} is the default, and the examples in
-this manual assume that.
-
-Since @code{readline()} installs a set of default key bindings the first
-time it is called, there is always the danger that a custom binding
-installed before the first call to @code{readline()} will be overridden.
-An alternate mechanism is to install custom key bindings in an
-initialization function assigned to the @code{rl_startup_hook} variable
-(@pxref{Readline Variables}).
-
-These functions manage key bindings.
-
-@deftypefun int rl_bind_key (int key, rl_command_func_t *function)
-Binds @var{key} to @var{function} in the currently active keymap.
-Returns non-zero in the case of an invalid @var{key}.
-@end deftypefun
-
-@deftypefun int rl_bind_key_in_map (int key, rl_command_func_t *function, Keymap map)
-Bind @var{key} to @var{function} in @var{map}.
-Returns non-zero in the case of an invalid @var{key}.
-@end deftypefun
-
-@deftypefun int rl_bind_key_if_unbound (int key, rl_command_func_t *function)
-Binds @var{key} to @var{function} if it is not already bound in the
-currently active keymap.
-Returns non-zero in the case of an invalid @var{key} or if @var{key} is
-already bound.
-@end deftypefun
-
-@deftypefun int rl_bind_key_if_unbound_in_map (int key, rl_command_func_t *function, Keymap map)
-Binds @var{key} to @var{function} if it is not already bound in @var{map}.
-Returns non-zero in the case of an invalid @var{key} or if @var{key} is
-already bound.
-@end deftypefun
-
-@deftypefun int rl_unbind_key (int key)
-Bind @var{key} to the null function in the currently active keymap.
-Returns non-zero in case of error.
-@end deftypefun
-
-@deftypefun int rl_unbind_key_in_map (int key, Keymap map)
-Bind @var{key} to the null function in @var{map}.
-Returns non-zero in case of error.
-@end deftypefun
-
-@deftypefun int rl_unbind_function_in_map (rl_command_func_t *function, Keymap map)
-Unbind all keys that execute @var{function} in @var{map}.
-@end deftypefun
-
-@deftypefun int rl_unbind_command_in_map (const char *command, Keymap map)
-Unbind all keys that are bound to @var{command} in @var{map}.
-@end deftypefun
-
-@deftypefun int rl_bind_keyseq (const char *keyseq, rl_command_func_t *function)
-Bind the key sequence represented by the string @var{keyseq} to the function
-@var{function}, beginning in the current keymap.
-This makes new keymaps as necessary.
-The return value is non-zero if @var{keyseq} is invalid.
-@end deftypefun
-
-@deftypefun int rl_bind_keyseq_in_map (const char *keyseq, rl_command_func_t *function, Keymap map)
-Bind the key sequence represented by the string @var{keyseq} to the function
-@var{function}.  This makes new keymaps as necessary.
-Initial bindings are performed in @var{map}.
-The return value is non-zero if @var{keyseq} is invalid.
-@end deftypefun
-
-@deftypefun int rl_set_key (const char *keyseq, rl_command_func_t *function, Keymap map)
-Equivalent to @code{rl_bind_keyseq_in_map}.
-@end deftypefun
-
-@deftypefun int rl_bind_keyseq_if_unbound (const char *keyseq, rl_command_func_t *function)
-Binds @var{keyseq} to @var{function} if it is not already bound in the
-currently active keymap.
-Returns non-zero in the case of an invalid @var{keyseq} or if @var{keyseq} is
-already bound.
-@end deftypefun
-
-@deftypefun int rl_bind_keyseq_if_unbound_in_map (const char *keyseq, rl_command_func_t *function, Keymap map)
-Binds @var{keyseq} to @var{function} if it is not already bound in @var{map}.
-Returns non-zero in the case of an invalid @var{keyseq} or if @var{keyseq} is
-already bound.
-@end deftypefun
-
-@deftypefun int rl_generic_bind (int type, const char *keyseq, char *data, Keymap map)
-Bind the key sequence represented by the string @var{keyseq} to the arbitrary
-pointer @var{data}.  @var{type} says what kind of data is pointed to by
-@var{data}; this can be a function (@code{ISFUNC}), a macro
-(@code{ISMACR}), or a keymap (@code{ISKMAP}).  This makes new keymaps as
-necessary.  The initial keymap in which to do bindings is @var{map}.
-@end deftypefun
-
-@deftypefun int rl_parse_and_bind (char *line)
-Parse @var{line} as if it had been read from the @code{inputrc} file and
-perform any key bindings and variable assignments found
-(@pxref{Readline Init File}).
-@end deftypefun
-
-@deftypefun int rl_read_init_file (const char *filename)
-Read keybindings and variable assignments from @var{filename}
-(@pxref{Readline Init File}).
-@end deftypefun
-
-@node Associating Function Names and Bindings
-@subsection Associating Function Names and Bindings
-
-These functions allow you to find out what keys invoke named functions
-and the functions invoked by a particular key sequence.  You may also
-associate a new function name with an arbitrary function.
-
-@deftypefun {rl_command_func_t *} rl_named_function (const char *name)
-Return the function with name @var{name}.
-@end deftypefun
-
-@deftypefun {rl_command_func_t *} rl_function_of_keyseq (const char *keyseq, Keymap map, int *type)
-Return the function invoked by @var{keyseq} in keymap @var{map}.
-If @var{map} is @code{NULL}, the current keymap is used.  If @var{type} is
-not @code{NULL}, the type of the object is returned in the @code{int} variable
-it points to (one of @code{ISFUNC}, @code{ISKMAP}, or @code{ISMACR}).
-@end deftypefun
-
-@deftypefun {char **} rl_invoking_keyseqs (rl_command_func_t *function)
-Return an array of strings representing the key sequences used to
-invoke @var{function} in the current keymap.
-@end deftypefun
-
-@deftypefun {char **} rl_invoking_keyseqs_in_map (rl_command_func_t *function, Keymap map)
-Return an array of strings representing the key sequences used to
-invoke @var{function} in the keymap @var{map}.
-@end deftypefun
-
-@deftypefun void rl_function_dumper (int readable)
-Print the readline function names and the key sequences currently
-bound to them to @code{rl_outstream}.  If @var{readable} is non-zero,
-the list is formatted in such a way that it can be made part of an
-@code{inputrc} file and re-read.
-@end deftypefun
-
-@deftypefun void rl_list_funmap_names (void)
-Print the names of all bindable Readline functions to @code{rl_outstream}.
-@end deftypefun
-
-@deftypefun {const char **} rl_funmap_names (void)
-Return a NULL terminated array of known function names.  The array is
-sorted.  The array itself is allocated, but not the strings inside.  You
-should free the array, but not the pointers, using @code{free} or
-@code{rl_free} when you are done.
-@end deftypefun
-
-@deftypefun int rl_add_funmap_entry (const char *name, rl_command_func_t *function)
-Add @var{name} to the list of bindable Readline command names, and make
-@var{function} the function to be called when @var{name} is invoked.
-@end deftypefun
-
-@node Allowing Undoing
-@subsection Allowing Undoing
-
-Supporting the undo command is a painless thing, and makes your
-functions much more useful.  It is certainly easy to try
-something if you know you can undo it.
-
-If your function simply inserts text once, or deletes text once, and
-uses @code{rl_insert_text()} or @code{rl_delete_text()} to do it, then
-undoing is already done for you automatically.
-
-If you do multiple insertions or multiple deletions, or any combination
-of these operations, you should group them together into one operation.
-This is done with @code{rl_begin_undo_group()} and
-@code{rl_end_undo_group()}.
-
-The types of events that can be undone are:
-
-@smallexample
-enum undo_code @{ UNDO_DELETE, UNDO_INSERT, UNDO_BEGIN, UNDO_END @}; 
-@end smallexample
-
-Notice that @code{UNDO_DELETE} means to insert some text, and
-@code{UNDO_INSERT} means to delete some text.  That is, the undo code
-tells what to undo, not how to undo it.  @code{UNDO_BEGIN} and
-@code{UNDO_END} are tags added by @code{rl_begin_undo_group()} and
-@code{rl_end_undo_group()}.
-
-@deftypefun int rl_begin_undo_group (void)
-Begins saving undo information in a group construct.  The undo
-information usually comes from calls to @code{rl_insert_text()} and
-@code{rl_delete_text()}, but could be the result of calls to
-@code{rl_add_undo()}.
-@end deftypefun
-
-@deftypefun int rl_end_undo_group (void)
-Closes the current undo group started with @code{rl_begin_undo_group
-()}.  There should be one call to @code{rl_end_undo_group()}
-for each call to @code{rl_begin_undo_group()}.
-@end deftypefun
-
-@deftypefun void rl_add_undo (enum undo_code what, int start, int end, char *text)
-Remember how to undo an event (according to @var{what}).  The affected
-text runs from @var{start} to @var{end}, and encompasses @var{text}.
-@end deftypefun
-
-@deftypefun void rl_free_undo_list (void)
-Free the existing undo list.
-@end deftypefun
-
-@deftypefun int rl_do_undo (void)
-Undo the first thing on the undo list.  Returns @code{0} if there was
-nothing to undo, non-zero if something was undone.
-@end deftypefun
-
-Finally, if you neither insert nor delete text, but directly modify the
-existing text (e.g., change its case), call @code{rl_modifying()}
-once, just before you modify the text.  You must supply the indices of
-the text range that you are going to modify.
-
-@deftypefun int rl_modifying (int start, int end)
-Tell Readline to save the text between @var{start} and @var{end} as a
-single undo unit.  It is assumed that you will subsequently modify
-that text.
-@end deftypefun
-
-@node Redisplay
-@subsection Redisplay
-
-@deftypefun void rl_redisplay (void)
-Change what's displayed on the screen to reflect the current contents
-of @code{rl_line_buffer}.
-@end deftypefun
-
-@deftypefun int rl_forced_update_display (void)
-Force the line to be updated and redisplayed, whether or not
-Readline thinks the screen display is correct.
-@end deftypefun
-
-@deftypefun int rl_on_new_line (void)
-Tell the update functions that we have moved onto a new (empty) line,
-usually after ouputting a newline.
-@end deftypefun
-
-@deftypefun int rl_on_new_line_with_prompt (void)
-Tell the update functions that we have moved onto a new line, with
-@var{rl_prompt} already displayed.
-This could be used by applications that want to output the prompt string
-themselves, but still need Readline to know the prompt string length for
-redisplay.
-It should be used after setting @var{rl_already_prompted}.
-@end deftypefun
-
-@deftypefun int rl_reset_line_state (void)
-Reset the display state to a clean state and redisplay the current line
-starting on a new line.
-@end deftypefun
-
-@deftypefun int rl_crlf (void)
-Move the cursor to the start of the next screen line.
-@end deftypefun
-
-@deftypefun int rl_show_char (int c)
-Display character @var{c} on @code{rl_outstream}.
-If Readline has not been set to display meta characters directly, this
-will convert meta characters to a meta-prefixed key sequence.
-This is intended for use by applications which wish to do their own
-redisplay.
-@end deftypefun
-
-@deftypefun int rl_message (const char *, @dots{})
-The arguments are a format string as would be supplied to @code{printf},
-possibly containing conversion specifications such as @samp{%d}, and
-any additional arguments necessary to satisfy the conversion specifications.
-The resulting string is displayed in the @dfn{echo area}.  The echo area
-is also used to display numeric arguments and search strings.
-You should call @code{rl_save_prompt} to save the prompt information
-before calling this function.
-@end deftypefun
-
-@deftypefun int rl_clear_message (void)
-Clear the message in the echo area.  If the prompt was saved with a call to
-@code{rl_save_prompt} before the last call to @code{rl_message},
-call @code{rl_restore_prompt} before calling this function.
-@end deftypefun
-
-@deftypefun void rl_save_prompt (void)
-Save the local Readline prompt display state in preparation for
-displaying a new message in the message area with @code{rl_message()}.
-@end deftypefun
-
-@deftypefun void rl_restore_prompt (void)
-Restore the local Readline prompt display state saved by the most
-recent call to @code{rl_save_prompt}.
-if @code{rl_save_prompt} was called to save the prompt before a call
-to @code{rl_message}, this function should be called before the
-corresponding call to @code{rl_clear_message}.
-@end deftypefun
-
-@deftypefun int rl_expand_prompt (char *prompt)
-Expand any special character sequences in @var{prompt} and set up the
-local Readline prompt redisplay variables.
-This function is called by @code{readline()}.  It may also be called to
-expand the primary prompt if the @code{rl_on_new_line_with_prompt()}
-function or @code{rl_already_prompted} variable is used.
-It returns the number of visible characters on the last line of the
-(possibly multi-line) prompt.
-Applications may indicate that the prompt contains characters that take
-up no physical screen space when displayed by bracketing a sequence of
-such characters with the special markers @code{RL_PROMPT_START_IGNORE}
-and @code{RL_PROMPT_END_IGNORE} (declared in @file{readline.h}.  This may
-be used to embed terminal-specific escape sequences in prompts.
-@end deftypefun
-
-@deftypefun int rl_set_prompt (const char *prompt)
-Make Readline use @var{prompt} for subsequent redisplay.  This calls
-@code{rl_expand_prompt()} to expand the prompt and sets @code{rl_prompt}
-to the result.
-@end deftypefun
-
-@node Modifying Text
-@subsection Modifying Text
-
-@deftypefun int rl_insert_text (const char *text)
-Insert @var{text} into the line at the current cursor position.
-Returns the number of characters inserted.
-@end deftypefun
-
-@deftypefun int rl_delete_text (int start, int end)
-Delete the text between @var{start} and @var{end} in the current line.
-Returns the number of characters deleted.
-@end deftypefun
-
-@deftypefun {char *} rl_copy_text (int start, int end)
-Return a copy of the text between @var{start} and @var{end} in
-the current line.
-@end deftypefun
-
-@deftypefun int rl_kill_text (int start, int end)
-Copy the text between @var{start} and @var{end} in the current line
-to the kill ring, appending or prepending to the last kill if the
-last command was a kill command.  The text is deleted.
-If @var{start} is less than @var{end},
-the text is appended, otherwise prepended.  If the last command was
-not a kill, a new kill ring slot is used.
-@end deftypefun
-
-@deftypefun int rl_push_macro_input (char *macro)
-Cause @var{macro} to be inserted into the line, as if it had been invoked
-by a key bound to a macro.  Not especially useful; use
-@code{rl_insert_text()} instead.
-@end deftypefun
-
-@node Character Input
-@subsection Character Input
-
-@deftypefun int rl_read_key (void)
-Return the next character available from Readline's current input stream.
-This handles input inserted into
-the input stream via @var{rl_pending_input} (@pxref{Readline Variables})
-and @code{rl_stuff_char()}, macros, and characters read from the keyboard.
-While waiting for input, this function will call any function assigned to
-the @code{rl_event_hook} variable.
-@end deftypefun
-
-@deftypefun int rl_getc (FILE *stream)
-Return the next character available from @var{stream}, which is assumed to
-be the keyboard.
-@end deftypefun
-
-@deftypefun int rl_stuff_char (int c)
-Insert @var{c} into the Readline input stream.  It will be "read"
-before Readline attempts to read characters from the terminal with
-@code{rl_read_key()}.  Up to 512 characters may be pushed back.
-@code{rl_stuff_char} returns 1 if the character was successfully inserted;
-0 otherwise.
-@end deftypefun
-
-@deftypefun int rl_execute_next (int c)
-Make @var{c} be the next command to be executed when @code{rl_read_key()}
-is called.  This sets @var{rl_pending_input}.
-@end deftypefun
-
-@deftypefun int rl_clear_pending_input (void)
-Unset @var{rl_pending_input}, effectively negating the effect of any
-previous call to @code{rl_execute_next()}.  This works only if the
-pending input has not already been read with @code{rl_read_key()}.
-@end deftypefun
-
-@deftypefun int rl_set_keyboard_input_timeout (int u)
-While waiting for keyboard input in @code{rl_read_key()}, Readline will
-wait for @var{u} microseconds for input before calling any function
-assigned to @code{rl_event_hook}.  @var{u} must be greater than or equal
-to zero (a zero-length timeout is equivalent to a poll).
-The default waiting period is one-tenth of a second.
-Returns the old timeout value.
-@end deftypefun
-
-@node Terminal Management
-@subsection Terminal Management
-
-@deftypefun void rl_prep_terminal (int meta_flag)
-Modify the terminal settings for Readline's use, so @code{readline()}
-can read a single character at a time from the keyboard.
-The @var{meta_flag} argument should be non-zero if Readline should
-read eight-bit input.
-@end deftypefun
-
-@deftypefun void rl_deprep_terminal (void)
-Undo the effects of @code{rl_prep_terminal()}, leaving the terminal in
-the state in which it was before the most recent call to
-@code{rl_prep_terminal()}.
-@end deftypefun
-
-@deftypefun void rl_tty_set_default_bindings (Keymap kmap)
-Read the operating system's terminal editing characters (as would be
-displayed by @code{stty}) to their Readline equivalents.
-The bindings are performed in @var{kmap}.
-@end deftypefun
-
-@deftypefun void rl_tty_unset_default_bindings (Keymap kmap)
-Reset the bindings manipulated by @code{rl_tty_set_default_bindings} so
-that the terminal editing characters are bound to @code{rl_insert}.
-The bindings are performed in @var{kmap}.
-@end deftypefun
-
-@deftypefun int rl_reset_terminal (const char *terminal_name)
-Reinitialize Readline's idea of the terminal settings using
-@var{terminal_name} as the terminal type (e.g., @code{vt100}).
-If @var{terminal_name} is @code{NULL}, the value of the @code{TERM}
-environment variable is used.
-@end deftypefun
-
-@node Utility Functions
-@subsection Utility Functions
-
-@deftypefun int rl_save_state (struct readline_state *sp)
-Save a snapshot of Readline's internal state to @var{sp}.
-The contents of the @var{readline_state} structure are documented
-in @file{readline.h}.
-The caller is responsible for allocating the structure.
-@end deftypefun
-
-@deftypefun int rl_restore_state (struct readline_state *sp)
-Restore Readline's internal state to that stored in @var{sp}, which must
-have been saved by a call to @code{rl_save_state}.
-The contents of the @var{readline_state} structure are documented
-in @file{readline.h}.
-The caller is responsible for freeing the structure.
-@end deftypefun
-
-@deftypefun void rl_free (void *mem)
-Deallocate the memory pointed to by @var{mem}.  @var{mem} must have been
-allocated by @code{malloc}.
-@end deftypefun
-
-@deftypefun void rl_replace_line (const char *text, int clear_undo)
-Replace the contents of @code{rl_line_buffer} with @var{text}.
-The point and mark are preserved, if possible.
-If @var{clear_undo} is non-zero, the undo list associated with the
-current line is cleared.
-@end deftypefun
-
-@deftypefun void rl_extend_line_buffer (int len)
-Ensure that @code{rl_line_buffer} has enough space to hold @var{len}
-characters, possibly reallocating it if necessary.
-@end deftypefun
-
-@deftypefun int rl_initialize (void)
-Initialize or re-initialize Readline's internal state.
-It's not strictly necessary to call this; @code{readline()} calls it before
-reading any input.
-@end deftypefun
-
-@deftypefun int rl_ding (void)
-Ring the terminal bell, obeying the setting of @code{bell-style}.
-@end deftypefun
-
-@deftypefun int rl_alphabetic (int c)
-Return 1 if @var{c} is an alphabetic character.
-@end deftypefun
-
-@deftypefun void rl_display_match_list (char **matches, int len, int max)
-A convenience function for displaying a list of strings in
-columnar format on Readline's output stream.  @code{matches} is the list
-of strings, in argv format, such as a list of completion matches.
-@code{len} is the number of strings in @code{matches}, and @code{max}
-is the length of the longest string in @code{matches}.  This function uses
-the setting of @code{print-completions-horizontally} to select how the
-matches are displayed (@pxref{Readline Init File Syntax}).
-@end deftypefun
-
-The following are implemented as macros, defined in @code{chardefs.h}.
-Applications should refrain from using them.
-
-@deftypefun int _rl_uppercase_p (int c)
-Return 1 if @var{c} is an uppercase alphabetic character.
-@end deftypefun
-
-@deftypefun int _rl_lowercase_p (int c)
-Return 1 if @var{c} is a lowercase alphabetic character.
-@end deftypefun
-
-@deftypefun int _rl_digit_p (int c)
-Return 1 if @var{c} is a numeric character.
-@end deftypefun
-
-@deftypefun int _rl_to_upper (int c)
-If @var{c} is a lowercase alphabetic character, return the corresponding
-uppercase character.
-@end deftypefun
-
-@deftypefun int _rl_to_lower (int c)
-If @var{c} is an uppercase alphabetic character, return the corresponding
-lowercase character.
-@end deftypefun
-
-@deftypefun int _rl_digit_value (int c)
-If @var{c} is a number, return the value it represents.
-@end deftypefun
-
-@node Miscellaneous Functions
-@subsection Miscellaneous Functions
-
-@deftypefun int rl_macro_bind (const char *keyseq, const char *macro, Keymap map)
-Bind the key sequence @var{keyseq} to invoke the macro @var{macro}.
-The binding is performed in @var{map}.  When @var{keyseq} is invoked, the
-@var{macro} will be inserted into the line.  This function is deprecated;
-use @code{rl_generic_bind()} instead.
-@end deftypefun
-
-@deftypefun void rl_macro_dumper (int readable)
-Print the key sequences bound to macros and their values, using
-the current keymap, to @code{rl_outstream}.
-If @var{readable} is non-zero, the list is formatted in such a way
-that it can be made part of an @code{inputrc} file and re-read.
-@end deftypefun
-
-@deftypefun int rl_variable_bind (const char *variable, const char *value)
-Make the Readline variable @var{variable} have @var{value}.
-This behaves as if the readline command
-@samp{set @var{variable} @var{value}} had been executed in an @code{inputrc}
-file (@pxref{Readline Init File Syntax}).
-@end deftypefun
-
-@deftypefun {char *} rl_variable_value (const char *variable)
-Return a string representing the value of the Readline variable @var{variable}.
-For boolean variables, this string is either @samp{on} or @samp{off}.
-@end deftypefun
-
-@deftypefun void rl_variable_dumper (int readable)
-Print the readline variable names and their current values
-to @code{rl_outstream}.
-If @var{readable} is non-zero, the list is formatted in such a way
-that it can be made part of an @code{inputrc} file and re-read.
-@end deftypefun
-
-@deftypefun int rl_set_paren_blink_timeout (int u)
-Set the time interval (in microseconds) that Readline waits when showing
-a balancing character when @code{blink-matching-paren} has been enabled.
-@end deftypefun
-
-@deftypefun {char *} rl_get_termcap (const char *cap)
-Retrieve the string value of the termcap capability @var{cap}.
-Readline fetches the termcap entry for the current terminal name and
-uses those capabilities to move around the screen line and perform other
-terminal-specific operations, like erasing a line.  Readline does not
-use all of a terminal's capabilities, and this function will return
-values for only those capabilities Readline uses.
-@end deftypefun
-
-@node Alternate Interface
-@subsection Alternate Interface
-
-An alternate interface is available to plain @code{readline()}.  Some
-applications need to interleave keyboard I/O with file, device, or
-window system I/O, typically by using a main loop to @code{select()}
-on various file descriptors.  To accomodate this need, readline can
-also be invoked as a `callback' function from an event loop.  There
-are functions available to make this easy.
-
-@deftypefun void rl_callback_handler_install (const char *prompt, rl_vcpfunc_t *lhandler)
-Set up the terminal for readline I/O and display the initial
-expanded value of @var{prompt}.  Save the value of @var{lhandler} to
-use as a function to call when a complete line of input has been entered.
-The function takes the text of the line as an argument.
-@end deftypefun
-
-@deftypefun void rl_callback_read_char (void)
-Whenever an application determines that keyboard input is available, it
-should call @code{rl_callback_read_char()}, which will read the next
-character from the current input source.
-If that character completes the line, @code{rl_callback_read_char} will
-invoke the @var{lhandler} function saved by @code{rl_callback_handler_install}
-to process the line.
-Before calling the @var{lhandler} function, the terminal settings are
-reset to the values they had before calling
-@code{rl_callback_handler_install}.
-If the @var{lhandler} function returns,
-the terminal settings are modified for Readline's use again.
-@code{EOF} is  indicated by calling @var{lhandler} with a
-@code{NULL} line.
-@end deftypefun
-
-@deftypefun void rl_callback_handler_remove (void)
-Restore the terminal to its initial state and remove the line handler.
-This may be called from within a callback as well as independently.
-If the @var{lhandler} installed by @code{rl_callback_handler_install}
-does not exit the program, either this function or the function referred
-to by the value of @code{rl_deprep_term_function} should be called before
-the program exits to reset the terminal settings.
-@end deftypefun
-
-@node A Readline Example
-@subsection A Readline Example
-
-Here is a function which changes lowercase characters to their uppercase
-equivalents, and uppercase characters to lowercase.  If
-this function was bound to @samp{M-c}, then typing @samp{M-c} would
-change the case of the character under point.  Typing @samp{M-1 0 M-c}
-would change the case of the following 10 characters, leaving the cursor on
-the last character changed.
-
-@example
-/* Invert the case of the COUNT following characters. */
-int
-invert_case_line (count, key)
-     int count, key;
-@{
-  register int start, end, i;
-
-  start = rl_point;
-
-  if (rl_point >= rl_end)
-    return (0);
-
-  if (count < 0)
-    @{
-      direction = -1;
-      count = -count;
-    @}
-  else
-    direction = 1;
-      
-  /* Find the end of the range to modify. */
-  end = start + (count * direction);
-
-  /* Force it to be within range. */
-  if (end > rl_end)
-    end = rl_end;
-  else if (end < 0)
-    end = 0;
-
-  if (start == end)
-    return (0);
-
-  if (start > end)
-    @{
-      int temp = start;
-      start = end;
-      end = temp;
-    @}
-
-  /* Tell readline that we are modifying the line,
-     so it will save the undo information. */
-  rl_modifying (start, end);
-
-  for (i = start; i != end; i++)
-    @{
-      if (_rl_uppercase_p (rl_line_buffer[i]))
-        rl_line_buffer[i] = _rl_to_lower (rl_line_buffer[i]);
-      else if (_rl_lowercase_p (rl_line_buffer[i]))
-        rl_line_buffer[i] = _rl_to_upper (rl_line_buffer[i]);
-    @}
-  /* Move point to on top of the last character changed. */
-  rl_point = (direction == 1) ? end - 1 : start;
-  return (0);
-@}
-@end example
-
-@node Readline Signal Handling
-@section Readline Signal Handling
-
-Signals are asynchronous events sent to a process by the Unix kernel,
-sometimes on behalf of another process.  They are intended to indicate
-exceptional events, like a user pressing the interrupt key on his terminal,
-or a network connection being broken.  There is a class of signals that can
-be sent to the process currently reading input from the keyboard.  Since
-Readline changes the terminal attributes when it is called, it needs to
-perform special processing when such a signal is received in order to
-restore the terminal to a sane state, or provide application writers with
-functions to do so manually. 
-
-Readline contains an internal signal handler that is installed for a
-number of signals (@code{SIGINT}, @code{SIGQUIT}, @code{SIGTERM},
-@code{SIGALRM}, @code{SIGTSTP}, @code{SIGTTIN}, and @code{SIGTTOU}).
-When one of these signals is received, the signal handler
-will reset the terminal attributes to those that were in effect before
-@code{readline()} was called, reset the signal handling to what it was
-before @code{readline()} was called, and resend the signal to the calling
-application.
-If and when the calling application's signal handler returns, Readline
-will reinitialize the terminal and continue to accept input.
-When a @code{SIGINT} is received, the Readline signal handler performs
-some additional work, which will cause any partially-entered line to be
-aborted (see the description of @code{rl_free_line_state()} below).
-
-There is an additional Readline signal handler, for @code{SIGWINCH}, which
-the kernel sends to a process whenever the terminal's size changes (for
-example, if a user resizes an @code{xterm}).  The Readline @code{SIGWINCH}
-handler updates Readline's internal screen size information, and then calls
-any @code{SIGWINCH} signal handler the calling application has installed. 
-Readline calls the application's @code{SIGWINCH} signal handler without
-resetting the terminal to its original state.  If the application's signal
-handler does more than update its idea of the terminal size and return (for
-example, a @code{longjmp} back to a main processing loop), it @emph{must}
-call @code{rl_cleanup_after_signal()} (described below), to restore the
-terminal state. 
-
-Readline provides two variables that allow application writers to
-control whether or not it will catch certain signals and act on them
-when they are received.  It is important that applications change the
-values of these variables only when calling @code{readline()}, not in
-a signal handler, so Readline's internal signal state is not corrupted.
-
-@deftypevar int rl_catch_signals
-If this variable is non-zero, Readline will install signal handlers for
-@code{SIGINT}, @code{SIGQUIT}, @code{SIGTERM}, @code{SIGALRM},
-@code{SIGTSTP}, @code{SIGTTIN}, and @code{SIGTTOU}.
-
-The default value of @code{rl_catch_signals} is 1.
-@end deftypevar
-
-@deftypevar int rl_catch_sigwinch
-If this variable is non-zero, Readline will install a signal handler for
-@code{SIGWINCH}.
-
-The default value of @code{rl_catch_sigwinch} is 1.
-@end deftypevar
-
-If an application does not wish to have Readline catch any signals, or
-to handle signals other than those Readline catches (@code{SIGHUP},
-for example), 
-Readline provides convenience functions to do the necessary terminal
-and internal state cleanup upon receipt of a signal.
-
-@deftypefun void rl_cleanup_after_signal (void)
-This function will reset the state of the terminal to what it was before
-@code{readline()} was called, and remove the Readline signal handlers for
-all signals, depending on the values of @code{rl_catch_signals} and
-@code{rl_catch_sigwinch}.
-@end deftypefun
-
-@deftypefun void rl_free_line_state (void)
-This will free any partial state associated with the current input line
-(undo information, any partial history entry, any partially-entered
-keyboard macro, and any partially-entered numeric argument).  This
-should be called before @code{rl_cleanup_after_signal()}.  The
-Readline signal handler for @code{SIGINT} calls this to abort the
-current input line.
-@end deftypefun
-
-@deftypefun void rl_reset_after_signal (void)
-This will reinitialize the terminal and reinstall any Readline signal
-handlers, depending on the values of @code{rl_catch_signals} and
-@code{rl_catch_sigwinch}.
-@end deftypefun
-
-If an application does not wish Readline to catch @code{SIGWINCH}, it may
-call @code{rl_resize_terminal()} or @code{rl_set_screen_size()} to force
-Readline to update its idea of the terminal size when a @code{SIGWINCH}
-is received.
-
-@deftypefun void rl_echo_signal_char (int sig)
-If an application wishes to install its own signal handlers, but still
-have readline display characters that generate signals, calling this
-function with @var{sig} set to @code{SIGINT}, @code{SIGQUIT}, or
-@code{SIGTSTP} will display the character generating that signal.
-@end deftypefun
-
-@deftypefun void rl_resize_terminal (void)
-Update Readline's internal screen size by reading values from the kernel.
-@end deftypefun
-
-@deftypefun void rl_set_screen_size (int rows, int cols)
-Set Readline's idea of the terminal size to @var{rows} rows and
-@var{cols} columns.  If either @var{rows} or @var{columns} is less than
-or equal to 0, Readline's idea of that terminal dimension is unchanged.
-@end deftypefun
-
-If an application does not want to install a @code{SIGWINCH} handler, but
-is still interested in the screen dimensions, Readline's idea of the screen
-size may be queried.
-
-@deftypefun void rl_get_screen_size (int *rows, int *cols)
-Return Readline's idea of the terminal's size in the
-variables pointed to by the arguments.
-@end deftypefun
-
-@deftypefun void rl_reset_screen_size (void)
-Cause Readline to reobtain the screen size and recalculate its dimensions.
-@end deftypefun
-
-The following functions install and remove Readline's signal handlers.
-
-@deftypefun int rl_set_signals (void)
-Install Readline's signal handler for @code{SIGINT}, @code{SIGQUIT},
-@code{SIGTERM}, @code{SIGALRM}, @code{SIGTSTP}, @code{SIGTTIN},
-@code{SIGTTOU}, and @code{SIGWINCH}, depending on the values of
-@code{rl_catch_signals} and @code{rl_catch_sigwinch}.
-@end deftypefun
-
-@deftypefun int rl_clear_signals (void)
-Remove all of the Readline signal handlers installed by
-@code{rl_set_signals()}.
-@end deftypefun
-
-@node Custom Completers
-@section Custom Completers
-@cindex application-specific completion functions
-
-Typically, a program that reads commands from the user has a way of
-disambiguating commands and data.  If your program is one of these, then
-it can provide completion for commands, data, or both.
-The following sections describe how your program and Readline
-cooperate to provide this service.
-
-@menu
-* How Completing Works::       The logic used to do completion.
-* Completion Functions::       Functions provided by Readline.
-* Completion Variables::       Variables which control completion.
-* A Short Completion Example:: An example of writing completer subroutines.
-@end menu
-
-@node How Completing Works
-@subsection How Completing Works
-
-In order to complete some text, the full list of possible completions
-must be available.  That is, it is not possible to accurately
-expand a partial word without knowing all of the possible words
-which make sense in that context.  The Readline library provides
-the user interface to completion, and two of the most common
-completion functions:  filename and username.  For completing other types
-of text, you must write your own completion function.  This section
-describes exactly what such functions must do, and provides an example.
-
-There are three major functions used to perform completion:
-
-@enumerate
-@item
-The user-interface function @code{rl_complete()}.  This function is
-called with the same arguments as other bindable Readline functions:
-@var{count} and @var{invoking_key}.
-It isolates the word to be completed and calls
-@code{rl_completion_matches()} to generate a list of possible completions.
-It then either lists the possible completions, inserts the possible
-completions, or actually performs the
-completion, depending on which behavior is desired.
-
-@item
-The internal function @code{rl_completion_matches()} uses an
-application-supplied @dfn{generator} function to generate the list of
-possible matches, and then returns the array of these matches.
-The caller should place the address of its generator function in
-@code{rl_completion_entry_function}.
-
-@item
-The generator function is called repeatedly from
-@code{rl_completion_matches()}, returning a string each time.  The
-arguments to the generator function are @var{text} and @var{state}.
-@var{text} is the partial word to be completed.  @var{state} is zero the
-first time the function is called, allowing the generator to perform
-any necessary initialization, and a positive non-zero integer for
-each subsequent call.  The generator function returns
-@code{(char *)NULL} to inform @code{rl_completion_matches()} that there are
-no more possibilities left.  Usually the generator function computes the
-list of possible completions when @var{state} is zero, and returns them
-one at a time on subsequent calls.  Each string the generator function
-returns as a match must be allocated with @code{malloc()}; Readline
-frees the strings when it has finished with them.
-Such a generator function is referred to as an
-@dfn{application-specific completion function}.
-
-@end enumerate
-
-@deftypefun int rl_complete (int ignore, int invoking_key)
-Complete the word at or before point.  You have supplied the function
-that does the initial simple matching selection algorithm (see
-@code{rl_completion_matches()}).  The default is to do filename completion.
-@end deftypefun
-
-@deftypevar {rl_compentry_func_t *} rl_completion_entry_function
-This is a pointer to the generator function for
-@code{rl_completion_matches()}.
-If the value of @code{rl_completion_entry_function} is
-@code{NULL} then the default filename generator
-function, @code{rl_filename_completion_function()}, is used.
-An @dfn{application-specific completion function} is a function whose
-address is assigned to @code{rl_completion_entry_function} and whose
-return values are used to  generate possible completions.
-@end deftypevar
-
-@node Completion Functions
-@subsection Completion Functions
-
-Here is the complete list of callable completion functions present in
-Readline.
-
-@deftypefun int rl_complete_internal (int what_to_do)
-Complete the word at or before point.  @var{what_to_do} says what to do
-with the completion.  A value of @samp{?} means list the possible
-completions.  @samp{TAB} means do standard completion.  @samp{*} means
-insert all of the possible completions.  @samp{!} means to display
-all of the possible completions, if there is more than one, as well as
-performing partial completion.  @samp{@@} is similar to @samp{!}, but
-possible completions are not listed if the possible completions share
-a common prefix.
-@end deftypefun
-
-@deftypefun int rl_complete (int ignore, int invoking_key)
-Complete the word at or before point.  You have supplied the function
-that does the initial simple matching selection algorithm (see
-@code{rl_completion_matches()} and @code{rl_completion_entry_function}).
-The default is to do filename
-completion.  This calls @code{rl_complete_internal()} with an
-argument depending on @var{invoking_key}.
-@end deftypefun
-
-@deftypefun int rl_possible_completions (int count, int invoking_key)
-List the possible completions.  See description of @code{rl_complete
-()}.  This calls @code{rl_complete_internal()} with an argument of
-@samp{?}.
-@end deftypefun
-
-@deftypefun int rl_insert_completions (int count, int invoking_key)
-Insert the list of possible completions into the line, deleting the
-partially-completed word.  See description of @code{rl_complete()}.
-This calls @code{rl_complete_internal()} with an argument of @samp{*}.
-@end deftypefun
-
-@deftypefun int rl_completion_mode (rl_command_func_t *cfunc)
-Returns the apppriate value to pass to @code{rl_complete_internal()}
-depending on whether @var{cfunc} was called twice in succession and
-the values of the @code{show-all-if-ambiguous} and
-@code{show-all-if-unmodified} variables.
-Application-specific completion functions may use this function to present
-the same interface as @code{rl_complete()}.
-@end deftypefun
-
-@deftypefun {char **} rl_completion_matches (const char *text, rl_compentry_func_t *entry_func)
-Returns an array of strings which is a list of completions for
-@var{text}.  If there are no completions, returns @code{NULL}.
-The first entry in the returned array is the substitution for @var{text}.
-The remaining entries are the possible completions.  The array is
-terminated with a @code{NULL} pointer.
-
-@var{entry_func} is a function of two args, and returns a
-@code{char *}.  The first argument is @var{text}.  The second is a
-state argument; it is zero on the first call, and non-zero on subsequent
-calls.  @var{entry_func} returns a @code{NULL}  pointer to the caller
-when there are no more matches.
-@end deftypefun
-
-@deftypefun {char *} rl_filename_completion_function (const char *text, int state)
-A generator function for filename completion in the general case.
-@var{text} is a partial filename.
-The Bash source is a useful reference for writing application-specific
-completion functions (the Bash completion functions call this and other
-Readline functions).
-@end deftypefun
-
-@deftypefun {char *} rl_username_completion_function (const char *text, int state)
-A completion generator for usernames.  @var{text} contains a partial
-username preceded by a random character (usually @samp{~}).  As with all
-completion generators, @var{state} is zero on the first call and non-zero
-for subsequent calls.
-@end deftypefun
-
-@node Completion Variables
-@subsection Completion Variables
-
-@deftypevar {rl_compentry_func_t *} rl_completion_entry_function
-A pointer to the generator function for @code{rl_completion_matches()}.
-@code{NULL} means to use @code{rl_filename_completion_function()},
-the default filename completer.
-@end deftypevar
-
-@deftypevar {rl_completion_func_t *} rl_attempted_completion_function
-A pointer to an alternative function to create matches.
-The function is called with @var{text}, @var{start}, and @var{end}.
-@var{start} and @var{end} are indices in @code{rl_line_buffer} defining
-the boundaries of @var{text}, which is a character string.
-If this function exists and returns @code{NULL}, or if this variable is
-set to @code{NULL}, then @code{rl_complete()} will call the value of
-@code{rl_completion_entry_function} to generate matches, otherwise the
-array of strings returned will be used.
-If this function sets the @code{rl_attempted_completion_over}
-variable to a non-zero value, Readline will not perform its default
-completion even if this function returns no matches.
-@end deftypevar
-
-@deftypevar {rl_quote_func_t *} rl_filename_quoting_function
-A pointer to a function that will quote a filename in an
-application-specific fashion.  This is called if filename completion is being
-attempted and one of the characters in @code{rl_filename_quote_characters}
-appears in a completed filename.  The function is called with
-@var{text}, @var{match_type}, and @var{quote_pointer}.  The @var{text}
-is the filename to be quoted.  The @var{match_type} is either
-@code{SINGLE_MATCH}, if there is only one completion match, or
-@code{MULT_MATCH}.  Some functions use this to decide whether or not to
-insert a closing quote character.  The @var{quote_pointer} is a pointer
-to any opening quote character the user typed.  Some functions choose
-to reset this character.
-@end deftypevar
-
-@deftypevar {rl_dequote_func_t *} rl_filename_dequoting_function
-A pointer to a function that will remove application-specific quoting
-characters from a filename before completion is attempted, so those
-characters do not interfere with matching the text against names in
-the filesystem.  It is called with @var{text}, the text of the word
-to be dequoted, and @var{quote_char}, which is the quoting character 
-that delimits the filename (usually @samp{'} or @samp{"}).  If
-@var{quote_char} is zero, the filename was not in an embedded string.
-@end deftypevar
-
-@deftypevar {rl_linebuf_func_t *} rl_char_is_quoted_p
-A pointer to a function to call that determines whether or not a specific
-character in the line buffer is quoted, according to whatever quoting
-mechanism the program calling Readline uses.  The function is called with
-two arguments: @var{text}, the text of the line, and @var{index}, the
-index of the character in the line.  It is used to decide whether a
-character found in @code{rl_completer_word_break_characters} should be
-used to break words for the completer.
-@end deftypevar
-
-@deftypevar {rl_compignore_func_t *} rl_ignore_some_completions_function
-This function, if defined, is called by the completer when real filename
-completion is done, after all the matching names have been generated.
-It is passed a @code{NULL} terminated array of matches.
-The first element (@code{matches[0]}) is the
-maximal substring common to all matches. This function can
-re-arrange the list of matches as required, but each element deleted
-from the array must be freed.
-@end deftypevar
-
-@deftypevar {rl_icppfunc_t *} rl_directory_completion_hook
-This function, if defined, is allowed to modify the directory portion
-of filenames Readline completes.  It is called with the address of a
-string (the current directory name) as an argument, and may modify that string.
-If the string is replaced with a new string, the old value should be freed.
-Any modified directory name should have a trailing slash.
-The modified value will be displayed as part of the completion, replacing
-the directory portion of the pathname the user typed.
-It returns an integer that should be non-zero if the function modifies
-its directory argument.
-It could be used to expand symbolic links or shell variables in pathnames.
-At the least, even if no other expansion is performed, this function should
-remove any quote characters from the directory name, because its result will
-be passed directly to @code{opendir()}.
-@end deftypevar
-
-@deftypevar {rl_compdisp_func_t *} rl_completion_display_matches_hook
-If non-zero, then this is the address of a function to call when
-completing a word would normally display the list of possible matches.
-This function is called in lieu of Readline displaying the list.
-It takes three arguments:
-(@code{char **}@var{matches}, @code{int} @var{num_matches}, @code{int} @var{max_length})
-where @var{matches} is the array of matching strings,
-@var{num_matches} is the number of strings in that array, and
-@var{max_length} is the length of the longest string in that array.
-Readline provides a convenience function, @code{rl_display_match_list},
-that takes care of doing the display to Readline's output stream.  That
-function may be called from this hook.
-@end deftypevar
-
-@deftypevar {const char *} rl_basic_word_break_characters
-The basic list of characters that signal a break between words for the
-completer routine.  The default value of this variable is the characters
-which break words for completion in Bash:
-@code{" \t\n\"\\'`@@$><=;|&@{("}.
-@end deftypevar
-
-@deftypevar {const char *} rl_basic_quote_characters
-A list of quote characters which can cause a word break.
-@end deftypevar
-
-@deftypevar {const char *} rl_completer_word_break_characters
-The list of characters that signal a break between words for
-@code{rl_complete_internal()}.  The default list is the value of
-@code{rl_basic_word_break_characters}.
-@end deftypevar
-
-@deftypevar {rl_cpvfunc_t *} rl_completion_word_break_hook
-If non-zero, this is the address of a function to call when Readline is
-deciding where to separate words for word completion.  It should return
-a character string like @code{rl_completer_word_break_characters} to be
-used to perform the current completion.  The function may choose to set
-@code{rl_completer_word_break_characters} itself.  If the function
-returns @code{NULL}, @code{rl_completer_word_break_characters} is used.
-@end deftypevar
-
-@deftypevar {const char *} rl_completer_quote_characters
-A list of characters which can be used to quote a substring of the line.
-Completion occurs on the entire substring, and within the substring
-@code{rl_completer_word_break_characters} are treated as any other character,
-unless they also appear within this list.
-@end deftypevar
-
-@deftypevar {const char *} rl_filename_quote_characters
-A list of characters that cause a filename to be quoted by the completer
-when they appear in a completed filename.  The default is the null string.
-@end deftypevar
-
-@deftypevar {const char *} rl_special_prefixes
-The list of characters that are word break characters, but should be
-left in @var{text} when it is passed to the completion function.
-Programs can use this to help determine what kind of completing to do.
-For instance, Bash sets this variable to "$@@" so that it can complete
-shell variables and hostnames.
-@end deftypevar
-
-@deftypevar int rl_completion_query_items
-Up to this many items will be displayed in response to a
-possible-completions call.  After that, readline asks the user if she is sure
-she wants to see them all.  The default value is 100.  A negative value 
-indicates that Readline should never ask the user.
-@end deftypevar
-
-@deftypevar {int} rl_completion_append_character
-When a single completion alternative matches at the end of the command
-line, this character is appended to the inserted completion text.  The
-default is a space character (@samp{ }).  Setting this to the null
-character (@samp{\0}) prevents anything being appended automatically.
-This can be changed in application-specific completion functions to
-provide the ``most sensible word separator character'' according to
-an application-specific command line syntax specification.
-@end deftypevar
-
-@deftypevar int rl_completion_suppress_append
-If non-zero, @var{rl_completion_append_character} is not appended to
-matches at the end of the command line, as described above.
-It is set to 0 before any application-specific completion function
-is called, and may only be changed within such a function.
-@end deftypevar
-
-@deftypevar int rl_completion_quote_character
-When Readline is completing quoted text, as delimited by one of the
-characters in @var{rl_completer_quote_characters}, it sets this variable
-to the quoting character found.
-This is set before any application-specific completion function is called.
-@end deftypevar
-
-@deftypevar int rl_completion_suppress_quote
-If non-zero, Readline does not append a matching quote character when
-performing completion on a quoted string.
-It is set to 0 before any application-specific completion function
-is called, and may only be changed within such a function.
-@end deftypevar
-
-@deftypevar int rl_completion_found_quote
-When Readline is completing quoted text, it sets this variable
-to a non-zero value if the word being completed contains or is delimited
-by any quoting characters, including backslashes.
-This is set before any application-specific completion function is called.
-@end deftypevar
-
-@deftypevar int rl_completion_mark_symlink_dirs
-If non-zero, a slash will be appended to completed filenames that are
-symbolic links to directory names, subject to the value of the
-user-settable @var{mark-directories} variable.
-This variable exists so that application-specific completion functions
-can override the user's global preference (set via the
-@var{mark-symlinked-directories} Readline variable) if appropriate.
-This variable is set to the user's preference before any
-application-specific completion function is called, so unless that
-function modifies the value, the user's preferences are honored.
-@end deftypevar
-
-@deftypevar int rl_ignore_completion_duplicates
-If non-zero, then duplicates in the matches are removed.
-The default is 1.
-@end deftypevar
-
-@deftypevar int rl_filename_completion_desired
-Non-zero means that the results of the matches are to be treated as
-filenames.  This is @emph{always} zero when completion is attempted,
-and can only be changed
-within an application-specific completion function.  If it is set to a
-non-zero value by such a function, directory names have a slash appended
-and Readline attempts to quote completed filenames if they contain any
-characters in @code{rl_filename_quote_characters} and
-@code{rl_filename_quoting_desired} is set to a non-zero value.
-@end deftypevar
-
-@deftypevar int rl_filename_quoting_desired
-Non-zero means that the results of the matches are to be quoted using
-double quotes (or an application-specific quoting mechanism) if the
-completed filename contains any characters in
-@code{rl_filename_quote_chars}.  This is @emph{always} non-zero
-when completion is attempted, and can only be changed within an
-application-specific completion function.
-The quoting is effected via a call to the function pointed to
-by @code{rl_filename_quoting_function}.
-@end deftypevar
-
-@deftypevar int rl_attempted_completion_over
-If an application-specific completion function assigned to
-@code{rl_attempted_completion_function} sets this variable to a non-zero
-value, Readline will not perform its default filename completion even
-if the application's completion function returns no matches.
-It should be set only by an application's completion function.
-@end deftypevar
-
-@deftypevar int rl_sort_completion_matches
-If an application sets this variable to 0, Readline will not sort the
-list of completions (which implies that it cannot remove any duplicate
-completions).  The default value is 1, which means that Readline will
-sort the completions and, depending on the value of
-@code{rl_ignore_completion_duplicates}, will attempt to remove duplicate
-matches.
-@end deftypevar
-
-@deftypevar int rl_completion_type
-Set to a character describing the type of completion Readline is currently
-attempting; see the description of @code{rl_complete_internal()}
-(@pxref{Completion Functions}) for the list of characters.
-This is set to the appropriate value before any application-specific
-completion function is called, allowing such functions to present
-the same interface as @code{rl_complete()}.
-@end deftypevar
-
-@deftypevar int rl_completion_invoking_key
-Set to the final character in the key sequence that invoked one of the
-completion functions that call @code{rl_complete_internal()}.  This is
-set to the appropriate value before any application-specific completion
-function is called.
-@end deftypevar
-
-@deftypevar int rl_inhibit_completion
-If this variable is non-zero, completion is inhibited.  The completion
-character will be inserted as any other bound to @code{self-insert}.
-@end deftypevar
-
-@node A Short Completion Example
-@subsection A Short Completion Example
-
-Here is a small application demonstrating the use of the GNU Readline
-library.  It is called @code{fileman}, and the source code resides in
-@file{examples/fileman.c}.  This sample application provides
-completion of command names, line editing features, and access to the
-history list.
-
-@page
-@smallexample
-/* fileman.c -- A tiny application which demonstrates how to use the
-   GNU Readline library.  This application interactively allows users
-   to manipulate files and their modes. */
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#include <sys/types.h>
-#ifdef HAVE_SYS_FILE_H
-#  include <sys/file.h>
-#endif
-#include <sys/stat.h>
-
-#ifdef HAVE_UNISTD_H
-#  include <unistd.h>
-#endif
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <errno.h>
-
-#if defined (HAVE_STRING_H)
-#  include <string.h>
-#else /* !HAVE_STRING_H */
-#  include <strings.h>
-#endif /* !HAVE_STRING_H */
-
-#ifdef HAVE_STDLIB_H
-#  include <stdlib.h>
-#endif
-
-#include <time.h>
-
-#include <readline/readline.h>
-#include <readline/history.h>
-
-extern char *xmalloc PARAMS((size_t));
-
-/* The names of functions that actually do the manipulation. */
-int com_list PARAMS((char *));
-int com_view PARAMS((char *));
-int com_rename PARAMS((char *));
-int com_stat PARAMS((char *));
-int com_pwd PARAMS((char *));
-int com_delete PARAMS((char *));
-int com_help PARAMS((char *));
-int com_cd PARAMS((char *));
-int com_quit PARAMS((char *));
-
-/* A structure which contains information on the commands this program
-   can understand. */
-
-typedef struct @{
-  char *name;                  /* User printable name of the function. */
-  rl_icpfunc_t *func;          /* Function to call to do the job. */
-  char *doc;                   /* Documentation for this function.  */
-@} COMMAND;
-
-COMMAND commands[] = @{
-  @{ "cd", com_cd, "Change to directory DIR" @},
-  @{ "delete", com_delete, "Delete FILE" @},
-  @{ "help", com_help, "Display this text" @},
-  @{ "?", com_help, "Synonym for `help'" @},
-  @{ "list", com_list, "List files in DIR" @},
-  @{ "ls", com_list, "Synonym for `list'" @},
-  @{ "pwd", com_pwd, "Print the current working directory" @},
-  @{ "quit", com_quit, "Quit using Fileman" @},
-  @{ "rename", com_rename, "Rename FILE to NEWNAME" @},
-  @{ "stat", com_stat, "Print out statistics on FILE" @},
-  @{ "view", com_view, "View the contents of FILE" @},
-  @{ (char *)NULL, (rl_icpfunc_t *)NULL, (char *)NULL @}
-@};
-
-/* Forward declarations. */
-char *stripwhite ();
-COMMAND *find_command ();
-
-/* The name of this program, as taken from argv[0]. */
-char *progname;
-
-/* When non-zero, this global means the user is done using this program. */
-int done;
-
-char *
-dupstr (s)
-     char *s;
-@{
-  char *r;
-
-  r = xmalloc (strlen (s) + 1);
-  strcpy (r, s);
-  return (r);
-@}
-
-main (argc, argv)
-     int argc;
-     char **argv;
-@{
-  char *line, *s;
-
-  progname = argv[0];
-
-  initialize_readline ();      /* Bind our completer. */
-
-  /* Loop reading and executing lines until the user quits. */
-  for ( ; done == 0; )
-    @{
-      line = readline ("FileMan: ");
-
-      if (!line)
-        break;
-
-      /* Remove leading and trailing whitespace from the line.
-         Then, if there is anything left, add it to the history list
-         and execute it. */
-      s = stripwhite (line);
-
-      if (*s)
-        @{
-          add_history (s);
-          execute_line (s);
-        @}
-
-      free (line);
-    @}
-  exit (0);
-@}
-
-/* Execute a command line. */
-int
-execute_line (line)
-     char *line;
-@{
-  register int i;
-  COMMAND *command;
-  char *word;
-
-  /* Isolate the command word. */
-  i = 0;
-  while (line[i] && whitespace (line[i]))
-    i++;
-  word = line + i;
-
-  while (line[i] && !whitespace (line[i]))
-    i++;
-
-  if (line[i])
-    line[i++] = '\0';
-
-  command = find_command (word);
-
-  if (!command)
-    @{
-      fprintf (stderr, "%s: No such command for FileMan.\n", word);
-      return (-1);
-    @}
-
-  /* Get argument to command, if any. */
-  while (whitespace (line[i]))
-    i++;
-
-  word = line + i;
-
-  /* Call the function. */
-  return ((*(command->func)) (word));
-@}
-
-/* Look up NAME as the name of a command, and return a pointer to that
-   command.  Return a NULL pointer if NAME isn't a command name. */
-COMMAND *
-find_command (name)
-     char *name;
-@{
-  register int i;
-
-  for (i = 0; commands[i].name; i++)
-    if (strcmp (name, commands[i].name) == 0)
-      return (&commands[i]);
-
-  return ((COMMAND *)NULL);
-@}
-
-/* Strip whitespace from the start and end of STRING.  Return a pointer
-   into STRING. */
-char *
-stripwhite (string)
-     char *string;
-@{
-  register char *s, *t;
-
-  for (s = string; whitespace (*s); s++)
-    ;
-    
-  if (*s == 0)
-    return (s);
-
-  t = s + strlen (s) - 1;
-  while (t > s && whitespace (*t))
-    t--;
-  *++t = '\0';
-
-  return s;
-@}
-
-/* **************************************************************** */
-/*                                                                  */
-/*                  Interface to Readline Completion                */
-/*                                                                  */
-/* **************************************************************** */
-
-char *command_generator PARAMS((const char *, int));
-char **fileman_completion PARAMS((const char *, int, int));
-
-/* Tell the GNU Readline library how to complete.  We want to try to complete
-   on command names if this is the first word in the line, or on filenames
-   if not. */
-initialize_readline ()
-@{
-  /* Allow conditional parsing of the ~/.inputrc file. */
-  rl_readline_name = "FileMan";
-
-  /* Tell the completer that we want a crack first. */
-  rl_attempted_completion_function = fileman_completion;
-@}
-
-/* Attempt to complete on the contents of TEXT.  START and END bound the
-   region of rl_line_buffer that contains the word to complete.  TEXT is
-   the word to complete.  We can use the entire contents of rl_line_buffer
-   in case we want to do some simple parsing.  Return the array of matches,
-   or NULL if there aren't any. */
-char **
-fileman_completion (text, start, end)
-     const char *text;
-     int start, end;
-@{
-  char **matches;
-
-  matches = (char **)NULL;
-
-  /* If this word is at the start of the line, then it is a command
-     to complete.  Otherwise it is the name of a file in the current
-     directory. */
-  if (start == 0)
-    matches = rl_completion_matches (text, command_generator);
-
-  return (matches);
-@}
-
-/* Generator function for command completion.  STATE lets us know whether
-   to start from scratch; without any state (i.e. STATE == 0), then we
-   start at the top of the list. */
-char *
-command_generator (text, state)
-     const char *text;
-     int state;
-@{
-  static int list_index, len;
-  char *name;
-
-  /* If this is a new word to complete, initialize now.  This includes
-     saving the length of TEXT for efficiency, and initializing the index
-     variable to 0. */
-  if (!state)
-    @{
-      list_index = 0;
-      len = strlen (text);
-    @}
-
-  /* Return the next name which partially matches from the command list. */
-  while (name = commands[list_index].name)
-    @{
-      list_index++;
-
-      if (strncmp (name, text, len) == 0)
-        return (dupstr(name));
-    @}
-
-  /* If no names matched, then return NULL. */
-  return ((char *)NULL);
-@}
-
-/* **************************************************************** */
-/*                                                                  */
-/*                       FileMan Commands                           */
-/*                                                                  */
-/* **************************************************************** */
-
-/* String to pass to system ().  This is for the LIST, VIEW and RENAME
-   commands. */
-static char syscom[1024];
-
-/* List the file(s) named in arg. */
-com_list (arg)
-     char *arg;
-@{
-  if (!arg)
-    arg = "";
-
-  sprintf (syscom, "ls -FClg %s", arg);
-  return (system (syscom));
-@}
-
-com_view (arg)
-     char *arg;
-@{
-  if (!valid_argument ("view", arg))
-    return 1;
-
-#if defined (__MSDOS__)
-  /* more.com doesn't grok slashes in pathnames */
-  sprintf (syscom, "less %s", arg);
-#else
-  sprintf (syscom, "more %s", arg);
-#endif
-  return (system (syscom));
-@}
-
-com_rename (arg)
-     char *arg;
-@{
-  too_dangerous ("rename");
-  return (1);
-@}
-
-com_stat (arg)
-     char *arg;
-@{
-  struct stat finfo;
-
-  if (!valid_argument ("stat", arg))
-    return (1);
-
-  if (stat (arg, &finfo) == -1)
-    @{
-      perror (arg);
-      return (1);
-    @}
-
-  printf ("Statistics for `%s':\n", arg);
-
-  printf ("%s has %d link%s, and is %d byte%s in length.\n",
-         arg,
-          finfo.st_nlink,
-          (finfo.st_nlink == 1) ? "" : "s",
-          finfo.st_size,
-          (finfo.st_size == 1) ? "" : "s");
-  printf ("Inode Last Change at: %s", ctime (&finfo.st_ctime));
-  printf ("      Last access at: %s", ctime (&finfo.st_atime));
-  printf ("    Last modified at: %s", ctime (&finfo.st_mtime));
-  return (0);
-@}
-
-com_delete (arg)
-     char *arg;
-@{
-  too_dangerous ("delete");
-  return (1);
-@}
-
-/* Print out help for ARG, or for all of the commands if ARG is
-   not present. */
-com_help (arg)
-     char *arg;
-@{
-  register int i;
-  int printed = 0;
-
-  for (i = 0; commands[i].name; i++)
-    @{
-      if (!*arg || (strcmp (arg, commands[i].name) == 0))
-        @{
-          printf ("%s\t\t%s.\n", commands[i].name, commands[i].doc);
-          printed++;
-        @}
-    @}
-
-  if (!printed)
-    @{
-      printf ("No commands match `%s'.  Possibilties are:\n", arg);
-
-      for (i = 0; commands[i].name; i++)
-        @{
-          /* Print in six columns. */
-          if (printed == 6)
-            @{
-              printed = 0;
-              printf ("\n");
-            @}
-
-          printf ("%s\t", commands[i].name);
-          printed++;
-        @}
-
-      if (printed)
-        printf ("\n");
-    @}
-  return (0);
-@}
-
-/* Change to the directory ARG. */
-com_cd (arg)
-     char *arg;
-@{
-  if (chdir (arg) == -1)
-    @{
-      perror (arg);
-      return 1;
-    @}
-
-  com_pwd ("");
-  return (0);
-@}
-
-/* Print out the current working directory. */
-com_pwd (ignore)
-     char *ignore;
-@{
-  char dir[1024], *s;
-
-  s = getcwd (dir, sizeof(dir) - 1);
-  if (s == 0)
-    @{
-      printf ("Error getting pwd: %s\n", dir);
-      return 1;
-    @}
-
-  printf ("Current directory is %s\n", dir);
-  return 0;
-@}
-
-/* The user wishes to quit using this program.  Just set DONE non-zero. */
-com_quit (arg)
-     char *arg;
-@{
-  done = 1;
-  return (0);
-@}
-
-/* Function which tells you that you can't do this. */
-too_dangerous (caller)
-     char *caller;
-@{
-  fprintf (stderr,
-           "%s: Too dangerous for me to distribute.  Write it yourself.\n",
-           caller);
-@}
-
-/* Return non-zero if ARG is a valid argument for CALLER, else print
-   an error message and return zero. */
-int
-valid_argument (caller, arg)
-     char *caller, *arg;
-@{
-  if (!arg || !*arg)
-    @{
-      fprintf (stderr, "%s: Argument required.\n", caller);
-      return (0);
-    @}
-
-  return (1);
-@}
-@end smallexample
diff --git a/lib/readline/doc/rluser.texi~ b/lib/readline/doc/rluser.texi~
deleted file mode 100644 (file)
index 619de1d..0000000
+++ /dev/null
@@ -1,2001 +0,0 @@
-@comment %**start of header (This is for running Texinfo on a region.)
-@setfilename rluser.info
-@comment %**end of header (This is for running Texinfo on a region.)
-
-@ignore
-This file documents the end user interface to the GNU command line
-editing features.  It is to be an appendix to manuals for programs which
-use these features.  There is a document entitled "readline.texinfo"
-which contains both end-user and programmer documentation for the
-GNU Readline Library.
-
-Copyright (C) 1988--2009 Free Software Foundation, Inc.
-
-Authored by Brian Fox and Chet Ramey.
-
-Permission is granted to process this file through Tex and print the
-results, provided the printed document carries copying permission notice
-identical to this one except for the removal of this paragraph (this
-paragraph not being relevant to the printed manual).
-
-Permission is granted to make and distribute verbatim copies of this manual
-provided the copyright notice and this permission notice are preserved on
-all copies.
-
-Permission is granted to copy and distribute modified versions of this
-manual under the conditions for verbatim copying, provided also that the
-GNU Copyright statement is available to the distributee, and provided that
-the entire resulting derived work is distributed under the terms of a
-permission notice identical to this one.
-
-Permission is granted to copy and distribute translations of this manual
-into another language, under the above conditions for modified versions.
-@end ignore
-
-@comment If you are including this manual as an appendix, then set the
-@comment variable readline-appendix.
-
-@ifclear BashFeatures
-@defcodeindex bt
-@end ifclear
-
-@node Command Line Editing
-@chapter Command Line Editing
-
-This chapter describes the basic features of the @sc{gnu}
-command line editing interface.
-@ifset BashFeatures
-Command line editing is provided by the Readline library, which is
-used by several different programs, including Bash.
-Command line editing is enabled by default when using an interactive shell,
-unless the @option{--noediting} option is supplied at shell invocation.
-Line editing is also used when using the @option{-e} option to the
-@code{read} builtin command (@pxref{Bash Builtins}).
-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 @option{-o emacs} or
-@option{-o vi} options to the @code{set} builtin command
-(@pxref{The Set Builtin}), or disabled using the @option{+o emacs} or 
-@option{+o vi} options to @code{set}.
-@end ifset
-
-@menu
-* Introduction and Notation::  Notation used in this text.
-* Readline Interaction::       The minimum set of commands for editing a line.
-* Readline Init File::         Customizing Readline from a user's view.
-* Bindable Readline Commands:: A description of most of the Readline commands
-                               available for binding
-* Readline vi Mode::           A short description of how to make Readline
-                               behave like the vi editor.
-@ifset BashFeatures
-* Programmable Completion::    How to specify the possible completions for
-                               a specific command.
-* Programmable Completion Builtins::   Builtin commands to specify how to
-                               complete arguments for a particular command.
-@end ifset
-@end menu
-
-@node Introduction and Notation
-@section Introduction to Line Editing
-
-The following paragraphs describe the notation used to represent
-keystrokes.
-
-The text @kbd{C-k} is read as `Control-K' and describes the character
-produced when the @key{k} key is pressed while the Control key
-is depressed.
-
-The text @kbd{M-k} is read as `Meta-K' and describes the character
-produced when the Meta key (if you have one) is depressed, and the @key{k}
-key is pressed.
-The Meta key is labeled @key{ALT} on many keyboards.
-On keyboards with two keys labeled @key{ALT} (usually to either side of
-the space bar), the @key{ALT} on the left side is generally set to
-work as a Meta key.
-The @key{ALT} key on the right may also be configured to work as a
-Meta key or may be configured as some other modifier, such as a
-Compose key for typing accented characters.
-
-If you do not have a Meta or @key{ALT} key, or another key working as
-a Meta key, the identical keystroke can be generated by typing @key{ESC}
-@emph{first}, and then typing @key{k}.
-Either process is known as @dfn{metafying} the @key{k} key.
-
-The text @kbd{M-C-k} is read as `Meta-Control-k' and describes the
-character produced by @dfn{metafying} @kbd{C-k}.
-
-In addition, several keys have their own names.  Specifically,
-@key{DEL}, @key{ESC}, @key{LFD}, @key{SPC}, @key{RET}, and @key{TAB} all
-stand for themselves when seen in this text, or in an init file
-(@pxref{Readline Init File}).
-If your keyboard lacks a @key{LFD} key, typing @key{C-j} will
-produce the desired character.
-The @key{RET} key may be labeled @key{Return} or @key{Enter} on
-some keyboards.
-
-@node Readline Interaction
-@section Readline Interaction
-@cindex interaction, readline
-
-Often during an interactive session you type in a long line of text,
-only to notice that the first word on the line is misspelled.  The
-Readline library gives you a set of commands for manipulating the text
-as you type it in, allowing you to just fix your typo, and not forcing
-you to retype the majority of the line.  Using these editing commands,
-you move the cursor to the place that needs correction, and delete or
-insert the text of the corrections.  Then, when you are satisfied with
-the line, you simply press @key{RET}.  You do not have to be at the
-end of the line to press @key{RET}; the entire line is accepted
-regardless of the location of the cursor within the line.
-
-@menu
-* Readline Bare Essentials::   The least you need to know about Readline.
-* Readline Movement Commands:: Moving about the input line.
-* Readline Killing Commands::  How to delete text, and how to get it back!
-* Readline Arguments::         Giving numeric arguments to commands.
-* Searching::                  Searching through previous lines.
-@end menu
-
-@node Readline Bare Essentials
-@subsection Readline Bare Essentials
-@cindex notation, readline
-@cindex command editing
-@cindex editing command lines
-
-In order to enter characters into the line, simply type them.  The typed
-character appears where the cursor was, and then the cursor moves one
-space to the right.  If you mistype a character, you can use your
-erase character to back up and delete the mistyped character.
-
-Sometimes you may mistype a character, and
-not notice the error until you have typed several other characters.  In
-that case, you can type @kbd{C-b} to move the cursor to the left, and then
-correct your mistake.  Afterwards, you can move the cursor to the right
-with @kbd{C-f}.
-
-When you add text in the middle of a line, you will notice that characters
-to the right of the cursor are `pushed over' to make room for the text
-that you have inserted.  Likewise, when you delete text behind the cursor,
-characters to the right of the cursor are `pulled back' to fill in the
-blank space created by the removal of the text.  A list of the bare
-essentials for editing the text of an input line follows.
-
-@table @asis
-@item @kbd{C-b}
-Move back one character.
-@item @kbd{C-f}
-Move forward one character.
-@item @key{DEL} or @key{Backspace}
-Delete the character to the left of the cursor.
-@item @kbd{C-d}
-Delete the character underneath the cursor.
-@item @w{Printing characters}
-Insert the character into the line at the cursor.
-@item @kbd{C-_} or @kbd{C-x C-u}
-Undo the last editing command.  You can undo all the way back to an
-empty line.
-@end table
-
-@noindent
-(Depending on your configuration, the @key{Backspace} key be set to
-delete the character to the left of the cursor and the @key{DEL} key set
-to delete the character underneath the cursor, like @kbd{C-d}, rather
-than the character to the left of the cursor.)
-
-@node Readline Movement Commands
-@subsection Readline Movement Commands
-
-
-The above table describes the most basic keystrokes that you need
-in order to do editing of the input line.  For your convenience, many
-other commands have been added in addition to @kbd{C-b}, @kbd{C-f},
-@kbd{C-d}, and @key{DEL}.  Here are some commands for moving more rapidly
-about the line.
-
-@table @kbd
-@item C-a
-Move to the start of the line.
-@item C-e
-Move to the end of the line.
-@item M-f
-Move forward a word, where a word is composed of letters and digits.
-@item M-b
-Move backward a word.
-@item C-l
-Clear the screen, reprinting the current line at the top.
-@end table
-
-Notice how @kbd{C-f} moves forward a character, while @kbd{M-f} moves
-forward a word.  It is a loose convention that control keystrokes
-operate on characters while meta keystrokes operate on words.
-
-@node Readline Killing Commands
-@subsection Readline Killing Commands
-
-@cindex killing text
-@cindex yanking text
-
-@dfn{Killing} text means to delete the text from the line, but to save
-it away for later use, usually by @dfn{yanking} (re-inserting)
-it back into the line.
-(`Cut' and `paste' are more recent jargon for `kill' and `yank'.)
-
-If the description for a command says that it `kills' text, then you can
-be sure that you can get the text back in a different (or the same)
-place later.
-
-When you use a kill command, the text is saved in a @dfn{kill-ring}.
-Any number of consecutive kills save all of the killed text together, so
-that when you yank it back, you get it all.  The kill
-ring is not line specific; the text that you killed on a previously
-typed line is available to be yanked back later, when you are typing
-another line.
-@cindex kill ring
-
-Here is the list of commands for killing text.
-
-@table @kbd
-@item C-k
-Kill the text from the current cursor position to the end of the line.
-
-@item M-d
-Kill from the cursor 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 @kbd{M-f}.
-
-@item M-@key{DEL}
-Kill from the cursor the start of the current word, or, if between
-words, to the start of the previous word.
-Word boundaries are the same as those used by @kbd{M-b}.
-
-@item C-w
-Kill from the cursor to the previous whitespace.  This is different than
-@kbd{M-@key{DEL}} because the word boundaries differ.
-
-@end table
-
-Here is how to @dfn{yank} the text back into the line.  Yanking
-means to copy the most-recently-killed text from the kill buffer.
-
-@table @kbd
-@item C-y
-Yank the most recently killed text back into the buffer at the cursor.
-
-@item M-y
-Rotate the kill-ring, and yank the new top.  You can only do this if
-the prior command is @kbd{C-y} or @kbd{M-y}.
-@end table
-
-@node Readline Arguments
-@subsection Readline Arguments
-
-You can pass numeric arguments to Readline commands.  Sometimes the
-argument acts as a repeat count, other times it is the @i{sign} of the
-argument that is significant.  If you pass a negative argument to a
-command which normally acts in a forward direction, that command will
-act in a backward direction.  For example, to kill text back to the
-start of the line, you might type @samp{M-- C-k}.
-
-The general way to pass numeric arguments to a command is to type meta
-digits before the command.  If the first `digit' typed is a minus
-sign (@samp{-}), then the sign of the argument will be negative.  Once
-you have typed one meta digit to get the argument started, you can type
-the remainder of the digits, and then the command.  For example, to give
-the @kbd{C-d} command an argument of 10, you could type @samp{M-1 0 C-d},
-which will delete the next ten characters on the input line.
-
-@node Searching
-@subsection Searching for Commands in the History
-
-Readline provides commands for searching through the command history
-@ifset BashFeatures
-(@pxref{Bash History Facilities})
-@end ifset
-for lines containing a specified string.
-There are two search modes:  @dfn{incremental} and @dfn{non-incremental}.
-
-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.
-To search backward in the history for a particular string, type
-@kbd{C-r}.  Typing @kbd{C-s} searches forward through the history.
-The characters present in the value of the @code{isearch-terminators} variable
-are used to terminate an incremental search.
-If that variable has not been assigned a value, the @key{ESC} and
-@kbd{C-J} characters will terminate an incremental search.
-@kbd{C-g} will abort an incremental search and restore the original line.
-When the search is terminated, the history entry containing the
-search string becomes the current line.
-
-To find other matching entries in the history list, type @kbd{C-r} or
-@kbd{C-s} 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 @key{RET} will terminate the search and accept
-the line, thereby executing the command from the history list.
-A movement command will terminate the search, make the last line found
-the current line, and begin editing.
-
-Readline remembers the last incremental search string.  If two
-@kbd{C-r}s are typed without any intervening characters defining a new
-search string, any remembered search string is used.
-
-Non-incremental searches read the entire search string before starting
-to search for matching history lines.  The search string may be
-typed by the user or be part of the contents of the current line.
-
-@node Readline Init File
-@section Readline Init File
-@cindex initialization file, readline
-
-Although the Readline library comes with a set of Emacs-like
-keybindings installed by default, it is possible to use a different set
-of keybindings.
-Any user can customize programs that use Readline by putting
-commands in an @dfn{inputrc} file, conventionally in his home directory.
-The name of this
-@ifset BashFeatures
-file is taken from the value of the shell variable @env{INPUTRC}.  If
-@end ifset
-@ifclear BashFeatures
-file is taken from the value of the environment variable @env{INPUTRC}.  If
-@end ifclear
-that variable is unset, the default is @file{~/.inputrc}.  If that
-file does not exist or cannot be read, the ultimate default is
-@file{/etc/inputrc}.
-
-When a program which uses the Readline library starts up, the
-init file is read, and the key bindings are set.
-
-In addition, the @code{C-x C-r} command re-reads this init file, thus
-incorporating any changes that you might have made to it.
-
-@menu
-* Readline Init File Syntax::  Syntax for the commands in the inputrc file.
-
-* Conditional Init Constructs::        Conditional key bindings in the inputrc file.
-
-* Sample Init File::           An example inputrc file.
-@end menu
-
-@node Readline Init File Syntax
-@subsection Readline Init File Syntax
-
-There are only a few basic constructs allowed in the
-Readline init file.  Blank lines are ignored.
-Lines beginning with a @samp{#} are comments.
-Lines beginning with a @samp{$} indicate conditional
-constructs (@pxref{Conditional Init Constructs}).  Other lines
-denote variable settings and key bindings.
-
-@table @asis
-@item Variable Settings
-You can modify the run-time behavior of Readline by
-altering the values of variables in Readline
-using the @code{set} command within the init file.
-The syntax is simple:
-
-@example
-set @var{variable} @var{value}
-@end example
-
-@noindent
-Here, for example, is how to
-change from the default Emacs-like key binding to use
-@code{vi} line editing commands:
-
-@example
-set editing-mode vi
-@end example
-
-Variable names and values, where appropriate, are recognized without regard
-to case.  Unrecognized variable names are ignored.
-
-Boolean variables (those that can be set to on or off) are set to on if
-the value is null or empty, @var{on} (case-insensitive), or 1.  Any other
-value results in the variable being set to off.
-
-@ifset BashFeatures
-The @w{@code{bind -V}} command lists the current Readline variable names
-and values.  @xref{Bash Builtins}.
-@end ifset
-
-A great deal of run-time behavior is changeable with the following
-variables.
-
-@cindex variables, readline
-@table @code
-
-@item bell-style
-@vindex bell-style
-Controls what happens when Readline wants to ring the terminal bell.
-If set to @samp{none}, Readline never rings the bell.  If set to
-@samp{visible}, Readline uses a visible bell if one is available.
-If set to @samp{audible} (the default), Readline attempts to ring
-the terminal's bell.
-
-@item bind-tty-special-chars
-@vindex bind-tty-special-chars
-If set to @samp{on}, Readline attempts to bind the control characters  
-treated specially by the kernel's terminal driver to their Readline
-equivalents.
-
-@item comment-begin
-@vindex comment-begin
-The string to insert at the beginning of the line when the
-@code{insert-comment} command is executed.  The default value
-is @code{"#"}.
-
-@item completion-ignore-case
-If set to @samp{on}, Readline performs filename matching and completion
-in a case-insensitive fashion.
-The default value is @samp{off}.
-
-@item completion-prefix-display-length
-@vindex completion-prefix-display-length
-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.
-
-@item completion-query-items
-@vindex completion-query-items
-The number of possible completions that determines when the user is
-asked whether the list of possibilities should be displayed.
-If the number of possible completions is greater than this value,
-Readline will ask the user whether or not he wishes to view
-them; otherwise, they are simply listed.
-This variable must be set to an integer value greater than or equal to 0.
-A negative value means Readline should never ask.
-The default limit is @code{100}.
-
-@item convert-meta
-@vindex convert-meta
-If set to @samp{on}, Readline will convert characters with the
-eighth bit set to an @sc{ascii} key sequence by stripping the eighth
-bit and prefixing an @key{ESC} character, converting them to a
-meta-prefixed key sequence.  The default value is @samp{on}.
-
-@item disable-completion
-@vindex disable-completion
-If set to @samp{On}, Readline will inhibit word completion.
-Completion  characters will be inserted into the line as if they had
-been mapped to @code{self-insert}.  The default is @samp{off}.
-
-@item editing-mode
-@vindex editing-mode
-The @code{editing-mode} variable controls which default set of
-key bindings is used.  By default, Readline starts up in Emacs editing
-mode, where the keystrokes are most similar to Emacs.  This variable can be
-set to either @samp{emacs} or @samp{vi}.
-
-@item echo-control-characters
-When set to @samp{on}, on operating systems that indicate they support it,
-readline echoes a character corresponding to a signal generated from the
-keyboard.  The default is @samp{on}.
-
-@item enable-keypad
-@vindex enable-keypad
-When set to @samp{on}, Readline will try to enable the application
-keypad when it is called.  Some systems need this to enable the
-arrow keys.  The default is @samp{off}.
-
-@item expand-tilde
-@vindex expand-tilde
-If set to @samp{on}, tilde expansion is performed when Readline
-attempts word completion.  The default is @samp{off}.
-
-@item history-preserve-point
-@vindex history-preserve-point
-If set to @samp{on}, the history code attempts to place the point (the
-current cursor position) at the
-same location on each history line retrieved with @code{previous-history}
-or @code{next-history}.  The default is @samp{off}.
-
-@item history-size
-@vindex history-size
-Set the maximum number of history entries saved in the history list.  If
-set to zero, the number of entries in the history list is not limited.
-
-@item horizontal-scroll-mode
-@vindex horizontal-scroll-mode
-This variable can be set to either @samp{on} or @samp{off}.  Setting it
-to @samp{on} means that the text of the lines being edited will scroll
-horizontally on a single screen line when they are longer than the width
-of the screen, instead of wrapping onto a new screen line.  By default,
-this variable is set to @samp{off}.
-
-@item input-meta
-@vindex input-meta
-@vindex meta-flag
-If set to @samp{on}, Readline will enable eight-bit input (it
-will not clear the eighth bit in the characters it reads),
-regardless of what the terminal claims it can support.  The
-default value is @samp{off}.  The name @code{meta-flag} is a
-synonym for this variable.
-
-@item isearch-terminators
-@vindex isearch-terminators
-The string of characters that should terminate an incremental search without
-subsequently executing the character as a command (@pxref{Searching}).
-If this variable has not been given a value, the characters @key{ESC} and
-@kbd{C-J} will terminate an incremental search.
-
-@item keymap
-@vindex keymap
-Sets Readline's idea of the current keymap for key binding commands.
-Acceptable @code{keymap} names are
-@code{emacs},
-@code{emacs-standard},
-@code{emacs-meta},
-@code{emacs-ctlx},
-@code{vi},
-@code{vi-move},
-@code{vi-command}, and
-@code{vi-insert}.
-@code{vi} is equivalent to @code{vi-command}; @code{emacs} is
-equivalent to @code{emacs-standard}.  The default value is @code{emacs}.
-The value of the @code{editing-mode} variable also affects the
-default keymap.
-
-@item mark-directories
-If set to @samp{on}, completed directory names have a slash
-appended.  The default is @samp{on}.
-
-@item mark-modified-lines
-@vindex mark-modified-lines
-This variable, when set to @samp{on}, causes Readline to display an
-asterisk (@samp{*}) at the start of history lines which have been modified.
-This variable is @samp{off} by default.
-
-@item mark-symlinked-directories
-@vindex mark-symlinked-directories
-If set to @samp{on}, completed names which are symbolic links
-to directories have a slash appended (subject to the value of
-@code{mark-directories}).
-The default is @samp{off}.
-
-@item match-hidden-files
-@vindex match-hidden-files
-This variable, when set to @samp{on}, causes Readline to match files whose
-names begin with a @samp{.} (hidden files) when performing filename
-completion, unless the leading @samp{.} is
-supplied by the user in the filename to be completed.
-This variable is @samp{on} by default.
-
-@item output-meta
-@vindex output-meta
-If set to @samp{on}, Readline will display characters with the
-eighth bit set directly rather than as a meta-prefixed escape
-sequence.  The default is @samp{off}.
-
-@item page-completions
-@vindex page-completions
-If set to @samp{on}, Readline uses an internal @code{more}-like pager
-to display a screenful of possible completions at a time.
-This variable is @samp{on} by default.
-
-@item print-completions-horizontally
-If set to @samp{on}, Readline will display completions with matches
-sorted horizontally in alphabetical order, rather than down the screen.
-The default is @samp{off}.
-
-@item revert-all-at-newline
-@vindex revert-all-at-newline
-If set to @samp{on}, Readline will undo all changes to history lines
-before returning when @code{accept-line} is executed.  By default,
-history lines may be modified and retain individual undo lists across
-calls to @code{readline}.  The default is @samp{off}.
-
-@item show-all-if-ambiguous
-@vindex show-all-if-ambiguous
-This alters the default behavior of the completion functions.  If
-set to @samp{on}, 
-words which have more than one possible completion cause the
-matches to be listed immediately instead of ringing the bell.
-The default value is @samp{off}.
-
-@item show-all-if-unmodified
-@vindex show-all-if-unmodified
-This alters the default behavior of the completion functions in
-a fashion similar to @var{show-all-if-ambiguous}.
-If set to @samp{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.
-The default value is @samp{off}.
-
-@item skip-completed-text
-@vindex skip-completed-text
-If set to @samp{on}, 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.
-For instance, if this is enabled, attempting completion when the cursor
-is after the @samp{e} in @samp{Makefile} will result in @samp{Makefile}
-rather than @samp{Makefilefile}, assuming there is a single possible
-completion.
-The default value is @samp{off}.
-
-@item visible-stats
-@vindex visible-stats
-If set to @samp{on}, a character denoting a file's type
-is appended to the filename when listing possible
-completions.  The default is @samp{off}.
-
-@end table
-
-@item Key Bindings
-The syntax for controlling key bindings in the init file is
-simple.  First you need to find the name of the command that you
-want to change.  The following sections contain tables of the command
-name, the default keybinding, if any, and a short description of what
-the command does.
-
-Once you know the name of the command, simply place on a line
-in the init file the name of the key
-you wish to bind the command to, a colon, and then the name of the
-command.
-There can be no space between the key name and the colon -- that will be
-interpreted as part of the key name.
-The name of the key can be expressed in different ways, depending on
-what you find most comfortable.
-
-In addition to command names, readline allows keys to be bound
-to a string that is inserted when the key is pressed (a @var{macro}).
-
-@ifset BashFeatures
-The @w{@code{bind -p}} command displays Readline function names and
-bindings in a format that can put directly into an initialization file.
-@xref{Bash Builtins}.
-@end ifset
-
-@table @asis
-@item @w{@var{keyname}: @var{function-name} or @var{macro}}
-@var{keyname} is the name of a key spelled out in English.  For example:
-@example
-Control-u: universal-argument
-Meta-Rubout: backward-kill-word
-Control-o: "> output"
-@end example
-
-In the above example, @kbd{C-u} is bound to the function
-@code{universal-argument},
-@kbd{M-DEL} is bound to the function @code{backward-kill-word}, and
-@kbd{C-o} is bound to run the macro
-expressed on the right hand side (that is, to insert the text
-@samp{> output} into the line).
-
-A number of symbolic character names are recognized while
-processing this key binding syntax:
-@var{DEL},
-@var{ESC},
-@var{ESCAPE},
-@var{LFD},
-@var{NEWLINE},
-@var{RET},
-@var{RETURN},
-@var{RUBOUT},
-@var{SPACE},
-@var{SPC},
-and
-@var{TAB}.
-
-@item @w{"@var{keyseq}": @var{function-name} or @var{macro}}
-@var{keyseq} differs from @var{keyname} above in that strings
-denoting an entire key sequence can be specified, by placing
-the key sequence in double quotes.  Some @sc{gnu} Emacs style key
-escapes can be used, as in the following example, but the
-special character names are not recognized.
-
-@example
-"\C-u": universal-argument
-"\C-x\C-r": re-read-init-file
-"\e[11~": "Function Key 1"
-@end example
-
-In the above example, @kbd{C-u} is again bound to the function
-@code{universal-argument} (just as it was in the first example),
-@samp{@kbd{C-x} @kbd{C-r}} is bound to the function @code{re-read-init-file},
-and @samp{@key{ESC} @key{[} @key{1} @key{1} @key{~}} is bound to insert
-the text @samp{Function Key 1}.
-
-@end table
-
-The following @sc{gnu} Emacs style escape sequences are available when
-specifying key sequences:
-
-@table @code
-@item @kbd{\C-}
-control prefix
-@item @kbd{\M-}
-meta prefix
-@item @kbd{\e}
-an escape character
-@item @kbd{\\}
-backslash
-@item @kbd{\"}
-@key{"}, a double quotation mark
-@item @kbd{\'}
-@key{'}, a single quote or apostrophe
-@end table
-
-In addition to the @sc{gnu} Emacs style escape sequences, a second
-set of backslash escapes is available:
-
-@table @code
-@item \a
-alert (bell)
-@item \b
-backspace
-@item \d
-delete
-@item \f
-form feed
-@item \n
-newline
-@item \r
-carriage return
-@item \t
-horizontal tab
-@item \v
-vertical tab
-@item \@var{nnn}
-the eight-bit character whose value is the octal value @var{nnn}
-(one to three digits)
-@item \x@var{HH}
-the eight-bit character whose value is the hexadecimal value @var{HH}
-(one or two hex digits)
-@end table
-
-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 @samp{"} and @samp{'}.
-For example, the following binding will make @samp{@kbd{C-x} \}
-insert a single @samp{\} into the line:
-@example
-"\C-x\\": "\\"
-@end example
-
-@end table
-
-@node Conditional Init Constructs
-@subsection Conditional Init Constructs
-
-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.
-
-@table @code
-@item $if
-The @code{$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.
-
-@table @code
-@item mode
-The @code{mode=} form of the @code{$if} directive is used to test
-whether Readline is in @code{emacs} or @code{vi} mode.
-This may be used in conjunction
-with the @samp{set keymap} command, for instance, to set bindings in
-the @code{emacs-standard} and @code{emacs-ctlx} keymaps only if
-Readline is starting out in @code{emacs} mode.
-
-@item term
-The @code{term=} 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
-@samp{=} is tested against both the full name of the terminal and
-the portion of the terminal name before the first @samp{-}.  This
-allows @code{sun} to match both @code{sun} and @code{sun-cmd},
-for instance.
-
-@item application
-The @var{application} construct is used to include
-application-specific settings.  Each program using the Readline
-library sets the @var{application name}, and you 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 Bash:
-@example
-$if Bash
-# Quote the current or previous word
-"\C-xq": "\eb\"\ef\""
-$endif
-@end example
-@end table
-
-@item $endif
-This command, as seen in the previous example, terminates an
-@code{$if} command.
-
-@item $else
-Commands in this branch of the @code{$if} directive are executed if
-the test fails.
-
-@item $include
-This directive takes a single filename as an argument and reads commands
-and bindings from that file.
-For example, the following directive reads from @file{/etc/inputrc}:
-@example
-$include /etc/inputrc
-@end example
-@end table
-
-@node Sample Init File
-@subsection Sample Init File
-
-Here is an example of an @var{inputrc} file.  This illustrates key
-binding, variable assignment, and conditional syntax.
-
-@example
-@page
-# This file controls the behaviour of line input editing for
-# programs that use the GNU Readline library.  Existing
-# programs include FTP, Bash, and GDB.
-#
-# You can re-read the inputrc file with C-x C-r.
-# Lines beginning with '#' are comments.
-#
-# First, include any systemwide bindings and variable
-# assignments from /etc/Inputrc
-$include /etc/Inputrc
-
-#
-# Set various bindings for emacs mode.
-
-set editing-mode emacs 
-
-$if mode=emacs
-
-Meta-Control-h:        backward-kill-word      Text after the function name is ignored
-
-#
-# Arrow keys in keypad mode
-#
-#"\M-OD":        backward-char
-#"\M-OC":        forward-char
-#"\M-OA":        previous-history
-#"\M-OB":        next-history
-#
-# Arrow keys in ANSI mode
-#
-"\M-[D":        backward-char
-"\M-[C":        forward-char
-"\M-[A":        previous-history
-"\M-[B":        next-history
-#
-# Arrow keys in 8 bit keypad mode
-#
-#"\M-\C-OD":       backward-char
-#"\M-\C-OC":       forward-char
-#"\M-\C-OA":       previous-history
-#"\M-\C-OB":       next-history
-#
-# Arrow keys in 8 bit ANSI mode
-#
-#"\M-\C-[D":       backward-char
-#"\M-\C-[C":       forward-char
-#"\M-\C-[A":       previous-history
-#"\M-\C-[B":       next-history
-
-C-q: quoted-insert
-
-$endif
-
-# An old-style binding.  This happens to be the default.
-TAB: complete
-
-# Macros that are convenient for shell interaction
-$if Bash
-# edit the path
-"\C-xp": "PATH=$@{PATH@}\e\C-e\C-a\ef\C-f"
-# prepare to type a quoted word --
-# insert open and close double quotes
-# and move to just after the open quote
-"\C-x\"": "\"\"\C-b"
-# insert a backslash (testing backslash escapes
-# in sequences and macros)
-"\C-x\\": "\\"
-# Quote the current or previous word
-"\C-xq": "\eb\"\ef\""
-# Add a binding to refresh the line, which is unbound
-"\C-xr": redraw-current-line
-# Edit variable on current line.
-"\M-\C-v": "\C-a\C-k$\C-y\M-\C-e\C-a\C-y="
-$endif
-
-# use a visible bell if one is available
-set bell-style visible
-
-# don't strip characters to 7 bits when reading
-set input-meta on
-
-# allow iso-latin1 characters to be inserted rather
-# than converted to prefix-meta sequences
-set convert-meta off
-
-# display characters with the eighth bit set directly
-# rather than as meta-prefixed characters
-set output-meta on
-
-# if there are more than 150 possible completions for
-# a word, ask the user if he wants to see all of them
-set completion-query-items 150
-
-# For FTP
-$if Ftp
-"\C-xg": "get \M-?"
-"\C-xt": "put \M-?"
-"\M-.": yank-last-arg
-$endif
-@end example
-
-@node Bindable Readline Commands
-@section Bindable Readline Commands
-
-@menu
-* Commands For Moving::                Moving about the line.
-* Commands For History::       Getting at previous lines.
-* Commands For Text::          Commands for changing text.
-* Commands For Killing::       Commands for killing and yanking.
-* Numeric Arguments::          Specifying numeric arguments, repeat counts.
-* Commands For Completion::    Getting Readline to do the typing for you.
-* Keyboard Macros::            Saving and re-executing typed characters
-* Miscellaneous Commands::     Other miscellaneous commands.
-@end menu
-
-This section describes Readline commands that may be bound to key
-sequences.
-@ifset BashFeatures
-You can list your key bindings by executing
-@w{@code{bind -P}} or, for a more terse format, suitable for an
-@var{inputrc} file, @w{@code{bind -p}}.  (@xref{Bash Builtins}.)
-@end ifset
-Command names without an accompanying key sequence are unbound by default.
-
-In the following descriptions, @dfn{point} refers to the current cursor
-position, and @dfn{mark} refers to a cursor position saved by the
-@code{set-mark} command.
-The text between the point and mark is referred to as the @dfn{region}.
-
-@node Commands For Moving
-@subsection Commands For Moving
-@ftable @code
-@item beginning-of-line (C-a)
-Move to the start of the current line.
-
-@item end-of-line (C-e)
-Move to the end of the line.
-
-@item forward-char (C-f)
-Move forward a character.
-
-@item backward-char (C-b)
-Move back a character.
-
-@item forward-word (M-f)
-Move forward to the end of the next word.
-Words are composed of letters and digits.
-
-@item backward-word (M-b)
-Move back to the start of the current or previous word.
-Words are composed of letters and digits.
-
-@ifset BashFeatures
-@item shell-forward-word ()
-Move forward to the end of the next word.
-Words are delimited by non-quoted shell metacharacters.
-
-@item shell-backward-word ()
-Move back to the start of the current or previous word.
-Words are delimited by non-quoted shell metacharacters.
-@end ifset
-
-@item clear-screen (C-l)
-Clear the screen and redraw the current line,
-leaving the current line at the top of the screen.
-
-@item redraw-current-line ()
-Refresh the current line.  By default, this is unbound.
-
-@end ftable
-
-@node Commands For History
-@subsection Commands For Manipulating The History
-
-@ftable @code
-@item accept-line (Newline or Return)
-@ifset BashFeatures
-Accept the line regardless of where the cursor is.
-If this line is
-non-empty, add it to the history list according to the setting of
-the @env{HISTCONTROL} and @env{HISTIGNORE} variables.
-If this line is a modified history line, then restore the history line
-to its original state.
-@end ifset
-@ifclear BashFeatures
-Accept the line regardless of where the cursor is.
-If this line is
-non-empty, it may be added to the history list for future recall with
-@code{add_history()}.
-If this line is a modified history line, the history line is restored
-to its original state.
-@end ifclear
-
-@item previous-history (C-p)
-Move `back' through the history list, fetching the previous command.
-
-@item next-history (C-n)
-Move `forward' through the history list, fetching the next command.
-
-@item beginning-of-history (M-<)
-Move to the first line in the history.
-
-@item end-of-history (M->)
-Move to the end of the input history, i.e., the line currently
-being entered.
-
-@item 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.
-
-@item forward-search-history (C-s)
-Search forward starting at the current line and moving `down' through
-the the history as necessary.  This is an incremental search.
-
-@item non-incremental-reverse-search-history (M-p)
-Search backward starting at the current line and moving `up'
-through the history as necessary using a non-incremental search
-for a string supplied by the user.
-
-@item non-incremental-forward-search-history (M-n)
-Search forward starting at the current line and moving `down'
-through the the history as necessary using a non-incremental search
-for a string supplied by the user.
-
-@item 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.
-By default, this command is unbound.
-
-@item 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.  By default, this command is unbound.
-
-@item 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 @var{n},
-insert the @var{n}th word from the previous command (the words
-in the previous command begin with word 0).  A negative argument
-inserts the @var{n}th word from the end of the previous command.
-Once the argument @var{n} is computed, the argument is extracted
-as if the @samp{!@var{n}} history expansion had been specified.
-
-@item yank-last-arg (M-. or M-_)
-Insert last argument to the previous command (the last word of the
-previous history entry).  With an
-argument, behave exactly like @code{yank-nth-arg}.
-Successive calls to @code{yank-last-arg} move back through the history
-list, inserting the last argument of each line in turn.
-The history expansion facilities are used to extract the last argument,
-as if the @samp{!$} history expansion had been specified.
-
-@end ftable
-
-@node Commands For Text
-@subsection Commands For Changing Text
-
-@ftable @code
-@item 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 @code{delete-char}, then
-return @sc{eof}.
-
-@item backward-delete-char (Rubout)
-Delete the character behind the cursor.  A numeric argument means
-to kill the characters instead of deleting them.
-
-@item 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.  By default, this is not bound to a key.
-
-@item quoted-insert (C-q or C-v)
-Add the next character typed to the line verbatim.  This is
-how to insert key sequences like @kbd{C-q}, for example.
-
-@ifclear BashFeatures
-@item tab-insert (M-@key{TAB})
-Insert a tab character.
-@end ifclear
-
-@item self-insert (a, b, A, 1, !, @dots{})
-Insert yourself.
-
-@item transpose-chars (C-t)
-Drag the character before the cursor forward over
-the character at the cursor, moving the
-cursor forward as well.  If the insertion point
-is at the end of the line, then this
-transposes the last two characters of the line.
-Negative arguments have no effect.
-
-@item transpose-words (M-t)
-Drag the word before point past the word after point,
-moving point past that word as well.
-If the insertion point is at the end of the line, this transposes
-the last two words on the line.
-
-@item upcase-word (M-u)
-Uppercase the current (or following) word.  With a negative argument,
-uppercase the previous word, but do not move the cursor.
-
-@item downcase-word (M-l)
-Lowercase the current (or following) word.  With a negative argument,
-lowercase the previous word, but do not move the cursor.
-
-@item capitalize-word (M-c)
-Capitalize the current (or following) word.  With a negative argument,
-capitalize the previous word, but do not move the cursor.
-
-@item 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
-@code{emacs} mode; @code{vi} mode does overwrite differently.
-Each call to @code{readline()} starts in insert mode.
-
-In overwrite mode, characters bound to @code{self-insert} replace
-the text at point rather than pushing the text to the right.
-Characters bound to @code{backward-delete-char} replace the character
-before point with a space.
-
-By default, this command is unbound.
-
-@end ftable
-
-@node Commands For Killing
-@subsection Killing And Yanking
-
-@ftable @code
-
-@item kill-line (C-k)
-Kill the text from point to the end of the line.
-
-@item backward-kill-line (C-x Rubout)
-Kill backward to the beginning of the line.
-
-@item unix-line-discard (C-u)
-Kill backward from the cursor to the beginning of the current line.
-
-@item kill-whole-line ()
-Kill all characters on the current line, no matter where point is.
-By default, this is unbound.
-
-@item 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 @code{forward-word}.
-
-@item backward-kill-word (M-@key{DEL})
-Kill the word behind point.
-Word boundaries are the same as @code{backward-word}.
-
-@ifset BashFeatures
-@item shell-kill-word ()
-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 @code{shell-forward-word}.
-
-@item backward-kill-word ()
-Kill the word behind point.
-Word boundaries are the same as @code{shell-backward-word}.
-@end ifset
-
-@item 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.
-
-@item 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.
-
-@item delete-horizontal-space ()
-Delete all spaces and tabs around point.  By default, this is unbound.
-
-@item kill-region ()
-Kill the text in the current region.
-By default, this command is unbound.
-
-@item copy-region-as-kill ()
-Copy the text in the region to the kill buffer, so it can be yanked
-right away.  By default, this command is unbound.
-
-@item copy-backward-word ()
-Copy the word before point to the kill buffer.
-The word boundaries are the same as @code{backward-word}.
-By default, this command is unbound.
-
-@item copy-forward-word ()
-Copy the word following point to the kill buffer.
-The word boundaries are the same as @code{forward-word}.
-By default, this command is unbound.
-
-@item yank (C-y)
-Yank the top of the kill ring into the buffer at point.
-
-@item yank-pop (M-y)
-Rotate the kill-ring, and yank the new top.  You can only do this if
-the prior command is @code{yank} or @code{yank-pop}.
-@end ftable
-
-@node Numeric Arguments
-@subsection Specifying Numeric Arguments
-@ftable @code
-
-@item digit-argument (@kbd{M-0}, @kbd{M-1}, @dots{} @kbd{M--})
-Add this digit to the argument already accumulating, or start a new
-argument.  @kbd{M--} starts a negative argument.
-
-@item 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 @code{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.
-By default, this is not bound to a key.
-@end ftable
-
-@node Commands For Completion
-@subsection Letting Readline Type For You
-
-@ftable @code
-@item complete (@key{TAB})
-Attempt to perform completion on the text before point.
-The actual completion performed is application-specific.
-@ifset BashFeatures
-Bash attempts completion treating the text as a variable (if the
-text begins with @samp{$}), username (if the text begins with
-@samp{~}), hostname (if the text begins with @samp{@@}), or
-command (including aliases and functions) in turn.  If none 
-of these produces a match, filename completion is attempted.
-@end ifset
-@ifclear BashFeatures
-The default is filename completion.
-@end ifclear
-
-@item possible-completions (M-?)
-List the possible completions of the text before point.
-
-@item insert-completions (M-*)
-Insert all completions of the text before point that would have
-been generated by @code{possible-completions}.
-
-@item menu-complete ()
-Similar to @code{complete}, but replaces the word to be completed
-with a single match from the list of possible completions.
-Repeated execution of @code{menu-complete} 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 @code{bell-style})
-and the original text is restored.
-An argument of @var{n} moves @var{n} 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 @key{TAB}, but is unbound
-by default.
-
-@item menu-complete-backward ()
-Identical to @code{menu-complete}, but moves backward through the list
-of possible completions, as if @code{menu-complete} had been given a
-negative argument.
-
-@item delete-char-or-list ()
-Deletes the character under the cursor if not at the beginning or
-end of the line (like @code{delete-char}).
-If at the end of the line, behaves identically to
-@code{possible-completions}.
-This command is unbound by default.
-
-@ifset BashFeatures
-@item complete-filename (M-/)
-Attempt filename completion on the text before point.
-
-@item possible-filename-completions (C-x /)
-List the possible completions of the text before point,
-treating it as a filename.
-
-@item complete-username (M-~)
-Attempt completion on the text before point, treating
-it as a username.
-
-@item possible-username-completions (C-x ~)
-List the possible completions of the text before point,
-treating it as a username.
-
-@item complete-variable (M-$)
-Attempt completion on the text before point, treating
-it as a shell variable.
-
-@item possible-variable-completions (C-x $)
-List the possible completions of the text before point,
-treating it as a shell variable.
-
-@item complete-hostname (M-@@)
-Attempt completion on the text before point, treating
-it as a hostname.
-
-@item possible-hostname-completions (C-x @@)
-List the possible completions of the text before point,
-treating it as a hostname.
-
-@item 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.
-
-@item possible-command-completions (C-x !)
-List the possible completions of the text before point,
-treating it as a command name.
-
-@item dynamic-complete-history (M-@key{TAB})
-Attempt completion on the text before point, comparing
-the text against lines from the history list for possible
-completion matches.
-
-@item dabbrev-expand ()
-Attempt menu completion on the text before point, comparing
-the text against lines from the history list for possible
-completion matches.
-
-@item 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
-(@pxref{Brace Expansion}).
-
-@end ifset
-@end ftable
-
-@node Keyboard Macros
-@subsection Keyboard Macros
-@ftable @code
-
-@item start-kbd-macro (C-x ()
-Begin saving the characters typed into the current keyboard macro.
-
-@item end-kbd-macro (C-x ))
-Stop saving the characters typed into the current keyboard macro
-and save the definition.
-
-@item 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.
-
-@end ftable
-
-@node Miscellaneous Commands
-@subsection Some Miscellaneous Commands
-@ftable @code
-
-@item re-read-init-file (C-x C-r)
-Read in the contents of the @var{inputrc} file, and incorporate
-any bindings or variable assignments found there.
-
-@item abort (C-g)
-Abort the current editing command and
-ring the terminal's bell (subject to the setting of
-@code{bell-style}).
-
-@item do-uppercase-version (M-a, M-b, M-@var{x}, @dots{})
-If the metafied character @var{x} is lowercase, run the command
-that is bound to the corresponding uppercase character.
-
-@item prefix-meta (@key{ESC})
-Metafy the next character typed.  This is for keyboards
-without a meta key.  Typing @samp{@key{ESC} f} is equivalent to typing
-@kbd{M-f}.
-
-@item undo (C-_ or C-x C-u)
-Incremental undo, separately remembered for each line.
-
-@item revert-line (M-r)
-Undo all changes made to this line.  This is like executing the @code{undo}
-command enough times to get back to the beginning.
-
-@ifset BashFeatures
-@item tilde-expand (M-&)
-@end ifset
-@ifclear BashFeatures
-@item tilde-expand (M-~)
-@end ifclear
-Perform tilde expansion on the current word.
-
-@item set-mark (C-@@)
-Set the mark to the point.  If a
-numeric argument is supplied, the mark is set to that position.
-
-@item 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.
-
-@item 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.
-
-@item 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.
-
-@item 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-[.
-
-@item insert-comment (M-#)
-Without a numeric argument, the value of the @code{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 @code{comment-begin}, the value is inserted, otherwise
-the characters in @code{comment-begin} are deleted from the beginning of
-the line.
-In either case, the line is accepted as if a newline had been typed.
-@ifset BashFeatures
-The default value of @code{comment-begin} 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.
-@end ifset
-
-@item 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 @var{inputrc} file.  This command is unbound by default.
-
-@item dump-variables ()
-Print all of the settable 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 @var{inputrc} file.  This command is unbound by default.
-
-@item 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 @var{inputrc} file.  This command is unbound by default.
-
-@ifset BashFeatures
-@item 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 file names for possible completions.
-
-@item glob-expand-word (C-x *)
-The word before point is treated as a pattern for pathname expansion,
-and the list of matching file names is inserted, replacing the word.
-If a numeric argument is supplied, a @samp{*} is appended before
-pathname expansion.
-
-@item glob-list-expansions (C-x g)
-The list of expansions that would have been generated by
-@code{glob-expand-word} is displayed, and the line is redrawn.
-If a numeric argument is supplied, a @samp{*} is appended before
-pathname expansion.
-
-@item display-shell-version (C-x C-v)
-Display version information about the current instance of Bash.
-
-@item 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 (@pxref{Shell Expansions}).
-
-@item history-expand-line (M-^)
-Perform history expansion on the current line.
-
-@item magic-space ()
-Perform history expansion on the current line and insert a space
-(@pxref{History Interaction}).
-
-@item alias-expand-line ()
-Perform alias expansion on the current line (@pxref{Aliases}).
-
-@item history-and-alias-expand-line ()
-Perform history and alias expansion on the current line.
-
-@item insert-last-argument (M-. or M-_)
-A synonym for @code{yank-last-arg}.
-
-@item 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.
-
-@item edit-and-execute-command (C-xC-e)
-Invoke an editor on the current command line, and execute the result as shell
-commands.
-Bash attempts to invoke
-@code{$VISUAL}, @code{$EDITOR}, and @code{emacs}
-as the editor, in that order.
-
-@end ifset
-
-@ifclear BashFeatures
-@item emacs-editing-mode (C-e)
-When in @code{vi} command mode, this causes a switch to @code{emacs}
-editing mode.
-
-@item vi-editing-mode (M-C-j)
-When in @code{emacs} editing mode, this causes a switch to @code{vi}
-editing mode.
-
-@end ifclear
-
-@end ftable
-
-@node Readline vi Mode
-@section Readline vi Mode
-
-While the Readline library does not have a full set of @code{vi}
-editing functions, it does contain enough to allow simple editing
-of the line.  The Readline @code{vi} mode behaves as specified in
-the @sc{posix} 1003.2 standard.
-
-@ifset BashFeatures
-In order to switch interactively between @code{emacs} and @code{vi}
-editing modes, use the @samp{set -o emacs} and @samp{set -o vi}
-commands (@pxref{The Set Builtin}).
-@end ifset
-@ifclear BashFeatures
-In order to switch interactively between @code{emacs} and @code{vi}
-editing modes, use the command @kbd{M-C-j} (bound to emacs-editing-mode
-when in @code{vi} mode and to vi-editing-mode in @code{emacs} mode).
-@end ifclear
-The Readline default is @code{emacs} mode.
-
-When you enter a line in @code{vi} mode, you are already placed in
-`insertion' mode, as if you had typed an @samp{i}.  Pressing @key{ESC}
-switches you into `command' mode, where you can edit the text of the
-line with the standard @code{vi} movement keys, move to previous
-history lines with @samp{k} and subsequent lines with @samp{j}, and
-so forth.
-
-@ifset BashFeatures
-@node Programmable Completion
-@section Programmable Completion
-@cindex programmable completion
-
-When word completion is attempted for an argument to a command for
-which a completion specification (a @var{compspec}) has been defined
-using the @code{complete} builtin (@pxref{Programmable Completion Builtins}),
-the programmable completion facilities are invoked. 
-
-First, the command name is identified.
-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 the empty string (completion attempted at the
-beginning of an empty line), any compspec defined with
-the @option{-E} option to @code{complete} is used.
-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 @option{-D} option to @code{complete} is used as the default.
-
-Once a compspec has been found, it is used to generate the list of
-matching words.
-If a compspec is not found, the default Bash completion
-described above (@pxref{Commands For Completion}) is performed.
-
-First, the actions specified by the compspec are used.
-Only matches which are prefixed by the word being completed are
-returned.
-When the @option{-f} or @option{-d} option is used for filename or
-directory name completion, the shell variable @env{FIGNORE} is
-used to filter the matches.
-@xref{Bash Variables}, for a description of @env{FIGNORE}.
-
-Any completions specified by a filename expansion pattern to the
-@option{-G} option are generated next.
-The words generated by the pattern need not match the word being completed.
-The @env{GLOBIGNORE} shell variable is not used to filter the matches,
-but the @env{FIGNORE} shell variable is used.
-
-Next, the string specified as the argument to the @option{-W} option
-is considered.
-The string is first split using the characters in the @env{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 (@pxref{Shell Expansions}).
-The results are split using the rules described above
-(@pxref{Word Splitting}).
-The results of the expansion are prefix-matched against the word being
-completed, and the matching words become the possible completions.
-
-After these matches have been generated, any shell function or command
-specified with the @option{-F} and @option{-C} options is invoked.
-When the command or function is invoked, the @env{COMP_LINE},
-@env{COMP_POINT}, @env{COMP_KEY}, and @env{COMP_TYPE} variables are
-assigned values as described above (@pxref{Bash Variables}).
-If a shell function is being invoked, the @env{COMP_WORDS} and
-@env{COMP_CWORD} variables are also set.
-When the function or command is invoked, the first argument is the
-name of the command whose arguments are being completed, the
-second argument is the word being completed, and the third argument
-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.
-
-Any function specified with @option{-F} is invoked first.
-The function may use any of the shell facilities, including the
-@code{compgen} and @code{compopt} builtins described below
-(@pxref{Programmable Completion Builtins}), to generate the matches.
-It must put the possible completions in the @env{COMPREPLY} array
-variable.
-
-Next, any command specified with the @option{-C} 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.
-
-After all of the possible completions are generated, any filter
-specified with the @option{-X} option is applied to the list.
-The filter is a pattern as used for pathname expansion; a @samp{&}
-in the pattern is replaced with the text of the word being completed.
-A literal @samp{&} 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 @samp{!} negates the pattern; in this case any completion
-not matching the pattern will be removed.
-
-Finally, any prefix and suffix specified with the @option{-P} and @option{-S}
-options are added to each member of the completion list, and the result is
-returned to the Readline completion code as the list of possible
-completions.
-
-If the previously-applied actions do not generate any matches, and the
-@option{-o dirnames} option was supplied to @code{complete} when the
-compspec was defined, directory name completion is attempted. 
-
-If the @option{-o plusdirs} option was supplied to @code{complete} when
-the compspec was defined, directory name completion is attempted and any
-matches are added to the results of the other actions.
-
-By default, if a compspec is found, whatever it generates is returned to
-the completion code as the full set of possible completions.
-The default Bash completions are not attempted, and the Readline default
-of filename completion is disabled.
-If the @option{-o bashdefault} option was supplied to @code{complete} when
-the compspec was defined, the default Bash completions are attempted
-if the compspec generates no matches.
-If the @option{-o default} option was supplied to @code{complete} when the
-compspec was defined, Readline's default completion will be performed
-if the compspec (and, if attempted, the default Bash completions)
-generate no matches.
-
-When a compspec indicates that directory name completion is desired,
-the programmable completion functions force Readline to append a slash
-to completed names which are symbolic links to directories, subject to
-the value of the @var{mark-directories} Readline variable, regardless
-of the setting of the @var{mark-symlinked-directories} Readline variable.
-
-There is some support for dynamically modifying completions.  This is
-most useful when used in combination with a default completion specified
-with @option{-D}.  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 compspec for that command.  This allows a set of
-completions to be built dynamically as completion is attempted, rather than
-being loaded all at once.
-
-For instance, assuming that there is a library of compspecs, each kept in a
-file corresponding to the name of the command, the following default
-completion function would load completions dynamically:
-
-@example
-_completion_loader()
-@{
-       . "/etc/bash_completion.d/$1.sh" >/dev/null 2>&1 && return 124
-@}
-complete -D -F _completion_loader
-@end example
-
-@node Programmable Completion Builtins
-@section Programmable Completion Builtins
-@cindex completion builtins
-
-Two builtin commands are available to manipulate the programmable completion
-facilities.
-
-@table @code
-@item compgen
-@btindex compgen
-@example
-@code{compgen [@var{option}] [@var{word}]}
-@end example
-
-Generate possible completion matches for @var{word} according to
-the @var{option}s, which may be any option accepted by the
-@code{complete}
-builtin with the exception of @option{-p} and @option{-r}, and write
-the matches to the standard output.
-When using the @option{-F} or @option{-C} options, the various shell variables
-set by the programmable completion facilities, while available, will not
-have useful values.
-
-The matches will be generated in the same way as if the programmable
-completion code had generated them directly from a completion specification
-with the same flags.
-If @var{word} is specified, only those completions matching @var{word}
-will be displayed.
-
-The return value is true unless an invalid option is supplied, or no
-matches were generated.
-
-@item complete
-@btindex complete
-@example
-@code{complete [-abcdefgjksuv] [-o @var{comp-option}] [-DE] [-A @var{action}] [-G @var{globpat}] [-W @var{wordlist}]
-[-F @var{function}] [-C @var{command}] [-X @var{filterpat}]
-[-P @var{prefix}] [-S @var{suffix}] @var{name} [@var{name} @dots{}]}
-@code{complete -pr [-DE] [@var{name} @dots{}]}
-@end example
-
-Specify how arguments to each @var{name} should be completed.
-If the @option{-p} 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 @option{-r} option removes a completion specification for
-each @var{name}, or, if no @var{name}s are supplied, all
-completion specifications.
-The @option{-D} 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 @option{-E} option indicates that the remaining options and actions should
-apply to ``empty'' command completion; that is, completion attempted on a 
-blank line.
-
-The process of applying these completion specifications when word completion
-is attempted is described above (@pxref{Programmable Completion}).  The
-@option{-D} option takes precedence over @option{-E}.
-
-Other options, if specified, have the following meanings.
-The arguments to the @option{-G}, @option{-W}, and @option{-X} options
-(and, if necessary, the @option{-P} and @option{-S} options)
-should be quoted to protect them from expansion before the
-@code{complete} builtin is invoked.
-
-
-@table @code
-@item -o @var{comp-option}
-The @var{comp-option} controls several aspects of the compspec's behavior
-beyond the simple generation of completions.
-@var{comp-option} may be one of: 
-
-@table @code
-
-@item bashdefault
-Perform the rest of the default Bash completions if the compspec
-generates no matches.
-
-@item default
-Use Readline's default filename completion if the compspec generates
-no matches.
-
-@item dirnames
-Perform directory name completion if the compspec generates no matches.
-
-@item 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).
-This option is intended to be used with shell functions specified
-with @option{-F}.
-
-@item nospace
-Tell Readline not to append a space (the default) to words completed at
-the end of the line.
-
-@item 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.
-
-@end table
-
-@item -A @var{action}
-The @var{action} may be one of the following to generate a list of possible
-completions:
-
-@table @code
-@item alias
-Alias names.  May also be specified as @option{-a}.
-
-@item arrayvar
-Array variable names.
-
-@item binding
-Readline key binding names (@pxref{Bindable Readline Commands}).
-
-@item builtin
-Names of shell builtin commands.  May also be specified as @option{-b}.
-
-@item command
-Command names.  May also be specified as @option{-c}.
-
-@item directory
-Directory names.  May also be specified as @option{-d}.
-
-@item disabled
-Names of disabled shell builtins.
-
-@item enabled
-Names of enabled shell builtins.
-
-@item export
-Names of exported shell variables.  May also be specified as @option{-e}.
-
-@item file
-File names.  May also be specified as @option{-f}.
-
-@item function
-Names of shell functions.
-
-@item group
-Group names.  May also be specified as @option{-g}.
-
-@item helptopic
-Help topics as accepted by the @code{help} builtin (@pxref{Bash Builtins}).
-
-@item hostname
-Hostnames, as taken from the file specified by the
-@env{HOSTFILE} shell variable (@pxref{Bash Variables}).
-
-@item job
-Job names, if job control is active.  May also be specified as @option{-j}.
-
-@item keyword
-Shell reserved words.  May also be specified as @option{-k}.
-
-@item running
-Names of running jobs, if job control is active.
-
-@item service
-Service names.  May also be specified as @option{-s}.
-
-@item setopt
-Valid arguments for the @option{-o} option to the @code{set} builtin
-(@pxref{The Set Builtin}).
-
-@item shopt
-Shell option names as accepted by the @code{shopt} builtin
-(@pxref{Bash Builtins}).
-
-@item signal
-Signal names.
-
-@item stopped
-Names of stopped jobs, if job control is active.
-
-@item user
-User names.  May also be specified as @option{-u}.
-
-@item variable
-Names of all shell variables.  May also be specified as @option{-v}.
-@end table
-
-@item -G @var{globpat}
-The filename expansion pattern @var{globpat} is expanded to generate
-the possible completions.
-
-@item -W @var{wordlist}
-The @var{wordlist} is split using the characters in the
-@env{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.
-
-@item -C @var{command}
-@var{command} is executed in a subshell environment, and its output is
-used as the possible completions.
-
-@item -F @var{function}
-The shell function @var{function} is executed in the current shell
-environment.
-When it finishes, the possible completions are retrieved from the value
-of the @env{COMPREPLY} array variable.
-
-@item -X @var{filterpat}
-@var{filterpat} is a pattern as used for filename expansion.
-It is applied to the list of possible completions generated by the
-preceding options and arguments, and each completion matching
-@var{filterpat} is removed from the list.
-A leading @samp{!} in @var{filterpat} negates the pattern; in this
-case, any completion not matching @var{filterpat} is removed.
-
-@item -P @var{prefix}
-@var{prefix} is added at the beginning of each possible completion
-after all other options have been applied.
-
-@item -S @var{suffix}
-@var{suffix} is appended to each possible completion
-after all other options have been applied.
-@end table
-
-The return value is true unless an invalid option is supplied, an option
-other than @option{-p} or @option{-r} is supplied without a @var{name}
-argument, an attempt is made to remove a completion specification for
-a @var{name} for which no specification exists, or
-an error occurs adding a completion specification.
-
-@item compopt
-@btindex compopt
-@example
-@code{compopt} [-o @var{option}] [-DE] [+o @var{option}] [@var{name}]
-@end example
-Modify completion options for each @var{name} according to the
-@var{option}s, or for the currently-execution completion if no @var{name}s
-are supplied.
-If no @var{option}s are given, display the completion options for each
-@var{name} or the current completion.
-The possible values of @var{option} are those valid for the @code{complete}
-builtin described above.
-The @option{-D} 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 @option{-E} option indicates that the remaining options should
-apply to ``empty'' command completion; that is, completion attempted on a 
-blank line.
-
-The @option{-D} option takes precedence over @option{-E}.
-
-The return value is true unless an invalid option is supplied, an attempt
-is made to modify the options for a @var{name} for which no completion
-specification exists, or an output error occurs.
-
-@end table
-
-@end ifset
diff --git a/lib/readline/doc/version.texi~ b/lib/readline/doc/version.texi~
deleted file mode 100644 (file)
index d8474ad..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-@ignore
-Copyright (C) 1988-2009 Free Software Foundation, Inc. 
-@end ignore
-
-@set EDITION 6.0
-@set VERSION 6.0
-@set UPDATED 31 August 2009
-@set UPDATED-MONTH August 2009
-
-@set LASTCHANGE Mon Aug 31 09:01:30 EDT 2009
diff --git a/lib/readline/funmap.c~ b/lib/readline/funmap.c~
deleted file mode 100644 (file)
index 314ecf8..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-/* funmap.c -- attach names to functions. */
-
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
-
-   This file is part of the GNU Readline Library (Readline), a library
-   for reading lines of text with interactive input and history editing.      
-
-   Readline is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   Readline is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#define READLINE_LIBRARY
-
-#if defined (HAVE_CONFIG_H)
-#  include <config.h>
-#endif
-
-#if !defined (BUFSIZ)
-#include <stdio.h>
-#endif /* BUFSIZ */
-
-#if defined (HAVE_STDLIB_H)
-#  include <stdlib.h>
-#else
-#  include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#include "rlconf.h"
-#include "readline.h"
-
-#include "xmalloc.h"
-
-#ifdef __STDC__
-typedef int QSFUNC (const void *, const void *);
-#else
-typedef int QSFUNC ();
-#endif
-
-extern int _rl_qsort_string_compare PARAMS((char **, char **));
-
-FUNMAP **funmap;
-static int funmap_size;
-static int funmap_entry;
-
-/* After initializing the function map, this is the index of the first
-   program specific function. */
-int funmap_program_specific_entry_start;
-
-static const FUNMAP default_funmap[] = {
-  { "abort", rl_abort },
-  { "accept-line", rl_newline },
-  { "arrow-key-prefix", rl_arrow_keys },
-  { "backward-byte", rl_backward_byte },
-  { "backward-char", rl_backward_char },
-  { "backward-delete-char", rl_rubout },
-  { "backward-kill-line", rl_backward_kill_line },
-  { "backward-kill-word", rl_backward_kill_word },
-  { "backward-word", rl_backward_word },
-  { "beginning-of-history", rl_beginning_of_history },
-  { "beginning-of-line", rl_beg_of_line },
-  { "call-last-kbd-macro", rl_call_last_kbd_macro },
-  { "capitalize-word", rl_capitalize_word },
-  { "character-search", rl_char_search },
-  { "character-search-backward", rl_backward_char_search },
-  { "clear-screen", rl_clear_screen },
-  { "complete", rl_complete },
-  { "copy-backward-word", rl_copy_backward_word },
-  { "copy-forward-word", rl_copy_forward_word },
-  { "copy-region-as-kill", rl_copy_region_to_kill },
-  { "delete-char", rl_delete },
-  { "delete-char-or-list", rl_delete_or_show_completions },
-  { "delete-horizontal-space", rl_delete_horizontal_space },
-  { "digit-argument", rl_digit_argument },
-  { "do-lowercase-version", rl_do_lowercase_version },
-  { "downcase-word", rl_downcase_word },
-  { "dump-functions", rl_dump_functions },
-  { "dump-macros", rl_dump_macros },
-  { "dump-variables", rl_dump_variables },
-  { "emacs-editing-mode", rl_emacs_editing_mode },
-  { "end-kbd-macro", rl_end_kbd_macro },
-  { "end-of-history", rl_end_of_history },
-  { "end-of-line", rl_end_of_line },
-  { "exchange-point-and-mark", rl_exchange_point_and_mark },
-  { "forward-backward-delete-char", rl_rubout_or_delete },
-  { "forward-byte", rl_forward_byte },
-  { "forward-char", rl_forward_char },
-  { "forward-search-history", rl_forward_search_history },
-  { "forward-word", rl_forward_word },
-  { "history-search-backward", rl_history_search_backward },
-  { "history-search-forward", rl_history_search_forward },
-  { "insert-comment", rl_insert_comment },
-  { "insert-completions", rl_insert_completions },
-  { "kill-whole-line", rl_kill_full_line },
-  { "kill-line", rl_kill_line },
-  { "kill-region", rl_kill_region },
-  { "kill-word", rl_kill_word },
-  { "menu-complete", rl_menu_complete },
-  { "menu-complete-backward", rl_backward_menu_complete },
-  { "next-history", rl_get_next_history },
-  { "non-incremental-forward-search-history", rl_noninc_forward_search },
-  { "non-incremental-reverse-search-history", rl_noninc_reverse_search },
-  { "non-incremental-forward-search-history-again", rl_noninc_forward_search_again },
-  { "non-incremental-reverse-search-history-again", rl_noninc_reverse_search_again },
-  { "overwrite-mode", rl_overwrite_mode },
-#ifdef __CYGWIN__
-  { "paste-from-clipboard", rl_paste_from_clipboard },
-#endif
-  { "possible-completions", rl_possible_completions },
-  { "previous-history", rl_get_previous_history },
-  { "quoted-insert", rl_quoted_insert },
-  { "re-read-init-file", rl_re_read_init_file },
-  { "redraw-current-line", rl_refresh_line},
-  { "reverse-search-history", rl_reverse_search_history },
-  { "revert-line", rl_revert_line },
-  { "self-insert", rl_insert },
-  { "set-mark", rl_set_mark },
-  { "start-kbd-macro", rl_start_kbd_macro },
-  { "tab-insert", rl_tab_insert },
-  { "tilde-expand", rl_tilde_expand },
-  { "transpose-chars", rl_transpose_chars },
-  { "transpose-words", rl_transpose_words },
-  { "tty-status", rl_tty_status },
-  { "undo", rl_undo_command },
-  { "universal-argument", rl_universal_argument },
-  { "unix-filename-rubout", rl_unix_filename_rubout },
-  { "unix-line-discard", rl_unix_line_discard },
-  { "unix-word-rubout", rl_unix_word_rubout },
-  { "upcase-word", rl_upcase_word },
-  { "yank", rl_yank },
-  { "yank-last-arg", rl_yank_last_arg },
-  { "yank-nth-arg", rl_yank_nth_arg },
-  { "yank-pop", rl_yank_pop },
-
-#if defined (VI_MODE)
-  { "vi-append-eol", rl_vi_append_eol },
-  { "vi-append-mode", rl_vi_append_mode },
-  { "vi-arg-digit", rl_vi_arg_digit },
-  { "vi-back-to-indent", rl_vi_back_to_indent },
-  { "vi-bWord", rl_vi_bWord },
-  { "vi-bword", rl_vi_bword },
-  { "vi-change-case", rl_vi_change_case },
-  { "vi-change-char", rl_vi_change_char },
-  { "vi-change-to", rl_vi_change_to },
-  { "vi-char-search", rl_vi_char_search },
-  { "vi-column", rl_vi_column },
-  { "vi-complete", rl_vi_complete },
-  { "vi-delete", rl_vi_delete },
-  { "vi-delete-to", rl_vi_delete_to },
-  { "vi-eWord", rl_vi_eWord },
-  { "vi-editing-mode", rl_vi_editing_mode },
-  { "vi-end-word", rl_vi_end_word },
-  { "vi-eof-maybe", rl_vi_eof_maybe },
-  { "vi-eword", rl_vi_eword },
-  { "vi-fWord", rl_vi_fWord },
-  { "vi-fetch-history", rl_vi_fetch_history },
-  { "vi-first-print", rl_vi_first_print },
-  { "vi-fword", rl_vi_fword },
-  { "vi-goto-mark", rl_vi_goto_mark },
-  { "vi-insert-beg", rl_vi_insert_beg },
-  { "vi-insertion-mode", rl_vi_insertion_mode },
-  { "vi-match", rl_vi_match },
-  { "vi-movement-mode", rl_vi_movement_mode },
-  { "vi-next-word", rl_vi_next_word },
-  { "vi-overstrike", rl_vi_overstrike },
-  { "vi-overstrike-delete", rl_vi_overstrike_delete },
-  { "vi-prev-word", rl_vi_prev_word },
-  { "vi-put", rl_vi_put },
-  { "vi-redo", rl_vi_redo },
-  { "vi-replace", rl_vi_replace },
-  { "vi-rubout", rl_vi_rubout },
-  { "vi-search", rl_vi_search },
-  { "vi-search-again", rl_vi_search_again },
-  { "vi-set-mark", rl_vi_set_mark },
-  { "vi-subst", rl_vi_subst },
-  { "vi-tilde-expand", rl_vi_tilde_expand },
-  { "vi-yank-arg", rl_vi_yank_arg },
-  { "vi-yank-to", rl_vi_yank_to },
-#endif /* VI_MODE */
-
- {(char *)NULL, (rl_command_func_t *)NULL }
-};
-
-int
-rl_add_funmap_entry (name, function)
-     const char *name;
-     rl_command_func_t *function;
-{
-  if (funmap_entry + 2 >= funmap_size)
-    {
-      funmap_size += 64;
-      funmap = (FUNMAP **)xrealloc (funmap, funmap_size * sizeof (FUNMAP *));
-    }
-  
-  funmap[funmap_entry] = (FUNMAP *)xmalloc (sizeof (FUNMAP));
-  funmap[funmap_entry]->name = name;
-  funmap[funmap_entry]->function = function;
-
-  funmap[++funmap_entry] = (FUNMAP *)NULL;
-  return funmap_entry;
-}
-
-static int funmap_initialized;
-
-/* Make the funmap contain all of the default entries. */
-void
-rl_initialize_funmap ()
-{
-  register int i;
-
-  if (funmap_initialized)
-    return;
-
-  for (i = 0; default_funmap[i].name; i++)
-    rl_add_funmap_entry (default_funmap[i].name, default_funmap[i].function);
-
-  funmap_initialized = 1;
-  funmap_program_specific_entry_start = i;
-}
-
-/* Produce a NULL terminated array of known function names.  The array
-   is sorted.  The array itself is allocated, but not the strings inside.
-   You should free () the array when you done, but not the pointrs. */
-const char **
-rl_funmap_names ()
-{
-  const char **result;
-  int result_size, result_index;
-
-  /* Make sure that the function map has been initialized. */
-  rl_initialize_funmap ();
-
-  for (result_index = result_size = 0, result = (const char **)NULL; funmap[result_index]; result_index++)
-    {
-      if (result_index + 2 > result_size)
-       {
-         result_size += 20;
-         result = (const char **)xrealloc (result, result_size * sizeof (char *));
-       }
-
-      result[result_index] = funmap[result_index]->name;
-      result[result_index + 1] = (char *)NULL;
-    }
-
-  qsort (result, result_index, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
-  return (result);
-}
diff --git a/lib/readline/input.c~ b/lib/readline/input.c~
deleted file mode 100644 (file)
index 65b7726..0000000
+++ /dev/null
@@ -1,595 +0,0 @@
-/* input.c -- character input functions for readline. */
-
-/* Copyright (C) 1994-2009 Free Software Foundation, Inc.
-
-   This file is part of the GNU Readline Library (Readline), a library
-   for reading lines of text with interactive input and history editing.      
-
-   Readline is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   Readline is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#define READLINE_LIBRARY
-
-#if defined (__TANDEM)
-#  include <floss.h>
-#endif
-
-#if defined (HAVE_CONFIG_H)
-#  include <config.h>
-#endif
-
-#include <sys/types.h>
-#include <fcntl.h>
-#if defined (HAVE_SYS_FILE_H)
-#  include <sys/file.h>
-#endif /* HAVE_SYS_FILE_H */
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#if defined (HAVE_STDLIB_H)
-#  include <stdlib.h>
-#else
-#  include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#include "posixselect.h"
-
-#if defined (FIONREAD_IN_SYS_IOCTL)
-#  include <sys/ioctl.h>
-#endif
-
-#include <stdio.h>
-#include <errno.h>
-
-#if !defined (errno)
-extern int errno;
-#endif /* !errno */
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-#include "rlmbutil.h"
-
-/* Some standard library routines. */
-#include "readline.h"
-
-#include "rlprivate.h"
-#include "rlshell.h"
-#include "xmalloc.h"
-
-/* What kind of non-blocking I/O do we have? */
-#if !defined (O_NDELAY) && defined (O_NONBLOCK)
-#  define O_NDELAY O_NONBLOCK  /* Posix style */
-#endif
-
-/* Non-null means it is a pointer to a function to run while waiting for
-   character input. */
-rl_hook_func_t *rl_event_hook = (rl_hook_func_t *)NULL;
-
-rl_getc_func_t *rl_getc_function = rl_getc;
-
-static int _keyboard_input_timeout = 100000;           /* 0.1 seconds; it's in usec */
-
-static int ibuffer_space PARAMS((void));
-static int rl_get_char PARAMS((int *));
-static int rl_gather_tyi PARAMS((void));
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Character Input Buffering                   */
-/*                                                                 */
-/* **************************************************************** */
-
-static int pop_index, push_index;
-static unsigned char ibuffer[512];
-static int ibuffer_len = sizeof (ibuffer) - 1;
-
-#define any_typein (push_index != pop_index)
-
-int
-_rl_any_typein ()
-{
-  return any_typein;
-}
-
-/* Return the amount of space available in the buffer for stuffing
-   characters. */
-static int
-ibuffer_space ()
-{
-  if (pop_index > push_index)
-    return (pop_index - push_index - 1);
-  else
-    return (ibuffer_len - (push_index - pop_index));
-}
-
-/* Get a key from the buffer of characters to be read.
-   Return the key in KEY.
-   Result is KEY if there was a key, or 0 if there wasn't. */
-static int
-rl_get_char (key)
-     int *key;
-{
-  if (push_index == pop_index)
-    return (0);
-
-  *key = ibuffer[pop_index++];
-#if 0
-  if (pop_index >= ibuffer_len)
-#else
-  if (pop_index > ibuffer_len)
-#endif
-    pop_index = 0;
-
-  return (1);
-}
-
-/* Stuff KEY into the *front* of the input buffer.
-   Returns non-zero if successful, zero if there is
-   no space left in the buffer. */
-int
-_rl_unget_char (key)
-     int key;
-{
-  if (ibuffer_space ())
-    {
-      pop_index--;
-      if (pop_index < 0)
-       pop_index = ibuffer_len;
-      ibuffer[pop_index] = key;
-      return (1);
-    }
-  return (0);
-}
-
-int
-_rl_pushed_input_available ()
-{
-  return (push_index != pop_index);
-}
-
-/* If a character is available to be read, then read it and stuff it into
-   IBUFFER.  Otherwise, just return.  Returns number of characters read
-   (0 if none available) and -1 on error (EIO). */
-static int
-rl_gather_tyi ()
-{
-  int tty;
-  register int tem, result;
-  int chars_avail, k;
-  char input;
-#if defined(HAVE_SELECT)
-  fd_set readfds, exceptfds;
-  struct timeval timeout;
-#endif
-
-  chars_avail = 0;
-  tty = fileno (rl_instream);
-
-#if defined (HAVE_SELECT)
-  FD_ZERO (&readfds);
-  FD_ZERO (&exceptfds);
-  FD_SET (tty, &readfds);
-  FD_SET (tty, &exceptfds);
-  timeout.tv_sec = 0;
-  timeout.tv_usec = _keyboard_input_timeout;
-  result = select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout);
-  if (result <= 0)
-    return 0;  /* Nothing to read. */
-#endif
-
-  result = -1;
-#if defined (FIONREAD)
-  errno = 0;
-  result = ioctl (tty, FIONREAD, &chars_avail);
-  if (result == -1 && errno == EIO)
-    return -1;
-#endif
-
-#if defined (O_NDELAY)
-  if (result == -1)
-    {
-      tem = fcntl (tty, F_GETFL, 0);
-
-      fcntl (tty, F_SETFL, (tem | O_NDELAY));
-      chars_avail = read (tty, &input, 1);
-
-      fcntl (tty, F_SETFL, tem);
-      if (chars_avail == -1 && errno == EAGAIN)
-       return 0;
-      if (chars_avail == 0)    /* EOF */
-       {
-         rl_stuff_char (EOF);
-         return (0);
-       }
-    }
-#endif /* O_NDELAY */
-
-#if defined (__MINGW32__)
-  /* Use getch/_kbhit to check for available console input, in the same way
-     that we read it normally. */
-   chars_avail = isatty (tty) ? _kbhit () : 0;
-   result = 0;
-#endif
-
-  /* If there's nothing available, don't waste time trying to read
-     something. */
-  if (chars_avail <= 0)
-    return 0;
-
-  tem = ibuffer_space ();
-
-  if (chars_avail > tem)
-    chars_avail = tem;
-
-  /* One cannot read all of the available input.  I can only read a single
-     character at a time, or else programs which require input can be
-     thwarted.  If the buffer is larger than one character, I lose.
-     Damn! */
-  if (tem < ibuffer_len)
-    chars_avail = 0;
-
-  if (result != -1)
-    {
-      while (chars_avail--)
-       {
-         RL_CHECK_SIGNALS ();
-         k = (*rl_getc_function) (rl_instream);
-         if (rl_stuff_char (k) == 0)
-           break;                      /* some problem; no more room */
-         if (k == NEWLINE || k == RETURN)
-           break;
-       }
-    }
-  else
-    {
-      if (chars_avail)
-       rl_stuff_char (input);
-    }
-
-  return 1;
-}
-
-int
-rl_set_keyboard_input_timeout (u)
-     int u;
-{
-  int o;
-
-  o = _keyboard_input_timeout;
-  if (u >= 0)
-    _keyboard_input_timeout = u;
-  return (o);
-}
-
-/* Is there input available to be read on the readline input file
-   descriptor?  Only works if the system has select(2) or FIONREAD.
-   Uses the value of _keyboard_input_timeout as the timeout; if another
-   readline function wants to specify a timeout and not leave it up to
-   the user, it should use _rl_input_queued(timeout_value_in_microseconds)
-   instead. */
-int
-_rl_input_available ()
-{
-#if defined(HAVE_SELECT)
-  fd_set readfds, exceptfds;
-  struct timeval timeout;
-#endif
-#if !defined (HAVE_SELECT) && defined(FIONREAD)
-  int chars_avail;
-#endif
-  int tty;
-
-  tty = fileno (rl_instream);
-
-#if defined (HAVE_SELECT)
-  FD_ZERO (&readfds);
-  FD_ZERO (&exceptfds);
-  FD_SET (tty, &readfds);
-  FD_SET (tty, &exceptfds);
-  timeout.tv_sec = 0;
-  timeout.tv_usec = _keyboard_input_timeout;
-  return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0);
-#else
-
-#if defined (FIONREAD)
-  if (ioctl (tty, FIONREAD, &chars_avail) == 0)
-    return (chars_avail);
-#endif
-
-#endif
-
-#if defined (__MINGW32__)
-  if (isatty (tty))
-    return (_kbhit ());
-#endif
-
-  return 0;
-}
-
-int
-_rl_input_queued (t)
-     int t;
-{
-  int old_timeout, r;
-
-  old_timeout = rl_set_keyboard_input_timeout (t);
-  r = _rl_input_available ();
-  rl_set_keyboard_input_timeout (old_timeout);
-  return r;
-}
-
-void
-_rl_insert_typein (c)
-     int c;     
-{      
-  int key, t, i;
-  char *string;
-
-  i = key = 0;
-  string = (char *)xmalloc (ibuffer_len + 1);
-  string[i++] = (char) c;
-
-  while ((t = rl_get_char (&key)) &&
-        _rl_keymap[key].type == ISFUNC &&
-        _rl_keymap[key].function == rl_insert)
-    string[i++] = key;
-
-  if (t)
-    _rl_unget_char (key);
-
-  string[i] = '\0';
-  rl_insert_text (string);
-  xfree (string);
-}
-
-/* Add KEY to the buffer of characters to be read.  Returns 1 if the
-   character was stuffed correctly; 0 otherwise. */
-int
-rl_stuff_char (key)
-     int key;
-{
-  if (ibuffer_space () == 0)
-    return 0;
-
-  if (key == EOF)
-    {
-      key = NEWLINE;
-      rl_pending_input = EOF;
-      RL_SETSTATE (RL_STATE_INPUTPENDING);
-    }
-  ibuffer[push_index++] = key;
-#if 0
-  if (push_index >= ibuffer_len)
-#else
-  if (push_index > ibuffer_len)
-#endif
-    push_index = 0;
-
-  return 1;
-}
-
-/* Make C be the next command to be executed. */
-int
-rl_execute_next (c)
-     int c;
-{
-  rl_pending_input = c;
-  RL_SETSTATE (RL_STATE_INPUTPENDING);
-  return 0;
-}
-
-/* Clear any pending input pushed with rl_execute_next() */
-int
-rl_clear_pending_input ()
-{
-  rl_pending_input = 0;
-  RL_UNSETSTATE (RL_STATE_INPUTPENDING);
-  return 0;
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*                          Character Input                        */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Read a key, including pending input. */
-int
-rl_read_key ()
-{
-  int c;
-
-  rl_key_sequence_length++;
-
-  if (rl_pending_input)
-    {
-      c = rl_pending_input;
-      rl_clear_pending_input ();
-    }
-  else
-    {
-      /* If input is coming from a macro, then use that. */
-      if (c = _rl_next_macro_key ())
-       return (c);
-
-      /* If the user has an event function, then call it periodically. */
-      if (rl_event_hook)
-       {
-         while (rl_event_hook && rl_get_char (&c) == 0)
-           {
-             (*rl_event_hook) ();
-             RL_CHECK_SIGNALS ();
-             if (rl_done)              /* XXX - experimental */
-               return ('\n');
-             if (rl_gather_tyi () < 0) /* XXX - EIO */
-               {
-                 rl_done = 1;
-                 return ('\n');
-               }
-           }
-       }
-      else
-       {
-         if (rl_get_char (&c) == 0)
-           c = (*rl_getc_function) (rl_instream);
-         RL_CHECK_SIGNALS ();
-       }
-    }
-
-  return (c);
-}
-
-int
-rl_getc (stream)
-     FILE *stream;
-{
-  int result;
-  unsigned char c;
-
-  while (1)
-    {
-      RL_CHECK_SIGNALS ();
-
-#if defined (__MINGW32__)
-      if (isatty (fileno (stream)))
-       return (getch ());
-#endif
-      result = read (fileno (stream), &c, sizeof (unsigned char));
-
-      if (result == sizeof (unsigned char))
-       return (c);
-
-      /* If zero characters are returned, then the file that we are
-        reading from is empty!  Return EOF in that case. */
-      if (result == 0)
-       return (EOF);
-
-#if defined (__BEOS__)
-      if (errno == EINTR)
-       continue;
-#endif
-
-#if defined (EWOULDBLOCK)
-#  define X_EWOULDBLOCK EWOULDBLOCK
-#else
-#  define X_EWOULDBLOCK -99
-#endif
-
-#if defined (EAGAIN)
-#  define X_EAGAIN EAGAIN
-#else
-#  define X_EAGAIN -99
-#endif
-
-      if (errno == X_EWOULDBLOCK || errno == X_EAGAIN)
-       {
-         if (sh_unset_nodelay_mode (fileno (stream)) < 0)
-           return (EOF);
-         continue;
-       }
-
-#undef X_EWOULDBLOCK
-#undef X_EAGAIN
-
-      /* If the error that we received was SIGINT, then try again,
-        this is simply an interrupted system call to read ().
-        Otherwise, some error ocurred, also signifying EOF. */
-      if (errno != EINTR)
-       return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF);
-    }
-}
-
-#if defined (HANDLE_MULTIBYTE)
-/* read multibyte char */
-int
-_rl_read_mbchar (mbchar, size)
-     char *mbchar;
-     int size;
-{
-  int mb_len, c;
-  size_t mbchar_bytes_length;
-  wchar_t wc;
-  mbstate_t ps, ps_back;
-
-  memset(&ps, 0, sizeof (mbstate_t));
-  memset(&ps_back, 0, sizeof (mbstate_t));
-
-  mb_len = 0;  
-  while (mb_len < size)
-    {
-      RL_SETSTATE(RL_STATE_MOREINPUT);
-      c = rl_read_key ();
-      RL_UNSETSTATE(RL_STATE_MOREINPUT);
-
-      if (c < 0)
-       break;
-
-      mbchar[mb_len++] = c;
-
-      mbchar_bytes_length = mbrtowc (&wc, mbchar, mb_len, &ps);
-      if (mbchar_bytes_length == (size_t)(-1))
-       break;          /* invalid byte sequence for the current locale */
-      else if (mbchar_bytes_length == (size_t)(-2))
-       {
-         /* shorted bytes */
-         ps = ps_back;
-         continue;
-       } 
-      else if (mbchar_bytes_length == 0)
-       {
-         mbchar[0] = '\0';     /* null wide character */
-         mb_len = 1;
-         break;
-       }
-      else if (mbchar_bytes_length > (size_t)(0))
-       break;
-    }
-
-  return mb_len;
-}
-
-/* Read a multibyte-character string whose first character is FIRST into
-   the buffer MB of length MLEN.  Returns the last character read, which
-   may be FIRST.  Used by the search functions, among others.  Very similar
-   to _rl_read_mbchar. */
-int
-_rl_read_mbstring (first, mb, mlen)
-     int first;
-     char *mb;
-     int mlen;
-{
-  int i, c;
-  mbstate_t ps;
-
-  c = first;
-  memset (mb, 0, mlen);
-  for (i = 0; c >= 0 && i < mlen; i++)
-    {
-      mb[i] = (char)c;
-      memset (&ps, 0, sizeof (mbstate_t));
-      if (_rl_get_char_len (mb, &ps) == -2)
-       {
-         /* Read more for multibyte character */
-         RL_SETSTATE (RL_STATE_MOREINPUT);
-         c = rl_read_key ();
-         RL_UNSETSTATE (RL_STATE_MOREINPUT);
-       }
-      else
-       break;
-    }
-  return c;
-}
-#endif /* HANDLE_MULTIBYTE */
diff --git a/lib/readline/keymaps.c~ b/lib/readline/keymaps.c~
deleted file mode 100644 (file)
index a033d5e..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/* keymaps.c -- Functions and keymaps for the GNU Readline library. */
-
-/* Copyright (C) 1988,1989-2009 Free Software Foundation, Inc.
-
-   This file is part of the GNU Readline Library (Readline), a library
-   for reading lines of text with interactive input and history editing.      
-
-   Readline is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   Readline is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#define READLINE_LIBRARY
-
-#if defined (HAVE_CONFIG_H)
-#  include <config.h>
-#endif
-
-#if defined (HAVE_STDLIB_H)
-#  include <stdlib.h>
-#else
-#  include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#include <stdio.h>     /* for FILE * definition for readline.h */
-
-#include "readline.h"
-#include "rlconf.h"
-
-#include "emacs_keymap.c"
-
-#if defined (VI_MODE)
-#include "vi_keymap.c"
-#endif
-
-#include "xmalloc.h"
-
-/* **************************************************************** */
-/*                                                                 */
-/*                   Functions for manipulating Keymaps.           */
-/*                                                                 */
-/* **************************************************************** */
-
-
-/* Return a new, empty keymap.
-   Free it with free() when you are done. */
-Keymap
-rl_make_bare_keymap ()
-{
-  register int i;
-  Keymap keymap = (Keymap)xmalloc (KEYMAP_SIZE * sizeof (KEYMAP_ENTRY));
-
-  for (i = 0; i < KEYMAP_SIZE; i++)
-    {
-      keymap[i].type = ISFUNC;
-      keymap[i].function = (rl_command_func_t *)NULL;
-    }
-
-#if 0
-  for (i = 'A'; i < ('Z' + 1); i++)
-    {
-      keymap[i].type = ISFUNC;
-      keymap[i].function = rl_do_lowercase_version;
-    }
-#endif
-
-  return (keymap);
-}
-
-/* Return a new keymap which is a copy of MAP. */
-Keymap
-rl_copy_keymap (map)
-     Keymap map;
-{
-  register int i;
-  Keymap temp;
-
-  temp = rl_make_bare_keymap ();
-  for (i = 0; i < KEYMAP_SIZE; i++)
-    {
-      temp[i].type = map[i].type;
-      temp[i].function = map[i].function;
-    }
-  return (temp);
-}
-
-/* Return a new keymap with the printing characters bound to rl_insert,
-   the uppercase Meta characters bound to run their lowercase equivalents,
-   and the Meta digits bound to produce numeric arguments. */
-Keymap
-rl_make_keymap ()
-{
-  register int i;
-  Keymap newmap;
-
-  newmap = rl_make_bare_keymap ();
-
-  /* All ASCII printing characters are self-inserting. */
-  for (i = ' '; i < 127; i++)
-    newmap[i].function = rl_insert;
-
-  newmap[TAB].function = rl_insert;
-  newmap[RUBOUT].function = rl_rubout; /* RUBOUT == 127 */
-  newmap[CTRL('H')].function = rl_rubout;
-
-#if KEYMAP_SIZE > 128
-  /* Printing characters in ISO Latin-1 and some 8-bit character sets. */
-  for (i = 128; i < 256; i++)
-    newmap[i].function = rl_insert;
-#endif /* KEYMAP_SIZE > 128 */
-
-  return (newmap);
-}
-
-/* Free the storage associated with MAP. */
-void
-rl_discard_keymap (map)
-     Keymap map;
-{
-  int i;
-
-  if (!map)
-    return;
-
-  for (i = 0; i < KEYMAP_SIZE; i++)
-    {
-      switch (map[i].type)
-       {
-       case ISFUNC:
-         break;
-
-       case ISKMAP:
-         rl_discard_keymap ((Keymap)map[i].function);
-         break;
-
-       case ISMACR:
-         free ((char *)map[i].function);
-         break;
-       }
-    }
-}
diff --git a/lib/readline/mbutil.c~ b/lib/readline/mbutil.c~
deleted file mode 100644 (file)
index f41618d..0000000
+++ /dev/null
@@ -1,372 +0,0 @@
-/* mbutil.c -- readline multibyte character utility functions */
-
-/* Copyright (C) 2001-2009 Free Software Foundation, Inc.
-
-   This file is part of the GNU Readline Library (Readline), a library
-   for reading lines of text with interactive input and history editing.      
-
-   Readline is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   Readline is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#define READLINE_LIBRARY
-
-#if defined (HAVE_CONFIG_H)
-#  include <config.h>
-#endif
-
-#include <sys/types.h>
-#include <fcntl.h>
-#include "posixjmp.h"
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>     /* for _POSIX_VERSION */
-#endif /* HAVE_UNISTD_H */
-
-#if defined (HAVE_STDLIB_H)
-#  include <stdlib.h>
-#else
-#  include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#include <stdio.h>
-#include <ctype.h>
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-#include "rlmbutil.h"
-
-#if defined (TIOCSTAT_IN_SYS_IOCTL)
-#  include <sys/ioctl.h>
-#endif /* TIOCSTAT_IN_SYS_IOCTL */
-
-/* Some standard library routines. */
-#include "readline.h"
-
-#include "rlprivate.h"
-#include "xmalloc.h"
-
-/* Declared here so it can be shared between the readline and history
-   libraries. */
-#if defined (HANDLE_MULTIBYTE)
-int rl_byte_oriented = 0;
-#else
-int rl_byte_oriented = 1;
-#endif
-
-/* **************************************************************** */
-/*                                                                 */
-/*             Multibyte Character Utility Functions               */
-/*                                                                 */
-/* **************************************************************** */
-
-#if defined(HANDLE_MULTIBYTE)
-
-static int
-_rl_find_next_mbchar_internal (string, seed, count, find_non_zero)
-     char *string;
-     int seed, count, find_non_zero;
-{
-  size_t tmp, len;
-  mbstate_t ps;
-  int point;
-  wchar_t wc;
-
-  tmp = 0;
-
-  memset(&ps, 0, sizeof (mbstate_t));
-  if (seed < 0)
-    seed = 0;
-  if (count <= 0)
-    return seed;
-
-  point = seed + _rl_adjust_point (string, seed, &ps);
-  /* if this is true, means that seed was not pointing to a byte indicating
-     the beginning of a multibyte character.  Correct the point and consume
-     one char. */
-  if (seed < point)
-    count--;
-
-  while (count > 0)  
-    {
-      tmp = mbrtowc (&wc, string+point, strlen(string + point), &ps);
-      if (MB_INVALIDCH ((size_t)tmp))
-       {
-         /* invalid bytes. assume a byte represents a character */
-         point++;
-         count--;
-         /* reset states. */
-         memset(&ps, 0, sizeof(mbstate_t));
-       }
-      else if (MB_NULLWCH (tmp))
-       break;                  /* found wide '\0' */
-      else
-       {
-         /* valid bytes */
-         point += tmp;
-         if (find_non_zero)
-           {
-             if (wcwidth (wc) == 0)
-               continue;
-             else
-               count--;
-           }
-         else
-           count--;
-       }
-    }
-
-  if (find_non_zero)
-    {
-      tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
-      while (MB_NULLWCH (tmp) == 0 && MB_INVALIDCH (tmp) == 0 && wcwidth (wc) == 0)
-       {
-         point += tmp;
-         tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
-       }
-    }
-
-  return point;
-}
-
-static int
-_rl_find_prev_mbchar_internal (string, seed, find_non_zero)
-     char *string;
-     int seed, find_non_zero;
-{
-  mbstate_t ps;
-  int prev, non_zero_prev, point, length;
-  size_t tmp;
-  wchar_t wc;
-
-  memset(&ps, 0, sizeof(mbstate_t));
-  length = strlen(string);
-  
-  if (seed < 0)
-    return 0;
-  else if (length < seed)
-    return length;
-
-  prev = non_zero_prev = point = 0;
-  while (point < seed)
-    {
-      tmp = mbrtowc (&wc, string + point, length - point, &ps);
-      if (MB_INVALIDCH ((size_t)tmp))
-       {
-         /* in this case, bytes are invalid or shorted to compose
-            multibyte char, so assume that the first byte represents
-            a single character anyway. */
-         tmp = 1;
-         /* clear the state of the byte sequence, because
-            in this case effect of mbstate is undefined  */
-         memset(&ps, 0, sizeof (mbstate_t));
-
-         /* Since we're assuming that this byte represents a single
-            non-zero-width character, don't forget about it. */
-         prev = point;
-       }
-      else if (MB_NULLWCH (tmp))
-       break;                  /* Found '\0' char.  Can this happen? */
-      else
-       {
-         if (find_non_zero)
-           {
-             if (wcwidth (wc) != 0)
-               prev = point;
-           }
-         else
-           prev = point;  
-       }
-
-      point += tmp;
-    }
-
-  return prev;
-}
-
-/* return the number of bytes parsed from the multibyte sequence starting
-   at src, if a non-L'\0' wide character was recognized. It returns 0, 
-   if a L'\0' wide character was recognized. It  returns (size_t)(-1), 
-   if an invalid multibyte sequence was encountered. It returns (size_t)(-2) 
-   if it couldn't parse a complete  multibyte character.  */
-int
-_rl_get_char_len (src, ps)
-     char *src;
-     mbstate_t *ps;
-{
-  size_t tmp;
-
-  tmp = mbrlen((const char *)src, (size_t)strlen (src), ps);
-  if (tmp == (size_t)(-2))
-    {
-      /* shorted to compose multibyte char */
-      if (ps)
-       memset (ps, 0, sizeof(mbstate_t));
-      return -2;
-    }
-  else if (tmp == (size_t)(-1))
-    {
-      /* invalid to compose multibyte char */
-      /* initialize the conversion state */
-      if (ps)
-       memset (ps, 0, sizeof(mbstate_t));
-      return -1;
-    }
-  else if (tmp == (size_t)0)
-    return 0;
-  else
-    return (int)tmp;
-}
-
-/* compare the specified two characters. If the characters matched,
-   return 1. Otherwise return 0. */
-int
-_rl_compare_chars (buf1, pos1, ps1, buf2, pos2, ps2)
-     char *buf1;
-     int pos1;
-     mbstate_t *ps1;
-     char *buf2;
-     int pos2;
-     mbstate_t *ps2;
-{
-  int i, w1, w2;
-
-  if ((w1 = _rl_get_char_len (&buf1[pos1], ps1)) <= 0 || 
-       (w2 = _rl_get_char_len (&buf2[pos2], ps2)) <= 0 ||
-       (w1 != w2) ||
-       (buf1[pos1] != buf2[pos2]))
-    return 0;
-
-  for (i = 1; i < w1; i++)
-    if (buf1[pos1+i] != buf2[pos2+i])
-      return 0;
-
-  return 1;
-}
-
-/* adjust pointed byte and find mbstate of the point of string.
-   adjusted point will be point <= adjusted_point, and returns
-   differences of the byte(adjusted_point - point).
-   if point is invalied (point < 0 || more than string length),
-   it returns -1 */
-int
-_rl_adjust_point(string, point, ps)
-     char *string;
-     int point;
-     mbstate_t *ps;
-{
-  size_t tmp = 0;
-  int length;
-  int pos = 0;
-
-  length = strlen(string);
-  if (point < 0)
-    return -1;
-  if (length < point)
-    return -1;
-  
-  while (pos < point)
-    {
-      tmp = mbrlen (string + pos, length - pos, ps);
-      if (MB_INVALIDCH ((size_t)tmp))
-       {
-         /* in this case, bytes are invalid or shorted to compose
-            multibyte char, so assume that the first byte represents
-            a single character anyway. */
-         pos++;
-         /* clear the state of the byte sequence, because
-            in this case effect of mbstate is undefined  */
-         if (ps)
-           memset (ps, 0, sizeof (mbstate_t));
-       }
-      else if (MB_NULLWCH (tmp))
-       pos++;
-      else
-       pos += tmp;
-    }
-
-  return (pos - point);
-}
-
-int
-_rl_is_mbchar_matched (string, seed, end, mbchar, length)
-     char *string;
-     int seed, end;
-     char *mbchar;
-     int length;
-{
-  int i;
-
-  if ((end - seed) < length)
-    return 0;
-
-  for (i = 0; i < length; i++)
-    if (string[seed + i] != mbchar[i])
-      return 0;
-  return 1;
-}
-
-wchar_t
-_rl_char_value (buf, ind)
-     char *buf;
-     int ind;
-{
-  size_t tmp;
-  wchar_t wc;
-  mbstate_t ps;
-  int l;
-
-  if (MB_LEN_MAX == 1 || rl_byte_oriented)
-    return ((wchar_t) buf[ind]);
-  l = strlen (buf);
-  if (ind >= l - 1)
-    return ((wchar_t) buf[ind]);
-  memset (&ps, 0, sizeof (mbstate_t));
-  tmp = mbrtowc (&wc, buf + ind, l - ind, &ps);
-  if (MB_INVALIDCH (tmp) || MB_NULLWCH (tmp))  
-    return ((wchar_t) buf[ind]);
-  return wc;
-}
-#endif /* HANDLE_MULTIBYTE */
-
-/* Find next `count' characters started byte point of the specified seed.
-   If flags is MB_FIND_NONZERO, we look for non-zero-width multibyte
-   characters. */
-#undef _rl_find_next_mbchar
-int
-_rl_find_next_mbchar (string, seed, count, flags)
-     char *string;
-     int seed, count, flags;
-{
-#if defined (HANDLE_MULTIBYTE)
-  return _rl_find_next_mbchar_internal (string, seed, count, flags);
-#else
-  return (seed + count);
-#endif
-}
-
-/* Find previous character started byte point of the specified seed.
-   Returned point will be point <= seed.  If flags is MB_FIND_NONZERO,
-   we look for non-zero-width multibyte characters. */
-#undef _rl_find_prev_mbchar
-int
-_rl_find_prev_mbchar (string, seed, flags)
-     char *string;
-     int seed, flags;
-{
-#if defined (HANDLE_MULTIBYTE)
-  return _rl_find_prev_mbchar_internal (string, seed, flags);
-#else
-  return ((seed == 0) ? seed : seed - 1);
-#endif
-}
diff --git a/lib/readline/parens.c~ b/lib/readline/parens.c~
deleted file mode 100644 (file)
index d6f7a1b..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/* parens.c -- implementation of matching parentheses feature. */
-
-/* Copyright (C) 1987, 1989, 1992-2009 Free Software Foundation, Inc.
-
-   This file is part of the GNU Readline Library (Readline), a library
-   for reading lines of text with interactive input and history editing.      
-
-   Readline is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   Readline is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#define READLINE_LIBRARY
-
-#if defined (__TANDEM)
-#  include <floss.h>
-#endif
-
-#include "rlconf.h"
-
-#if defined (HAVE_CONFIG_H)
-#  include <config.h>
-#endif
-
-#include <stdio.h>
-#include <sys/types.h>
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include "posixselect.h"
-
-#if defined (HAVE_STRING_H)
-#  include <string.h>
-#else /* !HAVE_STRING_H */
-#  include <strings.h>
-#endif /* !HAVE_STRING_H */
-
-#if !defined (strchr) && !defined (__STDC__)
-extern char *strchr (), *strrchr ();
-#endif /* !strchr && !__STDC__ */
-
-#include "readline.h"
-#include "rlprivate.h"
-
-static int find_matching_open PARAMS((char *, int, int));
-
-/* Non-zero means try to blink the matching open parenthesis when the
-   close parenthesis is inserted. */
-#if defined (HAVE_SELECT)
-int rl_blink_matching_paren = 1;
-#else /* !HAVE_SELECT */
-int rl_blink_matching_paren = 0;
-#endif /* !HAVE_SELECT */
-
-static int _paren_blink_usec = 500000;
-
-/* Change emacs_standard_keymap to have bindings for paren matching when
-   ON_OR_OFF is 1, change them back to self_insert when ON_OR_OFF == 0. */
-void
-_rl_enable_paren_matching (on_or_off)
-     int on_or_off;
-{
-  if (on_or_off)
-    {  /* ([{ */
-      rl_bind_key_in_map (')', rl_insert_close, emacs_standard_keymap);
-      rl_bind_key_in_map (']', rl_insert_close, emacs_standard_keymap);
-      rl_bind_key_in_map ('}', rl_insert_close, emacs_standard_keymap);
-    }
-  else
-    {  /* ([{ */
-      rl_bind_key_in_map (')', rl_insert, emacs_standard_keymap);
-      rl_bind_key_in_map (']', rl_insert, emacs_standard_keymap);
-      rl_bind_key_in_map ('}', rl_insert, emacs_standard_keymap);
-    }
-}
-
-int
-rl_set_paren_blink_timeout (u)
-     int u;
-{
-  int o;
-
-  o = _paren_blink_usec;
-  if (u > 0)
-    _paren_blink_usec = u;
-  return (o);
-}
-
-int
-rl_insert_close (count, invoking_key)
-     int count, invoking_key;
-{
-  if (rl_explicit_arg || !rl_blink_matching_paren)
-    _rl_insert_char (count, invoking_key);
-  else
-    {
-#if defined (HAVE_SELECT)
-      int orig_point, match_point, ready;
-      struct timeval timer;
-      fd_set readfds;
-
-      _rl_insert_char (1, invoking_key);
-      (*rl_redisplay_function) ();
-      match_point =
-       find_matching_open (rl_line_buffer, rl_point - 2, invoking_key);
-
-      /* Emacs might message or ring the bell here, but I don't. */
-      if (match_point < 0)
-       return -1;
-
-      FD_ZERO (&readfds);
-      FD_SET (fileno (rl_instream), &readfds);
-      timer.tv_sec = 0;
-      timer.tv_usec = _paren_blink_usec;
-
-      orig_point = rl_point;
-      rl_point = match_point;
-      (*rl_redisplay_function) ();
-      ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer);
-      rl_point = orig_point;
-#else /* !HAVE_SELECT */
-      _rl_insert_char (count, invoking_key);
-#endif /* !HAVE_SELECT */
-    }
-  return 0;
-}
-
-static int
-find_matching_open (string, from, closer)
-     char *string;
-     int from, closer;
-{
-  register int i;
-  int opener, level, delimiter;
-
-  switch (closer)
-    {
-    case ']': opener = '['; break;
-    case '}': opener = '{'; break;
-    case ')': opener = '('; break;
-    default:
-      return (-1);
-    }
-
-  level = 1;                   /* The closer passed in counts as 1. */
-  delimiter = 0;               /* Delimited state unknown. */
-
-  for (i = from; i > -1; i--)
-    {
-      if (delimiter && (string[i] == delimiter))
-       delimiter = 0;
-      else if (rl_basic_quote_characters && strchr (rl_basic_quote_characters, string[i]))
-       delimiter = string[i];
-      else if (!delimiter && (string[i] == closer))
-       level++;
-      else if (!delimiter && (string[i] == opener))
-       level--;
-
-      if (!level)
-       break;
-    }
-  return (i);
-}
diff --git a/lib/readline/readline.c~ b/lib/readline/readline.c~
deleted file mode 100644 (file)
index fee2d46..0000000
+++ /dev/null
@@ -1,1252 +0,0 @@
-/* readline.c -- a general facility for reading lines of input
-   with emacs style editing and completion. */
-
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
-
-   This file is part of the GNU Readline Library (Readline), a library
-   for reading lines of text with interactive input and history editing.      
-
-   Readline is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   Readline is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#define READLINE_LIBRARY
-
-#if defined (HAVE_CONFIG_H)
-#  include <config.h>
-#endif
-
-#include <sys/types.h>
-#include "posixstat.h"
-#include <fcntl.h>
-#if defined (HAVE_SYS_FILE_H)
-#  include <sys/file.h>
-#endif /* HAVE_SYS_FILE_H */
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#if defined (HAVE_STDLIB_H)
-#  include <stdlib.h>
-#else
-#  include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#if defined (HAVE_LOCALE_H)
-#  include <locale.h>
-#endif
-
-#include <stdio.h>
-#include "posixjmp.h"
-#include <errno.h>
-
-#if !defined (errno)
-extern int errno;
-#endif /* !errno */
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-#include "rlmbutil.h"
-
-#if defined (__EMX__)
-#  define INCL_DOSPROCESS
-#  include <os2.h>
-#endif /* __EMX__ */
-
-/* Some standard library routines. */
-#include "readline.h"
-#include "history.h"
-
-#include "rlprivate.h"
-#include "rlshell.h"
-#include "xmalloc.h"
-
-#ifndef RL_LIBRARY_VERSION
-#  define RL_LIBRARY_VERSION "5.1"
-#endif
-
-#ifndef RL_READLINE_VERSION
-#  define RL_READLINE_VERSION  0x0501
-#endif
-
-extern void _rl_free_history_entry PARAMS((HIST_ENTRY *));
-
-/* Forward declarations used in this file. */
-static char *readline_internal PARAMS((void));
-static void readline_initialize_everything PARAMS((void));
-
-static void bind_arrow_keys_internal PARAMS((Keymap));
-static void bind_arrow_keys PARAMS((void));
-
-static void readline_default_bindings PARAMS((void));
-static void reset_default_bindings PARAMS((void));
-
-static int _rl_subseq_result PARAMS((int, Keymap, int, int));
-static int _rl_subseq_getchar PARAMS((int));
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Line editing input utility                  */
-/*                                                                 */
-/* **************************************************************** */
-
-const char *rl_library_version = RL_LIBRARY_VERSION;
-
-int rl_readline_version = RL_READLINE_VERSION;
-
-/* True if this is `real' readline as opposed to some stub substitute. */
-int rl_gnu_readline_p = 1;
-
-/* A pointer to the keymap that is currently in use.
-   By default, it is the standard emacs keymap. */
-Keymap _rl_keymap = emacs_standard_keymap;
-
-
-/* The current style of editing. */
-int rl_editing_mode = emacs_mode;
-
-/* The current insert mode:  input (the default) or overwrite */
-int rl_insert_mode = RL_IM_DEFAULT;
-
-/* Non-zero if we called this function from _rl_dispatch().  It's present
-   so functions can find out whether they were called from a key binding
-   or directly from an application. */
-int rl_dispatching;
-
-/* Non-zero if the previous command was a kill command. */
-int _rl_last_command_was_kill = 0;
-
-/* The current value of the numeric argument specified by the user. */
-int rl_numeric_arg = 1;
-
-/* Non-zero if an argument was typed. */
-int rl_explicit_arg = 0;
-
-/* Temporary value used while generating the argument. */
-int rl_arg_sign = 1;
-
-/* Non-zero means we have been called at least once before. */
-static int rl_initialized;
-
-#if 0
-/* If non-zero, this program is running in an EMACS buffer. */
-static int running_in_emacs;
-#endif
-
-/* Flags word encapsulating the current readline state. */
-int rl_readline_state = RL_STATE_NONE;
-
-/* The current offset in the current input line. */
-int rl_point;
-
-/* Mark in the current input line. */
-int rl_mark;
-
-/* Length of the current input line. */
-int rl_end;
-
-/* Make this non-zero to return the current input_line. */
-int rl_done;
-
-/* The last function executed by readline. */
-rl_command_func_t *rl_last_func = (rl_command_func_t *)NULL;
-
-/* Top level environment for readline_internal (). */
-procenv_t _rl_top_level;
-
-/* The streams we interact with. */
-FILE *_rl_in_stream, *_rl_out_stream;
-
-/* The names of the streams that we do input and output to. */
-FILE *rl_instream = (FILE *)NULL;
-FILE *rl_outstream = (FILE *)NULL;
-
-/* Non-zero means echo characters as they are read.  Defaults to no echo;
-   set to 1 if there is a controlling terminal, we can get its attributes,
-   and the attributes include `echo'.  Look at rltty.c:prepare_terminal_settings
-   for the code that sets it. */
-int _rl_echoing_p = 0;
-
-/* Current prompt. */
-char *rl_prompt = (char *)NULL;
-int rl_visible_prompt_length = 0;
-
-/* Set to non-zero by calling application if it has already printed rl_prompt
-   and does not want readline to do it the first time. */
-int rl_already_prompted = 0;
-
-/* The number of characters read in order to type this complete command. */
-int rl_key_sequence_length = 0;
-
-/* If non-zero, then this is the address of a function to call just
-   before readline_internal_setup () prints the first prompt. */
-rl_hook_func_t *rl_startup_hook = (rl_hook_func_t *)NULL;
-
-/* If non-zero, this is the address of a function to call just before
-   readline_internal_setup () returns and readline_internal starts
-   reading input characters. */
-rl_hook_func_t *rl_pre_input_hook = (rl_hook_func_t *)NULL;
-
-/* What we use internally.  You should always refer to RL_LINE_BUFFER. */
-static char *the_line;
-
-/* The character that can generate an EOF.  Really read from
-   the terminal driver... just defaulted here. */
-int _rl_eof_char = CTRL ('D');
-
-/* Non-zero makes this the next keystroke to read. */
-int rl_pending_input = 0;
-
-/* Pointer to a useful terminal name. */
-const char *rl_terminal_name = (const char *)NULL;
-
-/* Non-zero means to always use horizontal scrolling in line display. */
-int _rl_horizontal_scroll_mode = 0;
-
-/* Non-zero means to display an asterisk at the starts of history lines
-   which have been modified. */
-int _rl_mark_modified_lines = 0;  
-
-/* The style of `bell' notification preferred.  This can be set to NO_BELL,
-   AUDIBLE_BELL, or VISIBLE_BELL. */
-int _rl_bell_preference = AUDIBLE_BELL;
-     
-/* String inserted into the line by rl_insert_comment (). */
-char *_rl_comment_begin;
-
-/* Keymap holding the function currently being executed. */
-Keymap rl_executing_keymap;
-
-/* Keymap we're currently using to dispatch. */
-Keymap _rl_dispatching_keymap;
-
-/* Non-zero means to erase entire line, including prompt, on empty input lines. */
-int rl_erase_empty_line = 0;
-
-/* Non-zero means to read only this many characters rather than up to a
-   character bound to accept-line. */
-int rl_num_chars_to_read;
-
-/* Line buffer and maintenence. */
-char *rl_line_buffer = (char *)NULL;
-int rl_line_buffer_len = 0;
-
-/* Key sequence `contexts' */
-_rl_keyseq_cxt *_rl_kscxt = 0;
-
-/* Forward declarations used by the display, termcap, and history code. */
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     `Forward' declarations                      */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Non-zero means do not parse any lines other than comments and
-   parser directives. */
-unsigned char _rl_parsing_conditionalized_out = 0;
-
-/* Non-zero means to convert characters with the meta bit set to
-   escape-prefixed characters so we can indirect through
-   emacs_meta_keymap or vi_escape_keymap. */
-int _rl_convert_meta_chars_to_ascii = 1;
-
-/* Non-zero means to output characters with the meta bit set directly
-   rather than as a meta-prefixed escape sequence. */
-int _rl_output_meta_chars = 0;
-
-/* Non-zero means to look at the termios special characters and bind
-   them to equivalent readline functions at startup. */
-int _rl_bind_stty_chars = 1;
-
-/* Non-zero means to go through the history list at every newline (or
-   whenever rl_done is set and readline returns) and revert each line to
-   its initial state. */
-int _rl_revert_all_at_newline = 0;
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Top Level Functions                         */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Non-zero means treat 0200 bit in terminal input as Meta bit. */
-int _rl_meta_flag = 0; /* Forward declaration */
-
-/* Set up the prompt and expand it.  Called from readline() and
-   rl_callback_handler_install (). */
-int
-rl_set_prompt (prompt)
-     const char *prompt;
-{
-  FREE (rl_prompt);
-  rl_prompt = prompt ? savestring (prompt) : (char *)NULL;
-  rl_display_prompt = rl_prompt ? rl_prompt : "";
-
-  rl_visible_prompt_length = rl_expand_prompt (rl_prompt);
-  return 0;
-}
-  
-/* Read a line of input.  Prompt with PROMPT.  An empty PROMPT means
-   none.  A return value of NULL means that EOF was encountered. */
-char *
-readline (prompt)
-     const char *prompt;
-{
-  char *value;
-#if 0
-  int in_callback;
-#endif
-
-  /* If we are at EOF return a NULL string. */
-  if (rl_pending_input == EOF)
-    {
-      rl_clear_pending_input ();
-      return ((char *)NULL);
-    }
-
-#if 0
-  /* If readline() is called after installing a callback handler, temporarily
-     turn off the callback state to avoid ensuing messiness.  Patch supplied
-     by the gdb folks.  XXX -- disabled.  This can be fooled and readline
-     left in a strange state by a poorly-timed longjmp. */
-  if (in_callback = RL_ISSTATE (RL_STATE_CALLBACK))
-    RL_UNSETSTATE (RL_STATE_CALLBACK);
-#endif
-
-  rl_set_prompt (prompt);
-
-  rl_initialize ();
-  if (rl_prep_term_function)
-    (*rl_prep_term_function) (_rl_meta_flag);
-
-#if defined (HANDLE_SIGNALS)
-  rl_set_signals ();
-#endif
-
-  value = readline_internal ();
-  if (rl_deprep_term_function)
-    (*rl_deprep_term_function) ();
-
-#if defined (HANDLE_SIGNALS)
-  rl_clear_signals ();
-#endif
-
-#if 0
-  if (in_callback)
-    RL_SETSTATE (RL_STATE_CALLBACK);
-#endif
-
-  return (value);
-}
-
-#if defined (READLINE_CALLBACKS)
-#  define STATIC_CALLBACK
-#else
-#  define STATIC_CALLBACK static
-#endif
-
-STATIC_CALLBACK void
-readline_internal_setup ()
-{
-  char *nprompt;
-
-  _rl_in_stream = rl_instream;
-  _rl_out_stream = rl_outstream;
-
-  if (rl_startup_hook)
-    (*rl_startup_hook) ();
-
-  /* If we're not echoing, we still want to at least print a prompt, because
-     rl_redisplay will not do it for us.  If the calling application has a
-     custom redisplay function, though, let that function handle it. */
-  if (_rl_echoing_p == 0 && rl_redisplay_function == rl_redisplay)
-    {
-      if (rl_prompt && rl_already_prompted == 0)
-       {
-         nprompt = _rl_strip_prompt (rl_prompt);
-         fprintf (_rl_out_stream, "%s", nprompt);
-         fflush (_rl_out_stream);
-         free (nprompt);
-       }
-    }
-  else
-    {
-      if (rl_prompt && rl_already_prompted)
-       rl_on_new_line_with_prompt ();
-      else
-       rl_on_new_line ();
-      (*rl_redisplay_function) ();
-    }
-
-#if defined (VI_MODE)
-  if (rl_editing_mode == vi_mode)
-    rl_vi_insert_mode (1, 'i');
-#endif /* VI_MODE */
-
-  if (rl_pre_input_hook)
-    (*rl_pre_input_hook) ();
-
-  RL_CHECK_SIGNALS ();
-}
-
-STATIC_CALLBACK char *
-readline_internal_teardown (eof)
-     int eof;
-{
-  char *temp;
-  HIST_ENTRY *entry;
-
-  RL_CHECK_SIGNALS ();
-
-  /* Restore the original of this history line, iff the line that we
-     are editing was originally in the history, AND the line has changed. */
-  entry = current_history ();
-
-  if (entry && rl_undo_list)
-    {
-      temp = savestring (the_line);
-      rl_revert_line (1, 0);
-      entry = replace_history_entry (where_history (), the_line, (histdata_t)NULL);
-      _rl_free_history_entry (entry);
-
-      strcpy (the_line, temp);
-      free (temp);
-    }
-
-  if (_rl_revert_all_at_newline)
-    _rl_revert_all_lines ();
-
-  /* At any rate, it is highly likely that this line has an undo list.  Get
-     rid of it now. */
-  if (rl_undo_list)
-    rl_free_undo_list ();
-
-  /* Restore normal cursor, if available. */
-  _rl_set_insert_mode (RL_IM_INSERT, 0);
-
-  return (eof ? (char *)NULL : savestring (the_line));
-}
-
-void
-_rl_internal_char_cleanup ()
-{
-#if defined (VI_MODE)
-  /* In vi mode, when you exit insert mode, the cursor moves back
-     over the previous character.  We explicitly check for that here. */
-  if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap)
-    rl_vi_check ();
-#endif /* VI_MODE */
-
-  if (rl_num_chars_to_read && rl_end >= rl_num_chars_to_read)
-    {
-      (*rl_redisplay_function) ();
-      _rl_want_redisplay = 0;
-      rl_newline (1, '\n');
-    }
-
-  if (rl_done == 0)
-    {
-      (*rl_redisplay_function) ();
-      _rl_want_redisplay = 0;
-    }
-
-  /* If the application writer has told us to erase the entire line if
-     the only character typed was something bound to rl_newline, do so. */
-  if (rl_erase_empty_line && rl_done && rl_last_func == rl_newline &&
-      rl_point == 0 && rl_end == 0)
-    _rl_erase_entire_line ();
-}
-
-STATIC_CALLBACK int
-#if defined (READLINE_CALLBACKS)
-readline_internal_char ()
-#else
-readline_internal_charloop ()
-#endif
-{
-  static int lastc, eof_found;
-  int c, code, lk;
-
-  lastc = -1;
-  eof_found = 0;
-
-#if !defined (READLINE_CALLBACKS)
-  while (rl_done == 0)
-    {
-#endif
-      lk = _rl_last_command_was_kill;
-
-      code = setjmp (_rl_top_level);
-
-      if (code)
-       {
-         (*rl_redisplay_function) ();
-         _rl_want_redisplay = 0;
-         /* If we get here, we're not being called from something dispatched
-            from _rl_callback_read_char(), which sets up its own value of
-            _rl_top_level (saving and restoring the old, of course), so
-            we can just return here. */
-         if (RL_ISSTATE (RL_STATE_CALLBACK))
-           return (0);
-       }
-
-      if (rl_pending_input == 0)
-       {
-         /* Then initialize the argument and number of keys read. */
-         _rl_reset_argument ();
-         rl_key_sequence_length = 0;
-       }
-
-      RL_SETSTATE(RL_STATE_READCMD);
-      c = rl_read_key ();
-      RL_UNSETSTATE(RL_STATE_READCMD);
-
-      /* look at input.c:rl_getc() for the circumstances under which this will
-        be returned; punt immediately on read error without converting it to
-        a newline. */
-      if (c == READERR)
-       {
-#if defined (READLINE_CALLBACKS)
-         RL_SETSTATE(RL_STATE_DONE);
-         return (rl_done = 1);
-#else
-         eof_found = 1;
-         break;
-#endif
-       }
-
-      /* EOF typed to a non-blank line is a <NL>. */
-      if (c == EOF && rl_end)
-       c = NEWLINE;
-
-      /* The character _rl_eof_char typed to blank line, and not as the
-        previous character is interpreted as EOF. */
-      if (((c == _rl_eof_char && lastc != c) || c == EOF) && !rl_end)
-       {
-#if defined (READLINE_CALLBACKS)
-         RL_SETSTATE(RL_STATE_DONE);
-         return (rl_done = 1);
-#else
-         eof_found = 1;
-         break;
-#endif
-       }
-
-      lastc = c;
-      _rl_dispatch ((unsigned char)c, _rl_keymap);
-      RL_CHECK_SIGNALS ();
-
-      /* If there was no change in _rl_last_command_was_kill, then no kill
-        has taken place.  Note that if input is pending we are reading
-        a prefix command, so nothing has changed yet. */
-      if (rl_pending_input == 0 && lk == _rl_last_command_was_kill)
-       _rl_last_command_was_kill = 0;
-
-      _rl_internal_char_cleanup ();
-
-#if defined (READLINE_CALLBACKS)
-      return 0;
-#else
-    }
-
-  return (eof_found);
-#endif
-}
-
-#if defined (READLINE_CALLBACKS)
-static int
-readline_internal_charloop ()
-{
-  int eof = 1;
-
-  while (rl_done == 0)
-    eof = readline_internal_char ();
-  return (eof);
-}
-#endif /* READLINE_CALLBACKS */
-
-/* Read a line of input from the global rl_instream, doing output on
-   the global rl_outstream.
-   If rl_prompt is non-null, then that is our prompt. */
-static char *
-readline_internal ()
-{
-  int eof;
-
-  readline_internal_setup ();
-  eof = readline_internal_charloop ();
-  return (readline_internal_teardown (eof));
-}
-
-void
-_rl_init_line_state ()
-{
-  rl_point = rl_end = rl_mark = 0;
-  the_line = rl_line_buffer;
-  the_line[0] = 0;
-}
-
-void
-_rl_set_the_line ()
-{
-  the_line = rl_line_buffer;
-}
-
-#if defined (READLINE_CALLBACKS)
-_rl_keyseq_cxt *
-_rl_keyseq_cxt_alloc ()
-{
-  _rl_keyseq_cxt *cxt;
-
-  cxt = (_rl_keyseq_cxt *)xmalloc (sizeof (_rl_keyseq_cxt));
-
-  cxt->flags = cxt->subseq_arg = cxt->subseq_retval = 0;
-
-  cxt->okey = 0;
-  cxt->ocxt = _rl_kscxt;
-  cxt->childval = 42;          /* sentinel value */
-
-  return cxt;
-}
-
-void
-_rl_keyseq_cxt_dispose (cxt)
-    _rl_keyseq_cxt *cxt;
-{
-  free (cxt);
-}
-
-void
-_rl_keyseq_chain_dispose ()
-{
-  _rl_keyseq_cxt *cxt;
-
-  while (_rl_kscxt)
-    {
-      cxt = _rl_kscxt;
-      _rl_kscxt = _rl_kscxt->ocxt;
-      _rl_keyseq_cxt_dispose (cxt);
-    }
-}
-#endif
-
-static int
-_rl_subseq_getchar (key)
-     int key;
-{
-  int k;
-
-  if (key == ESC)
-    RL_SETSTATE(RL_STATE_METANEXT);
-  RL_SETSTATE(RL_STATE_MOREINPUT);
-  k = rl_read_key ();
-  RL_UNSETSTATE(RL_STATE_MOREINPUT);
-  if (key == ESC)
-    RL_UNSETSTATE(RL_STATE_METANEXT);
-
-  return k;
-}
-
-#if defined (READLINE_CALLBACKS)
-int
-_rl_dispatch_callback (cxt)
-     _rl_keyseq_cxt *cxt;
-{
-  int nkey, r;
-
-  /* For now */
-  /* The first time this context is used, we want to read input and dispatch
-     on it.  When traversing the chain of contexts back `up', we want to use
-     the value from the next context down.  We're simulating recursion using
-     a chain of contexts. */
-  if ((cxt->flags & KSEQ_DISPATCHED) == 0)
-    {
-      nkey = _rl_subseq_getchar (cxt->okey);
-      if (nkey < 0)
-       {
-         _rl_abort_internal ();
-         return -1;
-       }
-      r = _rl_dispatch_subseq (nkey, cxt->dmap, cxt->subseq_arg);
-      cxt->flags |= KSEQ_DISPATCHED;
-    }
-  else
-    r = cxt->childval;
-
-  /* For now */
-  r = _rl_subseq_result (r, cxt->oldmap, cxt->okey, (cxt->flags & KSEQ_SUBSEQ));
-
-  RL_CHECK_SIGNALS ();
-  if (r == 0)                  /* success! */
-    {
-      _rl_keyseq_chain_dispose ();
-      RL_UNSETSTATE (RL_STATE_MULTIKEY);
-      return r;
-    }
-
-  if (r != -3)                 /* magic value that says we added to the chain */
-    _rl_kscxt = cxt->ocxt;
-  if (_rl_kscxt)
-    _rl_kscxt->childval = r;
-  if (r != -3)
-    _rl_keyseq_cxt_dispose (cxt);
-
-  return r;
-}
-#endif /* READLINE_CALLBACKS */
-  
-/* Do the command associated with KEY in MAP.
-   If the associated command is really a keymap, then read
-   another key, and dispatch into that map. */
-int
-_rl_dispatch (key, map)
-     register int key;
-     Keymap map;
-{
-  _rl_dispatching_keymap = map;
-  return _rl_dispatch_subseq (key, map, 0);
-}
-
-int
-_rl_dispatch_subseq (key, map, got_subseq)
-     register int key;
-     Keymap map;
-     int got_subseq;
-{
-  int r, newkey;
-  char *macro;
-  rl_command_func_t *func;
-#if defined (READLINE_CALLBACKS)
-  _rl_keyseq_cxt *cxt;
-#endif
-
-  if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii)
-    {
-      if (map[ESC].type == ISKMAP)
-       {
-         if (RL_ISSTATE (RL_STATE_MACRODEF))
-           _rl_add_macro_char (ESC);
-         map = FUNCTION_TO_KEYMAP (map, ESC);
-         key = UNMETA (key);
-         rl_key_sequence_length += 2;
-         return (_rl_dispatch (key, map));
-       }
-      else
-       rl_ding ();
-      return 0;
-    }
-
-  if (RL_ISSTATE (RL_STATE_MACRODEF))
-    _rl_add_macro_char (key);
-
-  r = 0;
-  switch (map[key].type)
-    {
-    case ISFUNC:
-      func = map[key].function;
-      if (func)
-       {
-         /* Special case rl_do_lowercase_version (). */
-         if (func == rl_do_lowercase_version)
-           return (_rl_dispatch (_rl_to_lower (key), map));
-
-         rl_executing_keymap = map;
-
-         rl_dispatching = 1;
-         RL_SETSTATE(RL_STATE_DISPATCHING);
-         (*map[key].function)(rl_numeric_arg * rl_arg_sign, key);
-         RL_UNSETSTATE(RL_STATE_DISPATCHING);
-         rl_dispatching = 0;
-
-         /* If we have input pending, then the last command was a prefix
-            command.  Don't change the state of rl_last_func.  Otherwise,
-            remember the last command executed in this variable. */
-         if (rl_pending_input == 0 && map[key].function != rl_digit_argument)
-           rl_last_func = map[key].function;
-
-         RL_CHECK_SIGNALS ();
-       }
-      else if (map[ANYOTHERKEY].function)
-       {
-         /* OK, there's no function bound in this map, but there is a
-            shadow function that was overridden when the current keymap
-            was created.  Return -2 to note  that. */
-         _rl_unget_char  (key);
-         return -2;
-       }
-      else if (got_subseq)
-       {
-         /* Return -1 to note that we're in a subsequence, but  we don't
-            have a matching key, nor was one overridden.  This means
-            we need to back up the recursion chain and find the last
-            subsequence that is bound to a function. */
-         _rl_unget_char (key);
-         return -1;
-       }
-      else
-       {
-#if defined (READLINE_CALLBACKS)
-         RL_UNSETSTATE (RL_STATE_MULTIKEY);
-         _rl_keyseq_chain_dispose ();
-#endif
-         _rl_abort_internal ();
-         return -1;
-       }
-      break;
-
-    case ISKMAP:
-      if (map[key].function != 0)
-       {
-#if defined (VI_MODE)
-         /* The only way this test will be true is if a subsequence has been
-            bound starting with ESC, generally the arrow keys.  What we do is
-            check whether there's input in the queue, which there generally
-            will be if an arrow key has been pressed, and, if there's not,
-            just dispatch to (what we assume is) rl_vi_movement_mode right
-            away.  This is essentially an input test with a zero timeout. */
-         if (rl_editing_mode == vi_mode && key == ESC && map == vi_insertion_keymap
-             && _rl_input_queued (0) == 0)
-           return (_rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key)));
-#endif
-
-         rl_key_sequence_length++;
-         _rl_dispatching_keymap = FUNCTION_TO_KEYMAP (map, key);
-
-         /* Allocate new context here.  Use linked contexts (linked through
-            cxt->ocxt) to simulate recursion */
-#if defined (READLINE_CALLBACKS)
-         if (RL_ISSTATE (RL_STATE_CALLBACK))
-           {
-             /* Return 0 only the first time, to indicate success to
-                _rl_callback_read_char.  The rest of the time, we're called
-                from _rl_dispatch_callback, so we return 3 to indicate
-                special handling is necessary. */
-             r = RL_ISSTATE (RL_STATE_MULTIKEY) ? -3 : 0;
-             cxt = _rl_keyseq_cxt_alloc ();
-
-             if (got_subseq)
-               cxt->flags |= KSEQ_SUBSEQ;
-             cxt->okey = key;
-             cxt->oldmap = map;
-             cxt->dmap = _rl_dispatching_keymap;
-             cxt->subseq_arg = got_subseq || cxt->dmap[ANYOTHERKEY].function;
-
-             RL_SETSTATE (RL_STATE_MULTIKEY);
-             _rl_kscxt = cxt;
-
-             return r;         /* don't indicate immediate success */
-           }
-#endif
-
-         newkey = _rl_subseq_getchar (key);
-         if (newkey < 0)
-           {
-             _rl_abort_internal ();
-             return -1;
-           }
-
-         r = _rl_dispatch_subseq (newkey, _rl_dispatching_keymap, got_subseq || map[ANYOTHERKEY].function);
-         return _rl_subseq_result (r, map, key, got_subseq);
-       }
-      else
-       {
-         _rl_abort_internal ();
-         return -1;
-       }
-      break;
-
-    case ISMACR:
-      if (map[key].function != 0)
-       {
-         macro = savestring ((char *)map[key].function);
-         _rl_with_macro_input (macro);
-         return 0;
-       }
-      break;
-    }
-#if defined (VI_MODE)
-  if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap &&
-      key != ANYOTHERKEY &&
-      _rl_vi_textmod_command (key))
-    _rl_vi_set_last (key, rl_numeric_arg, rl_arg_sign);
-#endif
-
-  return (r);
-}
-
-static int
-_rl_subseq_result (r, map, key, got_subseq)
-     int r;
-     Keymap map;
-     int key, got_subseq;
-{
-  Keymap m;
-  int type, nt;
-  rl_command_func_t *func, *nf;
-
-  if (r == -2)
-    /* We didn't match anything, and the keymap we're indexed into
-       shadowed a function previously bound to that prefix.  Call
-       the function.  The recursive call to _rl_dispatch_subseq has
-       already taken care of pushing any necessary input back onto
-       the input queue with _rl_unget_char. */
-    {
-      m = _rl_dispatching_keymap;
-      type = m[ANYOTHERKEY].type;
-      func = m[ANYOTHERKEY].function;
-      if (type == ISFUNC && func == rl_do_lowercase_version)
-       r = _rl_dispatch (_rl_to_lower (key), map);
-      else if (type == ISFUNC && func == rl_insert)
-       {
-         /* If the function that was shadowed was self-insert, we
-            somehow need a keymap with map[key].func == self-insert.
-            Let's use this one. */
-         nt = m[key].type;
-         nf = m[key].function;
-
-         m[key].type = type;
-         m[key].function = func;
-         r = _rl_dispatch (key, m);
-         m[key].type = nt;
-         m[key].function = nf;
-       }
-      else
-       r = _rl_dispatch (ANYOTHERKEY, m);
-    }
-  else if (r && map[ANYOTHERKEY].function)
-    {
-      /* We didn't match (r is probably -1), so return something to
-        tell the caller that it should try ANYOTHERKEY for an
-        overridden function. */
-      _rl_unget_char (key);
-      _rl_dispatching_keymap = map;
-      return -2;
-    }
-  else if (r && got_subseq)
-    {
-      /* OK, back up the chain. */
-      _rl_unget_char (key);
-      _rl_dispatching_keymap = map;
-      return -1;
-    }
-
-  return r;
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Initializations                             */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Initialize readline (and terminal if not already). */
-int
-rl_initialize ()
-{
-  /* If we have never been called before, initialize the
-     terminal and data structures. */
-  if (!rl_initialized)
-    {
-      RL_SETSTATE(RL_STATE_INITIALIZING);
-      readline_initialize_everything ();
-      RL_UNSETSTATE(RL_STATE_INITIALIZING);
-      rl_initialized++;
-      RL_SETSTATE(RL_STATE_INITIALIZED);
-    }
-
-  /* Initalize the current line information. */
-  _rl_init_line_state ();
-
-  /* We aren't done yet.  We haven't even gotten started yet! */
-  rl_done = 0;
-  RL_UNSETSTATE(RL_STATE_DONE);
-
-  /* Tell the history routines what is going on. */
-  _rl_start_using_history ();
-
-  /* Make the display buffer match the state of the line. */
-  rl_reset_line_state ();
-
-  /* No such function typed yet. */
-  rl_last_func = (rl_command_func_t *)NULL;
-
-  /* Parsing of key-bindings begins in an enabled state. */
-  _rl_parsing_conditionalized_out = 0;
-
-#if defined (VI_MODE)
-  if (rl_editing_mode == vi_mode)
-    _rl_vi_initialize_line ();
-#endif
-
-  /* Each line starts in insert mode (the default). */
-  _rl_set_insert_mode (RL_IM_DEFAULT, 1);
-
-  return 0;
-}
-
-#if 0
-#if defined (__EMX__)
-static void
-_emx_build_environ ()
-{
-  TIB *tibp;
-  PIB *pibp;
-  char *t, **tp;
-  int c;
-
-  DosGetInfoBlocks (&tibp, &pibp);
-  t = pibp->pib_pchenv;
-  for (c = 1; *t; c++)
-    t += strlen (t) + 1;
-  tp = environ = (char **)xmalloc ((c + 1) * sizeof (char *));
-  t = pibp->pib_pchenv;
-  while (*t)
-    {
-      *tp++ = t;
-      t += strlen (t) + 1;
-    }
-  *tp = 0;
-}
-#endif /* __EMX__ */
-#endif
-
-/* Initialize the entire state of the world. */
-static void
-readline_initialize_everything ()
-{
-#if 0
-#if defined (__EMX__)
-  if (environ == 0)
-    _emx_build_environ ();
-#endif
-#endif
-
-#if 0
-  /* Find out if we are running in Emacs -- UNUSED. */
-  running_in_emacs = sh_get_env_value ("EMACS") != (char *)0;
-#endif
-
-  /* Set up input and output if they are not already set up. */
-  if (!rl_instream)
-    rl_instream = stdin;
-
-  if (!rl_outstream)
-    rl_outstream = stdout;
-
-  /* Bind _rl_in_stream and _rl_out_stream immediately.  These values
-     may change, but they may also be used before readline_internal ()
-     is called. */
-  _rl_in_stream = rl_instream;
-  _rl_out_stream = rl_outstream;
-
-  /* Allocate data structures. */
-  if (rl_line_buffer == 0)
-    rl_line_buffer = (char *)xmalloc (rl_line_buffer_len = DEFAULT_BUFFER_SIZE);
-
-  /* Initialize the terminal interface. */
-  if (rl_terminal_name == 0)
-    rl_terminal_name = sh_get_env_value ("TERM");
-  _rl_init_terminal_io (rl_terminal_name);
-
-  /* Bind tty characters to readline functions. */
-  readline_default_bindings ();
-
-  /* Initialize the function names. */
-  rl_initialize_funmap ();
-
-  /* Decide whether we should automatically go into eight-bit mode. */
-  _rl_init_eightbit ();
-      
-  /* Read in the init file. */
-  rl_read_init_file ((char *)NULL);
-
-  /* XXX */
-  if (_rl_horizontal_scroll_mode && _rl_term_autowrap)
-    {
-      _rl_screenwidth--;
-      _rl_screenchars -= _rl_screenheight;
-    }
-
-  /* Override the effect of any `set keymap' assignments in the
-     inputrc file. */
-  rl_set_keymap_from_edit_mode ();
-
-  /* Try to bind a common arrow key prefix, if not already bound. */
-  bind_arrow_keys ();
-
-  /* Enable the meta key, if this terminal has one. */
-  if (_rl_enable_meta)
-    _rl_enable_meta_key ();
-
-  /* If the completion parser's default word break characters haven't
-     been set yet, then do so now. */
-  if (rl_completer_word_break_characters == (char *)NULL)
-    rl_completer_word_break_characters = (char *)rl_basic_word_break_characters;
-}
-
-/* If this system allows us to look at the values of the regular
-   input editing characters, then bind them to their readline
-   equivalents, iff the characters are not bound to keymaps. */
-static void
-readline_default_bindings ()
-{
-  if (_rl_bind_stty_chars)
-    rl_tty_set_default_bindings (_rl_keymap);
-}
-
-/* Reset the default bindings for the terminal special characters we're
-   interested in back to rl_insert and read the new ones. */
-static void
-reset_default_bindings ()
-{
-  if (_rl_bind_stty_chars)
-    {
-      rl_tty_unset_default_bindings (_rl_keymap);
-      rl_tty_set_default_bindings (_rl_keymap);
-    }
-}
-
-/* Bind some common arrow key sequences in MAP. */
-static void
-bind_arrow_keys_internal (map)
-     Keymap map;
-{
-  Keymap xkeymap;
-
-  xkeymap = _rl_keymap;
-  _rl_keymap = map;
-
-#if defined (__MSDOS__)
-  rl_bind_keyseq_if_unbound ("\033[0A", rl_get_previous_history);
-  rl_bind_keyseq_if_unbound ("\033[0B", rl_backward_char);
-  rl_bind_keyseq_if_unbound ("\033[0C", rl_forward_char);
-  rl_bind_keyseq_if_unbound ("\033[0D", rl_get_next_history);
-#endif
-
-  rl_bind_keyseq_if_unbound ("\033[A", rl_get_previous_history);
-  rl_bind_keyseq_if_unbound ("\033[B", rl_get_next_history);
-  rl_bind_keyseq_if_unbound ("\033[C", rl_forward_char);
-  rl_bind_keyseq_if_unbound ("\033[D", rl_backward_char);
-  rl_bind_keyseq_if_unbound ("\033[H", rl_beg_of_line);
-  rl_bind_keyseq_if_unbound ("\033[F", rl_end_of_line);
-
-  rl_bind_keyseq_if_unbound ("\033OA", rl_get_previous_history);
-  rl_bind_keyseq_if_unbound ("\033OB", rl_get_next_history);
-  rl_bind_keyseq_if_unbound ("\033OC", rl_forward_char);
-  rl_bind_keyseq_if_unbound ("\033OD", rl_backward_char);
-  rl_bind_keyseq_if_unbound ("\033OH", rl_beg_of_line);
-  rl_bind_keyseq_if_unbound ("\033OF", rl_end_of_line);
-
-#if defined (__MINGW32__)
-  rl_bind_keyseq_if_unbound ("\340H", rl_get_previous_history);
-  rl_bind_keyseq_if_unbound ("\340P", rl_get_next_history);
-  rl_bind_keyseq_if_unbound ("\340M", rl_forward_char);
-  rl_bind_keyseq_if_unbound ("\340K", rl_backward_char);
-#endif
-
-  _rl_keymap = xkeymap;
-}
-
-/* Try and bind the common arrow key prefixes after giving termcap and
-   the inputrc file a chance to bind them and create `real' keymaps
-   for the arrow key prefix. */
-static void
-bind_arrow_keys ()
-{
-  bind_arrow_keys_internal (emacs_standard_keymap);
-
-#if defined (VI_MODE)
-  bind_arrow_keys_internal (vi_movement_keymap);
-  /* Unbind vi_movement_keymap[ESC] to allow users to repeatedly hit ESC
-     in vi command mode while still allowing the arrow keys to work. */
-  if (vi_movement_keymap[ESC].type == ISKMAP)
-    rl_bind_keyseq_in_map ("\033", (rl_command_func_t *)NULL, vi_movement_keymap);
-  bind_arrow_keys_internal (vi_insertion_keymap);
-#endif
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*             Saving and Restoring Readline's state               */
-/*                                                                 */
-/* **************************************************************** */
-
-int
-rl_save_state (sp)
-     struct readline_state *sp;
-{
-  if (sp == 0)
-    return -1;
-
-  sp->point = rl_point;
-  sp->end = rl_end;
-  sp->mark = rl_mark;
-  sp->buffer = rl_line_buffer;
-  sp->buflen = rl_line_buffer_len;
-  sp->ul = rl_undo_list;
-  sp->prompt = rl_prompt;
-
-  sp->rlstate = rl_readline_state;
-  sp->done = rl_done;
-  sp->kmap = _rl_keymap;
-
-  sp->lastfunc = rl_last_func;
-  sp->insmode = rl_insert_mode;
-  sp->edmode = rl_editing_mode;
-  sp->kseqlen = rl_key_sequence_length;
-  sp->inf = rl_instream;
-  sp->outf = rl_outstream;
-  sp->pendingin = rl_pending_input;
-  sp->macro = rl_executing_macro;
-
-  sp->catchsigs = rl_catch_signals;
-  sp->catchsigwinch = rl_catch_sigwinch;
-
-  return (0);
-}
-
-int
-rl_restore_state (sp)
-     struct readline_state *sp;
-{
-  if (sp == 0)
-    return -1;
-
-  rl_point = sp->point;
-  rl_end = sp->end;
-  rl_mark = sp->mark;
-  the_line = rl_line_buffer = sp->buffer;
-  rl_line_buffer_len = sp->buflen;
-  rl_undo_list = sp->ul;
-  rl_prompt = sp->prompt;
-
-  rl_readline_state = sp->rlstate;
-  rl_done = sp->done;
-  _rl_keymap = sp->kmap;
-
-  rl_last_func = sp->lastfunc;
-  rl_insert_mode = sp->insmode;
-  rl_editing_mode = sp->edmode;
-  rl_key_sequence_length = sp->kseqlen;
-  rl_instream = sp->inf;
-  rl_outstream = sp->outf;
-  rl_pending_input = sp->pendingin;
-  rl_executing_macro = sp->macro;
-
-  rl_catch_signals = sp->catchsigs;
-  rl_catch_sigwinch = sp->catchsigwinch;
-
-  return (0);
-}
diff --git a/lib/readline/readline.h~ b/lib/readline/readline.h~
deleted file mode 100644 (file)
index c042d4e..0000000
+++ /dev/null
@@ -1,884 +0,0 @@
-/* Readline.h -- the names of functions callable from within readline. */
-
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
-
-   This file is part of the GNU Readline Library (Readline), a library
-   for reading lines of text with interactive input and history editing.      
-
-   Readline is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   Readline is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#if !defined (_READLINE_H_)
-#define _READLINE_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined (READLINE_LIBRARY)
-#  include "rlstdc.h"
-#  include "rltypedefs.h"
-#  include "keymaps.h"
-#  include "tilde.h"
-#else
-#  include <readline/rlstdc.h>
-#  include <readline/rltypedefs.h>
-#  include <readline/keymaps.h>
-#  include <readline/tilde.h>
-#endif
-
-/* Hex-encoded Readline version number. */
-#define RL_READLINE_VERSION    0x0600          /* Readline 6.0 */
-#define RL_VERSION_MAJOR       6
-#define RL_VERSION_MINOR       0
-
-/* Readline data structures. */
-
-/* Maintaining the state of undo.  We remember individual deletes and inserts
-   on a chain of things to do. */
-
-/* The actions that undo knows how to undo.  Notice that UNDO_DELETE means
-   to insert some text, and UNDO_INSERT means to delete some text.   I.e.,
-   the code tells undo what to undo, not how to undo it. */
-enum undo_code { UNDO_DELETE, UNDO_INSERT, UNDO_BEGIN, UNDO_END };
-
-/* What an element of THE_UNDO_LIST looks like. */
-typedef struct undo_list {
-  struct undo_list *next;
-  int start, end;              /* Where the change took place. */
-  char *text;                  /* The text to insert, if undoing a delete. */
-  enum undo_code what;         /* Delete, Insert, Begin, End. */
-} UNDO_LIST;
-
-/* The current undo list for RL_LINE_BUFFER. */
-extern UNDO_LIST *rl_undo_list;
-
-/* The data structure for mapping textual names to code addresses. */
-typedef struct _funmap {
-  const char *name;
-  rl_command_func_t *function;
-} FUNMAP;
-
-extern FUNMAP **funmap;
-
-/* **************************************************************** */
-/*                                                                 */
-/*          Functions available to bind to key sequences           */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Bindable commands for numeric arguments. */
-extern int rl_digit_argument PARAMS((int, int));
-extern int rl_universal_argument PARAMS((int, int));
-
-/* Bindable commands for moving the cursor. */
-extern int rl_forward_byte PARAMS((int, int));
-extern int rl_forward_char PARAMS((int, int));
-extern int rl_forward PARAMS((int, int));
-extern int rl_backward_byte PARAMS((int, int));
-extern int rl_backward_char PARAMS((int, int));
-extern int rl_backward PARAMS((int, int));
-extern int rl_beg_of_line PARAMS((int, int));
-extern int rl_end_of_line PARAMS((int, int));
-extern int rl_forward_word PARAMS((int, int));
-extern int rl_backward_word PARAMS((int, int));
-extern int rl_refresh_line PARAMS((int, int));
-extern int rl_clear_screen PARAMS((int, int));
-extern int rl_skip_csi_sequence PARAMS((int, int));
-extern int rl_arrow_keys PARAMS((int, int));
-
-/* Bindable commands for inserting and deleting text. */
-extern int rl_insert PARAMS((int, int));
-extern int rl_quoted_insert PARAMS((int, int));
-extern int rl_tab_insert PARAMS((int, int));
-extern int rl_newline PARAMS((int, int));
-extern int rl_do_lowercase_version PARAMS((int, int));
-extern int rl_rubout PARAMS((int, int));
-extern int rl_delete PARAMS((int, int));
-extern int rl_rubout_or_delete PARAMS((int, int));
-extern int rl_delete_horizontal_space PARAMS((int, int));
-extern int rl_delete_or_show_completions PARAMS((int, int));
-extern int rl_insert_comment PARAMS((int, int));
-
-/* Bindable commands for changing case. */
-extern int rl_upcase_word PARAMS((int, int));
-extern int rl_downcase_word PARAMS((int, int));
-extern int rl_capitalize_word PARAMS((int, int));
-
-/* Bindable commands for transposing characters and words. */
-extern int rl_transpose_words PARAMS((int, int));
-extern int rl_transpose_chars PARAMS((int, int));
-
-/* Bindable commands for searching within a line. */
-extern int rl_char_search PARAMS((int, int));
-extern int rl_backward_char_search PARAMS((int, int));
-
-/* Bindable commands for readline's interface to the command history. */
-extern int rl_beginning_of_history PARAMS((int, int));
-extern int rl_end_of_history PARAMS((int, int));
-extern int rl_get_next_history PARAMS((int, int));
-extern int rl_get_previous_history PARAMS((int, int));
-
-/* Bindable commands for managing the mark and region. */
-extern int rl_set_mark PARAMS((int, int));
-extern int rl_exchange_point_and_mark PARAMS((int, int));
-
-/* Bindable commands to set the editing mode (emacs or vi). */
-extern int rl_vi_editing_mode PARAMS((int, int));
-extern int rl_emacs_editing_mode PARAMS((int, int));
-
-/* Bindable commands to change the insert mode (insert or overwrite) */
-extern int rl_overwrite_mode PARAMS((int, int));
-
-/* Bindable commands for managing key bindings. */
-extern int rl_re_read_init_file PARAMS((int, int));
-extern int rl_dump_functions PARAMS((int, int));
-extern int rl_dump_macros PARAMS((int, int));
-extern int rl_dump_variables PARAMS((int, int));
-
-/* Bindable commands for word completion. */
-extern int rl_complete PARAMS((int, int));
-extern int rl_possible_completions PARAMS((int, int));
-extern int rl_insert_completions PARAMS((int, int));
-extern int rl_menu_complete PARAMS((int, int));
-extern int rl_backward_menu_complete PARAMS((int, int));
-
-/* Bindable commands for killing and yanking text, and managing the kill ring. */
-extern int rl_kill_word PARAMS((int, int));
-extern int rl_backward_kill_word PARAMS((int, int));
-extern int rl_kill_line PARAMS((int, int));
-extern int rl_backward_kill_line PARAMS((int, int));
-extern int rl_kill_full_line PARAMS((int, int));
-extern int rl_unix_word_rubout PARAMS((int, int));
-extern int rl_unix_filename_rubout PARAMS((int, int));
-extern int rl_unix_line_discard PARAMS((int, int));
-extern int rl_copy_region_to_kill PARAMS((int, int));
-extern int rl_kill_region PARAMS((int, int));
-extern int rl_copy_forward_word PARAMS((int, int));
-extern int rl_copy_backward_word PARAMS((int, int));
-extern int rl_yank PARAMS((int, int));
-extern int rl_yank_pop PARAMS((int, int));
-extern int rl_yank_nth_arg PARAMS((int, int));
-extern int rl_yank_last_arg PARAMS((int, int));
-/* Not available unless __CYGWIN__ is defined. */
-#ifdef __CYGWIN__
-extern int rl_paste_from_clipboard PARAMS((int, int));
-#endif
-
-/* Bindable commands for incremental searching. */
-extern int rl_reverse_search_history PARAMS((int, int));
-extern int rl_forward_search_history PARAMS((int, int));
-
-/* Bindable keyboard macro commands. */
-extern int rl_start_kbd_macro PARAMS((int, int));
-extern int rl_end_kbd_macro PARAMS((int, int));
-extern int rl_call_last_kbd_macro PARAMS((int, int));
-
-/* Bindable undo commands. */
-extern int rl_revert_line PARAMS((int, int));
-extern int rl_undo_command PARAMS((int, int));
-
-/* Bindable tilde expansion commands. */
-extern int rl_tilde_expand PARAMS((int, int));
-
-/* Bindable terminal control commands. */
-extern int rl_restart_output PARAMS((int, int));
-extern int rl_stop_output PARAMS((int, int));
-
-/* Miscellaneous bindable commands. */
-extern int rl_abort PARAMS((int, int));
-extern int rl_tty_status PARAMS((int, int));
-
-/* Bindable commands for incremental and non-incremental history searching. */
-extern int rl_history_search_forward PARAMS((int, int));
-extern int rl_history_search_backward PARAMS((int, int));
-extern int rl_noninc_forward_search PARAMS((int, int));
-extern int rl_noninc_reverse_search PARAMS((int, int));
-extern int rl_noninc_forward_search_again PARAMS((int, int));
-extern int rl_noninc_reverse_search_again PARAMS((int, int));
-
-/* Bindable command used when inserting a matching close character. */
-extern int rl_insert_close PARAMS((int, int));
-
-/* Not available unless READLINE_CALLBACKS is defined. */
-extern void rl_callback_handler_install PARAMS((const char *, rl_vcpfunc_t *));
-extern void rl_callback_read_char PARAMS((void));
-extern void rl_callback_handler_remove PARAMS((void));
-
-/* Things for vi mode. Not available unless readline is compiled -DVI_MODE. */
-/* VI-mode bindable commands. */
-extern int rl_vi_redo PARAMS((int, int));
-extern int rl_vi_undo PARAMS((int, int));
-extern int rl_vi_yank_arg PARAMS((int, int));
-extern int rl_vi_fetch_history PARAMS((int, int));
-extern int rl_vi_search_again PARAMS((int, int));
-extern int rl_vi_search PARAMS((int, int));
-extern int rl_vi_complete PARAMS((int, int));
-extern int rl_vi_tilde_expand PARAMS((int, int));
-extern int rl_vi_prev_word PARAMS((int, int));
-extern int rl_vi_next_word PARAMS((int, int));
-extern int rl_vi_end_word PARAMS((int, int));
-extern int rl_vi_insert_beg PARAMS((int, int));
-extern int rl_vi_append_mode PARAMS((int, int));
-extern int rl_vi_append_eol PARAMS((int, int));
-extern int rl_vi_eof_maybe PARAMS((int, int));
-extern int rl_vi_insertion_mode PARAMS((int, int));
-extern int rl_vi_insert_mode PARAMS((int, int));
-extern int rl_vi_movement_mode PARAMS((int, int));
-extern int rl_vi_arg_digit PARAMS((int, int));
-extern int rl_vi_change_case PARAMS((int, int));
-extern int rl_vi_put PARAMS((int, int));
-extern int rl_vi_column PARAMS((int, int));
-extern int rl_vi_delete_to PARAMS((int, int));
-extern int rl_vi_change_to PARAMS((int, int));
-extern int rl_vi_yank_to PARAMS((int, int));
-extern int rl_vi_rubout PARAMS((int, int));
-extern int rl_vi_delete PARAMS((int, int));
-extern int rl_vi_back_to_indent PARAMS((int, int));
-extern int rl_vi_first_print PARAMS((int, int));
-extern int rl_vi_char_search PARAMS((int, int));
-extern int rl_vi_match PARAMS((int, int));
-extern int rl_vi_change_char PARAMS((int, int));
-extern int rl_vi_subst PARAMS((int, int));
-extern int rl_vi_overstrike PARAMS((int, int));
-extern int rl_vi_overstrike_delete PARAMS((int, int));
-extern int rl_vi_replace PARAMS((int, int));
-extern int rl_vi_set_mark PARAMS((int, int));
-extern int rl_vi_goto_mark PARAMS((int, int));
-
-/* VI-mode utility functions. */
-extern int rl_vi_check PARAMS((void));
-extern int rl_vi_domove PARAMS((int, int *));
-extern int rl_vi_bracktype PARAMS((int));
-
-extern void rl_vi_start_inserting PARAMS((int, int, int));
-
-/* VI-mode pseudo-bindable commands, used as utility functions. */
-extern int rl_vi_fWord PARAMS((int, int));
-extern int rl_vi_bWord PARAMS((int, int));
-extern int rl_vi_eWord PARAMS((int, int));
-extern int rl_vi_fword PARAMS((int, int));
-extern int rl_vi_bword PARAMS((int, int));
-extern int rl_vi_eword PARAMS((int, int));
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Well Published Functions                    */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Readline functions. */
-/* Read a line of input.  Prompt with PROMPT.  A NULL PROMPT means none. */
-extern char *readline PARAMS((const char *));
-
-extern int rl_set_prompt PARAMS((const char *));
-extern int rl_expand_prompt PARAMS((char *));
-
-extern int rl_initialize PARAMS((void));
-
-/* Undocumented; unused by readline */
-extern int rl_discard_argument PARAMS((void));
-
-/* Utility functions to bind keys to readline commands. */
-extern int rl_add_defun PARAMS((const char *, rl_command_func_t *, int));
-extern int rl_bind_key PARAMS((int, rl_command_func_t *));
-extern int rl_bind_key_in_map PARAMS((int, rl_command_func_t *, Keymap));
-extern int rl_unbind_key PARAMS((int));
-extern int rl_unbind_key_in_map PARAMS((int, Keymap));
-extern int rl_bind_key_if_unbound PARAMS((int, rl_command_func_t *));
-extern int rl_bind_key_if_unbound_in_map PARAMS((int, rl_command_func_t *, Keymap));
-extern int rl_unbind_function_in_map PARAMS((rl_command_func_t *, Keymap));
-extern int rl_unbind_command_in_map PARAMS((const char *, Keymap));
-extern int rl_bind_keyseq PARAMS((const char *, rl_command_func_t *));
-extern int rl_bind_keyseq_in_map PARAMS((const char *, rl_command_func_t *, Keymap));
-extern int rl_bind_keyseq_if_unbound PARAMS((const char *, rl_command_func_t *));
-extern int rl_bind_keyseq_if_unbound_in_map PARAMS((const char *, rl_command_func_t *, Keymap));
-extern int rl_generic_bind PARAMS((int, const char *, char *, Keymap));
-
-extern char *rl_variable_value PARAMS((const char *));
-extern int rl_variable_bind PARAMS((const char *, const char *));
-
-/* Backwards compatibility, use rl_bind_keyseq_in_map instead. */
-extern int rl_set_key PARAMS((const char *, rl_command_func_t *, Keymap));
-
-/* Backwards compatibility, use rl_generic_bind instead. */
-extern int rl_macro_bind PARAMS((const char *, const char *, Keymap));
-
-/* Undocumented in the texinfo manual; not really useful to programs. */
-extern int rl_translate_keyseq PARAMS((const char *, char *, int *));
-extern char *rl_untranslate_keyseq PARAMS((int));
-
-extern rl_command_func_t *rl_named_function PARAMS((const char *));
-extern rl_command_func_t *rl_function_of_keyseq PARAMS((const char *, Keymap, int *));
-
-extern void rl_list_funmap_names PARAMS((void));
-extern char **rl_invoking_keyseqs_in_map PARAMS((rl_command_func_t *, Keymap));
-extern char **rl_invoking_keyseqs PARAMS((rl_command_func_t *));
-extern void rl_function_dumper PARAMS((int));
-extern void rl_macro_dumper PARAMS((int));
-extern void rl_variable_dumper PARAMS((int));
-
-extern int rl_read_init_file PARAMS((const char *));
-extern int rl_parse_and_bind PARAMS((char *));
-
-/* Functions for manipulating keymaps. */
-extern Keymap rl_make_bare_keymap PARAMS((void));
-extern Keymap rl_copy_keymap PARAMS((Keymap));
-extern Keymap rl_make_keymap PARAMS((void));
-extern void rl_discard_keymap PARAMS((Keymap));
-
-extern Keymap rl_get_keymap_by_name PARAMS((const char *));
-extern char *rl_get_keymap_name PARAMS((Keymap));
-extern void rl_set_keymap PARAMS((Keymap));
-extern Keymap rl_get_keymap PARAMS((void));
-/* Undocumented; used internally only. */
-extern void rl_set_keymap_from_edit_mode PARAMS((void));
-extern char *rl_get_keymap_name_from_edit_mode PARAMS((void));
-
-/* Functions for manipulating the funmap, which maps command names to functions. */
-extern int rl_add_funmap_entry PARAMS((const char *, rl_command_func_t *));
-extern const char **rl_funmap_names PARAMS((void));
-/* Undocumented, only used internally -- there is only one funmap, and this
-   function may be called only once. */
-extern void rl_initialize_funmap PARAMS((void));
-
-/* Utility functions for managing keyboard macros. */
-extern void rl_push_macro_input PARAMS((char *));
-
-/* Functions for undoing, from undo.c */
-extern void rl_add_undo PARAMS((enum undo_code, int, int, char *));
-extern void rl_free_undo_list PARAMS((void));
-extern int rl_do_undo PARAMS((void));
-extern int rl_begin_undo_group PARAMS((void));
-extern int rl_end_undo_group PARAMS((void));
-extern int rl_modifying PARAMS((int, int));
-
-/* Functions for redisplay. */
-extern void rl_redisplay PARAMS((void));
-extern int rl_on_new_line PARAMS((void));
-extern int rl_on_new_line_with_prompt PARAMS((void));
-extern int rl_forced_update_display PARAMS((void));
-extern int rl_clear_message PARAMS((void));
-extern int rl_reset_line_state PARAMS((void));
-extern int rl_crlf PARAMS((void));
-
-#if defined (USE_VARARGS) && defined (PREFER_STDARG)
-extern int rl_message (const char *, ...)  __attribute__((__format__ (printf, 1, 2)));
-#else
-extern int rl_message ();
-#endif
-
-extern int rl_show_char PARAMS((int));
-
-/* Undocumented in texinfo manual. */
-extern int rl_character_len PARAMS((int, int));
-
-/* Save and restore internal prompt redisplay information. */
-extern void rl_save_prompt PARAMS((void));
-extern void rl_restore_prompt PARAMS((void));
-
-/* Modifying text. */
-extern void rl_replace_line PARAMS((const char *, int));
-extern int rl_insert_text PARAMS((const char *));
-extern int rl_delete_text PARAMS((int, int));
-extern int rl_kill_text PARAMS((int, int));
-extern char *rl_copy_text PARAMS((int, int));
-
-/* Terminal and tty mode management. */
-extern void rl_prep_terminal PARAMS((int));
-extern void rl_deprep_terminal PARAMS((void));
-extern void rl_tty_set_default_bindings PARAMS((Keymap));
-extern void rl_tty_unset_default_bindings PARAMS((Keymap));
-
-extern int rl_reset_terminal PARAMS((const char *));
-extern void rl_resize_terminal PARAMS((void));
-extern void rl_set_screen_size PARAMS((int, int));
-extern void rl_get_screen_size PARAMS((int *, int *));
-extern void rl_reset_screen_size PARAMS((void));
-
-extern char *rl_get_termcap PARAMS((const char *));
-
-/* Functions for character input. */
-extern int rl_stuff_char PARAMS((int));
-extern int rl_execute_next PARAMS((int));
-extern int rl_clear_pending_input PARAMS((void));
-extern int rl_read_key PARAMS((void));
-extern int rl_getc PARAMS((FILE *));
-extern int rl_set_keyboard_input_timeout PARAMS((int));
-
-/* `Public' utility functions . */
-extern void rl_extend_line_buffer PARAMS((int));
-extern int rl_ding PARAMS((void));
-extern int rl_alphabetic PARAMS((int));
-extern void rl_free PARAMS((void *));
-
-/* Readline signal handling, from signals.c */
-extern int rl_set_signals PARAMS((void));
-extern int rl_clear_signals PARAMS((void));
-extern void rl_cleanup_after_signal PARAMS((void));
-extern void rl_reset_after_signal PARAMS((void));
-extern void rl_free_line_state PARAMS((void));
-
-extern void rl_echo_signal_char PARAMS((int)); 
-
-extern int rl_set_paren_blink_timeout PARAMS((int));
-
-/* Undocumented. */
-extern int rl_maybe_save_line PARAMS((void));
-extern int rl_maybe_unsave_line PARAMS((void));
-extern int rl_maybe_replace_line PARAMS((void));
-
-/* Completion functions. */
-extern int rl_complete_internal PARAMS((int));
-extern void rl_display_match_list PARAMS((char **, int, int));
-
-extern char **rl_completion_matches PARAMS((const char *, rl_compentry_func_t *));
-extern char *rl_username_completion_function PARAMS((const char *, int));
-extern char *rl_filename_completion_function PARAMS((const char *, int));
-
-extern int rl_completion_mode PARAMS((rl_command_func_t *));
-
-#if 0
-/* Backwards compatibility (compat.c).  These will go away sometime. */
-extern void free_undo_list PARAMS((void));
-extern int maybe_save_line PARAMS((void));
-extern int maybe_unsave_line PARAMS((void));
-extern int maybe_replace_line PARAMS((void));
-
-extern int ding PARAMS((void));
-extern int alphabetic PARAMS((int));
-extern int crlf PARAMS((void));
-
-extern char **completion_matches PARAMS((char *, rl_compentry_func_t *));
-extern char *username_completion_function PARAMS((const char *, int));
-extern char *filename_completion_function PARAMS((const char *, int));
-#endif
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Well Published Variables                    */
-/*                                                                 */
-/* **************************************************************** */
-
-/* The version of this incarnation of the readline library. */
-extern const char *rl_library_version;         /* e.g., "4.2" */
-extern int rl_readline_version;                        /* e.g., 0x0402 */
-
-/* True if this is real GNU readline. */
-extern int rl_gnu_readline_p;
-
-/* Flags word encapsulating the current readline state. */
-extern int rl_readline_state;
-
-/* Says which editing mode readline is currently using.  1 means emacs mode;
-   0 means vi mode. */
-extern int rl_editing_mode;
-
-/* Insert or overwrite mode for emacs mode.  1 means insert mode; 0 means
-   overwrite mode.  Reset to insert mode on each input line. */
-extern int rl_insert_mode;
-
-/* The name of the calling program.  You should initialize this to
-   whatever was in argv[0].  It is used when parsing conditionals. */
-extern const char *rl_readline_name;
-
-/* The prompt readline uses.  This is set from the argument to
-   readline (), and should not be assigned to directly. */
-extern char *rl_prompt;
-
-/* The prompt string that is actually displayed by rl_redisplay.  Public so
-   applications can more easily supply their own redisplay functions. */
-extern char *rl_display_prompt;
-
-/* The line buffer that is in use. */
-extern char *rl_line_buffer;
-
-/* The location of point, and end. */
-extern int rl_point;
-extern int rl_end;
-
-/* The mark, or saved cursor position. */
-extern int rl_mark;
-
-/* Flag to indicate that readline has finished with the current input
-   line and should return it. */
-extern int rl_done;
-
-/* If set to a character value, that will be the next keystroke read. */
-extern int rl_pending_input;
-
-/* Non-zero if we called this function from _rl_dispatch().  It's present
-   so functions can find out whether they were called from a key binding
-   or directly from an application. */
-extern int rl_dispatching;
-
-/* Non-zero if the user typed a numeric argument before executing the
-   current function. */
-extern int rl_explicit_arg;
-
-/* The current value of the numeric argument specified by the user. */
-extern int rl_numeric_arg;
-
-/* The address of the last command function Readline executed. */
-extern rl_command_func_t *rl_last_func;
-
-/* The name of the terminal to use. */
-extern const char *rl_terminal_name;
-
-/* The input and output streams. */
-extern FILE *rl_instream;
-extern FILE *rl_outstream;
-
-/* If non-zero, Readline gives values of LINES and COLUMNS from the environment
-   greater precedence than values fetched from the kernel when computing the
-   screen dimensions. */
-extern int rl_prefer_env_winsize;
-
-/* If non-zero, then this is the address of a function to call just
-   before readline_internal () prints the first prompt. */
-extern rl_hook_func_t *rl_startup_hook;
-
-/* If non-zero, this is the address of a function to call just before
-   readline_internal_setup () returns and readline_internal starts
-   reading input characters. */
-extern rl_hook_func_t *rl_pre_input_hook;
-      
-/* The address of a function to call periodically while Readline is
-   awaiting character input, or NULL, for no event handling. */
-extern rl_hook_func_t *rl_event_hook;
-
-/* The address of the function to call to fetch a character from the current
-   Readline input stream */
-extern rl_getc_func_t *rl_getc_function;
-
-extern rl_voidfunc_t *rl_redisplay_function;
-
-extern rl_vintfunc_t *rl_prep_term_function;
-extern rl_voidfunc_t *rl_deprep_term_function;
-
-/* Dispatch variables. */
-extern Keymap rl_executing_keymap;
-extern Keymap rl_binding_keymap;
-
-/* Display variables. */
-/* If non-zero, readline will erase the entire line, including any prompt,
-   if the only thing typed on an otherwise-blank line is something bound to
-   rl_newline. */
-extern int rl_erase_empty_line;
-
-/* If non-zero, the application has already printed the prompt (rl_prompt)
-   before calling readline, so readline should not output it the first time
-   redisplay is done. */
-extern int rl_already_prompted;
-
-/* A non-zero value means to read only this many characters rather than
-   up to a character bound to accept-line. */
-extern int rl_num_chars_to_read;
-
-/* The text of a currently-executing keyboard macro. */
-extern char *rl_executing_macro;
-
-/* Variables to control readline signal handling. */
-/* If non-zero, readline will install its own signal handlers for
-   SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */
-extern int rl_catch_signals;
-
-/* If non-zero, readline will install a signal handler for SIGWINCH
-   that also attempts to call any calling application's SIGWINCH signal
-   handler.  Note that the terminal is not cleaned up before the
-   application's signal handler is called; use rl_cleanup_after_signal()
-   to do that. */
-extern int rl_catch_sigwinch;
-
-/* Completion variables. */
-/* Pointer to the generator function for completion_matches ().
-   NULL means to use rl_filename_completion_function (), the default
-   filename completer. */
-extern rl_compentry_func_t *rl_completion_entry_function;
-
-/* Optional generator for menu completion.  Default is
-   rl_completion_entry_function (rl_filename_completion_function). */
- extern rl_compentry_func_t *rl_menu_completion_entry_function;
-
-/* If rl_ignore_some_completions_function is non-NULL it is the address
-   of a function to call after all of the possible matches have been
-   generated, but before the actual completion is done to the input line.
-   The function is called with one argument; a NULL terminated array
-   of (char *).  If your function removes any of the elements, they
-   must be free()'ed. */
-extern rl_compignore_func_t *rl_ignore_some_completions_function;
-
-/* Pointer to alternative function to create matches.
-   Function is called with TEXT, START, and END.
-   START and END are indices in RL_LINE_BUFFER saying what the boundaries
-   of TEXT are.
-   If this function exists and returns NULL then call the value of
-   rl_completion_entry_function to try to match, otherwise use the
-   array of strings returned. */
-extern rl_completion_func_t *rl_attempted_completion_function;
-
-/* The basic list of characters that signal a break between words for the
-   completer routine.  The initial contents of this variable is what
-   breaks words in the shell, i.e. "n\"\\'`@$>". */
-extern const char *rl_basic_word_break_characters;
-
-/* The list of characters that signal a break between words for
-   rl_complete_internal.  The default list is the contents of
-   rl_basic_word_break_characters.  */
-extern /*const*/ char *rl_completer_word_break_characters;
-
-/* Hook function to allow an application to set the completion word
-   break characters before readline breaks up the line.  Allows
-   position-dependent word break characters. */
-extern rl_cpvfunc_t *rl_completion_word_break_hook;
-
-/* List of characters which can be used to quote a substring of the line.
-   Completion occurs on the entire substring, and within the substring   
-   rl_completer_word_break_characters are treated as any other character,
-   unless they also appear within this list. */
-extern const char *rl_completer_quote_characters;
-
-/* List of quote characters which cause a word break. */
-extern const char *rl_basic_quote_characters;
-
-/* List of characters that need to be quoted in filenames by the completer. */
-extern const char *rl_filename_quote_characters;
-
-/* List of characters that are word break characters, but should be left
-   in TEXT when it is passed to the completion function.  The shell uses
-   this to help determine what kind of completing to do. */
-extern const char *rl_special_prefixes;
-
-/* If non-zero, then this is the address of a function to call when
-   completing on a directory name.  The function is called with
-   the address of a string (the current directory name) as an arg.  It
-   changes what is displayed when the possible completions are printed
-   or inserted. */
-extern rl_icppfunc_t *rl_directory_completion_hook;
-
-/* If non-zero, this is the address of a function to call when completing
-   a directory name.  This function takes the address of the directory name
-   to be modified as an argument.  Unlike rl_directory_completion_hook, it
-   only modifies the directory name used in opendir(2), not what is displayed
-   when the possible completions are printed or inserted.  It is called
-   before rl_directory_completion_hook.  I'm not happy with how this works
-   yet, so it's undocumented. */
-extern rl_icppfunc_t *rl_directory_rewrite_hook;
-
-/* If non-zero, this is the address of a function to call when reading
-   directory entries from the filesystem for completion and comparing
-   them to the partial word to be completed.  The function should
-   either return its first argument (if no conversion takes place) or
-   newly-allocated memory.  This can, for instance, convert filenames
-   between character sets for comparison against what's typed at the
-   keyboard.  The returned value is what is added to the list of
-   matches.  The second argument is the length of the filename to be
-   converted. */
-extern rl_dequote_func_t *rl_filename_rewrite_hook;
-
-/* Backwards compatibility with previous versions of readline. */
-#define rl_symbolic_link_hook rl_directory_completion_hook
-
-/* If non-zero, then this is the address of a function to call when
-   completing a word would normally display the list of possible matches.
-   This function is called instead of actually doing the display.
-   It takes three arguments: (char **matches, int num_matches, int max_length)
-   where MATCHES is the array of strings that matched, NUM_MATCHES is the
-   number of strings in that array, and MAX_LENGTH is the length of the
-   longest string in that array. */
-extern rl_compdisp_func_t *rl_completion_display_matches_hook;
-
-/* Non-zero means that the results of the matches are to be treated
-   as filenames.  This is ALWAYS zero on entry, and can only be changed
-   within a completion entry finder function. */
-extern int rl_filename_completion_desired;
-
-/* Non-zero means that the results of the matches are to be quoted using
-   double quotes (or an application-specific quoting mechanism) if the
-   filename contains any characters in rl_word_break_chars.  This is
-   ALWAYS non-zero on entry, and can only be changed within a completion
-   entry finder function. */
-extern int rl_filename_quoting_desired;
-
-/* Set to a function to quote a filename in an application-specific fashion.
-   Called with the text to quote, the type of match found (single or multiple)
-   and a pointer to the quoting character to be used, which the function can
-   reset if desired. */
-extern rl_quote_func_t *rl_filename_quoting_function;
-
-/* Function to call to remove quoting characters from a filename.  Called
-   before completion is attempted, so the embedded quotes do not interfere
-   with matching names in the file system. */
-extern rl_dequote_func_t *rl_filename_dequoting_function;
-
-/* Function to call to decide whether or not a word break character is
-   quoted.  If a character is quoted, it does not break words for the
-   completer. */
-extern rl_linebuf_func_t *rl_char_is_quoted_p;
-
-/* Non-zero means to suppress normal filename completion after the
-   user-specified completion function has been called. */
-extern int rl_attempted_completion_over;
-
-/* Set to a character describing the type of completion being attempted by
-   rl_complete_internal; available for use by application completion
-   functions. */
-extern int rl_completion_type;
-
-/* Set to the last key used to invoke one of the completion functions */
-extern int rl_completion_invoking_key;
-
-/* Up to this many items will be displayed in response to a
-   possible-completions call.  After that, we ask the user if she
-   is sure she wants to see them all.  The default value is 100. */
-extern int rl_completion_query_items;
-
-/* Character appended to completed words when at the end of the line.  The
-   default is a space.  Nothing is added if this is '\0'. */
-extern int rl_completion_append_character;
-
-/* If set to non-zero by an application completion function,
-   rl_completion_append_character will not be appended. */
-extern int rl_completion_suppress_append;
-
-/* Set to any quote character readline thinks it finds before any application
-   completion function is called. */
-extern int rl_completion_quote_character;
-
-/* Set to a non-zero value if readline found quoting anywhere in the word to
-   be completed; set before any application completion function is called. */
-extern int rl_completion_found_quote;
-
-/* If non-zero, the completion functions don't append any closing quote.
-   This is set to 0 by rl_complete_internal and may be changed by an
-   application-specific completion function. */
-extern int rl_completion_suppress_quote;
-
-/* If non-zero, readline will sort the completion matches.  On by default. */
-extern int rl_sort_completion_matches;
-
-/* If non-zero, a slash will be appended to completed filenames that are
-   symbolic links to directory names, subject to the value of the
-   mark-directories variable (which is user-settable).  This exists so
-   that application completion functions can override the user's preference
-   (set via the mark-symlinked-directories variable) if appropriate.
-   It's set to the value of _rl_complete_mark_symlink_dirs in
-   rl_complete_internal before any application-specific completion
-   function is called, so without that function doing anything, the user's
-   preferences are honored. */
-extern int rl_completion_mark_symlink_dirs;
-
-/* If non-zero, then disallow duplicates in the matches. */
-extern int rl_ignore_completion_duplicates;
-
-/* If this is non-zero, completion is (temporarily) inhibited, and the
-   completion character will be inserted as any other. */
-extern int rl_inhibit_completion;
-
-/* Input error; can be returned by (*rl_getc_function) if readline is reading
-   a top-level command (RL_ISSTATE (RL_STATE_READCMD)). */
-#define READERR                        (-2)
-
-/* Definitions available for use by readline clients. */
-#define RL_PROMPT_START_IGNORE '\001'
-#define RL_PROMPT_END_IGNORE   '\002'
-
-/* Possible values for do_replace argument to rl_filename_quoting_function,
-   called by rl_complete_internal. */
-#define NO_MATCH        0
-#define SINGLE_MATCH    1
-#define MULT_MATCH      2
-
-/* Possible state values for rl_readline_state */
-#define RL_STATE_NONE          0x000000                /* no state; before first call */
-
-#define RL_STATE_INITIALIZING  0x000001        /* initializing */
-#define RL_STATE_INITIALIZED   0x000002        /* initialization done */
-#define RL_STATE_TERMPREPPED   0x000004        /* terminal is prepped */
-#define RL_STATE_READCMD       0x000008        /* reading a command key */
-#define RL_STATE_METANEXT      0x000010        /* reading input after ESC */
-#define RL_STATE_DISPATCHING   0x000020        /* dispatching to a command */
-#define RL_STATE_MOREINPUT     0x000040        /* reading more input in a command function */
-#define RL_STATE_ISEARCH       0x000080        /* doing incremental search */
-#define RL_STATE_NSEARCH       0x000100        /* doing non-inc search */
-#define RL_STATE_SEARCH                0x000200        /* doing a history search */
-#define RL_STATE_NUMERICARG    0x000400        /* reading numeric argument */
-#define RL_STATE_MACROINPUT    0x000800        /* getting input from a macro */
-#define RL_STATE_MACRODEF      0x001000        /* defining keyboard macro */
-#define RL_STATE_OVERWRITE     0x002000        /* overwrite mode */
-#define RL_STATE_COMPLETING    0x004000        /* doing completion */
-#define RL_STATE_SIGHANDLER    0x008000        /* in readline sighandler */
-#define RL_STATE_UNDOING       0x010000        /* doing an undo */
-#define RL_STATE_INPUTPENDING  0x020000        /* rl_execute_next called */
-#define RL_STATE_TTYCSAVED     0x040000        /* tty special chars saved */
-#define RL_STATE_CALLBACK      0x080000        /* using the callback interface */
-#define RL_STATE_VIMOTION      0x100000        /* reading vi motion arg */
-#define RL_STATE_MULTIKEY      0x200000        /* reading multiple-key command */
-#define RL_STATE_VICMDONCE     0x400000        /* entered vi command mode at least once */
-#define RL_STATE_REDISPLAYING  0x800000        /* updating terminal display */
-
-#define RL_STATE_DONE          0x1000000       /* done; accepted line */
-
-#define RL_SETSTATE(x)         (rl_readline_state |= (x))
-#define RL_UNSETSTATE(x)       (rl_readline_state &= ~(x))
-#define RL_ISSTATE(x)          (rl_readline_state & (x))
-
-struct readline_state {
-  /* line state */
-  int point;
-  int end;
-  int mark;
-  char *buffer;
-  int buflen;
-  UNDO_LIST *ul;
-  char *prompt;
-
-  /* global state */
-  int rlstate;
-  int done;
-  Keymap kmap;
-
-  /* input state */
-  rl_command_func_t *lastfunc;
-  int insmode;
-  int edmode;
-  int kseqlen;
-  FILE *inf;
-  FILE *outf;
-  int pendingin;
-  char *macro;
-
-  /* signal state */
-  int catchsigs;
-  int catchsigwinch;
-
-  /* search state */
-
-  /* completion state */
-
-  /* options state */
-
-  /* reserved for future expansion, so the struct size doesn't change */
-  char reserved[64];
-};
-
-extern int rl_save_state PARAMS((struct readline_state *));
-extern int rl_restore_state PARAMS((struct readline_state *));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _READLINE_H_ */
diff --git a/lib/readline/rlprivate.h~ b/lib/readline/rlprivate.h~
deleted file mode 100644 (file)
index 492185b..0000000
+++ /dev/null
@@ -1,473 +0,0 @@
-/* rlprivate.h -- functions and variables global to the readline library,
-                 but not intended for use by applications. */
-
-/* Copyright (C) 1999-2009 Free Software Foundation, Inc.
-
-   This file is part of the GNU Readline Library (Readline), a library
-   for reading lines of text with interactive input and history editing.      
-
-   Readline is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   Readline is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#if !defined (_RL_PRIVATE_H_)
-#define _RL_PRIVATE_H_
-
-#include "rlconf.h"    /* for VISIBLE_STATS */
-#include "rlstdc.h"
-#include "posixjmp.h"  /* defines procenv_t */
-
-/*************************************************************************
- *                                                                      *
- * Convenience definitions                                              *
- *                                                                      *
- *************************************************************************/
-
-#define EMACS_MODE()           (rl_editing_mode == emacs_mode)
-#define VI_COMMAND_MODE()      (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap)
-#define VI_INSERT_MODE()       (rl_editing_mode == vi_mode && _rl_keymap == vi_insertion_keymap)
-
-#define RL_CHECK_SIGNALS() \
-       do { \
-         if (_rl_caught_signal) _rl_signal_handler (_rl_caught_signal); \
-       } while (0)
-
-/*************************************************************************
- *                                                                      *
- * Global structs undocumented in texinfo manual and not in readline.h   *
- *                                                                      *
- *************************************************************************/
-/* search types */
-#define RL_SEARCH_ISEARCH      0x01            /* incremental search */
-#define RL_SEARCH_NSEARCH      0x02            /* non-incremental search */
-#define RL_SEARCH_CSEARCH      0x04            /* intra-line char search */
-
-/* search flags */
-#define SF_REVERSE             0x01
-#define SF_FOUND               0x02
-#define SF_FAILED              0x04
-
-typedef struct  __rl_search_context
-{
-  int type;
-  int sflags;
-
-  char *search_string;
-  int search_string_index;
-  int search_string_size;
-
-  char **lines;
-  char *allocated_line;    
-  int hlen;
-  int hindex;
-
-  int save_point;
-  int save_mark;
-  int save_line;
-  int last_found_line;
-  char *prev_line_found;
-
-  UNDO_LIST *save_undo_list;
-
-  int history_pos;
-  int direction;
-
-  int lastc;
-#if defined (HANDLE_MULTIBYTE)
-  char mb[MB_LEN_MAX];
-#endif
-
-  char *sline;
-  int sline_len;
-  int sline_index;
-
-  char  *search_terminators;
-} _rl_search_cxt;
-
-/* Callback data for reading numeric arguments */
-#define NUM_SAWMINUS   0x01
-#define NUM_SAWDIGITS  0x02
-#define NUM_READONE    0x04
-
-typedef int _rl_arg_cxt;
-
-/* A context for reading key sequences longer than a single character when
-   using the callback interface. */
-#define KSEQ_DISPATCHED        0x01
-#define KSEQ_SUBSEQ    0x02
-#define KSEQ_RECURSIVE 0x04
-
-typedef struct __rl_keyseq_context
-{
-  int flags;
-  int subseq_arg;
-  int subseq_retval;           /* XXX */
-  Keymap dmap;
-
-  Keymap oldmap;
-  int okey;
-  struct __rl_keyseq_context *ocxt;
-  int childval;
-} _rl_keyseq_cxt;
-
-  /* fill in more as needed */
-/* `Generic' callback data and functions */
-typedef struct __rl_callback_generic_arg 
-{
-  int count;
-  int i1, i2;
-  /* add here as needed */
-} _rl_callback_generic_arg;
-
-typedef int _rl_callback_func_t PARAMS((_rl_callback_generic_arg *));
-
-/*************************************************************************
- *                                                                      *
- * Global functions undocumented in texinfo manual and not in readline.h *
- *                                                                      *
- *************************************************************************/
-
-/*************************************************************************
- *                                                                      *
- * Global variables undocumented in texinfo manual and not in readline.h *
- *                                                                      *
- *************************************************************************/
-
-/* complete.c */
-extern int rl_complete_with_tilde_expansion;
-#if defined (VISIBLE_STATS)
-extern int rl_visible_stats;
-#endif /* VISIBLE_STATS */
-
-/* readline.c */
-extern int rl_line_buffer_len;
-extern int rl_arg_sign;
-extern int rl_visible_prompt_length;
-extern int rl_key_sequence_length;
-extern int rl_byte_oriented;
-
-/* display.c */
-extern int rl_display_fixed;
-
-/* parens.c */
-extern int rl_blink_matching_paren;
-
-/*************************************************************************
- *                                                                      *
- * Global functions and variables unsed and undocumented                *
- *                                                                      *
- *************************************************************************/
-
-/* kill.c */
-extern int rl_set_retained_kills PARAMS((int));
-
-/* terminal.c */
-extern void _rl_set_screen_size PARAMS((int, int));
-
-/* undo.c */
-extern int _rl_fix_last_undo_of_type PARAMS((int, int, int));
-
-/* util.c */
-extern char *_rl_savestring PARAMS((const char *));
-
-/*************************************************************************
- *                                                                      *
- * Functions and variables private to the readline library              *
- *                                                                      *
- *************************************************************************/
-
-/* NOTE: Functions and variables prefixed with `_rl_' are
-   pseudo-global: they are global so they can be shared
-   between files in the readline library, but are not intended
-   to be visible to readline callers. */
-
-/*************************************************************************
- * Undocumented private functions                                       *
- *************************************************************************/
-
-#if defined(READLINE_CALLBACKS)
-
-/* readline.c */
-extern void readline_internal_setup PARAMS((void));
-extern char *readline_internal_teardown PARAMS((int));
-extern int readline_internal_char PARAMS((void));
-
-extern _rl_keyseq_cxt *_rl_keyseq_cxt_alloc PARAMS((void));
-extern void _rl_keyseq_cxt_dispose PARAMS((_rl_keyseq_cxt *));
-extern void _rl_keyseq_chain_dispose PARAMS((void));
-
-extern int _rl_dispatch_callback PARAMS((_rl_keyseq_cxt *));
-     
-/* callback.c */
-extern _rl_callback_generic_arg *_rl_callback_data_alloc PARAMS((int));
-extern void _rl_callback_data_dispose PARAMS((_rl_callback_generic_arg *));
-
-#endif /* READLINE_CALLBACKS */
-
-/* bind.c */
-
-/* complete.c */
-extern void _rl_reset_completion_state PARAMS((void));
-extern char _rl_find_completion_word PARAMS((int *, int *));
-extern void _rl_free_match_list PARAMS((char **));
-
-/* display.c */
-extern char *_rl_strip_prompt PARAMS((char *));
-extern void _rl_move_cursor_relative PARAMS((int, const char *));
-extern void _rl_move_vert PARAMS((int));
-extern void _rl_save_prompt PARAMS((void));
-extern void _rl_restore_prompt PARAMS((void));
-extern char *_rl_make_prompt_for_search PARAMS((int));
-extern void _rl_erase_at_end_of_line PARAMS((int));
-extern void _rl_clear_to_eol PARAMS((int));
-extern void _rl_clear_screen PARAMS((void));
-extern void _rl_update_final PARAMS((void));
-extern void _rl_redisplay_after_sigwinch PARAMS((void));
-extern void _rl_clean_up_for_exit PARAMS((void));
-extern void _rl_erase_entire_line PARAMS((void));
-extern int _rl_current_display_line PARAMS((void));
-
-/* input.c */
-extern int _rl_any_typein PARAMS((void));
-extern int _rl_input_available PARAMS((void));
-extern int _rl_input_queued PARAMS((int));
-extern void _rl_insert_typein PARAMS((int));
-extern int _rl_unget_char PARAMS((int));
-extern int _rl_pushed_input_available PARAMS((void));
-
-/* isearch.c */
-extern _rl_search_cxt *_rl_scxt_alloc PARAMS((int, int));
-extern void _rl_scxt_dispose PARAMS((_rl_search_cxt *, int));
-
-extern int _rl_isearch_dispatch PARAMS((_rl_search_cxt *, int));
-extern int _rl_isearch_callback PARAMS((_rl_search_cxt *));
-
-extern int _rl_search_getchar PARAMS((_rl_search_cxt *));
-
-/* macro.c */
-extern void _rl_with_macro_input PARAMS((char *));
-extern int _rl_next_macro_key PARAMS((void));
-extern void _rl_push_executing_macro PARAMS((void));
-extern void _rl_pop_executing_macro PARAMS((void));
-extern void _rl_add_macro_char PARAMS((int));
-extern void _rl_kill_kbd_macro PARAMS((void));
-
-/* misc.c */
-extern int _rl_arg_overflow PARAMS((void));
-extern void _rl_arg_init PARAMS((void));
-extern int _rl_arg_getchar PARAMS((void));
-extern int _rl_arg_callback PARAMS((_rl_arg_cxt));
-extern void _rl_reset_argument PARAMS((void));
-
-extern void _rl_start_using_history PARAMS((void));
-extern int _rl_free_saved_history_line PARAMS((void));
-extern void _rl_set_insert_mode PARAMS((int, int));
-
-extern void _rl_revert_all_lines PARAMS((void));
-
-/* nls.c */
-extern int _rl_init_eightbit PARAMS((void));
-
-/* parens.c */
-extern void _rl_enable_paren_matching PARAMS((int));
-
-/* readline.c */
-extern void _rl_init_line_state PARAMS((void));
-extern void _rl_set_the_line PARAMS((void));
-extern int _rl_dispatch PARAMS((int, Keymap));
-extern int _rl_dispatch_subseq PARAMS((int, Keymap, int));
-extern void _rl_internal_char_cleanup PARAMS((void));
-
-/* rltty.c */
-extern int _rl_disable_tty_signals PARAMS((void));
-extern int _rl_restore_tty_signals PARAMS((void));
-
-/* search.c */
-extern int _rl_nsearch_callback PARAMS((_rl_search_cxt *));
-
-/* signals.c */
-extern void _rl_signal_handler PARAMS((int));
-
-extern void _rl_block_sigint PARAMS((void));
-extern void _rl_release_sigint PARAMS((void));
-extern void _rl_block_sigwinch PARAMS((void));
-extern void _rl_release_sigwinch PARAMS((void));
-
-/* terminal.c */
-extern void _rl_get_screen_size PARAMS((int, int));
-extern int _rl_init_terminal_io PARAMS((const char *));
-#ifdef _MINIX
-extern void _rl_output_character_function PARAMS((int));
-#else
-extern int _rl_output_character_function PARAMS((int));
-#endif
-extern void _rl_output_some_chars PARAMS((const char *, int));
-extern int _rl_backspace PARAMS((int));
-extern void _rl_enable_meta_key PARAMS((void));
-extern void _rl_control_keypad PARAMS((int));
-extern void _rl_set_cursor PARAMS((int, int));
-
-/* text.c */
-extern void _rl_fix_point PARAMS((int));
-extern int _rl_replace_text PARAMS((const char *, int, int));
-extern int _rl_insert_char PARAMS((int, int));
-extern int _rl_overwrite_char PARAMS((int, int));
-extern int _rl_overwrite_rubout PARAMS((int, int));
-extern int _rl_rubout_char PARAMS((int, int));
-#if defined (HANDLE_MULTIBYTE)
-extern int _rl_char_search_internal PARAMS((int, int, char *, int));
-#else
-extern int _rl_char_search_internal PARAMS((int, int, int));
-#endif
-extern int _rl_set_mark_at_pos PARAMS((int));
-
-/* undo.c */
-extern UNDO_LIST *_rl_copy_undo_entry PARAMS((UNDO_LIST *));
-extern UNDO_LIST *_rl_copy_undo_list PARAMS((UNDO_LIST *));
-
-/* util.c */
-#if defined (USE_VARARGS) && defined (PREFER_STDARG)
-extern void _rl_ttymsg (const char *, ...)  __attribute__((__format__ (printf, 1, 2)));
-extern void _rl_errmsg (const char *, ...)  __attribute__((__format__ (printf, 1, 2)));
-extern void _rl_trace (const char *, ...)  __attribute__((__format__ (printf, 1, 2)));
-#else
-extern void _rl_ttymsg ();
-extern void _rl_errmsg ();
-extern void _rl_trace ();
-#endif
-
-extern int _rl_tropen PARAMS((void));
-
-extern int _rl_abort_internal PARAMS((void));
-extern int _rl_null_function PARAMS((int, int));
-extern char *_rl_strindex PARAMS((const char *, const char *));
-extern int _rl_qsort_string_compare PARAMS((char **, char **));
-extern int (_rl_uppercase_p) PARAMS((int));
-extern int (_rl_lowercase_p) PARAMS((int));
-extern int (_rl_pure_alphabetic) PARAMS((int));
-extern int (_rl_digit_p) PARAMS((int));
-extern int (_rl_to_lower) PARAMS((int));
-extern int (_rl_to_upper) PARAMS((int));
-extern int (_rl_digit_value) PARAMS((int));
-
-/* vi_mode.c */
-extern void _rl_vi_initialize_line PARAMS((void));
-extern void _rl_vi_reset_last PARAMS((void));
-extern void _rl_vi_set_last PARAMS((int, int, int));
-extern int _rl_vi_textmod_command PARAMS((int));
-extern void _rl_vi_done_inserting PARAMS((void));
-
-/*************************************************************************
- * Undocumented private variables                                       *
- *************************************************************************/
-
-/* bind.c */
-extern const char * const _rl_possible_control_prefixes[];
-extern const char * const _rl_possible_meta_prefixes[];
-
-/* callback.c */
-extern _rl_callback_func_t *_rl_callback_func;
-extern _rl_callback_generic_arg *_rl_callback_data;
-
-/* complete.c */
-extern int _rl_complete_show_all;
-extern int _rl_complete_show_unmodified;
-extern int _rl_complete_mark_directories;
-extern int _rl_complete_mark_symlink_dirs;
-extern int _rl_completion_prefix_display_length;
-extern int _rl_print_completions_horizontally;
-extern int _rl_completion_case_fold;
-extern int _rl_match_hidden_files;
-extern int _rl_page_completions;
-
-/* display.c */
-extern int _rl_vis_botlin;
-extern int _rl_last_c_pos;
-extern int _rl_suppress_redisplay;
-extern int _rl_want_redisplay;
-
-/* isearch.c */
-extern char *_rl_isearch_terminators;
-
-extern _rl_search_cxt *_rl_iscxt;
-
-/* macro.c */
-extern char *_rl_executing_macro;
-
-/* misc.c */
-extern int _rl_history_preserve_point;
-extern int _rl_history_saved_point;
-
-extern _rl_arg_cxt _rl_argcxt;
-
-/* readline.c */
-extern int _rl_echoing_p;
-extern int _rl_horizontal_scroll_mode;
-extern int _rl_mark_modified_lines;
-extern int _rl_bell_preference;
-extern int _rl_meta_flag;
-extern int _rl_convert_meta_chars_to_ascii;
-extern int _rl_output_meta_chars;
-extern int _rl_bind_stty_chars;
-extern int _rl_revert_all_at_newline;
-extern char *_rl_comment_begin;
-extern unsigned char _rl_parsing_conditionalized_out;
-extern Keymap _rl_keymap;
-extern FILE *_rl_in_stream;
-extern FILE *_rl_out_stream;
-extern int _rl_last_command_was_kill;
-extern int _rl_eof_char;
-extern procenv_t _rl_top_level;
-extern _rl_keyseq_cxt *_rl_kscxt;
-
-/* search.c */
-extern _rl_search_cxt *_rl_nscxt;
-
-/* signals.c */
-extern int _rl_interrupt_immediately;
-extern int volatile _rl_caught_signal;
-
-extern int _rl_echoctl;
-
-extern int _rl_intr_char;
-extern int _rl_quit_char;
-extern int _rl_susp_char;
-
-/* terminal.c */
-extern int _rl_enable_keypad;
-extern int _rl_enable_meta;
-extern char *_rl_term_clreol;
-extern char *_rl_term_clrpag;
-extern char *_rl_term_im;
-extern char *_rl_term_ic;
-extern char *_rl_term_ei;
-extern char *_rl_term_DC;
-extern char *_rl_term_up;
-extern char *_rl_term_dc;
-extern char *_rl_term_cr;
-extern char *_rl_term_IC;
-extern char *_rl_term_forward_char;
-extern int _rl_screenheight;
-extern int _rl_screenwidth;
-extern int _rl_screenchars;
-extern int _rl_terminal_can_insert;
-extern int _rl_term_autowrap;
-
-/* undo.c */
-extern int _rl_doing_an_undo;
-extern int _rl_undo_group_level;
-
-/* vi_mode.c */
-extern int _rl_vi_last_command;
-
-#endif /* _RL_PRIVATE_H_ */
diff --git a/lib/readline/signals.c.save b/lib/readline/signals.c.save
deleted file mode 100644 (file)
index 325ae8c..0000000
+++ /dev/null
@@ -1,613 +0,0 @@
-/* signals.c -- signal handling support for readline. */
-
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
-
-   This file is part of the GNU Readline Library (Readline), a library
-   for reading lines of text with interactive input and history editing.      
-
-   Readline is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   Readline is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#define READLINE_LIBRARY
-
-#if defined (HAVE_CONFIG_H)
-#  include <config.h>
-#endif
-
-#include <stdio.h>             /* Just for NULL.  Yuck. */
-#include <sys/types.h>
-#include <signal.h>
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-
-#if defined (GWINSZ_IN_SYS_IOCTL)
-#  include <sys/ioctl.h>
-#endif /* GWINSZ_IN_SYS_IOCTL */
-
-/* Some standard library routines. */
-#include "readline.h"
-#include "history.h"
-
-#include "rlprivate.h"
-
-#if defined (HANDLE_SIGNALS)
-
-#if !defined (RETSIGTYPE)
-#  if defined (VOID_SIGHANDLER)
-#    define RETSIGTYPE void
-#  else
-#    define RETSIGTYPE int
-#  endif /* !VOID_SIGHANDLER */
-#endif /* !RETSIGTYPE */
-
-#if defined (VOID_SIGHANDLER)
-#  define SIGHANDLER_RETURN return
-#else
-#  define SIGHANDLER_RETURN return (0)
-#endif
-
-/* This typedef is equivalent to the one for Function; it allows us
-   to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
-typedef RETSIGTYPE SigHandler ();
-
-#if defined (HAVE_POSIX_SIGNALS)
-typedef struct sigaction sighandler_cxt;
-#  define rl_sigaction(s, nh, oh)      sigaction(s, nh, oh)
-#else
-typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt;
-#  define sigemptyset(m)
-#endif /* !HAVE_POSIX_SIGNALS */
-
-#ifndef SA_RESTART
-#  define SA_RESTART 0
-#endif
-
-static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
-static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
-
-static RETSIGTYPE rl_signal_handler PARAMS((int));
-static RETSIGTYPE _rl_handle_signal PARAMS((int));
-     
-/* Exported variables for use by applications. */
-
-/* If non-zero, readline will install its own signal handlers for
-   SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */
-int rl_catch_signals = 1;
-
-/* If non-zero, readline will install a signal handler for SIGWINCH. */
-#ifdef SIGWINCH
-int rl_catch_sigwinch = 1;
-#else
-int rl_catch_sigwinch = 0;     /* for the readline state struct in readline.c */
-#endif
-
-/* Private variables. */
-int _rl_interrupt_immediately = 0;
-int volatile _rl_caught_signal = 0;    /* should be sig_atomic_t, but that requires including <signal.h> everywhere */
-
-/* If non-zero, print characters corresponding to received signals. */
-int _rl_echoctl = 0;
-
-int _rl_intr_char = 0;
-int _rl_quit_char = 0;
-int _rl_susp_char = 0;
-
-static int signals_set_flag;
-static int sigwinch_set_flag;
-
-/* **************************************************************** */
-/*                                                                 */
-/*                        Signal Handling                          */
-/*                                                                 */
-/* **************************************************************** */
-
-static sighandler_cxt old_int, old_term, old_alrm, old_quit;
-#if defined (SIGTSTP)
-static sighandler_cxt old_tstp, old_ttou, old_ttin;
-#endif
-#if defined (SIGWINCH)
-static sighandler_cxt old_winch;
-#endif
-
-/* Readline signal handler functions. */
-
-/* Called from RL_CHECK_SIGNALS() macro */
-RETSIGTYPE
-_rl_signal_handler (sig)
-{
-  _rl_caught_signal = 0;       /* XXX */
-
-  _rl_handle_signal (sig);
-  SIGHANDLER_RETURN;
-}
-
-static RETSIGTYPE
-rl_signal_handler (sig)
-     int sig;
-{
-  if (_rl_interrupt_immediately)
-    {
-      _rl_interrupt_immediately = 0;
-      _rl_handle_signal (sig);
-    }
-
-  _rl_caught_signal = sig;
-  SIGHANDLER_RETURN;
-}
-
-static RETSIGTYPE
-_rl_handle_signal (sig)
-     int sig;
-{
-#if defined (HAVE_POSIX_SIGNALS)
-  sigset_t set;
-#else /* !HAVE_POSIX_SIGNALS */
-#  if defined (HAVE_BSD_SIGNALS)
-  long omask;
-#  else /* !HAVE_BSD_SIGNALS */
-  sighandler_cxt dummy_cxt;    /* needed for rl_set_sighandler call */
-#  endif /* !HAVE_BSD_SIGNALS */
-#endif /* !HAVE_POSIX_SIGNALS */
-
-  RL_SETSTATE(RL_STATE_SIGHANDLER);
-
-#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
-  /* Since the signal will not be blocked while we are in the signal
-     handler, ignore it until rl_clear_signals resets the catcher. */
-#  if defined (SIGALRM)
-  if (sig == SIGINT || sig == SIGALRM)
-#  else
-  if (sig == SIGINT)
-#  endif
-    rl_set_sighandler (sig, SIG_IGN, &dummy_cxt);
-#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
-
-  switch (sig)
-    {
-    case SIGINT:
-      _rl_reset_completion_state ();
-      rl_free_line_state ();
-      /* FALLTHROUGH */
-
-    case SIGTERM:
-#if defined (SIGTSTP)
-    case SIGTSTP:
-    case SIGTTOU:
-    case SIGTTIN:
-#endif /* SIGTSTP */
-#if defined (SIGALRM)
-    case SIGALRM:
-#endif
-#if defined (SIGQUIT)
-    case SIGQUIT:
-#endif
-      rl_echo_signal_char (sig);
-      rl_cleanup_after_signal ();
-
-#if defined (HAVE_POSIX_SIGNALS)
-      sigemptyset (&set);
-      sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
-      sigdelset (&set, sig);
-#else /* !HAVE_POSIX_SIGNALS */
-#  if defined (HAVE_BSD_SIGNALS)
-      omask = sigblock (0);
-#  endif /* HAVE_BSD_SIGNALS */
-#endif /* !HAVE_POSIX_SIGNALS */
-
-#if defined (__EMX__)
-      signal (sig, SIG_ACK);
-#endif
-
-#if defined (HAVE_KILL)
-      kill (getpid (), sig);
-#else
-      raise (sig);             /* assume we have raise */
-#endif
-
-      /* Let the signal that we just sent through.  */
-#if defined (HAVE_POSIX_SIGNALS)
-      sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
-#else /* !HAVE_POSIX_SIGNALS */
-#  if defined (HAVE_BSD_SIGNALS)
-      sigsetmask (omask & ~(sigmask (sig)));
-#  endif /* HAVE_BSD_SIGNALS */
-#endif /* !HAVE_POSIX_SIGNALS */
-
-      rl_reset_after_signal ();
-    }
-
-  RL_UNSETSTATE(RL_STATE_SIGHANDLER);
-  SIGHANDLER_RETURN;
-}
-
-#if defined (SIGWINCH)
-static RETSIGTYPE
-rl_sigwinch_handler (sig)
-     int sig;
-{
-  SigHandler *oh;
-
-#if defined (MUST_REINSTALL_SIGHANDLERS)
-  sighandler_cxt dummy_winch;
-
-  /* We don't want to change old_winch -- it holds the state of SIGWINCH
-     disposition set by the calling application.  We need this state
-     because we call the application's SIGWINCH handler after updating
-     our own idea of the screen size. */
-  rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch);
-#endif
-
-  RL_SETSTATE(RL_STATE_SIGHANDLER);
-  rl_resize_terminal ();
-
-  /* If another sigwinch handler has been installed, call it. */
-  oh = (SigHandler *)old_winch.sa_handler;
-  if (oh &&  oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL)
-    (*oh) (sig);
-
-  RL_UNSETSTATE(RL_STATE_SIGHANDLER);
-  SIGHANDLER_RETURN;
-}
-#endif  /* SIGWINCH */
-
-/* Functions to manage signal handling. */
-
-#if !defined (HAVE_POSIX_SIGNALS)
-static int
-rl_sigaction (sig, nh, oh)
-     int sig;
-     sighandler_cxt *nh, *oh;
-{
-  oh->sa_handler = signal (sig, nh->sa_handler);
-  return 0;
-}
-#endif /* !HAVE_POSIX_SIGNALS */
-
-/* Set up a readline-specific signal handler, saving the old signal
-   information in OHANDLER.  Return the old signal handler, like
-   signal(). */
-static SigHandler *
-rl_set_sighandler (sig, handler, ohandler)
-     int sig;
-     SigHandler *handler;
-     sighandler_cxt *ohandler;
-{
-  sighandler_cxt old_handler;
-#if defined (HAVE_POSIX_SIGNALS)
-  struct sigaction act;
-
-  act.sa_handler = handler;
-#  if defined (SIGWINCH)
-  act.sa_flags = (sig == SIGWINCH) ? SA_RESTART : 0;
-#  else
-  act.sa_flags = 0;
-#  endif /* SIGWINCH */
-  sigemptyset (&act.sa_mask);
-  sigemptyset (&ohandler->sa_mask);
-  sigaction (sig, &act, &old_handler);
-#else
-  old_handler.sa_handler = (SigHandler *)signal (sig, handler);
-#endif /* !HAVE_POSIX_SIGNALS */
-
-  /* XXX -- assume we have memcpy */
-  /* If rl_set_signals is called twice in a row, don't set the old handler to
-     rl_signal_handler, because that would cause infinite recursion. */
-  if (handler != rl_signal_handler || old_handler.sa_handler != rl_signal_handler)
-    memcpy (ohandler, &old_handler, sizeof (sighandler_cxt));
-
-  return (ohandler->sa_handler);
-}
-
-static void
-rl_maybe_set_sighandler (sig, handler, ohandler)
-     int sig;
-     SigHandler *handler;
-     sighandler_cxt *ohandler;
-{
-  sighandler_cxt dummy;
-  SigHandler *oh;
-
-  sigemptyset (&dummy.sa_mask);
-  oh = rl_set_sighandler (sig, handler, ohandler);
-  if (oh == (SigHandler *)SIG_IGN)
-    rl_sigaction (sig, ohandler, &dummy);
-}
-
-int
-rl_set_signals ()
-{
-  sighandler_cxt dummy;
-  SigHandler *oh;
-#if defined (HAVE_POSIX_SIGNALS)
-  static int sigmask_set = 0;
-  static sigset_t bset, oset;
-#endif
-
-#if defined (HAVE_POSIX_SIGNALS)
-  if (rl_catch_signals && sigmask_set == 0)
-    {
-      sigemptyset (&bset);
-
-      sigaddset (&bset, SIGINT);
-      sigaddset (&bset, SIGTERM);
-#if defined (SIGQUIT)
-      sigaddset (&bset, SIGQUIT);
-#endif
-#if defined (SIGALRM)
-      sigaddset (&bset, SIGALRM);
-#endif
-#if defined (SIGTSTP)
-      sigaddset (&bset, SIGTSTP);
-#endif
-#if defined (SIGTTIN)
-      sigaddset (&bset, SIGTTIN);
-#endif
-#if defined (SIGTTOU)
-      sigaddset (&bset, SIGTTOU);
-#endif
-      sigmask_set = 1;
-    }      
-#endif /* HAVE_POSIX_SIGNALS */
-
-  if (rl_catch_signals && signals_set_flag == 0)
-    {
-#if defined (HAVE_POSIX_SIGNALS)
-      sigemptyset (&oset);
-      sigprocmask (SIG_BLOCK, &bset, &oset);
-#endif
-
-      rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int);
-      rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
-#if defined (SIGQUIT)
-      rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit);
-#endif
-
-#if defined (SIGALRM)
-      oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm);
-      if (oh == (SigHandler *)SIG_IGN)
-       rl_sigaction (SIGALRM, &old_alrm, &dummy);
-#if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART)
-      /* If the application using readline has already installed a signal
-        handler with SA_RESTART, SIGALRM will cause reads to be restarted
-        automatically, so readline should just get out of the way.  Since
-        we tested for SIG_IGN above, we can just test for SIG_DFL here. */
-      if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART))
-       rl_sigaction (SIGALRM, &old_alrm, &dummy);
-#endif /* HAVE_POSIX_SIGNALS */
-#endif /* SIGALRM */
-
-#if defined (SIGTSTP)
-      rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
-#endif /* SIGTSTP */
-
-#if defined (SIGTTOU)
-      rl_maybe_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou);
-#endif /* SIGTTOU */
-
-#if defined (SIGTTIN)
-      rl_maybe_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin);
-#endif /* SIGTTIN */
-
-      signals_set_flag = 1;
-
-#if defined (HAVE_POSIX_SIGNALS)
-      sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
-#endif
-    }
-
-#if defined (SIGWINCH)
-  if (rl_catch_sigwinch && sigwinch_set_flag == 0)
-    {
-      rl_maybe_set_sighandler (SIGWINCH, rl_sigwinch_handler, &old_winch);
-      sigwinch_set_flag = 1;
-    }
-#endif /* SIGWINCH */
-
-  return 0;
-}
-
-int
-rl_clear_signals ()
-{
-  sighandler_cxt dummy;
-
-  if (rl_catch_signals && signals_set_flag == 1)
-    {
-      sigemptyset (&dummy.sa_mask);
-
-      rl_sigaction (SIGINT, &old_int, &dummy);
-      rl_sigaction (SIGTERM, &old_term, &dummy);
-#if defined (SIGQUIT)
-      rl_sigaction (SIGQUIT, &old_quit, &dummy);
-#endif
-#if defined (SIGALRM)
-      rl_sigaction (SIGALRM, &old_alrm, &dummy);
-#endif
-
-#if defined (SIGTSTP)
-      rl_sigaction (SIGTSTP, &old_tstp, &dummy);
-#endif /* SIGTSTP */
-
-#if defined (SIGTTOU)
-      rl_sigaction (SIGTTOU, &old_ttou, &dummy);
-#endif /* SIGTTOU */
-
-#if defined (SIGTTIN)
-      rl_sigaction (SIGTTIN, &old_ttin, &dummy);
-#endif /* SIGTTIN */
-
-      signals_set_flag = 0;
-    }
-
-#if defined (SIGWINCH)
-  if (rl_catch_sigwinch && sigwinch_set_flag == 1)
-    {
-      sigemptyset (&dummy.sa_mask);
-      rl_sigaction (SIGWINCH, &old_winch, &dummy);
-      sigwinch_set_flag = 0;
-    }
-#endif
-
-  return 0;
-}
-
-/* Clean up the terminal and readline state after catching a signal, before
-   resending it to the calling application. */
-void
-rl_cleanup_after_signal ()
-{
-  _rl_clean_up_for_exit ();
-  if (rl_deprep_term_function)
-    (*rl_deprep_term_function) ();
-  rl_clear_pending_input ();
-  rl_clear_signals ();
-}
-
-/* Reset the terminal and readline state after a signal handler returns. */
-void
-rl_reset_after_signal ()
-{
-  if (rl_prep_term_function)
-    (*rl_prep_term_function) (_rl_meta_flag);
-  rl_set_signals ();
-}
-
-/* Free up the readline variable line state for the current line (undo list,
-   any partial history entry, any keyboard macros in progress, and any
-   numeric arguments in process) after catching a signal, before calling
-   rl_cleanup_after_signal(). */ 
-void
-rl_free_line_state ()
-{
-  register HIST_ENTRY *entry;
-
-  rl_free_undo_list ();
-
-  entry = current_history ();
-  if (entry)
-    entry->data = (char *)NULL;
-
-  _rl_kill_kbd_macro ();
-  rl_clear_message ();
-  _rl_reset_argument ();
-}
-
-#endif  /* HANDLE_SIGNALS */
-
-/* **************************************************************** */
-/*                                                                 */
-/*                        SIGINT Management                        */
-/*                                                                 */
-/* **************************************************************** */
-
-#if defined (HAVE_POSIX_SIGNALS)
-static sigset_t sigint_set, sigint_oset;
-#else /* !HAVE_POSIX_SIGNALS */
-#  if defined (HAVE_BSD_SIGNALS)
-static int sigint_oldmask;
-#  endif /* HAVE_BSD_SIGNALS */
-#endif /* !HAVE_POSIX_SIGNALS */
-
-static int sigint_blocked;
-
-/* Cause SIGINT to not be delivered until the corresponding call to
-   release_sigint(). */
-void
-_rl_block_sigint ()
-{
-  if (sigint_blocked)
-    return;
-
-#if defined (HAVE_POSIX_SIGNALS)
-  sigemptyset (&sigint_set);
-  sigemptyset (&sigint_oset);
-  sigaddset (&sigint_set, SIGINT);
-  sigprocmask (SIG_BLOCK, &sigint_set, &sigint_oset);
-#else /* !HAVE_POSIX_SIGNALS */
-#  if defined (HAVE_BSD_SIGNALS)
-  sigint_oldmask = sigblock (sigmask (SIGINT));
-#  else /* !HAVE_BSD_SIGNALS */
-#    if defined (HAVE_USG_SIGHOLD)
-  sighold (SIGINT);
-#    endif /* HAVE_USG_SIGHOLD */
-#  endif /* !HAVE_BSD_SIGNALS */
-#endif /* !HAVE_POSIX_SIGNALS */
-
-  sigint_blocked = 1;
-}
-
-/* Allow SIGINT to be delivered. */
-void
-_rl_release_sigint ()
-{
-  if (sigint_blocked == 0)
-    return;
-
-#if defined (HAVE_POSIX_SIGNALS)
-  sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL);
-#else
-#  if defined (HAVE_BSD_SIGNALS)
-  sigsetmask (sigint_oldmask);
-#  else /* !HAVE_BSD_SIGNALS */
-#    if defined (HAVE_USG_SIGHOLD)
-  sigrelse (SIGINT);
-#    endif /* HAVE_USG_SIGHOLD */
-#  endif /* !HAVE_BSD_SIGNALS */
-#endif /* !HAVE_POSIX_SIGNALS */
-
-  sigint_blocked = 0;
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*             Echoing special control characters                  */
-/*                                                                 */
-/* **************************************************************** */
-void
-rl_echo_signal_char (sig)
-     int sig;
-{
-  char cstr[3];
-  int cslen, c;
-
-  if (_rl_echoctl == 0)
-    return;
-
-  switch (sig)
-    {
-    case SIGINT:  c = _rl_intr_char; break;
-    case SIGQUIT: c = _rl_quit_char; break;
-    case SIGTSTP: c = _rl_susp_char; break;
-    default: return;
-    }
-
-  if (CTRL_CHAR (c) || c == RUBOUT)
-    {
-      cstr[0] = '^';
-      cstr[1] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
-      cstr[cslen = 2] = '\0';
-    }
-  else
-    {
-      cstr[0] = c;
-      cstr[cslen = 1] = '\0';
-    }
-
-  _rl_output_some_chars (cstr, cslen);
-}
diff --git a/lib/readline/signals.c~ b/lib/readline/signals.c~
deleted file mode 100644 (file)
index 71bd2fd..0000000
+++ /dev/null
@@ -1,670 +0,0 @@
-/* signals.c -- signal handling support for readline. */
-
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
-
-   This file is part of the GNU Readline Library (Readline), a library
-   for reading lines of text with interactive input and history editing.      
-
-   Readline is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   Readline is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#define READLINE_LIBRARY
-
-#if defined (HAVE_CONFIG_H)
-#  include <config.h>
-#endif
-
-#include <stdio.h>             /* Just for NULL.  Yuck. */
-#include <sys/types.h>
-#include <signal.h>
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-
-#if defined (GWINSZ_IN_SYS_IOCTL)
-#  include <sys/ioctl.h>
-#endif /* GWINSZ_IN_SYS_IOCTL */
-
-/* Some standard library routines. */
-#include "readline.h"
-#include "history.h"
-
-#include "rlprivate.h"
-
-#if defined (HANDLE_SIGNALS)
-
-#if !defined (RETSIGTYPE)
-#  if defined (VOID_SIGHANDLER)
-#    define RETSIGTYPE void
-#  else
-#    define RETSIGTYPE int
-#  endif /* !VOID_SIGHANDLER */
-#endif /* !RETSIGTYPE */
-
-#if defined (VOID_SIGHANDLER)
-#  define SIGHANDLER_RETURN return
-#else
-#  define SIGHANDLER_RETURN return (0)
-#endif
-
-/* This typedef is equivalent to the one for Function; it allows us
-   to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
-typedef RETSIGTYPE SigHandler ();
-
-#if defined (HAVE_POSIX_SIGNALS)
-typedef struct sigaction sighandler_cxt;
-#  define rl_sigaction(s, nh, oh)      sigaction(s, nh, oh)
-#else
-typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt;
-#  define sigemptyset(m)
-#endif /* !HAVE_POSIX_SIGNALS */
-
-#ifndef SA_RESTART
-#  define SA_RESTART 0
-#endif
-
-static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
-static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
-
-static RETSIGTYPE rl_signal_handler PARAMS((int));
-static RETSIGTYPE _rl_handle_signal PARAMS((int));
-     
-/* Exported variables for use by applications. */
-
-/* If non-zero, readline will install its own signal handlers for
-   SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */
-int rl_catch_signals = 1;
-
-/* If non-zero, readline will install a signal handler for SIGWINCH. */
-#ifdef SIGWINCH
-int rl_catch_sigwinch = 1;
-#else
-int rl_catch_sigwinch = 0;     /* for the readline state struct in readline.c */
-#endif
-
-/* Private variables. */
-int _rl_interrupt_immediately = 0;
-int volatile _rl_caught_signal = 0;    /* should be sig_atomic_t, but that requires including <signal.h> everywhere */
-
-/* If non-zero, print characters corresponding to received signals as long as
-   the user has indicated his desire to do so (_rl_echo_control_chars). */
-int _rl_echoctl = 0;
-
-int _rl_intr_char = 0;
-int _rl_quit_char = 0;
-int _rl_susp_char = 0;
-
-static int signals_set_flag;
-static int sigwinch_set_flag;
-
-/* **************************************************************** */
-/*                                                                 */
-/*                        Signal Handling                          */
-/*                                                                 */
-/* **************************************************************** */
-
-static sighandler_cxt old_int, old_term, old_alrm, old_quit;
-#if defined (SIGTSTP)
-static sighandler_cxt old_tstp, old_ttou, old_ttin;
-#endif
-#if defined (SIGWINCH)
-static sighandler_cxt old_winch;
-#endif
-
-/* Readline signal handler functions. */
-
-/* Called from RL_CHECK_SIGNALS() macro */
-RETSIGTYPE
-_rl_signal_handler (sig)
-{
-  _rl_caught_signal = 0;       /* XXX */
-
-  _rl_handle_signal (sig);
-  SIGHANDLER_RETURN;
-}
-
-static RETSIGTYPE
-rl_signal_handler (sig)
-     int sig;
-{
-  if (_rl_interrupt_immediately)
-    {
-      _rl_interrupt_immediately = 0;
-      _rl_handle_signal (sig);
-    }
-  else
-    _rl_caught_signal = sig;
-
-  SIGHANDLER_RETURN;
-}
-
-static RETSIGTYPE
-_rl_handle_signal (sig)
-     int sig;
-{
-#if defined (HAVE_POSIX_SIGNALS)
-  sigset_t set;
-#else /* !HAVE_POSIX_SIGNALS */
-#  if defined (HAVE_BSD_SIGNALS)
-  long omask;
-#  else /* !HAVE_BSD_SIGNALS */
-  sighandler_cxt dummy_cxt;    /* needed for rl_set_sighandler call */
-#  endif /* !HAVE_BSD_SIGNALS */
-#endif /* !HAVE_POSIX_SIGNALS */
-
-  RL_SETSTATE(RL_STATE_SIGHANDLER);
-
-#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
-  /* Since the signal will not be blocked while we are in the signal
-     handler, ignore it until rl_clear_signals resets the catcher. */
-#  if defined (SIGALRM)
-  if (sig == SIGINT || sig == SIGALRM)
-#  else
-  if (sig == SIGINT)
-#  endif
-    rl_set_sighandler (sig, SIG_IGN, &dummy_cxt);
-#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
-
-  switch (sig)
-    {
-    case SIGINT:
-      _rl_reset_completion_state ();
-      rl_free_line_state ();
-      /* FALLTHROUGH */
-
-    case SIGTERM:
-#if defined (SIGTSTP)
-    case SIGTSTP:
-    case SIGTTOU:
-    case SIGTTIN:
-#endif /* SIGTSTP */
-#if defined (SIGALRM)
-    case SIGALRM:
-#endif
-#if defined (SIGQUIT)
-    case SIGQUIT:
-#endif
-      rl_echo_signal_char (sig);
-      rl_cleanup_after_signal ();
-
-#if defined (HAVE_POSIX_SIGNALS)
-      sigemptyset (&set);
-      sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
-      sigdelset (&set, sig);
-#else /* !HAVE_POSIX_SIGNALS */
-#  if defined (HAVE_BSD_SIGNALS)
-      omask = sigblock (0);
-#  endif /* HAVE_BSD_SIGNALS */
-#endif /* !HAVE_POSIX_SIGNALS */
-
-#if defined (__EMX__)
-      signal (sig, SIG_ACK);
-#endif
-
-#if defined (HAVE_KILL)
-      kill (getpid (), sig);
-#else
-      raise (sig);             /* assume we have raise */
-#endif
-
-      /* Let the signal that we just sent through.  */
-#if defined (HAVE_POSIX_SIGNALS)
-      sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
-#else /* !HAVE_POSIX_SIGNALS */
-#  if defined (HAVE_BSD_SIGNALS)
-      sigsetmask (omask & ~(sigmask (sig)));
-#  endif /* HAVE_BSD_SIGNALS */
-#endif /* !HAVE_POSIX_SIGNALS */
-
-      rl_reset_after_signal ();
-    }
-
-  RL_UNSETSTATE(RL_STATE_SIGHANDLER);
-  SIGHANDLER_RETURN;
-}
-
-#if defined (SIGWINCH)
-static RETSIGTYPE
-rl_sigwinch_handler (sig)
-     int sig;
-{
-  SigHandler *oh;
-
-#if defined (MUST_REINSTALL_SIGHANDLERS)
-  sighandler_cxt dummy_winch;
-
-  /* We don't want to change old_winch -- it holds the state of SIGWINCH
-     disposition set by the calling application.  We need this state
-     because we call the application's SIGWINCH handler after updating
-     our own idea of the screen size. */
-  rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch);
-#endif
-
-  RL_SETSTATE(RL_STATE_SIGHANDLER);
-  rl_resize_terminal ();
-
-  /* If another sigwinch handler has been installed, call it. */
-  oh = (SigHandler *)old_winch.sa_handler;
-  if (oh &&  oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL)
-    (*oh) (sig);
-
-  RL_UNSETSTATE(RL_STATE_SIGHANDLER);
-  SIGHANDLER_RETURN;
-}
-#endif  /* SIGWINCH */
-
-/* Functions to manage signal handling. */
-
-#if !defined (HAVE_POSIX_SIGNALS)
-static int
-rl_sigaction (sig, nh, oh)
-     int sig;
-     sighandler_cxt *nh, *oh;
-{
-  oh->sa_handler = signal (sig, nh->sa_handler);
-  return 0;
-}
-#endif /* !HAVE_POSIX_SIGNALS */
-
-/* Set up a readline-specific signal handler, saving the old signal
-   information in OHANDLER.  Return the old signal handler, like
-   signal(). */
-static SigHandler *
-rl_set_sighandler (sig, handler, ohandler)
-     int sig;
-     SigHandler *handler;
-     sighandler_cxt *ohandler;
-{
-  sighandler_cxt old_handler;
-#if defined (HAVE_POSIX_SIGNALS)
-  struct sigaction act;
-
-  act.sa_handler = handler;
-#  if defined (SIGWINCH)
-  act.sa_flags = (sig == SIGWINCH) ? SA_RESTART : 0;
-#  else
-  act.sa_flags = 0;
-#  endif /* SIGWINCH */
-  sigemptyset (&act.sa_mask);
-  sigemptyset (&ohandler->sa_mask);
-  sigaction (sig, &act, &old_handler);
-#else
-  old_handler.sa_handler = (SigHandler *)signal (sig, handler);
-#endif /* !HAVE_POSIX_SIGNALS */
-
-  /* XXX -- assume we have memcpy */
-  /* If rl_set_signals is called twice in a row, don't set the old handler to
-     rl_signal_handler, because that would cause infinite recursion. */
-  if (handler != rl_signal_handler || old_handler.sa_handler != rl_signal_handler)
-    memcpy (ohandler, &old_handler, sizeof (sighandler_cxt));
-
-  return (ohandler->sa_handler);
-}
-
-static void
-rl_maybe_set_sighandler (sig, handler, ohandler)
-     int sig;
-     SigHandler *handler;
-     sighandler_cxt *ohandler;
-{
-  sighandler_cxt dummy;
-  SigHandler *oh;
-
-  sigemptyset (&dummy.sa_mask);
-  oh = rl_set_sighandler (sig, handler, ohandler);
-  if (oh == (SigHandler *)SIG_IGN)
-    rl_sigaction (sig, ohandler, &dummy);
-}
-
-int
-rl_set_signals ()
-{
-  sighandler_cxt dummy;
-  SigHandler *oh;
-#if defined (HAVE_POSIX_SIGNALS)
-  static int sigmask_set = 0;
-  static sigset_t bset, oset;
-#endif
-
-#if defined (HAVE_POSIX_SIGNALS)
-  if (rl_catch_signals && sigmask_set == 0)
-    {
-      sigemptyset (&bset);
-
-      sigaddset (&bset, SIGINT);
-      sigaddset (&bset, SIGTERM);
-#if defined (SIGQUIT)
-      sigaddset (&bset, SIGQUIT);
-#endif
-#if defined (SIGALRM)
-      sigaddset (&bset, SIGALRM);
-#endif
-#if defined (SIGTSTP)
-      sigaddset (&bset, SIGTSTP);
-#endif
-#if defined (SIGTTIN)
-      sigaddset (&bset, SIGTTIN);
-#endif
-#if defined (SIGTTOU)
-      sigaddset (&bset, SIGTTOU);
-#endif
-      sigmask_set = 1;
-    }      
-#endif /* HAVE_POSIX_SIGNALS */
-
-  if (rl_catch_signals && signals_set_flag == 0)
-    {
-#if defined (HAVE_POSIX_SIGNALS)
-      sigemptyset (&oset);
-      sigprocmask (SIG_BLOCK, &bset, &oset);
-#endif
-
-      rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int);
-      rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
-#if defined (SIGQUIT)
-      rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit);
-#endif
-
-#if defined (SIGALRM)
-      oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm);
-      if (oh == (SigHandler *)SIG_IGN)
-       rl_sigaction (SIGALRM, &old_alrm, &dummy);
-#if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART)
-      /* If the application using readline has already installed a signal
-        handler with SA_RESTART, SIGALRM will cause reads to be restarted
-        automatically, so readline should just get out of the way.  Since
-        we tested for SIG_IGN above, we can just test for SIG_DFL here. */
-      if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART))
-       rl_sigaction (SIGALRM, &old_alrm, &dummy);
-#endif /* HAVE_POSIX_SIGNALS */
-#endif /* SIGALRM */
-
-#if defined (SIGTSTP)
-      rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
-#endif /* SIGTSTP */
-
-#if defined (SIGTTOU)
-      rl_maybe_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou);
-#endif /* SIGTTOU */
-
-#if defined (SIGTTIN)
-      rl_maybe_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin);
-#endif /* SIGTTIN */
-
-      signals_set_flag = 1;
-
-#if defined (HAVE_POSIX_SIGNALS)
-      sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
-#endif
-    }
-
-#if defined (SIGWINCH)
-  if (rl_catch_sigwinch && sigwinch_set_flag == 0)
-    {
-      rl_maybe_set_sighandler (SIGWINCH, rl_sigwinch_handler, &old_winch);
-      sigwinch_set_flag = 1;
-    }
-#endif /* SIGWINCH */
-
-  return 0;
-}
-
-int
-rl_clear_signals ()
-{
-  sighandler_cxt dummy;
-
-  if (rl_catch_signals && signals_set_flag == 1)
-    {
-      sigemptyset (&dummy.sa_mask);
-
-      rl_sigaction (SIGINT, &old_int, &dummy);
-      rl_sigaction (SIGTERM, &old_term, &dummy);
-#if defined (SIGQUIT)
-      rl_sigaction (SIGQUIT, &old_quit, &dummy);
-#endif
-#if defined (SIGALRM)
-      rl_sigaction (SIGALRM, &old_alrm, &dummy);
-#endif
-
-#if defined (SIGTSTP)
-      rl_sigaction (SIGTSTP, &old_tstp, &dummy);
-#endif /* SIGTSTP */
-
-#if defined (SIGTTOU)
-      rl_sigaction (SIGTTOU, &old_ttou, &dummy);
-#endif /* SIGTTOU */
-
-#if defined (SIGTTIN)
-      rl_sigaction (SIGTTIN, &old_ttin, &dummy);
-#endif /* SIGTTIN */
-
-      signals_set_flag = 0;
-    }
-
-#if defined (SIGWINCH)
-  if (rl_catch_sigwinch && sigwinch_set_flag == 1)
-    {
-      sigemptyset (&dummy.sa_mask);
-      rl_sigaction (SIGWINCH, &old_winch, &dummy);
-      sigwinch_set_flag = 0;
-    }
-#endif
-
-  return 0;
-}
-
-/* Clean up the terminal and readline state after catching a signal, before
-   resending it to the calling application. */
-void
-rl_cleanup_after_signal ()
-{
-  _rl_clean_up_for_exit ();
-  if (rl_deprep_term_function)
-    (*rl_deprep_term_function) ();
-  rl_clear_pending_input ();
-  rl_clear_signals ();
-}
-
-/* Reset the terminal and readline state after a signal handler returns. */
-void
-rl_reset_after_signal ()
-{
-  if (rl_prep_term_function)
-    (*rl_prep_term_function) (_rl_meta_flag);
-  rl_set_signals ();
-}
-
-/* Free up the readline variable line state for the current line (undo list,
-   any partial history entry, any keyboard macros in progress, and any
-   numeric arguments in process) after catching a signal, before calling
-   rl_cleanup_after_signal(). */ 
-void
-rl_free_line_state ()
-{
-  register HIST_ENTRY *entry;
-
-  rl_free_undo_list ();
-
-  entry = current_history ();
-  if (entry)
-    entry->data = (char *)NULL;
-
-  _rl_kill_kbd_macro ();
-  rl_clear_message ();
-  _rl_reset_argument ();
-}
-
-#endif  /* HANDLE_SIGNALS */
-
-/* **************************************************************** */
-/*                                                                 */
-/*                        SIGINT Management                        */
-/*                                                                 */
-/* **************************************************************** */
-
-#if defined (HAVE_POSIX_SIGNALS)
-static sigset_t sigint_set, sigint_oset;
-static sigset_t sigwinch_set, sigwinch_oset;
-#else /* !HAVE_POSIX_SIGNALS */
-#  if defined (HAVE_BSD_SIGNALS)
-static int sigint_oldmask;
-static int sigwinch_oldmask;
-#  endif /* HAVE_BSD_SIGNALS */
-#endif /* !HAVE_POSIX_SIGNALS */
-
-static int sigint_blocked;
-static int sigwinch_blocked;
-
-/* Cause SIGINT to not be delivered until the corresponding call to
-   release_sigint(). */
-void
-_rl_block_sigint ()
-{
-  if (sigint_blocked)
-    return;
-
-#if defined (HAVE_POSIX_SIGNALS)
-  sigemptyset (&sigint_set);
-  sigemptyset (&sigint_oset);
-  sigaddset (&sigint_set, SIGINT);
-  sigprocmask (SIG_BLOCK, &sigint_set, &sigint_oset);
-#else /* !HAVE_POSIX_SIGNALS */
-#  if defined (HAVE_BSD_SIGNALS)
-  sigint_oldmask = sigblock (sigmask (SIGINT));
-#  else /* !HAVE_BSD_SIGNALS */
-#    if defined (HAVE_USG_SIGHOLD)
-  sighold (SIGINT);
-#    endif /* HAVE_USG_SIGHOLD */
-#  endif /* !HAVE_BSD_SIGNALS */
-#endif /* !HAVE_POSIX_SIGNALS */
-
-  sigint_blocked = 1;
-}
-
-/* Allow SIGINT to be delivered. */
-void
-_rl_release_sigint ()
-{
-  if (sigint_blocked == 0)
-    return;
-
-#if defined (HAVE_POSIX_SIGNALS)
-  sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL);
-#else
-#  if defined (HAVE_BSD_SIGNALS)
-  sigsetmask (sigint_oldmask);
-#  else /* !HAVE_BSD_SIGNALS */
-#    if defined (HAVE_USG_SIGHOLD)
-  sigrelse (SIGINT);
-#    endif /* HAVE_USG_SIGHOLD */
-#  endif /* !HAVE_BSD_SIGNALS */
-#endif /* !HAVE_POSIX_SIGNALS */
-
-  sigint_blocked = 0;
-}
-
-/* Cause SIGWINCH to not be delivered until the corresponding call to
-   release_sigwinch(). */
-void
-_rl_block_sigwinch ()
-{
-  if (sigwinch_blocked)
-    return;
-
-#if defined (HAVE_POSIX_SIGNALS)
-  sigemptyset (&sigwinch_set);
-  sigemptyset (&sigwinch_oset);
-  sigaddset (&sigwinch_set, SIGWINCH);
-  sigprocmask (SIG_BLOCK, &sigwinch_set, &sigwinch_oset);
-#else /* !HAVE_POSIX_SIGNALS */
-#  if defined (HAVE_BSD_SIGNALS)
-  sigwinch_oldmask = sigblock (sigmask (SIGWINCH));
-#  else /* !HAVE_BSD_SIGNALS */
-#    if defined (HAVE_USG_SIGHOLD)
-  sighold (SIGWINCH);
-#    endif /* HAVE_USG_SIGHOLD */
-#  endif /* !HAVE_BSD_SIGNALS */
-#endif /* !HAVE_POSIX_SIGNALS */
-
-  sigwinch_blocked = 1;
-}
-
-/* Allow SIGWINCH to be delivered. */
-void
-_rl_release_sigwinch ()
-{
-  if (sigwinch_blocked == 0)
-    return;
-
-#if defined (HAVE_POSIX_SIGNALS)
-  sigprocmask (SIG_SETMASK, &sigwinch_oset, (sigset_t *)NULL);
-#else
-#  if defined (HAVE_BSD_SIGNALS)
-  sigsetmask (sigwinch_oldmask);
-#  else /* !HAVE_BSD_SIGNALS */
-#    if defined (HAVE_USG_SIGHOLD)
-  sigrelse (SIGWINCH);
-#    endif /* HAVE_USG_SIGHOLD */
-#  endif /* !HAVE_BSD_SIGNALS */
-#endif /* !HAVE_POSIX_SIGNALS */
-
-  sigwinch_blocked = 0;
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*             Echoing special control characters                  */
-/*                                                                 */
-/* **************************************************************** */
-void
-rl_echo_signal_char (sig)
-     int sig;
-{
-  char cstr[3];
-  int cslen, c;
-
-  if (_rl_echoctl == 0 || _rl_echo_control_chars == 0)
-    return;
-
-  switch (sig)
-    {
-    case SIGINT:  c = _rl_intr_char; break;
-#if defined (SIGQUIT)
-    case SIGQUIT: c = _rl_quit_char; break;
-#endif
-#if defined (SIGTSTP)
-    case SIGTSTP: c = _rl_susp_char; break;
-#endif
-    default: return;
-    }
-
-  if (CTRL_CHAR (c) || c == RUBOUT)
-    {
-      cstr[0] = '^';
-      cstr[1] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
-      cstr[cslen = 2] = '\0';
-    }
-  else
-    {
-      cstr[0] = c;
-      cstr[cslen = 1] = '\0';
-    }
-
-  _rl_output_some_chars (cstr, cslen);
-}
diff --git a/lib/readline/text.c~ b/lib/readline/text.c~
deleted file mode 100644 (file)
index 4e1aa0c..0000000
+++ /dev/null
@@ -1,1679 +0,0 @@
-/* text.c -- text handling commands for readline. */
-
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
-
-   This file is part of the GNU Readline Library (Readline), a library
-   for reading lines of text with interactive input and history editing.      
-
-   Readline is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   Readline is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#define READLINE_LIBRARY
-
-#if defined (HAVE_CONFIG_H)
-#  include <config.h>
-#endif
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#if defined (HAVE_STDLIB_H)
-#  include <stdlib.h>
-#else
-#  include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#if defined (HAVE_LOCALE_H)
-#  include <locale.h>
-#endif
-
-#include <stdio.h>
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-#include "rlmbutil.h"
-
-#if defined (__EMX__)
-#  define INCL_DOSPROCESS
-#  include <os2.h>
-#endif /* __EMX__ */
-
-/* Some standard library routines. */
-#include "readline.h"
-#include "history.h"
-
-#include "rlprivate.h"
-#include "rlshell.h"
-#include "xmalloc.h"
-
-/* Forward declarations. */
-static int rl_change_case PARAMS((int, int));
-static int _rl_char_search PARAMS((int, int, int));
-
-#if defined (READLINE_CALLBACKS)
-static int _rl_insert_next_callback PARAMS((_rl_callback_generic_arg *));
-static int _rl_char_search_callback PARAMS((_rl_callback_generic_arg *));
-#endif
-
-/* The largest chunk of text that can be inserted in one call to
-   rl_insert_text.  Text blocks larger than this are divided. */
-#define TEXT_COUNT_MAX 1024
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Insert and Delete                           */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Insert a string of text into the line at point.  This is the only
-   way that you should do insertion.  _rl_insert_char () calls this
-   function.  Returns the number of characters inserted. */
-int
-rl_insert_text (string)
-     const char *string;
-{
-  register int i, l;
-
-  l = (string && *string) ? strlen (string) : 0;
-  if (l == 0)
-    return 0;
-
-  if (rl_end + l >= rl_line_buffer_len)
-    rl_extend_line_buffer (rl_end + l);
-
-  for (i = rl_end; i >= rl_point; i--)
-    rl_line_buffer[i + l] = rl_line_buffer[i];
-  strncpy (rl_line_buffer + rl_point, string, l);
-
-  /* Remember how to undo this if we aren't undoing something. */
-  if (_rl_doing_an_undo == 0)
-    {
-      /* If possible and desirable, concatenate the undos. */
-      if ((l == 1) &&
-         rl_undo_list &&
-         (rl_undo_list->what == UNDO_INSERT) &&
-         (rl_undo_list->end == rl_point) &&
-         (rl_undo_list->end - rl_undo_list->start < 20))
-       rl_undo_list->end++;
-      else
-       rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL);
-    }
-  rl_point += l;
-  rl_end += l;
-  rl_line_buffer[rl_end] = '\0';
-  return l;
-}
-
-/* Delete the string between FROM and TO.  FROM is inclusive, TO is not.
-   Returns the number of characters deleted. */
-int
-rl_delete_text (from, to)
-     int from, to;
-{
-  register char *text;
-  register int diff, i;
-
-  /* Fix it if the caller is confused. */
-  if (from > to)
-    SWAP (from, to);
-
-  /* fix boundaries */
-  if (to > rl_end)
-    {
-      to = rl_end;
-      if (from > to)
-       from = to;
-    }
-  if (from < 0)
-    from = 0;
-
-  text = rl_copy_text (from, to);
-
-  /* Some versions of strncpy() can't handle overlapping arguments. */
-  diff = to - from;
-  for (i = from; i < rl_end - diff; i++)
-    rl_line_buffer[i] = rl_line_buffer[i + diff];
-
-  /* Remember how to undo this delete. */
-  if (_rl_doing_an_undo == 0)
-    rl_add_undo (UNDO_DELETE, from, to, text);
-  else
-    free (text);
-
-  rl_end -= diff;
-  rl_line_buffer[rl_end] = '\0';
-  return (diff);
-}
-
-/* Fix up point so that it is within the line boundaries after killing
-   text.  If FIX_MARK_TOO is non-zero, the mark is forced within line
-   boundaries also. */
-
-#define _RL_FIX_POINT(x) \
-       do { \
-       if (x > rl_end) \
-         x = rl_end; \
-       else if (x < 0) \
-         x = 0; \
-       } while (0)
-
-void
-_rl_fix_point (fix_mark_too)
-     int fix_mark_too;
-{
-  _RL_FIX_POINT (rl_point);
-  if (fix_mark_too)
-    _RL_FIX_POINT (rl_mark);
-}
-#undef _RL_FIX_POINT
-
-/* Replace the contents of the line buffer between START and END with
-   TEXT.  The operation is undoable.  To replace the entire line in an
-   undoable mode, use _rl_replace_text(text, 0, rl_end); */
-int
-_rl_replace_text (text, start, end)
-     const char *text;
-     int start, end;
-{
-  int n;
-
-  n = 0;
-  rl_begin_undo_group ();
-  if (start <= end)
-    rl_delete_text (start, end + 1);
-  rl_point = start;
-  if (*text)
-    n = rl_insert_text (text);
-  rl_end_undo_group ();
-
-  return n;
-}
-
-/* Replace the current line buffer contents with TEXT.  If CLEAR_UNDO is
-   non-zero, we free the current undo list. */
-void
-rl_replace_line (text, clear_undo)
-     const char *text;
-     int clear_undo;
-{
-  int len;
-
-  len = strlen (text);
-  if (len >= rl_line_buffer_len)
-    rl_extend_line_buffer (len);
-  strcpy (rl_line_buffer, text);
-  rl_end = len;
-
-  if (clear_undo)
-    rl_free_undo_list ();
-
-  _rl_fix_point (1);
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Readline character functions                */
-/*                                                                 */
-/* **************************************************************** */
-
-/* This is not a gap editor, just a stupid line input routine.  No hair
-   is involved in writing any of the functions, and none should be. */
-
-/* Note that:
-
-   rl_end is the place in the string that we would place '\0';
-   i.e., it is always safe to place '\0' there.
-
-   rl_point is the place in the string where the cursor is.  Sometimes
-   this is the same as rl_end.
-
-   Any command that is called interactively receives two arguments.
-   The first is a count: the numeric arg pased to this command.
-   The second is the key which invoked this command.
-*/
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Movement Commands                           */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Note that if you `optimize' the display for these functions, you cannot
-   use said functions in other functions which do not do optimizing display.
-   I.e., you will have to update the data base for rl_redisplay, and you
-   might as well let rl_redisplay do that job. */
-
-/* Move forward COUNT bytes. */
-int
-rl_forward_byte (count, key)
-     int count, key;
-{
-  if (count < 0)
-    return (rl_backward_byte (-count, key));
-
-  if (count > 0)
-    {
-      int end = rl_point + count;
-#if defined (VI_MODE)
-      int lend = rl_end > 0 ? rl_end - (VI_COMMAND_MODE()) : rl_end;
-#else
-      int lend = rl_end;
-#endif
-
-      if (end > lend)
-       {
-         rl_point = lend;
-         rl_ding ();
-       }
-      else
-       rl_point = end;
-    }
-
-  if (rl_end < 0)
-    rl_end = 0;
-
-  return 0;
-}
-
-#if defined (HANDLE_MULTIBYTE)
-/* Move forward COUNT characters. */
-int
-rl_forward_char (count, key)
-     int count, key;
-{
-  int point;
-
-  if (MB_CUR_MAX == 1 || rl_byte_oriented)
-    return (rl_forward_byte (count, key));
-
-  if (count < 0)
-    return (rl_backward_char (-count, key));
-
-  if (count > 0)
-    {
-      if (rl_point == rl_end && EMACS_MODE())
-       {
-         rl_ding ();
-         return 0;
-       }
-
-      point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
-
-#if defined (VI_MODE)
-      if (point >= rl_end && VI_COMMAND_MODE())
-       point = _rl_find_prev_mbchar (rl_line_buffer, rl_end, MB_FIND_NONZERO);
-#endif
-
-      if (rl_point == point)
-       rl_ding ();
-
-      rl_point = point;
-
-      if (rl_end < 0)
-       rl_end = 0;
-    }
-
-  return 0;
-}
-#else /* !HANDLE_MULTIBYTE */
-int
-rl_forward_char (count, key)
-     int count, key;
-{
-  return (rl_forward_byte (count, key));
-}
-#endif /* !HANDLE_MULTIBYTE */
-  
-/* Backwards compatibility. */
-int
-rl_forward (count, key)
-     int count, key;
-{
-  return (rl_forward_char (count, key));
-}
-
-/* Move backward COUNT bytes. */
-int
-rl_backward_byte (count, key)
-     int count, key;
-{
-  if (count < 0)
-    return (rl_forward_byte (-count, key));
-
-  if (count > 0)
-    {
-      if (rl_point < count)
-       {
-         rl_point = 0;
-         rl_ding ();
-       }
-      else
-       rl_point -= count;
-    }
-
-  if (rl_point < 0)
-    rl_point = 0;
-
-  return 0;
-}
-
-#if defined (HANDLE_MULTIBYTE)
-/* Move backward COUNT characters. */
-int
-rl_backward_char (count, key)
-     int count, key;
-{
-  int point;
-
-  if (MB_CUR_MAX == 1 || rl_byte_oriented)
-    return (rl_backward_byte (count, key));
-
-  if (count < 0)
-    return (rl_forward_char (-count, key));
-
-  if (count > 0)
-    {
-      point = rl_point;
-
-      while (count > 0 && point > 0)
-       {
-         point = _rl_find_prev_mbchar (rl_line_buffer, point, MB_FIND_NONZERO);
-         count--;
-       }
-      if (count > 0)
-       {
-         rl_point = 0;
-         rl_ding ();
-       }
-      else
-        rl_point = point;
-    }
-
-  return 0;
-}
-#else
-int
-rl_backward_char (count, key)
-     int count, key;
-{
-  return (rl_backward_byte (count, key));
-}
-#endif
-
-/* Backwards compatibility. */
-int
-rl_backward (count, key)
-     int count, key;
-{
-  return (rl_backward_char (count, key));
-}
-
-/* Move to the beginning of the line. */
-int
-rl_beg_of_line (count, key)
-     int count, key;
-{
-  rl_point = 0;
-  return 0;
-}
-
-/* Move to the end of the line. */
-int
-rl_end_of_line (count, key)
-     int count, key;
-{
-  rl_point = rl_end;
-  return 0;
-}
-
-/* Move forward a word.  We do what Emacs does.  Handles multibyte chars. */
-int
-rl_forward_word (count, key)
-     int count, key;
-{
-  int c;
-
-  if (count < 0)
-    return (rl_backward_word (-count, key));
-
-  while (count)
-    {
-      if (rl_point == rl_end)
-       return 0;
-
-      /* If we are not in a word, move forward until we are in one.
-        Then, move forward until we hit a non-alphabetic character. */
-      c = _rl_char_value (rl_line_buffer, rl_point);
-
-      if (_rl_walphabetic (c) == 0)
-       {
-         rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
-         while (rl_point < rl_end)
-           {
-             c = _rl_char_value (rl_line_buffer, rl_point);
-             if (_rl_walphabetic (c))
-               break;
-             rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
-           }
-       }
-
-      if (rl_point == rl_end)
-       return 0;
-
-      rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
-      while (rl_point < rl_end)
-       {
-         c = _rl_char_value (rl_line_buffer, rl_point);
-         if (_rl_walphabetic (c) == 0)
-           break;
-         rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
-       }
-
-      --count;
-    }
-
-  return 0;
-}
-
-/* Move backward a word.  We do what Emacs does.  Handles multibyte chars. */
-int
-rl_backward_word (count, key)
-     int count, key;
-{
-  int c, p;
-
-  if (count < 0)
-    return (rl_forward_word (-count, key));
-
-  while (count)
-    {
-      if (rl_point == 0)
-       return 0;
-
-      /* Like rl_forward_word (), except that we look at the characters
-        just before point. */
-
-      p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
-      c = _rl_char_value (rl_line_buffer, p);
-
-      if (_rl_walphabetic (c) == 0)
-       {
-         rl_point = p;
-         while (rl_point > 0)
-           {
-             p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
-             c = _rl_char_value (rl_line_buffer, p);
-             if (_rl_walphabetic (c))
-               break;
-             rl_point = p;
-           }
-       }
-
-      while (rl_point)
-       {
-         p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
-         c = _rl_char_value (rl_line_buffer, p);         
-         if (_rl_walphabetic (c) == 0)
-           break;
-         else
-           rl_point = p;
-       }
-
-      --count;
-    }
-
-  return 0;
-}
-
-/* Clear the current line.  Numeric argument to C-l does this. */
-int
-rl_refresh_line (ignore1, ignore2)
-     int ignore1, ignore2;
-{
-  int curr_line;
-
-  curr_line = _rl_current_display_line ();
-
-  _rl_move_vert (curr_line);
-  _rl_move_cursor_relative (0, rl_line_buffer);   /* XXX is this right */
-
-  _rl_clear_to_eol (0);                /* arg of 0 means to not use spaces */
-
-  rl_forced_update_display ();
-  rl_display_fixed = 1;
-
-  return 0;
-}
-
-/* C-l typed to a line without quoting clears the screen, and then reprints
-   the prompt and the current input line.  Given a numeric arg, redraw only
-   the current line. */
-int
-rl_clear_screen (count, key)
-     int count, key;
-{
-  if (rl_explicit_arg)
-    {
-      rl_refresh_line (count, key);
-      return 0;
-    }
-
-  _rl_clear_screen ();         /* calls termcap function to clear screen */
-  rl_forced_update_display ();
-  rl_display_fixed = 1;
-
-  return 0;
-}
-
-int
-rl_skip_csi_sequence (count, key)
-     int count, key;
-{
-  int ch;
-
-  RL_SETSTATE (RL_STATE_MOREINPUT);
-  do
-    ch = rl_read_key ();
-  while (ch >= 0x20 && ch < 0x40);
-  RL_UNSETSTATE (RL_STATE_MOREINPUT);
-
-  return 0;
-}
-
-int
-rl_arrow_keys (count, c)
-     int count, c;
-{
-  int ch;
-
-  RL_SETSTATE(RL_STATE_MOREINPUT);
-  ch = rl_read_key ();
-  RL_UNSETSTATE(RL_STATE_MOREINPUT);
-
-  switch (_rl_to_upper (ch))
-    {
-    case 'A':
-      rl_get_previous_history (count, ch);
-      break;
-
-    case 'B':
-      rl_get_next_history (count, ch);
-      break;
-
-    case 'C':
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-       rl_forward_char (count, ch);
-      else
-       rl_forward_byte (count, ch);
-      break;
-
-    case 'D':
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-       rl_backward_char (count, ch);
-      else
-       rl_backward_byte (count, ch);
-      break;
-
-    default:
-      rl_ding ();
-    }
-
-  return 0;
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Text commands                               */
-/*                                                                 */
-/* **************************************************************** */
-
-#ifdef HANDLE_MULTIBYTE
-static char pending_bytes[MB_LEN_MAX];
-static int pending_bytes_length = 0;
-static mbstate_t ps = {0};
-#endif
-
-/* Insert the character C at the current location, moving point forward.
-   If C introduces a multibyte sequence, we read the whole sequence and
-   then insert the multibyte char into the line buffer. */
-int
-_rl_insert_char (count, c)
-     int count, c;
-{
-  register int i;
-  char *string;
-#ifdef HANDLE_MULTIBYTE
-  int string_size;
-  char incoming[MB_LEN_MAX + 1];
-  int incoming_length = 0;
-  mbstate_t ps_back;
-  static int stored_count = 0;
-#endif
-
-  if (count <= 0)
-    return 0;
-
-#if defined (HANDLE_MULTIBYTE)
-  if (MB_CUR_MAX == 1 || rl_byte_oriented)
-    {
-      incoming[0] = c;
-      incoming[1] = '\0';
-      incoming_length = 1;
-    }
-  else
-    {
-      wchar_t wc;
-      size_t ret;
-
-      if (stored_count <= 0)
-       stored_count = count;
-      else
-       count = stored_count;
-
-      ps_back = ps;
-      pending_bytes[pending_bytes_length++] = c;
-      ret = mbrtowc (&wc, pending_bytes, pending_bytes_length, &ps);
-
-      if (ret == (size_t)-2)
-       {
-         /* Bytes too short to compose character, try to wait for next byte.
-            Restore the state of the byte sequence, because in this case the
-            effect of mbstate is undefined. */
-         ps = ps_back;
-         return 1;
-       }
-      else if (ret == (size_t)-1)
-       {
-         /* Invalid byte sequence for the current locale.  Treat first byte
-            as a single character. */
-         incoming[0] = pending_bytes[0];
-         incoming[1] = '\0';
-         incoming_length = 1;
-         pending_bytes_length--;
-         memmove (pending_bytes, pending_bytes + 1, pending_bytes_length);
-         /* Clear the state of the byte sequence, because in this case the
-            effect of mbstate is undefined. */
-         memset (&ps, 0, sizeof (mbstate_t));
-       }
-      else if (ret == (size_t)0)
-       {
-         incoming[0] = '\0';
-         incoming_length = 0;
-         pending_bytes_length--;
-         /* Clear the state of the byte sequence, because in this case the
-            effect of mbstate is undefined. */
-         memset (&ps, 0, sizeof (mbstate_t));
-       }
-      else
-       {
-         /* We successfully read a single multibyte character. */
-         memcpy (incoming, pending_bytes, pending_bytes_length);
-         incoming[pending_bytes_length] = '\0';
-         incoming_length = pending_bytes_length;
-         pending_bytes_length = 0;
-       }
-    }
-#endif /* HANDLE_MULTIBYTE */
-         
-  /* If we can optimize, then do it.  But don't let people crash
-     readline because of extra large arguments. */
-  if (count > 1 && count <= TEXT_COUNT_MAX)
-    {
-#if defined (HANDLE_MULTIBYTE)
-      string_size = count * incoming_length;
-      string = (char *)xmalloc (1 + string_size);
-
-      i = 0;
-      while (i < string_size)
-       {
-         strncpy (string + i, incoming, incoming_length);
-         i += incoming_length;
-       }
-      incoming_length = 0;
-      stored_count = 0;
-#else /* !HANDLE_MULTIBYTE */
-      string = (char *)xmalloc (1 + count);
-
-      for (i = 0; i < count; i++)
-       string[i] = c;
-#endif /* !HANDLE_MULTIBYTE */
-
-      string[i] = '\0';
-      rl_insert_text (string);
-      free (string);
-
-      return 0;
-    }
-
-  if (count > TEXT_COUNT_MAX)
-    {
-      int decreaser;
-#if defined (HANDLE_MULTIBYTE)
-      string_size = incoming_length * TEXT_COUNT_MAX;
-      string = (char *)xmalloc (1 + string_size);
-
-      i = 0;
-      while (i < string_size)
-       {
-         strncpy (string + i, incoming, incoming_length);
-         i += incoming_length;
-       }
-
-      while (count)
-       {
-         decreaser = (count > TEXT_COUNT_MAX) ? TEXT_COUNT_MAX : count;
-         string[decreaser*incoming_length] = '\0';
-         rl_insert_text (string);
-         count -= decreaser;
-       }
-
-      free (string);
-      incoming_length = 0;
-      stored_count = 0;
-#else /* !HANDLE_MULTIBYTE */
-      char str[TEXT_COUNT_MAX+1];
-
-      for (i = 0; i < TEXT_COUNT_MAX; i++)
-       str[i] = c;
-
-      while (count)
-       {
-         decreaser = (count > TEXT_COUNT_MAX ? TEXT_COUNT_MAX : count);
-         str[decreaser] = '\0';
-         rl_insert_text (str);
-         count -= decreaser;
-       }
-#endif /* !HANDLE_MULTIBYTE */
-
-      return 0;
-    }
-
-  if (MB_CUR_MAX == 1 || rl_byte_oriented)
-    {
-      /* We are inserting a single character.
-        If there is pending input, then make a string of all of the
-        pending characters that are bound to rl_insert, and insert
-        them all. */
-      if (_rl_any_typein ())
-       _rl_insert_typein (c);
-      else
-       {
-         /* Inserting a single character. */
-         char str[2];
-
-         str[1] = '\0';
-         str[0] = c;
-         rl_insert_text (str);
-       }
-    }
-#if defined (HANDLE_MULTIBYTE)
-  else
-    {
-      rl_insert_text (incoming);
-      stored_count = 0;
-    }
-#endif
-
-  return 0;
-}
-
-/* Overwrite the character at point (or next COUNT characters) with C.
-   If C introduces a multibyte character sequence, read the entire sequence
-   before starting the overwrite loop. */
-int
-_rl_overwrite_char (count, c)
-     int count, c;
-{
-  int i;
-#if defined (HANDLE_MULTIBYTE)
-  char mbkey[MB_LEN_MAX];
-  int k;
-
-  /* Read an entire multibyte character sequence to insert COUNT times. */
-  if (count > 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-    k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX);
-#endif
-
-  rl_begin_undo_group ();
-
-  for (i = 0; i < count; i++)
-    {
-#if defined (HANDLE_MULTIBYTE)
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-       rl_insert_text (mbkey);
-      else
-#endif
-       _rl_insert_char (1, c);
-
-      if (rl_point < rl_end)
-       rl_delete (1, c);
-    }
-
-  rl_end_undo_group ();
-
-  return 0;
-}
-
-int
-rl_insert (count, c)
-     int count, c;
-{
-  return (rl_insert_mode == RL_IM_INSERT ? _rl_insert_char (count, c)
-                                        : _rl_overwrite_char (count, c));
-}
-
-/* Insert the next typed character verbatim. */
-static int
-_rl_insert_next (count)
-     int count;
-{
-  int c;
-
-  RL_SETSTATE(RL_STATE_MOREINPUT);
-  c = rl_read_key ();
-  RL_UNSETSTATE(RL_STATE_MOREINPUT);
-
-  if (c < 0)
-    return -1;
-
-#if defined (HANDLE_SIGNALS)
-  if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
-    _rl_restore_tty_signals ();
-#endif
-
-  return (_rl_insert_char (count, c));  
-}
-
-#if defined (READLINE_CALLBACKS)
-static int
-_rl_insert_next_callback (data)
-     _rl_callback_generic_arg *data;
-{
-  int count;
-
-  count = data->count;
-
-  /* Deregister function, let rl_callback_read_char deallocate data */
-  _rl_callback_func = 0;
-  _rl_want_redisplay = 1;
-  return _rl_insert_next (count);
-}
-#endif
-  
-int
-rl_quoted_insert (count, key)
-     int count, key;
-{
-  /* Let's see...should the callback interface futz with signal handling? */
-#if defined (HANDLE_SIGNALS)
-  if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
-    _rl_disable_tty_signals ();
-#endif
-
-#if defined (READLINE_CALLBACKS)
-  if (RL_ISSTATE (RL_STATE_CALLBACK))
-    {
-      _rl_callback_data = _rl_callback_data_alloc (count);
-      _rl_callback_func = _rl_insert_next_callback;
-      return (0);
-    }
-#endif
-      
-  return _rl_insert_next (count);
-}
-
-/* Insert a tab character. */
-int
-rl_tab_insert (count, key)
-     int count, key;
-{
-  return (_rl_insert_char (count, '\t'));
-}
-
-/* What to do when a NEWLINE is pressed.  We accept the whole line.
-   KEY is the key that invoked this command.  I guess it could have
-   meaning in the future. */
-int
-rl_newline (count, key)
-     int count, key;
-{
-  rl_done = 1;
-
-  if (_rl_history_preserve_point)
-    _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
-
-  RL_SETSTATE(RL_STATE_DONE);
-
-#if defined (VI_MODE)
-  if (rl_editing_mode == vi_mode)
-    {
-      _rl_vi_done_inserting ();
-      if (_rl_vi_textmod_command (_rl_vi_last_command) == 0)   /* XXX */
-       _rl_vi_reset_last ();
-    }
-#endif /* VI_MODE */
-
-  /* If we've been asked to erase empty lines, suppress the final update,
-     since _rl_update_final calls rl_crlf(). */
-  if (rl_erase_empty_line && rl_point == 0 && rl_end == 0)
-    return 0;
-
-  if (_rl_echoing_p)
-    _rl_update_final ();
-  return 0;
-}
-
-/* What to do for some uppercase characters, like meta characters,
-   and some characters appearing in emacs_ctlx_keymap.  This function
-   is just a stub, you bind keys to it and the code in _rl_dispatch ()
-   is special cased. */
-int
-rl_do_lowercase_version (ignore1, ignore2)
-     int ignore1, ignore2;
-{
-  return 0;
-}
-
-/* This is different from what vi does, so the code's not shared.  Emacs
-   rubout in overwrite mode has one oddity:  it replaces a control
-   character that's displayed as two characters (^X) with two spaces. */
-int
-_rl_overwrite_rubout (count, key)
-     int count, key;
-{
-  int opoint;
-  int i, l;
-
-  if (rl_point == 0)
-    {
-      rl_ding ();
-      return 1;
-    }
-
-  opoint = rl_point;
-
-  /* L == number of spaces to insert */
-  for (i = l = 0; i < count; i++)
-    {
-      rl_backward_char (1, key);
-      l += rl_character_len (rl_line_buffer[rl_point], rl_point);      /* not exactly right */
-    }
-
-  rl_begin_undo_group ();
-
-  if (count > 1 || rl_explicit_arg)
-    rl_kill_text (opoint, rl_point);
-  else
-    rl_delete_text (opoint, rl_point);
-
-  /* Emacs puts point at the beginning of the sequence of spaces. */
-  if (rl_point < rl_end)
-    {
-      opoint = rl_point;
-      _rl_insert_char (l, ' ');
-      rl_point = opoint;
-    }
-
-  rl_end_undo_group ();
-
-  return 0;
-}
-  
-/* Rubout the character behind point. */
-int
-rl_rubout (count, key)
-     int count, key;
-{
-  if (count < 0)
-    return (rl_delete (-count, key));
-
-  if (!rl_point)
-    {
-      rl_ding ();
-      return -1;
-    }
-
-  if (rl_insert_mode == RL_IM_OVERWRITE)
-    return (_rl_overwrite_rubout (count, key));
-
-  return (_rl_rubout_char (count, key));
-}
-
-int
-_rl_rubout_char (count, key)
-     int count, key;
-{
-  int orig_point;
-  unsigned char c;
-
-  /* Duplicated code because this is called from other parts of the library. */
-  if (count < 0)
-    return (rl_delete (-count, key));
-
-  if (rl_point == 0)
-    {
-      rl_ding ();
-      return -1;
-    }
-
-  orig_point = rl_point;
-  if (count > 1 || rl_explicit_arg)
-    {
-      rl_backward_char (count, key);
-      rl_kill_text (orig_point, rl_point);
-    }
-  else if (MB_CUR_MAX == 1 || rl_byte_oriented)
-    {
-      c = rl_line_buffer[--rl_point];
-      rl_delete_text (rl_point, orig_point);
-      /* The erase-at-end-of-line hack is of questionable merit now. */
-      if (rl_point == rl_end && ISPRINT (c) && _rl_last_c_pos)
-       {
-         int l;
-         l = rl_character_len (c, rl_point);
-         _rl_erase_at_end_of_line (l);
-       }
-    }
-  else
-    {
-      rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
-      rl_delete_text (rl_point, orig_point);
-    }
-
-  return 0;
-}
-
-/* Delete the character under the cursor.  Given a numeric argument,
-   kill that many characters instead. */
-int
-rl_delete (count, key)
-     int count, key;
-{
-  int xpoint;
-
-  if (count < 0)
-    return (_rl_rubout_char (-count, key));
-
-  if (rl_point == rl_end)
-    {
-      rl_ding ();
-      return -1;
-    }
-
-  if (count > 1 || rl_explicit_arg)
-    {
-      xpoint = rl_point;
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-       rl_forward_char (count, key);
-      else
-       rl_forward_byte (count, key);
-
-      rl_kill_text (xpoint, rl_point);
-      rl_point = xpoint;
-    }
-  else
-    {
-      xpoint = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
-      rl_delete_text (rl_point, xpoint);
-    }
-  return 0;
-}
-
-/* Delete the character under the cursor, unless the insertion
-   point is at the end of the line, in which case the character
-   behind the cursor is deleted.  COUNT is obeyed and may be used
-   to delete forward or backward that many characters. */      
-int
-rl_rubout_or_delete (count, key)
-     int count, key;
-{
-  if (rl_end != 0 && rl_point == rl_end)
-    return (_rl_rubout_char (count, key));
-  else
-    return (rl_delete (count, key));
-}  
-
-/* Delete all spaces and tabs around point. */
-int
-rl_delete_horizontal_space (count, ignore)
-     int count, ignore;
-{
-  int start = rl_point;
-
-  while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
-    rl_point--;
-
-  start = rl_point;
-
-  while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
-    rl_point++;
-
-  if (start != rl_point)
-    {
-      rl_delete_text (start, rl_point);
-      rl_point = start;
-    }
-
-  if (rl_point < 0)
-    rl_point = 0;
-
-  return 0;
-}
-
-/* Like the tcsh editing function delete-char-or-list.  The eof character
-   is caught before this is invoked, so this really does the same thing as
-   delete-char-or-list-or-eof, as long as it's bound to the eof character. */
-int
-rl_delete_or_show_completions (count, key)
-     int count, key;
-{
-  if (rl_end != 0 && rl_point == rl_end)
-    return (rl_possible_completions (count, key));
-  else
-    return (rl_delete (count, key));
-}
-
-#ifndef RL_COMMENT_BEGIN_DEFAULT
-#define RL_COMMENT_BEGIN_DEFAULT "#"
-#endif
-
-/* Turn the current line into a comment in shell history.
-   A K*rn shell style function. */
-int
-rl_insert_comment (count, key)
-     int count, key;
-{
-  char *rl_comment_text;
-  int rl_comment_len;
-
-  rl_beg_of_line (1, key);
-  rl_comment_text = _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT;
-
-  if (rl_explicit_arg == 0)
-    rl_insert_text (rl_comment_text);
-  else
-    {
-      rl_comment_len = strlen (rl_comment_text);
-      if (STREQN (rl_comment_text, rl_line_buffer, rl_comment_len))
-       rl_delete_text (rl_point, rl_point + rl_comment_len);
-      else
-       rl_insert_text (rl_comment_text);
-    }
-
-  (*rl_redisplay_function) ();
-  rl_newline (1, '\n');
-
-  return (0);
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Changing Case                               */
-/*                                                                 */
-/* **************************************************************** */
-
-/* The three kinds of things that we know how to do. */
-#define UpCase 1
-#define DownCase 2
-#define CapCase 3
-
-/* Uppercase the word at point. */
-int
-rl_upcase_word (count, key)
-     int count, key;
-{
-  return (rl_change_case (count, UpCase));
-}
-
-/* Lowercase the word at point. */
-int
-rl_downcase_word (count, key)
-     int count, key;
-{
-  return (rl_change_case (count, DownCase));
-}
-
-/* Upcase the first letter, downcase the rest. */
-int
-rl_capitalize_word (count, key)
-     int count, key;
-{
- return (rl_change_case (count, CapCase));
-}
-
-/* The meaty function.
-   Change the case of COUNT words, performing OP on them.
-   OP is one of UpCase, DownCase, or CapCase.
-   If a negative argument is given, leave point where it started,
-   otherwise, leave it where it moves to. */
-static int
-rl_change_case (count, op)
-     int count, op;
-{
-  int start, next, end;
-  int inword, c, nc, nop;
-#if defined (HANDLE_MULTIBYTE)
-  wchar_t wc, nwc;
-  char mb[MB_LEN_MAX+1];
-  int mlen;
-  size_t m;
-  mbstate_t mps;
-#endif
-
-  start = rl_point;
-  rl_forward_word (count, 0);
-  end = rl_point;
-
-  if (op != UpCase && op != DownCase && op != CapCase)
-    {
-      rl_ding ();
-      return -1;
-    }
-
-  if (count < 0)
-    SWAP (start, end);
-
-#if defined (HANDLE_MULTIBYTE)
-  memset (&mps, 0, sizeof (mbstate_t));
-#endif
-
-  /* We are going to modify some text, so let's prepare to undo it. */
-  rl_modifying (start, end);
-
-  inword = 0;
-  while (start < end)
-    {
-      c = _rl_char_value (rl_line_buffer, start);
-      /*  This assumes that the upper and lower case versions are the same width. */
-      next = MB_NEXTCHAR (rl_line_buffer, start, 1, MB_FIND_NONZERO);
-
-      if (_rl_walphabetic (c) == 0)
-       {
-         inword = 0;
-         start = next;
-         continue;
-       }
-
-      if (op == CapCase)
-       {
-         nop = inword ? DownCase : UpCase;
-         inword = 1;
-       }
-      else
-       nop = op;
-      if (MB_CUR_MAX == 1 || rl_byte_oriented || isascii (c))
-       {
-         nc = (nop == UpCase) ? _rl_to_upper (c) : _rl_to_lower (c);
-         rl_line_buffer[start] = nc;
-       }
-#if defined (HANDLE_MULTIBYTE)
-      else
-       {
-         m = mbrtowc (&wc, rl_line_buffer + start, end - start, &mps);
-         if (MB_INVALIDCH (m))
-           wc = (wchar_t)rl_line_buffer[start];
-         else if (MB_NULLWCH (m))
-           wc = L'\0';
-         nwc = (nop == UpCase) ? _rl_to_wupper (wc) : _rl_to_wlower (wc);
-         if  (nwc != wc)       /*  just skip unchanged characters */
-           {
-             mlen = wcrtomb (mb, nwc, &mps);
-             if (mlen > 0)
-               mb[mlen] = '\0';
-             /* Assume the same width */
-             strncpy (rl_line_buffer + start, mb, mlen);
-           }
-       }
-#endif
-
-      start = next;
-    }
-
-  rl_point = end;
-  return 0;
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Transposition                               */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Transpose the words at point.  If point is at the end of the line,
-   transpose the two words before point. */
-int
-rl_transpose_words (count, key)
-     int count, key;
-{
-  char *word1, *word2;
-  int w1_beg, w1_end, w2_beg, w2_end;
-  int orig_point = rl_point;
-
-  if (!count)
-    return 0;
-
-  /* Find the two words. */
-  rl_forward_word (count, key);
-  w2_end = rl_point;
-  rl_backward_word (1, key);
-  w2_beg = rl_point;
-  rl_backward_word (count, key);
-  w1_beg = rl_point;
-  rl_forward_word (1, key);
-  w1_end = rl_point;
-
-  /* Do some check to make sure that there really are two words. */
-  if ((w1_beg == w2_beg) || (w2_beg < w1_end))
-    {
-      rl_ding ();
-      rl_point = orig_point;
-      return -1;
-    }
-
-  /* Get the text of the words. */
-  word1 = rl_copy_text (w1_beg, w1_end);
-  word2 = rl_copy_text (w2_beg, w2_end);
-
-  /* We are about to do many insertions and deletions.  Remember them
-     as one operation. */
-  rl_begin_undo_group ();
-
-  /* Do the stuff at word2 first, so that we don't have to worry
-     about word1 moving. */
-  rl_point = w2_beg;
-  rl_delete_text (w2_beg, w2_end);
-  rl_insert_text (word1);
-
-  rl_point = w1_beg;
-  rl_delete_text (w1_beg, w1_end);
-  rl_insert_text (word2);
-
-  /* This is exactly correct since the text before this point has not
-     changed in length. */
-  rl_point = w2_end;
-
-  /* I think that does it. */
-  rl_end_undo_group ();
-  free (word1);
-  free (word2);
-
-  return 0;
-}
-
-/* Transpose the characters at point.  If point is at the end of the line,
-   then transpose the characters before point. */
-int
-rl_transpose_chars (count, key)
-     int count, key;
-{
-#if defined (HANDLE_MULTIBYTE)
-  char *dummy;
-  int i;
-#else
-  char dummy[2];
-#endif
-  int char_length, prev_point;
-
-  if (count == 0)
-    return 0;
-
-  if (!rl_point || rl_end < 2)
-    {
-      rl_ding ();
-      return -1;
-    }
-
-  rl_begin_undo_group ();
-
-  if (rl_point == rl_end)
-    {
-      rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
-      count = 1;
-    }
-
-  prev_point = rl_point;
-  rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
-
-#if defined (HANDLE_MULTIBYTE)
-  char_length = prev_point - rl_point;
-  dummy = (char *)xmalloc (char_length + 1);
-  for (i = 0; i < char_length; i++)
-    dummy[i] = rl_line_buffer[rl_point + i];
-  dummy[i] = '\0';
-#else
-  dummy[0] = rl_line_buffer[rl_point];
-  dummy[char_length = 1] = '\0';
-#endif
-
-  rl_delete_text (rl_point, rl_point + char_length);
-
-  rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
-
-  _rl_fix_point (0);
-  rl_insert_text (dummy);
-  rl_end_undo_group ();
-
-#if defined (HANDLE_MULTIBYTE)
-  free (dummy);
-#endif
-
-  return 0;
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Character Searching                         */
-/*                                                                 */
-/* **************************************************************** */
-
-int
-#if defined (HANDLE_MULTIBYTE)
-_rl_char_search_internal (count, dir, smbchar, len)
-     int count, dir;
-     char *smbchar;
-     int len;
-#else
-_rl_char_search_internal (count, dir, schar)
-     int count, dir, schar;
-#endif
-{
-  int pos, inc;
-#if defined (HANDLE_MULTIBYTE)
-  int prepos;
-#endif
-
-  pos = rl_point;
-  inc = (dir < 0) ? -1 : 1;
-  while (count)
-    {
-      if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= rl_end))
-       {
-         rl_ding ();
-         return -1;
-       }
-
-#if defined (HANDLE_MULTIBYTE)
-      pos = (inc > 0) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
-                     : _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
-#else
-      pos += inc;
-#endif
-      do
-       {
-#if defined (HANDLE_MULTIBYTE)
-         if (_rl_is_mbchar_matched (rl_line_buffer, pos, rl_end, smbchar, len))
-#else
-         if (rl_line_buffer[pos] == schar)
-#endif
-           {
-             count--;
-             if (dir < 0)
-               rl_point = (dir == BTO) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
-                                       : pos;
-             else
-               rl_point = (dir == FTO) ? _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)
-                                       : pos;
-             break;
-           }
-#if defined (HANDLE_MULTIBYTE)
-         prepos = pos;
-#endif
-       }
-#if defined (HANDLE_MULTIBYTE)
-      while ((dir < 0) ? (pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)) != prepos
-                      : (pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)) != prepos);
-#else
-      while ((dir < 0) ? pos-- : ++pos < rl_end);
-#endif
-    }
-  return (0);
-}
-
-/* Search COUNT times for a character read from the current input stream.
-   FDIR is the direction to search if COUNT is non-negative; otherwise
-   the search goes in BDIR.  So much is dependent on HANDLE_MULTIBYTE
-   that there are two separate versions of this function. */
-#if defined (HANDLE_MULTIBYTE)
-static int
-_rl_char_search (count, fdir, bdir)
-     int count, fdir, bdir;
-{
-  char mbchar[MB_LEN_MAX];
-  int mb_len;
-
-  mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX);
-
-  if (mb_len <= 0)
-    return -1;
-
-  if (count < 0)
-    return (_rl_char_search_internal (-count, bdir, mbchar, mb_len));
-  else
-    return (_rl_char_search_internal (count, fdir, mbchar, mb_len));
-}
-#else /* !HANDLE_MULTIBYTE */
-static int
-_rl_char_search (count, fdir, bdir)
-     int count, fdir, bdir;
-{
-  int c;
-
-  RL_SETSTATE(RL_STATE_MOREINPUT);
-  c = rl_read_key ();
-  RL_UNSETSTATE(RL_STATE_MOREINPUT);
-
-  if (c < 0)
-    return -1;
-
-  if (count < 0)
-    return (_rl_char_search_internal (-count, bdir, c));
-  else
-    return (_rl_char_search_internal (count, fdir, c));
-}
-#endif /* !HANDLE_MULTIBYTE */
-
-#if defined (READLINE_CALLBACKS)
-static int
-_rl_char_search_callback (data)
-     _rl_callback_generic_arg *data;
-{
-  _rl_callback_func = 0;
-  _rl_want_redisplay = 1;
-
-  return (_rl_char_search (data->count, data->i1, data->i2));
-}
-#endif
-
-int
-rl_char_search (count, key)
-     int count, key;
-{
-#if defined (READLINE_CALLBACKS)
-  if (RL_ISSTATE (RL_STATE_CALLBACK))
-    {
-      _rl_callback_data = _rl_callback_data_alloc (count);
-      _rl_callback_data->i1 = FFIND;
-      _rl_callback_data->i2 = BFIND;
-      _rl_callback_func = _rl_char_search_callback;
-      return (0);
-    }
-#endif
-  
-  return (_rl_char_search (count, FFIND, BFIND));
-}
-
-int
-rl_backward_char_search (count, key)
-     int count, key;
-{
-#if defined (READLINE_CALLBACKS)
-  if (RL_ISSTATE (RL_STATE_CALLBACK))
-    {
-      _rl_callback_data = _rl_callback_data_alloc (count);
-      _rl_callback_data->i1 = BFIND;
-      _rl_callback_data->i2 = FFIND;
-      _rl_callback_func = _rl_char_search_callback;
-      return (0);
-    }
-#endif
-
-  return (_rl_char_search (count, BFIND, FFIND));
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*                The Mark and the Region.                         */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Set the mark at POSITION. */
-int
-_rl_set_mark_at_pos (position)
-     int position;
-{
-  if (position > rl_end)
-    return -1;
-
-  rl_mark = position;
-  return 0;
-}
-
-/* A bindable command to set the mark. */
-int
-rl_set_mark (count, key)
-     int count, key;
-{
-  return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point));
-}
-
-/* Exchange the position of mark and point. */
-int
-rl_exchange_point_and_mark (count, key)
-     int count, key;
-{
-  if (rl_mark > rl_end)
-    rl_mark = -1;
-
-  if (rl_mark == -1)
-    {
-      rl_ding ();
-      return -1;
-    }
-  else
-    SWAP (rl_point, rl_mark);
-
-  return 0;
-}
diff --git a/lib/readline/undo.c~ b/lib/readline/undo.c~
deleted file mode 100644 (file)
index c0ba631..0000000
+++ /dev/null
@@ -1,328 +0,0 @@
-/* readline.c -- a general facility for reading lines of input
-   with emacs style editing and completion. */
-
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
-
-   This file is part of the GNU Readline Library (Readline), a library
-   for reading lines of text with interactive input and history editing.      
-
-   Readline is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   Readline is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#define READLINE_LIBRARY
-
-#if defined (HAVE_CONFIG_H)
-#  include <config.h>
-#endif
-
-#include <sys/types.h>
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>           /* for _POSIX_VERSION */
-#endif /* HAVE_UNISTD_H */
-
-#if defined (HAVE_STDLIB_H)
-#  include <stdlib.h>
-#else
-#  include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#include <stdio.h>
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-
-/* Some standard library routines. */
-#include "readline.h"
-#include "history.h"
-
-#include "rlprivate.h"
-#include "xmalloc.h"
-
-extern void replace_history_data PARAMS((int, histdata_t *, histdata_t *));
-
-/* Non-zero tells rl_delete_text and rl_insert_text to not add to
-   the undo list. */
-int _rl_doing_an_undo = 0;
-
-/* How many unclosed undo groups we currently have. */
-int _rl_undo_group_level = 0;
-
-/* The current undo list for THE_LINE. */
-UNDO_LIST *rl_undo_list = (UNDO_LIST *)NULL;
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Undo, and Undoing                           */
-/*                                                                 */
-/* **************************************************************** */
-
-static UNDO_LIST *
-alloc_undo_entry (what, start, end, text)
-     enum undo_code what;
-     int start, end;
-     char *text;
-{
-  UNDO_LIST *temp;
-
-  temp = (UNDO_LIST *)xmalloc (sizeof (UNDO_LIST));
-  temp->what = what;
-  temp->start = start;
-  temp->end = end;
-  temp->text = text;
-
-  temp->next = (UNDO_LIST *)NULL;
-  return temp;
-}
-
-/* Remember how to undo something.  Concatenate some undos if that
-   seems right. */
-void
-rl_add_undo (what, start, end, text)
-     enum undo_code what;
-     int start, end;
-     char *text;
-{
-  UNDO_LIST *temp;
-
-  temp = alloc_undo_entry (what, start, end, text);
-  temp->next = rl_undo_list;
-  rl_undo_list = temp;
-}
-
-/* Free the existing undo list. */
-void
-rl_free_undo_list ()
-{
-  UNDO_LIST *release, *orig_list;
-
-  orig_list = rl_undo_list;
-  while (rl_undo_list)
-    {
-      release = rl_undo_list;
-      rl_undo_list = rl_undo_list->next;
-
-      if (release->what == UNDO_DELETE)
-       xfree (release->text);
-
-      xfree (release);
-    }
-  rl_undo_list = (UNDO_LIST *)NULL;
-  replace_history_data (-1, (histdata_t *)orig_list, (histdata_t *)NULL);
-}
-
-UNDO_LIST *
-_rl_copy_undo_entry (entry)
-     UNDO_LIST *entry;
-{
-  UNDO_LIST *new;
-
-  new = alloc_undo_entry (entry->what, entry->start, entry->end, (char *)NULL);
-  new->text = entry->text ? savestring (entry->text) : 0;
-  return new;
-}
-
-UNDO_LIST *
-_rl_copy_undo_list (head)
-     UNDO_LIST *head;
-{
-  UNDO_LIST *list, *new, *roving, *c;
-
-  list = head;
-  new = 0;
-  while (list)
-    {
-      c = _rl_copy_undo_entry (list);
-      if (new == 0)
-       roving = new = c;
-      else
-       {
-         roving->next = c;
-         roving = roving->next;
-       }
-      list = list->next;
-    }
-
-  roving->next = 0;
-  return new;
-}
-
-/* Undo the next thing in the list.  Return 0 if there
-   is nothing to undo, or non-zero if there was. */
-int
-rl_do_undo ()
-{
-  UNDO_LIST *release;
-  int waiting_for_begin, start, end;
-
-#define TRANS(i) ((i) == -1 ? rl_point : ((i) == -2 ? rl_end : (i)))
-
-  start = end = waiting_for_begin = 0;
-  do
-    {
-      if (rl_undo_list == 0)
-       return (0);
-
-      _rl_doing_an_undo = 1;
-      RL_SETSTATE(RL_STATE_UNDOING);
-
-      /* To better support vi-mode, a start or end value of -1 means
-        rl_point, and a value of -2 means rl_end. */
-      if (rl_undo_list->what == UNDO_DELETE || rl_undo_list->what == UNDO_INSERT)
-       {
-         start = TRANS (rl_undo_list->start);
-         end = TRANS (rl_undo_list->end);
-       }
-
-      switch (rl_undo_list->what)
-       {
-       /* Undoing deletes means inserting some text. */
-       case UNDO_DELETE:
-         rl_point = start;
-         rl_insert_text (rl_undo_list->text);
-         xfree (rl_undo_list->text);
-         break;
-
-       /* Undoing inserts means deleting some text. */
-       case UNDO_INSERT:
-         rl_delete_text (start, end);
-         rl_point = start;
-         break;
-
-       /* Undoing an END means undoing everything 'til we get to a BEGIN. */
-       case UNDO_END:
-         waiting_for_begin++;
-         break;
-
-       /* Undoing a BEGIN means that we are done with this group. */
-       case UNDO_BEGIN:
-         if (waiting_for_begin)
-           waiting_for_begin--;
-         else
-           rl_ding ();
-         break;
-       }
-
-      _rl_doing_an_undo = 0;
-      RL_UNSETSTATE(RL_STATE_UNDOING);
-
-      release = rl_undo_list;
-      rl_undo_list = rl_undo_list->next;
-      replace_history_data (-1, (histdata_t *)release, (histdata_t *)rl_undo_list);
-
-      xfree (release);
-    }
-  while (waiting_for_begin);
-
-  return (1);
-}
-#undef TRANS
-
-int
-_rl_fix_last_undo_of_type (type, start, end)
-     int type, start, end;
-{
-  UNDO_LIST *rl;
-
-  for (rl = rl_undo_list; rl; rl = rl->next)
-    {
-      if (rl->what == type)
-       {
-         rl->start = start;
-         rl->end = end;
-         return 0;
-       }
-    }
-  return 1;
-}
-
-/* Begin a group.  Subsequent undos are undone as an atomic operation. */
-int
-rl_begin_undo_group ()
-{
-  rl_add_undo (UNDO_BEGIN, 0, 0, 0);
-  _rl_undo_group_level++;
-  return 0;
-}
-
-/* End an undo group started with rl_begin_undo_group (). */
-int
-rl_end_undo_group ()
-{
-  rl_add_undo (UNDO_END, 0, 0, 0);
-  _rl_undo_group_level--;
-  return 0;
-}
-
-/* Save an undo entry for the text from START to END. */
-int
-rl_modifying (start, end)
-     int start, end;
-{
-  if (start > end)
-    {
-      SWAP (start, end);
-    }
-
-  if (start != end)
-    {
-      char *temp = rl_copy_text (start, end);
-      rl_begin_undo_group ();
-      rl_add_undo (UNDO_DELETE, start, end, temp);
-      rl_add_undo (UNDO_INSERT, start, end, (char *)NULL);
-      rl_end_undo_group ();
-    }
-  return 0;
-}
-
-/* Revert the current line to its previous state. */
-int
-rl_revert_line (count, key)
-     int count, key;
-{
-  if (rl_undo_list == 0)
-    rl_ding ();
-  else
-    {
-      while (rl_undo_list)
-       rl_do_undo ();
-#if defined (VI_MODE)
-      if (rl_editing_mode == vi_mode)
-       rl_point = rl_mark = 0;         /* rl_end should be set correctly */
-#endif
-    }
-    
-  return 0;
-}
-
-/* Do some undoing of things that were done. */
-int
-rl_undo_command (count, key)
-     int count, key;
-{
-  if (count < 0)
-    return 0;  /* Nothing to do. */
-
-  while (count)
-    {
-      if (rl_do_undo ())
-       count--;
-      else
-       {
-         rl_ding ();
-         break;
-       }
-    }
-  return 0;
-}
diff --git a/lib/readline/util.c~ b/lib/readline/util.c~
deleted file mode 100644 (file)
index a07cb10..0000000
+++ /dev/null
@@ -1,512 +0,0 @@
-/* util.c -- readline utility functions */
-
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
-
-   This file is part of the GNU Readline Library (Readline), a library
-   for reading lines of text with interactive input and history editing.      
-
-   Readline is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   Readline is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#define READLINE_LIBRARY
-
-#if defined (HAVE_CONFIG_H)
-#  include <config.h>
-#endif
-
-#include <sys/types.h>
-#include <fcntl.h>
-#include "posixjmp.h"
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>           /* for _POSIX_VERSION */
-#endif /* HAVE_UNISTD_H */
-
-#if defined (HAVE_STDLIB_H)
-#  include <stdlib.h>
-#else
-#  include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#include <stdio.h>
-#include <ctype.h>
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-#include "rlmbutil.h"
-
-#if defined (TIOCSTAT_IN_SYS_IOCTL)
-#  include <sys/ioctl.h>
-#endif /* TIOCSTAT_IN_SYS_IOCTL */
-
-/* Some standard library routines. */
-#include "readline.h"
-
-#include "rlprivate.h"
-#include "xmalloc.h"
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Utility Functions                           */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Return 0 if C is not a member of the class of characters that belong
-   in words, or 1 if it is. */
-
-int _rl_allow_pathname_alphabetic_chars = 0;
-static const char * const pathname_alphabetic_chars = "/-_=~.#$";
-
-int
-rl_alphabetic (c)
-     int c;
-{
-  if (ALPHABETIC (c))
-    return (1);
-
-  return (_rl_allow_pathname_alphabetic_chars &&
-           strchr (pathname_alphabetic_chars, c) != NULL);
-}
-
-#if defined (HANDLE_MULTIBYTE)
-int
-_rl_walphabetic (wc)
-     wchar_t wc;
-{
-  int c;
-
-  if (iswalnum (wc))
-    return (1);     
-
-  c = wc & 0177;
-  return (_rl_allow_pathname_alphabetic_chars &&
-           strchr (pathname_alphabetic_chars, c) != NULL);
-}
-#endif
-
-/* How to abort things. */
-int
-_rl_abort_internal ()
-{
-  rl_ding ();
-  rl_clear_message ();
-  _rl_reset_argument ();
-  rl_clear_pending_input ();
-
-  RL_UNSETSTATE (RL_STATE_MACRODEF);
-  while (rl_executing_macro)
-    _rl_pop_executing_macro ();
-
-  rl_last_func = (rl_command_func_t *)NULL;
-  longjmp (_rl_top_level, 1);
-  return (0);
-}
-
-int
-rl_abort (count, key)
-     int count, key;
-{
-  return (_rl_abort_internal ());
-}
-
-int
-_rl_null_function (count, key)
-     int count, key;
-{
-  return 0;
-}
-
-int
-rl_tty_status (count, key)
-     int count, key;
-{
-#if defined (TIOCSTAT)
-  ioctl (1, TIOCSTAT, (char *)0);
-  rl_refresh_line (count, key);
-#else
-  rl_ding ();
-#endif
-  return 0;
-}
-
-/* Return a copy of the string between FROM and TO.
-   FROM is inclusive, TO is not. */
-char *
-rl_copy_text (from, to)
-     int from, to;
-{
-  register int length;
-  char *copy;
-
-  /* Fix it if the caller is confused. */
-  if (from > to)
-    SWAP (from, to);
-
-  length = to - from;
-  copy = (char *)xmalloc (1 + length);
-  strncpy (copy, rl_line_buffer + from, length);
-  copy[length] = '\0';
-  return (copy);
-}
-
-/* Increase the size of RL_LINE_BUFFER until it has enough space to hold
-   LEN characters. */
-void
-rl_extend_line_buffer (len)
-     int len;
-{
-  while (len >= rl_line_buffer_len)
-    {
-      rl_line_buffer_len += DEFAULT_BUFFER_SIZE;
-      rl_line_buffer = (char *)xrealloc (rl_line_buffer, rl_line_buffer_len);
-    }
-
-  _rl_set_the_line ();
-}
-
-
-/* A function for simple tilde expansion. */
-int
-rl_tilde_expand (ignore, key)
-     int ignore, key;
-{
-  register int start, end;
-  char *homedir, *temp;
-  int len;
-
-  end = rl_point;
-  start = end - 1;
-
-  if (rl_point == rl_end && rl_line_buffer[rl_point] == '~')
-    {
-      homedir = tilde_expand ("~");
-      _rl_replace_text (homedir, start, end);
-      xfree (homedir);
-      return (0);
-    }
-  else if (rl_line_buffer[start] != '~')
-    {
-      for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--)
-        ;
-      start++;
-    }
-
-  end = start;
-  do
-    end++;
-  while (whitespace (rl_line_buffer[end]) == 0 && end < rl_end);
-
-  if (whitespace (rl_line_buffer[end]) || end >= rl_end)
-    end--;
-
-  /* If the first character of the current word is a tilde, perform
-     tilde expansion and insert the result.  If not a tilde, do
-     nothing. */
-  if (rl_line_buffer[start] == '~')
-    {
-      len = end - start + 1;
-      temp = (char *)xmalloc (len + 1);
-      strncpy (temp, rl_line_buffer + start, len);
-      temp[len] = '\0';
-      homedir = tilde_expand (temp);
-      xfree (temp);
-
-      _rl_replace_text (homedir, start, end);
-      xfree (homedir);
-    }
-
-  return (0);
-}
-
-#if defined (USE_VARARGS)
-void
-#if defined (PREFER_STDARG)
-_rl_ttymsg (const char *format, ...)
-#else
-_rl_ttymsg (va_alist)
-     va_dcl
-#endif
-{
-  va_list args;
-#if defined (PREFER_VARARGS)
-  char *format;
-#endif
-
-#if defined (PREFER_STDARG)
-  va_start (args, format);
-#else
-  va_start (args);
-  format = va_arg (args, char *);
-#endif
-
-  fprintf (stderr, "readline: ");
-  vfprintf (stderr, format, args);
-  fprintf (stderr, "\n");
-  fflush (stderr);
-
-  va_end (args);
-
-  rl_forced_update_display ();
-}
-
-void
-#if defined (PREFER_STDARG)
-_rl_errmsg (const char *format, ...)
-#else
-_rl_errmsg (va_alist)
-     va_dcl
-#endif
-{
-  va_list args;
-#if defined (PREFER_VARARGS)
-  char *format;
-#endif
-
-#if defined (PREFER_STDARG)
-  va_start (args, format);
-#else
-  va_start (args);
-  format = va_arg (args, char *);
-#endif
-
-  fprintf (stderr, "readline: ");
-  vfprintf (stderr, format, args);
-  fprintf (stderr, "\n");
-  fflush (stderr);
-
-  va_end (args);
-}
-
-#else /* !USE_VARARGS */
-void
-_rl_ttymsg (format, arg1, arg2)
-     char *format;
-{
-  fprintf (stderr, "readline: ");
-  fprintf (stderr, format, arg1, arg2);
-  fprintf (stderr, "\n");
-
-  rl_forced_update_display ();
-}
-
-void
-_rl_errmsg (format, arg1, arg2)
-     char *format;
-{
-  fprintf (stderr, "readline: ");
-  fprintf (stderr, format, arg1, arg2);
-  fprintf (stderr, "\n");
-}
-#endif /* !USE_VARARGS */
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     String Utility Functions                    */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Determine if s2 occurs in s1.  If so, return a pointer to the
-   match in s1.  The compare is case insensitive. */
-char *
-_rl_strindex (s1, s2)
-     register const char *s1, *s2;
-{
-  register int i, l, len;
-
-  for (i = 0, l = strlen (s2), len = strlen (s1); (len - i) >= l; i++)
-    if (_rl_strnicmp (s1 + i, s2, l) == 0)
-      return ((char *) (s1 + i));
-  return ((char *)NULL);
-}
-
-#ifndef HAVE_STRPBRK
-/* Find the first occurrence in STRING1 of any character from STRING2.
-   Return a pointer to the character in STRING1. */
-char *
-_rl_strpbrk (string1, string2)
-     const char *string1, *string2;
-{
-  register const char *scan;
-#if defined (HANDLE_MULTIBYTE)
-  mbstate_t ps;
-  register int i, v;
-
-  memset (&ps, 0, sizeof (mbstate_t));
-#endif
-
-  for (; *string1; string1++)
-    {
-      for (scan = string2; *scan; scan++)
-       {
-         if (*string1 == *scan)
-           return ((char *)string1);
-       }
-#if defined (HANDLE_MULTIBYTE)
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-       {
-         v = _rl_get_char_len (string1, &ps);
-         if (v > 1)
-           string1 += v - 1;   /* -1 to account for auto-increment in loop */
-       }
-#endif
-    }
-  return ((char *)NULL);
-}
-#endif
-
-#if !defined (HAVE_STRCASECMP)
-/* Compare at most COUNT characters from string1 to string2.  Case
-   doesn't matter. */
-int
-_rl_strnicmp (string1, string2, count)
-     char *string1, *string2;
-     int count;
-{
-  register char ch1, ch2;
-
-  while (count)
-    {
-      ch1 = *string1++;
-      ch2 = *string2++;
-      if (_rl_to_upper(ch1) == _rl_to_upper(ch2))
-       count--;
-      else
-        break;
-    }
-  return (count);
-}
-
-/* strcmp (), but caseless. */
-int
-_rl_stricmp (string1, string2)
-     char *string1, *string2;
-{
-  register char ch1, ch2;
-
-  while (*string1 && *string2)
-    {
-      ch1 = *string1++;
-      ch2 = *string2++;
-      if (_rl_to_upper(ch1) != _rl_to_upper(ch2))
-       return (1);
-    }
-  return (*string1 - *string2);
-}
-#endif /* !HAVE_STRCASECMP */
-
-/* Stupid comparison routine for qsort () ing strings. */
-int
-_rl_qsort_string_compare (s1, s2)
-  char **s1, **s2;
-{
-#if defined (HAVE_STRCOLL)
-  return (strcoll (*s1, *s2));
-#else
-  int result;
-
-  result = **s1 - **s2;
-  if (result == 0)
-    result = strcmp (*s1, *s2);
-
-  return result;
-#endif
-}
-
-/* Function equivalents for the macros defined in chardefs.h. */
-#define FUNCTION_FOR_MACRO(f)  int (f) (c) int c; { return f (c); }
-
-FUNCTION_FOR_MACRO (_rl_digit_p)
-FUNCTION_FOR_MACRO (_rl_digit_value)
-FUNCTION_FOR_MACRO (_rl_lowercase_p)
-FUNCTION_FOR_MACRO (_rl_pure_alphabetic)
-FUNCTION_FOR_MACRO (_rl_to_lower)
-FUNCTION_FOR_MACRO (_rl_to_upper)
-FUNCTION_FOR_MACRO (_rl_uppercase_p)
-
-/* A convenience function, to force memory deallocation to be performed
-   by readline.  DLLs on Windows apparently require this. */
-void
-rl_free (mem)
-     void *mem;
-{
-  if (mem)
-    free (mem);
-}
-
-/* Backwards compatibility, now that savestring has been removed from
-   all `public' readline header files. */
-#undef _rl_savestring
-char *
-_rl_savestring (s)
-     const char *s;
-{
-  return (strcpy ((char *)xmalloc (1 + (int)strlen (s)), (s)));
-}
-
-#if defined (USE_VARARGS)
-static FILE *_rl_tracefp;
-
-void
-#if defined (PREFER_STDARG)
-_rl_trace (const char *format, ...)
-#else
-_rl_trace (va_alist)
-     va_dcl
-#endif
-{
-  va_list args;
-#if defined (PREFER_VARARGS)
-  char *format;
-#endif
-
-#if defined (PREFER_STDARG)
-  va_start (args, format);
-#else
-  va_start (args);
-  format = va_arg (args, char *);
-#endif
-
-  if (_rl_tracefp == 0)
-    _rl_tropen ();
-  vfprintf (_rl_tracefp, format, args);
-  fprintf (_rl_tracefp, "\n");
-  fflush (_rl_tracefp);
-
-  va_end (args);
-}
-
-int
-_rl_tropen ()
-{
-  char fnbuf[128];
-
-  if (_rl_tracefp)
-    fclose (_rl_tracefp);
-  sprintf (fnbuf, "/var/tmp/rltrace.%ld", getpid());
-  unlink(fnbuf);
-  _rl_tracefp = fopen (fnbuf, "w+");
-  return _rl_tracefp != 0;
-}
-
-int
-_rl_trclose ()
-{
-  int r;
-
-  r = fclose (_rl_tracefp);
-  _rl_tracefp = 0;
-  return r;
-}
-
-#endif
diff --git a/lib/readline/vi_mode.c~ b/lib/readline/vi_mode.c~
deleted file mode 100644 (file)
index 57a363c..0000000
+++ /dev/null
@@ -1,1820 +0,0 @@
-/* vi_mode.c -- A vi emulation mode for Bash.
-   Derived from code written by Jeff Sparkes (jsparkes@bnr.ca).  */
-
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
-
-   This file is part of the GNU Readline Library (Readline), a library
-   for reading lines of text with interactive input and history editing.      
-
-   Readline is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   Readline is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#define READLINE_LIBRARY
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     VI Emulation Mode                           */
-/*                                                                 */
-/* **************************************************************** */
-#include "rlconf.h"
-
-#if defined (VI_MODE)
-
-#if defined (HAVE_CONFIG_H)
-#  include <config.h>
-#endif
-
-#include <sys/types.h>
-
-#if defined (HAVE_STDLIB_H)
-#  include <stdlib.h>
-#else
-#  include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include <stdio.h>
-
-/* Some standard library routines. */
-#include "rldefs.h"
-#include "rlmbutil.h"
-
-#include "readline.h"
-#include "history.h"
-
-#include "rlprivate.h"
-#include "xmalloc.h"
-
-#ifndef member
-#define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0)
-#endif
-
-int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
-
-/* Non-zero means enter insertion mode. */
-static int _rl_vi_doing_insert;
-
-/* Command keys which do movement for xxx_to commands. */
-static const char * const vi_motion = " hl^$0ftFT;,%wbeWBE|`";
-
-/* Keymap used for vi replace characters.  Created dynamically since
-   rarely used. */
-static Keymap vi_replace_map;
-
-/* The number of characters inserted in the last replace operation. */
-static int vi_replace_count;
-
-/* If non-zero, we have text inserted after a c[motion] command that put
-   us implicitly into insert mode.  Some people want this text to be
-   attached to the command so that it is `redoable' with `.'. */
-static int vi_continued_command;
-static char *vi_insert_buffer;
-static int vi_insert_buffer_size;
-
-static int _rl_vi_last_repeat = 1;
-static int _rl_vi_last_arg_sign = 1;
-static int _rl_vi_last_motion;
-#if defined (HANDLE_MULTIBYTE)
-static char _rl_vi_last_search_mbchar[MB_LEN_MAX];
-static int _rl_vi_last_search_mblen;
-#else
-static int _rl_vi_last_search_char;
-#endif
-static int _rl_vi_last_replacement;
-
-static int _rl_vi_last_key_before_insert;
-
-static int vi_redoing;
-
-/* Text modification commands.  These are the `redoable' commands. */
-static const char * const vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
-
-/* Arrays for the saved marks. */
-static int vi_mark_chars['z' - 'a' + 1];
-
-static void _rl_vi_stuff_insert PARAMS((int));
-static void _rl_vi_save_insert PARAMS((UNDO_LIST *));
-
-static void _rl_vi_backup PARAMS((void));
-
-static int _rl_vi_arg_dispatch PARAMS((int));
-static int rl_digit_loop1 PARAMS((void));
-
-static int _rl_vi_set_mark PARAMS((void));
-static int _rl_vi_goto_mark PARAMS((void));
-
-static void _rl_vi_append_forward PARAMS((int));
-
-static int _rl_vi_callback_getchar PARAMS((char *, int));
-
-#if defined (READLINE_CALLBACKS)
-static int _rl_vi_callback_set_mark PARAMS((_rl_callback_generic_arg *));
-static int _rl_vi_callback_goto_mark PARAMS((_rl_callback_generic_arg *));
-static int _rl_vi_callback_change_char PARAMS((_rl_callback_generic_arg *));
-static int _rl_vi_callback_char_search PARAMS((_rl_callback_generic_arg *));
-#endif
-
-void
-_rl_vi_initialize_line ()
-{
-  register int i, n;
-
-  n = sizeof (vi_mark_chars) / sizeof (vi_mark_chars[0]);
-  for (i = 0; i < n; i++)
-    vi_mark_chars[i] = -1;
-
-  RL_UNSETSTATE(RL_STATE_VICMDONCE);
-}
-
-void
-_rl_vi_reset_last ()
-{
-  _rl_vi_last_command = 'i';
-  _rl_vi_last_repeat = 1;
-  _rl_vi_last_arg_sign = 1;
-  _rl_vi_last_motion = 0;
-}
-
-void
-_rl_vi_set_last (key, repeat, sign)
-     int key, repeat, sign;
-{
-  _rl_vi_last_command = key;
-  _rl_vi_last_repeat = repeat;
-  _rl_vi_last_arg_sign = sign;
-}
-
-/* A convenience function that calls _rl_vi_set_last to save the last command
-   information and enters insertion mode. */
-void
-rl_vi_start_inserting (key, repeat, sign)
-     int key, repeat, sign;
-{
-  _rl_vi_set_last (key, repeat, sign);
-  rl_vi_insertion_mode (1, key);
-}
-
-/* Is the command C a VI mode text modification command? */
-int
-_rl_vi_textmod_command (c)
-     int c;
-{
-  return (member (c, vi_textmod));
-}
-
-static void
-_rl_vi_stuff_insert (count)
-     int count;
-{
-  rl_begin_undo_group ();
-  while (count--)
-    rl_insert_text (vi_insert_buffer);
-  rl_end_undo_group ();
-}
-
-/* Bound to `.'.  Called from command mode, so we know that we have to
-   redo a text modification command.  The default for _rl_vi_last_command
-   puts you back into insert mode. */
-int
-rl_vi_redo (count, c)
-     int count, c;
-{
-  int r;
-
-  if (!rl_explicit_arg)
-    {
-      rl_numeric_arg = _rl_vi_last_repeat;
-      rl_arg_sign = _rl_vi_last_arg_sign;
-    }
-
-  r = 0;
-  vi_redoing = 1;
-  /* If we're redoing an insert with `i', stuff in the inserted text
-     and do not go into insertion mode. */
-  if (_rl_vi_last_command == 'i' && vi_insert_buffer && *vi_insert_buffer)
-    {
-      _rl_vi_stuff_insert (count);
-      /* And back up point over the last character inserted. */
-      if (rl_point > 0)
-       _rl_vi_backup ();
-    }
-  /* Ditto for redoing an insert with `I', but move to the beginning of the
-     line like the `I' command does. */
-  else if (_rl_vi_last_command == 'I' && vi_insert_buffer && *vi_insert_buffer)
-    {
-      rl_beg_of_line (1, 'I');
-      _rl_vi_stuff_insert (count);
-      if (rl_point > 0)
-       _rl_vi_backup ();
-    }
-  /* Ditto for redoing an insert with `a', but move forward a character first
-     like the `a' command does. */
-  else if (_rl_vi_last_command == 'a' && vi_insert_buffer && *vi_insert_buffer)
-    {
-      _rl_vi_append_forward ('a');
-      _rl_vi_stuff_insert (count);
-      if (rl_point > 0)
-       _rl_vi_backup ();
-    }
-  /* Ditto for redoing an insert with `A', but move to the end of the line
-     like the `A' command does. */
-  else if (_rl_vi_last_command == 'A' && vi_insert_buffer && *vi_insert_buffer)
-    {
-      rl_end_of_line (1, 'A');
-      _rl_vi_stuff_insert (count);
-      if (rl_point > 0)
-       _rl_vi_backup ();
-    }
-  else
-    r = _rl_dispatch (_rl_vi_last_command, _rl_keymap);
-  vi_redoing = 0;
-
-  return (r);
-}
-
-/* A placeholder for further expansion. */
-int
-rl_vi_undo (count, key)
-     int count, key;
-{
-  return (rl_undo_command (count, key));
-}
-    
-/* Yank the nth arg from the previous line into this line at point. */
-int
-rl_vi_yank_arg (count, key)
-     int count, key;
-{
-  /* Readline thinks that the first word on a line is the 0th, while vi
-     thinks the first word on a line is the 1st.  Compensate. */
-  if (rl_explicit_arg)
-    rl_yank_nth_arg (count - 1, 0);
-  else
-    rl_yank_nth_arg ('$', 0);
-
-  return (0);
-}
-
-/* With an argument, move back that many history lines, else move to the
-   beginning of history. */
-int
-rl_vi_fetch_history (count, c)
-     int count, c;
-{
-  int wanted;
-
-  /* Giving an argument of n means we want the nth command in the history
-     file.  The command number is interpreted the same way that the bash
-     `history' command does it -- that is, giving an argument count of 450
-     to this command would get the command listed as number 450 in the
-     output of `history'. */
-  if (rl_explicit_arg)
-    {
-      wanted = history_base + where_history () - count;
-      if (wanted <= 0)
-        rl_beginning_of_history (0, 0);
-      else
-        rl_get_previous_history (wanted, c);
-    }
-  else
-    rl_beginning_of_history (count, 0);
-  return (0);
-}
-
-/* Search again for the last thing searched for. */
-int
-rl_vi_search_again (count, key)
-     int count, key;
-{
-  switch (key)
-    {
-    case 'n':
-      rl_noninc_reverse_search_again (count, key);
-      break;
-
-    case 'N':
-      rl_noninc_forward_search_again (count, key);
-      break;
-    }
-  return (0);
-}
-
-/* Do a vi style search. */
-int
-rl_vi_search (count, key)
-     int count, key;
-{
-  switch (key)
-    {
-    case '?':
-      _rl_free_saved_history_line ();
-      rl_noninc_forward_search (count, key);
-      break;
-
-    case '/':
-      _rl_free_saved_history_line ();
-      rl_noninc_reverse_search (count, key);
-      break;
-
-    default:
-      rl_ding ();
-      break;
-    }
-  return (0);
-}
-
-/* Completion, from vi's point of view. */
-int
-rl_vi_complete (ignore, key)
-     int ignore, key;
-{
-  if ((rl_point < rl_end) && (!whitespace (rl_line_buffer[rl_point])))
-    {
-      if (!whitespace (rl_line_buffer[rl_point + 1]))
-       rl_vi_end_word (1, 'E');
-      rl_point++;
-    }
-
-  if (key == '*')
-    rl_complete_internal ('*');        /* Expansion and replacement. */
-  else if (key == '=')
-    rl_complete_internal ('?');        /* List possible completions. */
-  else if (key == '\\')
-    rl_complete_internal (TAB);        /* Standard Readline completion. */
-  else
-    rl_complete (0, key);
-
-  if (key == '*' || key == '\\')
-    rl_vi_start_inserting (key, 1, rl_arg_sign);
-
-  return (0);
-}
-
-/* Tilde expansion for vi mode. */
-int
-rl_vi_tilde_expand (ignore, key)
-     int ignore, key;
-{
-  rl_tilde_expand (0, key);
-  rl_vi_start_inserting (key, 1, rl_arg_sign);
-  return (0);
-}
-
-/* Previous word in vi mode. */
-int
-rl_vi_prev_word (count, key)
-     int count, key;
-{
-  if (count < 0)
-    return (rl_vi_next_word (-count, key));
-
-  if (rl_point == 0)
-    {
-      rl_ding ();
-      return (0);
-    }
-
-  if (_rl_uppercase_p (key))
-    rl_vi_bWord (count, key);
-  else
-    rl_vi_bword (count, key);
-
-  return (0);
-}
-
-/* Next word in vi mode. */
-int
-rl_vi_next_word (count, key)
-     int count, key;
-{
-  if (count < 0)
-    return (rl_vi_prev_word (-count, key));
-
-  if (rl_point >= (rl_end - 1))
-    {
-      rl_ding ();
-      return (0);
-    }
-
-  if (_rl_uppercase_p (key))
-    rl_vi_fWord (count, key);
-  else
-    rl_vi_fword (count, key);
-  return (0);
-}
-
-/* Move to the end of the ?next? word. */
-int
-rl_vi_end_word (count, key)
-     int count, key;
-{
-  if (count < 0)
-    {
-      rl_ding ();
-      return -1;
-    }
-
-  if (_rl_uppercase_p (key))
-    rl_vi_eWord (count, key);
-  else
-    rl_vi_eword (count, key);
-  return (0);
-}
-
-/* Move forward a word the way that 'W' does. */
-int
-rl_vi_fWord (count, ignore)
-     int count, ignore;
-{
-  while (count-- && rl_point < (rl_end - 1))
-    {
-      /* Skip until whitespace. */
-      while (!whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
-       rl_point++;
-
-      /* Now skip whitespace. */
-      while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
-       rl_point++;
-    }
-  return (0);
-}
-
-int
-rl_vi_bWord (count, ignore)
-     int count, ignore;
-{
-  while (count-- && rl_point > 0)
-    {
-      /* If we are at the start of a word, move back to whitespace so
-        we will go back to the start of the previous word. */
-      if (!whitespace (rl_line_buffer[rl_point]) &&
-         whitespace (rl_line_buffer[rl_point - 1]))
-       rl_point--;
-
-      while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
-       rl_point--;
-
-      if (rl_point > 0)
-       {
-         while (--rl_point >= 0 && !whitespace (rl_line_buffer[rl_point]));
-         rl_point++;
-       }
-    }
-  return (0);
-}
-
-int
-rl_vi_eWord (count, ignore)
-     int count, ignore;
-{
-  while (count-- && rl_point < (rl_end - 1))
-    {
-      if (!whitespace (rl_line_buffer[rl_point]))
-       rl_point++;
-
-      /* Move to the next non-whitespace character (to the start of the
-        next word). */
-      while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
-       rl_point++;
-
-      if (rl_point && rl_point < rl_end)
-       {
-         /* Skip whitespace. */
-         while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
-           rl_point++;
-
-         /* Skip until whitespace. */
-         while (rl_point < rl_end && !whitespace (rl_line_buffer[rl_point]))
-           rl_point++;
-
-         /* Move back to the last character of the word. */
-         rl_point--;
-       }
-    }
-  return (0);
-}
-
-int
-rl_vi_fword (count, ignore)
-     int count, ignore;
-{
-  while (count-- && rl_point < (rl_end - 1))
-    {
-      /* Move to white space (really non-identifer). */
-      if (_rl_isident (rl_line_buffer[rl_point]))
-       {
-         while (_rl_isident (rl_line_buffer[rl_point]) && rl_point < rl_end)
-           rl_point++;
-       }
-      else /* if (!whitespace (rl_line_buffer[rl_point])) */
-       {
-         while (!_rl_isident (rl_line_buffer[rl_point]) &&
-                !whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
-           rl_point++;
-       }
-
-      /* Move past whitespace. */
-      while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
-       rl_point++;
-    }
-  return (0);
-}
-
-int
-rl_vi_bword (count, ignore)
-     int count, ignore;
-{
-  while (count-- && rl_point > 0)
-    {
-      int last_is_ident;
-
-      /* If we are at the start of a word, move back to whitespace
-        so we will go back to the start of the previous word. */
-      if (!whitespace (rl_line_buffer[rl_point]) &&
-         whitespace (rl_line_buffer[rl_point - 1]))
-       rl_point--;
-
-      /* If this character and the previous character are `opposite', move
-        back so we don't get messed up by the rl_point++ down there in
-        the while loop.  Without this code, words like `l;' screw up the
-        function. */
-      last_is_ident = _rl_isident (rl_line_buffer[rl_point - 1]);
-      if ((_rl_isident (rl_line_buffer[rl_point]) && !last_is_ident) ||
-         (!_rl_isident (rl_line_buffer[rl_point]) && last_is_ident))
-       rl_point--;
-
-      while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
-       rl_point--;
-
-      if (rl_point > 0)
-       {
-         if (_rl_isident (rl_line_buffer[rl_point]))
-           while (--rl_point >= 0 && _rl_isident (rl_line_buffer[rl_point]));
-         else
-           while (--rl_point >= 0 && !_rl_isident (rl_line_buffer[rl_point]) &&
-                  !whitespace (rl_line_buffer[rl_point]));
-         rl_point++;
-       }
-    }
-  return (0);
-}
-
-int
-rl_vi_eword (count, ignore)
-     int count, ignore;
-{
-  while (count-- && rl_point < rl_end - 1)
-    {
-      if (!whitespace (rl_line_buffer[rl_point]))
-       rl_point++;
-
-      while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
-       rl_point++;
-
-      if (rl_point < rl_end)
-       {
-         if (_rl_isident (rl_line_buffer[rl_point]))
-           while (++rl_point < rl_end && _rl_isident (rl_line_buffer[rl_point]));
-         else
-           while (++rl_point < rl_end && !_rl_isident (rl_line_buffer[rl_point])
-                  && !whitespace (rl_line_buffer[rl_point]));
-       }
-      rl_point--;
-    }
-  return (0);
-}
-
-int
-rl_vi_insert_beg (count, key)
-     int count, key;
-{
-  rl_beg_of_line (1, key);
-  rl_vi_insert_mode (1, key);
-  return (0);
-}
-
-static void
-_rl_vi_append_forward (key)
-     int key;
-{
-  int point;
-
-  if (rl_point < rl_end)
-    {
-      if (MB_CUR_MAX == 1 || rl_byte_oriented)
-       rl_point++;
-      else
-        {
-          point = rl_point;
-          rl_forward_char (1, key);
-          if (point == rl_point)
-            rl_point = rl_end;
-        }
-    }
-}
-
-int
-rl_vi_append_mode (count, key)
-     int count, key;
-{
-  _rl_vi_append_forward (key);
-  rl_vi_start_inserting (key, 1, rl_arg_sign);
-  return (0);
-}
-
-int
-rl_vi_append_eol (count, key)
-     int count, key;
-{
-  rl_end_of_line (1, key);
-  rl_vi_append_mode (1, key);
-  return (0);
-}
-
-/* What to do in the case of C-d. */
-int
-rl_vi_eof_maybe (count, c)
-     int count, c;
-{
-  return (rl_newline (1, '\n'));
-}
-
-/* Insertion mode stuff. */
-
-/* Switching from one mode to the other really just involves
-   switching keymaps. */
-int
-rl_vi_insertion_mode (count, key)
-     int count, key;
-{
-  _rl_keymap = vi_insertion_keymap;
-  _rl_vi_last_key_before_insert = key;
-  return (0);
-}
-
-int
-rl_vi_insert_mode (count, key)
-     int count, key;
-{
-  rl_vi_start_inserting (key, 1, rl_arg_sign);
-  return (0);
-}
-
-static void
-_rl_vi_save_insert (up)
-      UNDO_LIST *up;
-{
-  int len, start, end;
-
-  if (up == 0 || up->what != UNDO_INSERT)
-    {
-      if (vi_insert_buffer_size >= 1)
-       vi_insert_buffer[0] = '\0';
-      return;
-    }
-
-  start = up->start;
-  end = up->end;
-  len = end - start + 1;
-  if (len >= vi_insert_buffer_size)
-    {
-      vi_insert_buffer_size += (len + 32) - (len % 32);
-      vi_insert_buffer = (char *)xrealloc (vi_insert_buffer, vi_insert_buffer_size);
-    }
-  strncpy (vi_insert_buffer, rl_line_buffer + start, len - 1);
-  vi_insert_buffer[len-1] = '\0';
-}
-    
-void
-_rl_vi_done_inserting ()
-{
-  if (_rl_vi_doing_insert)
-    {
-      /* The `C', `s', and `S' commands set this. */
-      rl_end_undo_group ();
-      /* Now, the text between rl_undo_list->next->start and
-        rl_undo_list->next->end is what was inserted while in insert
-        mode.  It gets copied to VI_INSERT_BUFFER because it depends
-        on absolute indices into the line which may change (though they
-        probably will not). */
-      _rl_vi_doing_insert = 0;
-      _rl_vi_save_insert (rl_undo_list->next);
-      vi_continued_command = 1;
-    }
-  else
-    {
-      if (rl_undo_list && (_rl_vi_last_key_before_insert == 'i' ||
-                          _rl_vi_last_key_before_insert == 'a' ||
-                          _rl_vi_last_key_before_insert == 'I' ||
-                          _rl_vi_last_key_before_insert == 'A'))
-        _rl_vi_save_insert (rl_undo_list);
-      /* XXX - Other keys probably need to be checked. */
-      else if (_rl_vi_last_key_before_insert == 'C')
-       rl_end_undo_group ();
-      while (_rl_undo_group_level > 0)
-       rl_end_undo_group ();
-      vi_continued_command = 0;
-    }
-}
-
-int
-rl_vi_movement_mode (count, key)
-     int count, key;
-{
-  if (rl_point > 0)
-    rl_backward_char (1, key);
-
-  _rl_keymap = vi_movement_keymap;
-  _rl_vi_done_inserting ();
-
-  /* This is how POSIX.2 says `U' should behave -- everything up until the
-     first time you go into command mode should not be undone. */
-  if (RL_ISSTATE (RL_STATE_VICMDONCE) == 0)
-    rl_free_undo_list ();
-
-  RL_SETSTATE (RL_STATE_VICMDONCE);
-  return (0);
-}
-
-int
-rl_vi_arg_digit (count, c)
-     int count, c;
-{
-  if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg)
-    return (rl_beg_of_line (1, c));
-  else
-    return (rl_digit_argument (count, c));
-}
-
-/* Change the case of the next COUNT characters. */
-#if defined (HANDLE_MULTIBYTE)
-static int
-_rl_vi_change_mbchar_case (count)
-     int count;
-{
-  wchar_t wc;
-  char mb[MB_LEN_MAX+1];
-  int mlen, p;
-  mbstate_t ps;
-
-  memset (&ps, 0, sizeof (mbstate_t));
-  if (_rl_adjust_point (rl_line_buffer, rl_point, &ps) > 0)
-    count--;
-  while (count-- && rl_point < rl_end)
-    {
-      mbrtowc (&wc, rl_line_buffer + rl_point, rl_end - rl_point, &ps);
-      if (iswupper (wc))
-       wc = towlower (wc);
-      else if (iswlower (wc))
-       wc = towupper (wc);
-      else
-       {
-         /* Just skip over chars neither upper nor lower case */
-         rl_forward_char (1, 0);
-         continue;
-       }
-
-      /* Vi is kind of strange here. */
-      if (wc)
-       {
-         p = rl_point;
-         mlen = wcrtomb (mb, wc, &ps);
-         if (mlen >= 0)
-           mb[mlen] = '\0';
-         rl_begin_undo_group ();
-         rl_vi_delete (1, 0);
-         if (rl_point < p)     /* Did we retreat at EOL? */
-           rl_point++; /* XXX - should we advance more than 1 for mbchar? */
-         rl_insert_text (mb);
-         rl_end_undo_group ();
-         rl_vi_check ();
-       }
-      else
-        rl_forward_char (1, 0);
-    }
-
-  return 0;
-}
-#endif
-
-int
-rl_vi_change_case (count, ignore)
-     int count, ignore;
-{
-  int c, p;
-
-  /* Don't try this on an empty line. */
-  if (rl_point >= rl_end)
-    return (0);
-
-  c = 0;
-#if defined (HANDLE_MULTIBYTE)
-  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-    return (_rl_vi_change_mbchar_case (count));
-#endif
-
-  while (count-- && rl_point < rl_end)
-    {
-      if (_rl_uppercase_p (rl_line_buffer[rl_point]))
-       c = _rl_to_lower (rl_line_buffer[rl_point]);
-      else if (_rl_lowercase_p (rl_line_buffer[rl_point]))
-       c = _rl_to_upper (rl_line_buffer[rl_point]);
-      else
-       {
-         /* Just skip over characters neither upper nor lower case. */
-         rl_forward_char (1, c);
-         continue;
-       }
-
-      /* Vi is kind of strange here. */
-      if (c)
-       {
-         p = rl_point;
-         rl_begin_undo_group ();
-         rl_vi_delete (1, c);
-         if (rl_point < p)     /* Did we retreat at EOL? */
-           rl_point++;
-         _rl_insert_char (1, c);
-         rl_end_undo_group ();
-         rl_vi_check ();
-        }
-      else
-       rl_forward_char (1, c);
-    }
-  return (0);
-}
-
-int
-rl_vi_put (count, key)
-     int count, key;
-{
-  if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end))
-    rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
-
-  while (count--)
-    rl_yank (1, key);
-
-  rl_backward_char (1, key);
-  return (0);
-}
-
-static void
-_rl_vi_backup ()
-{
-  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-    rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
-  else
-    rl_point--;
-}
-
-int
-rl_vi_check ()
-{
-  if (rl_point && rl_point == rl_end)
-    {
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-       rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
-      else
-        rl_point--;
-    }
-  return (0);
-}
-
-int
-rl_vi_column (count, key)
-     int count, key;
-{
-  if (count > rl_end)
-    rl_end_of_line (1, key);
-  else
-    rl_point = count - 1;
-  return (0);
-}
-
-int
-rl_vi_domove (key, nextkey)
-     int key, *nextkey;
-{
-  int c, save;
-  int old_end;
-
-  rl_mark = rl_point;
-  RL_SETSTATE(RL_STATE_MOREINPUT);
-  c = rl_read_key ();
-  RL_UNSETSTATE(RL_STATE_MOREINPUT);
-
-  if (c < 0)
-    {
-      *nextkey = 0;
-      return -1;
-    }
-
-  *nextkey = c;
-
-  if (!member (c, vi_motion))
-    {
-      if (_rl_digit_p (c))
-       {
-         save = rl_numeric_arg;
-         rl_numeric_arg = _rl_digit_value (c);
-         rl_explicit_arg = 1;
-         RL_SETSTATE (RL_STATE_NUMERICARG|RL_STATE_VIMOTION);
-         rl_digit_loop1 ();
-         RL_UNSETSTATE (RL_STATE_VIMOTION);
-         rl_numeric_arg *= save;
-         RL_SETSTATE(RL_STATE_MOREINPUT);
-         c = rl_read_key ();   /* real command */
-         RL_UNSETSTATE(RL_STATE_MOREINPUT);
-         if (c < 0)
-           {
-             *nextkey = 0;
-             return -1;
-           }
-         *nextkey = c;
-       }
-      else if (key == c && (key == 'd' || key == 'y' || key == 'c'))
-       {
-         rl_mark = rl_end;
-         rl_beg_of_line (1, c);
-         _rl_vi_last_motion = c;
-         return (0);
-       }
-      else
-       return (-1);
-    }
-
-  _rl_vi_last_motion = c;
-
-  /* Append a blank character temporarily so that the motion routines
-     work right at the end of the line. */
-  old_end = rl_end;
-  rl_line_buffer[rl_end++] = ' ';
-  rl_line_buffer[rl_end] = '\0';
-
-  _rl_dispatch (c, _rl_keymap);
-
-  /* Remove the blank that we added. */
-  rl_end = old_end;
-  rl_line_buffer[rl_end] = '\0';
-  if (rl_point > rl_end)
-    rl_point = rl_end;
-
-  /* No change in position means the command failed. */
-  if (rl_mark == rl_point)
-    return (-1);
-
-  /* rl_vi_f[wW]ord () leaves the cursor on the first character of the next
-     word.  If we are not at the end of the line, and we are on a
-     non-whitespace character, move back one (presumably to whitespace). */
-  if ((_rl_to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark &&
-      !whitespace (rl_line_buffer[rl_point]))
-    rl_point--;
-
-  /* If cw or cW, back up to the end of a word, so the behaviour of ce
-     or cE is the actual result.  Brute-force, no subtlety. */
-  if (key == 'c' && rl_point >= rl_mark && (_rl_to_upper (c) == 'W'))
-    {
-      /* Don't move farther back than where we started. */
-      while (rl_point > rl_mark && whitespace (rl_line_buffer[rl_point]))
-       rl_point--;
-
-      /* Posix.2 says that if cw or cW moves the cursor towards the end of
-        the line, the character under the cursor should be deleted. */
-      if (rl_point == rl_mark)
-        rl_point++;
-      else
-       {
-         /* Move past the end of the word so that the kill doesn't
-            remove the last letter of the previous word.  Only do this
-            if we are not at the end of the line. */
-         if (rl_point >= 0 && rl_point < (rl_end - 1) && !whitespace (rl_line_buffer[rl_point]))
-           rl_point++;
-       }
-    }
-
-  if (rl_mark < rl_point)
-    SWAP (rl_point, rl_mark);
-
-  return (0);
-}
-
-/* Process C as part of the current numeric argument.  Return -1 if the
-   argument should be aborted, 0 if we should not read any more chars, and
-   1 if we should continue to read chars. */
-static int
-_rl_vi_arg_dispatch (c)
-     int c;
-{
-  int key;
-
-  key = c;
-  if (c >= 0 && _rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
-    {
-      rl_numeric_arg *= 4;
-      return 1;
-    }
-
-  c = UNMETA (c);
-
-  if (_rl_digit_p (c))
-    {
-      if (rl_explicit_arg)
-       rl_numeric_arg = (rl_numeric_arg * 10) + _rl_digit_value (c);
-      else
-       rl_numeric_arg = _rl_digit_value (c);
-      rl_explicit_arg = 1;
-      return 1;
-    }
-  else
-    {
-      rl_clear_message ();
-      rl_stuff_char (key);
-      return 0;
-    }
-}
-
-/* A simplified loop for vi. Don't dispatch key at end.
-   Don't recognize minus sign?
-   Should this do rl_save_prompt/rl_restore_prompt? */
-static int
-rl_digit_loop1 ()
-{
-  int c, r;
-
-  while (1)
-    {
-      if (_rl_arg_overflow ())
-       return 1;
-
-      c = _rl_arg_getchar ();
-
-      r = _rl_vi_arg_dispatch (c);
-      if (r <= 0)
-       break;
-    }
-
-  RL_UNSETSTATE(RL_STATE_NUMERICARG);
-  return (0);
-}
-
-int
-rl_vi_delete_to (count, key)
-     int count, key;
-{
-  int c, start_pos;
-
-  if (_rl_uppercase_p (key))
-    rl_stuff_char ('$');
-  else if (vi_redoing)
-    rl_stuff_char (_rl_vi_last_motion);
-
-  start_pos = rl_point;
-
-  if (rl_vi_domove (key, &c))
-    {
-      rl_ding ();
-      return -1;
-    }
-
-  /* These are the motion commands that do not require adjusting the
-     mark. */
-  if (((strchr (" l|h^0bBFT`", c) == 0) && (rl_point >= start_pos)) &&
-      (rl_mark < rl_end))
-    rl_mark++;
-
-  rl_kill_text (rl_point, rl_mark);
-  return (0);
-}
-
-int
-rl_vi_change_to (count, key)
-     int count, key;
-{
-  int c, start_pos;
-
-  if (_rl_uppercase_p (key))
-    rl_stuff_char ('$');
-  else if (vi_redoing)
-    rl_stuff_char (_rl_vi_last_motion);
-
-  start_pos = rl_point;
-
-  if (rl_vi_domove (key, &c))
-    {
-      rl_ding ();
-      return -1;
-    }
-
-  /* These are the motion commands that do not require adjusting the
-     mark.  c[wW] are handled by special-case code in rl_vi_domove(),
-     and already leave the mark at the correct location. */
-  if (((strchr (" l|hwW^0bBFT`", c) == 0) && (rl_point >= start_pos)) &&
-      (rl_mark < rl_end))
-    rl_mark++;
-
-  /* The cursor never moves with c[wW]. */
-  if ((_rl_to_upper (c) == 'W') && rl_point < start_pos)
-    rl_point = start_pos;
-
-  if (vi_redoing)
-    {
-      if (vi_insert_buffer && *vi_insert_buffer)
-       rl_begin_undo_group ();
-      rl_delete_text (rl_point, rl_mark);
-      if (vi_insert_buffer && *vi_insert_buffer)
-       {
-         rl_insert_text (vi_insert_buffer);
-         rl_end_undo_group ();
-       }
-    }
-  else
-    {
-      rl_begin_undo_group ();          /* to make the `u' command work */
-      rl_kill_text (rl_point, rl_mark);
-      /* `C' does not save the text inserted for undoing or redoing. */
-      if (_rl_uppercase_p (key) == 0)
-        _rl_vi_doing_insert = 1;
-      rl_vi_start_inserting (key, rl_numeric_arg, rl_arg_sign);
-    }
-
-  return (0);
-}
-
-int
-rl_vi_yank_to (count, key)
-     int count, key;
-{
-  int c, start_pos;
-
-  if (_rl_uppercase_p (key))
-    rl_stuff_char ('$');
-
-  start_pos = rl_point;
-
-  if (rl_vi_domove (key, &c))
-    {
-      rl_ding ();
-      return -1;
-    }
-
-  /* These are the motion commands that do not require adjusting the
-     mark. */
-  if (((strchr (" l|h^0%bBFT`", c) == 0) && (rl_point >= start_pos)) &&
-      (rl_mark < rl_end))
-    rl_mark++;
-
-  rl_begin_undo_group ();
-  rl_kill_text (rl_point, rl_mark);
-  rl_end_undo_group ();
-  rl_do_undo ();
-  rl_point = start_pos;
-
-  return (0);
-}
-
-int
-rl_vi_rubout (count, key)
-     int count, key;
-{
-  int opoint;
-
-  if (count < 0)
-    return (rl_vi_delete (-count, key));
-
-  if (rl_point == 0)
-    {
-      rl_ding ();
-      return -1;
-    }
-
-  opoint = rl_point;
-  if (count > 1 && MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-    rl_backward_char (count, key);
-  else if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-    rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
-  else
-    rl_point -= count;
-
-  if (rl_point < 0)
-    rl_point = 0;
-
-  rl_kill_text (rl_point, opoint);
-  
-  return (0);
-}
-
-int
-rl_vi_delete (count, key)
-     int count, key;
-{
-  int end;
-
-  if (count < 0)
-    return (rl_vi_rubout (-count, key));
-
-  if (rl_end == 0)
-    {
-      rl_ding ();
-      return -1;
-    }
-
-  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-    end = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
-  else
-    end = rl_point + count;
-
-  if (end >= rl_end)
-    end = rl_end;
-
-  rl_kill_text (rl_point, end);
-  
-  if (rl_point > 0 && rl_point == rl_end)
-    rl_backward_char (1, key);
-
-  return (0);
-}
-
-int
-rl_vi_back_to_indent (count, key)
-     int count, key;
-{
-  rl_beg_of_line (1, key);
-  while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
-    rl_point++;
-  return (0);
-}
-
-int
-rl_vi_first_print (count, key)
-     int count, key;
-{
-  return (rl_vi_back_to_indent (1, key));
-}
-
-static int _rl_cs_dir, _rl_cs_orig_dir;
-
-#if defined (READLINE_CALLBACKS)
-static int
-_rl_vi_callback_char_search (data)
-     _rl_callback_generic_arg *data;
-{
-  int c;
-#if defined (HANDLE_MULTIBYTE)
-  c = _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
-#else
-  RL_SETSTATE(RL_STATE_MOREINPUT);
-  c = rl_read_key ();
-  RL_UNSETSTATE(RL_STATE_MOREINPUT);
-#endif
-
-  if (c <= 0)
-    return -1;
-
-#if !defined (HANDLE_MULTIBYTE)
-  _rl_vi_last_search_char = c;
-#endif
-
-  _rl_callback_func = 0;
-  _rl_want_redisplay = 1;
-
-#if defined (HANDLE_MULTIBYTE)
-  return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_mbchar, _rl_vi_last_search_mblen));
-#else
-  return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_char));
-#endif  
-}
-#endif
-
-int
-rl_vi_char_search (count, key)
-     int count, key;
-{
-  int c;
-#if defined (HANDLE_MULTIBYTE)
-  static char *target;
-  static int tlen;
-#else
-  static char target;
-#endif
-
-  if (key == ';' || key == ',')
-    _rl_cs_dir = (key == ';') ? _rl_cs_orig_dir : -_rl_cs_orig_dir;
-  else
-    {
-      switch (key)
-        {
-        case 't':
-          _rl_cs_orig_dir = _rl_cs_dir = FTO;
-          break;
-
-        case 'T':
-          _rl_cs_orig_dir = _rl_cs_dir = BTO;
-          break;
-
-        case 'f':
-          _rl_cs_orig_dir = _rl_cs_dir = FFIND;
-          break;
-
-        case 'F':
-          _rl_cs_orig_dir = _rl_cs_dir = BFIND;
-          break;
-        }
-
-      if (vi_redoing)
-       {
-         /* set target and tlen below */
-       }
-#if defined (READLINE_CALLBACKS)
-      else if (RL_ISSTATE (RL_STATE_CALLBACK))
-        {
-          _rl_callback_data = _rl_callback_data_alloc (count);
-          _rl_callback_data->i1 = _rl_cs_dir;
-          _rl_callback_func = _rl_vi_callback_char_search;
-          return (0);
-        }
-#endif
-      else
-       {
-#if defined (HANDLE_MULTIBYTE)
-         c = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
-         if (c <= 0)
-           return -1;
-         _rl_vi_last_search_mblen = c;
-#else
-         RL_SETSTATE(RL_STATE_MOREINPUT);
-         c = rl_read_key ();
-         RL_UNSETSTATE(RL_STATE_MOREINPUT);
-         if (c < 0)
-           return -1;
-         _rl_vi_last_search_char = c;
-#endif
-       }
-    }
-
-#if defined (HANDLE_MULTIBYTE)
-  target = _rl_vi_last_search_mbchar;
-  tlen = _rl_vi_last_search_mblen;
-#else
-  target = _rl_vi_last_search_char;
-#endif
-
-#if defined (HANDLE_MULTIBYTE)
-  return (_rl_char_search_internal (count, _rl_cs_dir, target, tlen));
-#else
-  return (_rl_char_search_internal (count, _rl_cs_dir, target));
-#endif
-}
-
-/* Match brackets */
-int
-rl_vi_match (ignore, key)
-     int ignore, key;
-{
-  int count = 1, brack, pos, tmp, pre;
-
-  pos = rl_point;
-  if ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0)
-    {
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-       {
-         while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0)
-           {
-             pre = rl_point;
-             rl_forward_char (1, key);
-             if (pre == rl_point)
-               break;
-           }
-       }
-      else
-       while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 &&
-               rl_point < rl_end - 1)
-         rl_forward_char (1, key);
-
-      if (brack <= 0)
-       {
-         rl_point = pos;
-         rl_ding ();
-         return -1;
-       }
-    }
-
-  pos = rl_point;
-
-  if (brack < 0)
-    {
-      while (count)
-       {
-         tmp = pos;
-         if (MB_CUR_MAX == 1 || rl_byte_oriented)
-           pos--;
-         else
-           {
-             pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
-             if (tmp == pos)
-               pos--;
-           }
-         if (pos >= 0)
-           {
-             int b = rl_vi_bracktype (rl_line_buffer[pos]);
-             if (b == -brack)
-               count--;
-             else if (b == brack)
-               count++;
-           }
-         else
-           {
-             rl_ding ();
-             return -1;
-           }
-       }
-    }
-  else
-    {                  /* brack > 0 */
-      while (count)
-       {
-         if (MB_CUR_MAX == 1 || rl_byte_oriented)
-           pos++;
-         else
-           pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY);
-
-         if (pos < rl_end)
-           {
-             int b = rl_vi_bracktype (rl_line_buffer[pos]);
-             if (b == -brack)
-               count--;
-             else if (b == brack)
-               count++;
-           }
-         else
-           {
-             rl_ding ();
-             return -1;
-           }
-       }
-    }
-  rl_point = pos;
-  return (0);
-}
-
-int
-rl_vi_bracktype (c)
-     int c;
-{
-  switch (c)
-    {
-    case '(': return  1;
-    case ')': return -1;
-    case '[': return  2;
-    case ']': return -2;
-    case '{': return  3;
-    case '}': return -3;
-    default:  return  0;
-    }
-}
-
-static int
-_rl_vi_change_char (count, c, mb)
-     int count, c;
-     char *mb;
-{
-  int p;
-
-  if (c == '\033' || c == CTRL ('C'))
-    return -1;
-
-  rl_begin_undo_group ();
-  while (count-- && rl_point < rl_end)
-    {
-      p = rl_point;
-      rl_vi_delete (1, c);
-      if (rl_point < p)                /* Did we retreat at EOL? */
-       rl_point++;
-#if defined (HANDLE_MULTIBYTE)
-      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-       rl_insert_text (mb);
-      else
-#endif
-       _rl_insert_char (1, c);
-    }
-
-  /* The cursor shall be left on the last character changed. */
-  rl_backward_char (1, c);
-
-  rl_end_undo_group ();
-
-  return (0);
-}
-
-static int
-_rl_vi_callback_getchar (mb, mlen)
-     char *mb;
-     int mlen;
-{
-  int c;
-
-  RL_SETSTATE(RL_STATE_MOREINPUT);
-  c = rl_read_key ();
-  RL_UNSETSTATE(RL_STATE_MOREINPUT);
-
-  if (c < 0)
-    return -1;
-
-#if defined (HANDLE_MULTIBYTE)
-  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
-    c = _rl_read_mbstring (c, mb, mlen);
-#endif
-
-  return c;
-}
-
-#if defined (READLINE_CALLBACKS)
-static int
-_rl_vi_callback_change_char (data)
-     _rl_callback_generic_arg *data;
-{
-  int c;
-  char mb[MB_LEN_MAX];
-
-  _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
-
-  if (c < 0)
-    return -1;
-
-  _rl_callback_func = 0;
-  _rl_want_redisplay = 1;
-
-  return (_rl_vi_change_char (data->count, c, mb));
-}
-#endif
-
-int
-rl_vi_change_char (count, key)
-     int count, key;
-{
-  int c;
-  char mb[MB_LEN_MAX];
-
-  if (vi_redoing)
-    {
-      c = _rl_vi_last_replacement;
-      mb[0] = c;
-      mb[1] = '\0';
-    }
-#if defined (READLINE_CALLBACKS)
-  else if (RL_ISSTATE (RL_STATE_CALLBACK))
-    {
-      _rl_callback_data = _rl_callback_data_alloc (count);
-      _rl_callback_func = _rl_vi_callback_change_char;
-      return (0);
-    }
-#endif
-  else
-    _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
-
-  if (c < 0)
-    return -1;
-
-  return (_rl_vi_change_char (count, c, mb));
-}
-
-int
-rl_vi_subst (count, key)
-     int count, key;
-{
-  /* If we are redoing, rl_vi_change_to will stuff the last motion char */
-  if (vi_redoing == 0)
-    rl_stuff_char ((key == 'S') ? 'c' : 'l');  /* `S' == `cc', `s' == `cl' */
-
-  return (rl_vi_change_to (count, 'c'));
-}
-
-int
-rl_vi_overstrike (count, key)
-     int count, key;
-{
-  if (_rl_vi_doing_insert == 0)
-    {
-      _rl_vi_doing_insert = 1;
-      rl_begin_undo_group ();
-    }
-
-  if (count > 0)
-    {
-      _rl_overwrite_char (count, key);
-      vi_replace_count += count;
-    }
-
-  return (0);
-}
-
-int
-rl_vi_overstrike_delete (count, key)
-     int count, key;
-{
-  int i, s;
-
-  for (i = 0; i < count; i++)
-    {
-      if (vi_replace_count == 0)
-       {
-         rl_ding ();
-         break;
-       }
-      s = rl_point;
-
-      if (rl_do_undo ())
-       vi_replace_count--;
-
-      if (rl_point == s)
-       rl_backward_char (1, key);
-    }
-
-  if (vi_replace_count == 0 && _rl_vi_doing_insert)
-    {
-      rl_end_undo_group ();
-      rl_do_undo ();
-      _rl_vi_doing_insert = 0;
-    }
-  return (0);
-}
-
-int
-rl_vi_replace (count, key)
-     int count, key;
-{
-  int i;
-
-  vi_replace_count = 0;
-
-  if (!vi_replace_map)
-    {
-      vi_replace_map = rl_make_bare_keymap ();
-
-      for (i = ' '; i < KEYMAP_SIZE; i++)
-       vi_replace_map[i].function = rl_vi_overstrike;
-
-      vi_replace_map[RUBOUT].function = rl_vi_overstrike_delete;
-      vi_replace_map[ESC].function = rl_vi_movement_mode;
-      vi_replace_map[RETURN].function = rl_newline;
-      vi_replace_map[NEWLINE].function = rl_newline;
-
-      /* If the normal vi insertion keymap has ^H bound to erase, do the
-         same here.  Probably should remove the assignment to RUBOUT up
-         there, but I don't think it will make a difference in real life. */
-      if (vi_insertion_keymap[CTRL ('H')].type == ISFUNC &&
-         vi_insertion_keymap[CTRL ('H')].function == rl_rubout)
-       vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete;
-
-    }
-  _rl_keymap = vi_replace_map;
-  return (0);
-}
-
-#if 0
-/* Try to complete the word we are standing on or the word that ends with
-   the previous character.  A space matches everything.  Word delimiters are
-   space and ;. */
-int
-rl_vi_possible_completions()
-{
-  int save_pos = rl_point;
-
-  if (rl_line_buffer[rl_point] != ' ' && rl_line_buffer[rl_point] != ';')
-    {
-      while (rl_point < rl_end && rl_line_buffer[rl_point] != ' ' &&
-            rl_line_buffer[rl_point] != ';')
-       rl_point++;
-    }
-  else if (rl_line_buffer[rl_point - 1] == ';')
-    {
-      rl_ding ();
-      return (0);
-    }
-
-  rl_possible_completions ();
-  rl_point = save_pos;
-
-  return (0);
-}
-#endif
-
-/* Functions to save and restore marks. */
-static int
-_rl_vi_set_mark ()
-{
-  int ch;
-
-  RL_SETSTATE(RL_STATE_MOREINPUT);
-  ch = rl_read_key ();
-  RL_UNSETSTATE(RL_STATE_MOREINPUT);
-
-  if (ch < 0 || ch < 'a' || ch > 'z')  /* make test against 0 explicit */
-    {
-      rl_ding ();
-      return -1;
-    }
-  ch -= 'a';
-  vi_mark_chars[ch] = rl_point;
-  return 0;
-}
-
-#if defined (READLINE_CALLBACKS)
-static int
-_rl_vi_callback_set_mark (data)
-     _rl_callback_generic_arg *data;
-{
-  _rl_callback_func = 0;
-  _rl_want_redisplay = 1;
-
-  return (_rl_vi_set_mark ());
-}
-#endif
-
-int
-rl_vi_set_mark (count, key)
-     int count, key;
-{
-#if defined (READLINE_CALLBACKS)
-  if (RL_ISSTATE (RL_STATE_CALLBACK))
-    {
-      _rl_callback_data = 0;
-      _rl_callback_func = _rl_vi_callback_set_mark;
-      return (0);
-    }
-#endif
-
-  return (_rl_vi_set_mark ());
-}
-
-static int
-_rl_vi_goto_mark ()
-{
-  int ch;
-
-  RL_SETSTATE(RL_STATE_MOREINPUT);
-  ch = rl_read_key ();
-  RL_UNSETSTATE(RL_STATE_MOREINPUT);
-
-  if (ch == '`')
-    {
-      rl_point = rl_mark;
-      return 0;
-    }
-  else if (ch < 0 || ch < 'a' || ch > 'z')     /* make test against 0 explicit */
-    {
-      rl_ding ();
-      return -1;
-    }
-
-  ch -= 'a';
-  if (vi_mark_chars[ch] == -1)
-    {
-      rl_ding ();
-      return -1;
-    }
-  rl_point = vi_mark_chars[ch];
-  return 0;
-}
-
-#if defined (READLINE_CALLBACKS)
-static int
-_rl_vi_callback_goto_mark (data)
-     _rl_callback_generic_arg *data;
-{
-  _rl_callback_func = 0;
-  _rl_want_redisplay = 1;
-
-  return (_rl_vi_goto_mark ());
-}
-#endif
-
-int
-rl_vi_goto_mark (count, key)
-     int count, key;
-{
-#if defined (READLINE_CALLBACKS)
-  if (RL_ISSTATE (RL_STATE_CALLBACK))
-    {
-      _rl_callback_data = 0;
-      _rl_callback_func = _rl_vi_callback_goto_mark;
-      return (0);
-    }
-#endif
-
-  return (_rl_vi_goto_mark ());
-}
-#endif /* VI_MODE */
diff --git a/lib/sh/Makefile.in~ b/lib/sh/Makefile.in~
deleted file mode 100644 (file)
index f5c05af..0000000
+++ /dev/null
@@ -1,535 +0,0 @@
-#
-# Makefile for the Bash library
-#
-#
-# Copyright (C) 1998-2009 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
-
-PACKAGE = @PACKAGE_NAME@
-VERSION = @PACKAGE_VERSION@
-
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-
-srcdir = @srcdir@
-VPATH = .:@srcdir@
-topdir = @top_srcdir@
-BUILD_DIR = @BUILD_DIR@
-
-LIBBUILD = ${BUILD_DIR}/lib
-
-BASHINCDIR = ${topdir}/include
-
-INTL_LIBSRC = ${topdir}/lib/intl
-INTL_BUILDDIR = ${LIBBUILD}/intl
-INTL_INC = @INTL_INC@
-LIBINTL_H = @LIBINTL_H@
-
-datarootdir = @datarootdir@
-
-INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_DATA = @INSTALL_DATA@
-
-CC = @CC@
-RANLIB = @RANLIB@
-AR = @AR@
-ARFLAGS = @ARFLAGS@
-RM = rm -f
-CP = cp
-MV = mv
-
-SHELL = @MAKE_SHELL@
-
-CFLAGS = @CFLAGS@
-LOCAL_CFLAGS = @LOCAL_CFLAGS@ ${DEBUG}
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@ @LOCAL_LDFLAGS@
-
-PROFILE_FLAGS = @PROFILE_FLAGS@
-
-DEFS = @DEFS@
-LOCAL_DEFS = @LOCAL_DEFS@
-
-INCLUDES = -I. -I../.. -I$(topdir) -I$(topdir)/lib -I$(BASHINCDIR) -I$(srcdir) $(INTL_INC)
-
-CCFLAGS = ${PROFILE_FLAGS} ${INCLUDES} $(DEFS) $(LOCAL_DEFS) $(LOCAL_CFLAGS) \
-         $(CFLAGS) $(CPPFLAGS) 
-
-GCC_LINT_FLAGS = -Wall -Wshadow -Wpointer-arith -Wcast-qual \
-                -Wcast-align -Wstrict-prototypes -Wconversion \
-                -Wmissing-prototypes -Wtraditional -Wredundant-decls -pedantic
-
-.c.o:
-       $(CC) -c $(CCFLAGS) $<
-
-# The name of the library target.
-LIBRARY_NAME = libsh.a
-
-# The C code source files for this library.
-CSOURCES = clktck.c clock.c getcwd.c getenv.c oslib.c setlinebuf.c \
-          strcasecmp.c strerror.c strtod.c strtol.c strtoul.c \
-          vprint.c itos.c rename.c zread.c zwrite.c shtty.c \
-          inet_aton.c netconn.c netopen.c strpbrk.c timeval.c makepath.c \
-          pathcanon.c pathphys.c tmpfile.c stringlist.c stringvec.c spell.c \
-          shquote.c strtrans.c strcasestr.c snprintf.c mailstat.c \
-          fmtulong.c fmtullong.c fmtumax.c shmatch.c strnlen.c \
-          strtoll.c strtoull.c strtoimax.c strtoumax.c memset.c strstr.c \
-          mktime.c strftime.c mbschr.c zcatfd.c zmapfd.c winsize.c eaccess.c \
-          wcsdup.c fpurge.c zgetline.c mbscmp.c uconvert.c ufuncs.c \
-          casemod.c fdprintf.c input_avail.c mbscasecmp.c
-
-# The header files for this library.
-HSOURCES = 
-
-# The object files contained in $(LIBRARY_NAME)
-LIBOBJS = @LIBOBJS@
-OBJECTS = clktck.o clock.o getenv.o oslib.o setlinebuf.o strnlen.o \
-         itos.o zread.o zwrite.o shtty.o shmatch.o eaccess.o \
-         netconn.o netopen.o timeval.o makepath.o pathcanon.o \
-         pathphys.o tmpfile.o stringlist.o stringvec.o spell.o shquote.o \
-         strtrans.o snprintf.o mailstat.o fmtulong.o \
-         fmtullong.o fmtumax.o zcatfd.o zmapfd.o winsize.o wcsdup.o \
-         fpurge.o zgetline.o mbscmp.o uconvert.o ufuncs.o casemod.o \
-         fdprintf.o input_avail.o mbscasecmp.o ${LIBOBJS}
-
-SUPPORT = Makefile
-
-all: $(LIBRARY_NAME)
-
-$(LIBRARY_NAME): $(OBJECTS)
-       $(RM) $@
-       $(AR) $(ARFLAGS) $@ $(OBJECTS)
-       -test -n "$(RANLIB)" && $(RANLIB) $@
-
-force:
-
-# The rule for 'includes' is written funny so that the if statement
-# always returns TRUE unless there really was an error installing the
-# include files.
-install:
-
-clean:
-       $(RM) $(OBJECTS) $(LIBRARY_NAME)
-
-realclean distclean maintainer-clean: clean
-       $(RM) Makefile
-
-mostlyclean: clean
-
-# Dependencies
-
-${BUILD_DIR}/version.h: ${BUILD_DIR}/config.h ${BUILD_DIR}/Makefile Makefile
-       -( cd ${BUILD_DIR} && ${MAKE} ${MFLAGS} version.h )
-
-# rules for losing makes, like SunOS
-casemod.o: casemod.c
-clktck.o: clktck.c
-clock.o: clock.c
-eaccess.o: eaccess.c
-fdprintf.o: fdprintf.c
-fmtullong.o: fmtullong.c
-fmtulong.o: fmtulong.c
-fmtumax.o: fmtumax.c
-fpurge.o: fpurge.c
-getcwd.o: getcwd.c
-getenv.o: getenv.c
-inet_aton.o: inet_aton.c
-input_avail.o: input_avail.c
-itos.o: itos.c
-mailstat.o: mailstat.c
-makepath.o: makepath.c
-mbscasecmp.o: mbscasecmp.c
-mbscmp.o: mbscmp.c
-memset.o: memset.c
-mktime.o: mktime.c
-netconn.o: netconn.c
-netopen.o: netopen.c
-oslib.o: oslib.c
-pathcanon.o: pathcanon.c
-pathphys.o: pathphys.c
-rename.o: rename.c
-setlinebuf.o: setlinebuf.c
-shquote.o: shquote.c
-shtty.o: shtty.c
-snprintf.o: snprintf.c
-spell.o: spell.c
-strcasecmp.o: strcasecmp.c
-strerror.o: strerror.c
-strftime.o: strftime.c
-strcasestr.o: strcasestr.c
-stringlist.o: stringlist.c
-stringvec.o: stringvec.c
-strnlen.o: strnlen.c
-strpbrk.o: strpbrk.c
-strtod.o: strtod.c
-strtoimax.o: strtoimax.c
-strtol.o: strtol.c
-strtoll.o: strtoll.c
-strtoul.o: strtoul.c
-strtoull.o: strtoull.c
-strtoumax.o: strtoumax.c
-strtrans.o: strtrans.c
-times.o: times.c
-timeval.o: timeval.c
-tmpfile.o: tmpfile.c
-uconvert.o: uconvert.c
-ufuncs.o: ufuncs.c
-vprint.o: vprint.c
-wcsdup.o: wcsdup.c
-mbschr.o: mbschr.c
-zcatfd.o: zcatfd.c
-zmapfd.o: zmapfd.c
-zgetline.o: zgetline.c
-zread.o: zread.c
-zwrite.o: zwrite.c
-
-# dependencies for c files that include other c files
-fmtullong.o: fmtulong.c
-fmtumax.o: fmtulong.c
-strtoll.o: strtol.c
-strtoul.o: strtol.c
-strtoull.o: strtol.c
-
-# all files in the library depend on config.h
-casemod.o: ${BUILD_DIR}/config.h
-clktck.o: ${BUILD_DIR}/config.h
-clock.o: ${BUILD_DIR}/config.h
-eaccess.o: ${BUILD_DIR}/config.h
-fdprintf.o: ${BUILD_DIR}/config.h
-fmtullong.o: ${BUILD_DIR}/config.h
-fmtulong.o: ${BUILD_DIR}/config.h
-fmtumax.o: ${BUILD_DIR}/config.h
-fpurge.o: ${BUILD_DIR}/config.h
-getcwd.o: ${BUILD_DIR}/config.h
-getenv.o: ${BUILD_DIR}/config.h
-inet_aton.o: ${BUILD_DIR}/config.h
-input_avail.o: ${BUILD_DIR}/config.h
-itos.o: ${BUILD_DIR}/config.h
-mailstat.o: ${BUILD_DIR}/config.h
-makepath.o: ${BUILD_DIR}/config.h
-mbscasecmp.o: ${BUILD_DIR}/config.h
-mbscmp.o: ${BUILD_DIR}/config.h
-memset.o: ${BUILD_DIR}/config.h
-mktime.o: ${BUILD_DIR}/config.h
-netconn.o: ${BUILD_DIR}/config.h
-netopen.o: ${BUILD_DIR}/config.h
-oslib.o: ${BUILD_DIR}/config.h
-pathcanon.o: ${BUILD_DIR}/config.h
-pathphys.o: ${BUILD_DIR}/config.h
-rename.o: ${BUILD_DIR}/config.h
-setlinebuf.o: ${BUILD_DIR}/config.h
-shquote.o: ${BUILD_DIR}/config.h
-shtty.o: ${BUILD_DIR}/config.h
-snprintf.o: ${BUILD_DIR}/config.h
-spell.o: ${BUILD_DIR}/config.h
-strcasecmp.o: ${BUILD_DIR}/config.h
-strerror.o: ${BUILD_DIR}/config.h
-strftime.o: ${BUILD_DIR}/config.h
-strcasestr.o: ${BUILD_DIR}/config.h
-stringlist.o: ${BUILD_DIR}/config.h
-stringvec.o: ${BUILD_DIR}/config.h
-strnlen.o: ${BUILD_DIR}/config.h
-strpbrk.o: ${BUILD_DIR}/config.h
-strtod.o: ${BUILD_DIR}/config.h
-strtoimax.o: ${BUILD_DIR}/config.h
-strtol.o: ${BUILD_DIR}/config.h
-strtoll.o: ${BUILD_DIR}/config.h
-strtoul.o: ${BUILD_DIR}/config.h
-strtoull.o: ${BUILD_DIR}/config.h
-strtoumax.o: ${BUILD_DIR}/config.h
-strtrans.o: ${BUILD_DIR}/config.h
-times.o: ${BUILD_DIR}/config.h
-timeval.o: ${BUILD_DIR}/config.h
-tmpfile.o: ${BUILD_DIR}/config.h
-uconvert.o: ${BUILD_DIR}/config.h
-ufuncs.o: ${BUILD_DIR}/config.h
-vprint.o: ${BUILD_DIR}/config.h
-wcsdup.o: ${BUILD_DIR}/config.h
-mbschr.o: ${BUILD_DIR}/config.h
-zcatfd.o: ${BUILD_DIR}/config.h
-zgetline.o: ${BUILD_DIR}/config.h
-zmapfd.o: ${BUILD_DIR}/config.h
-zread.o: ${BUILD_DIR}/config.h
-zwrite.o: ${BUILD_DIR}/config.h
-
-clktck.o: ${topdir}/bashtypes.h
-
-getcwd.o: ${topdir}/bashtypes.h ${topdir}/bashansi.h ${BASHINCDIR}/maxpath.h
-getcwd.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/posixdir.h
-getcwd.o: ${BASHINCDIR}/memalloc.h ${BASHINCDIR}/ansi_stdlib.h
-
-getenv.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-getenv.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h
-getenv.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h
-getenv.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h
-getenv.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h
-getenv.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h
-getenv.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h
-getenv.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h
-getenv.o: ${BUILD_DIR}/version.h
-
-inet_aton.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-inet_aton.o: ${BASHINCDIR}/stdc.h
-
-itos.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-itos.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h
-itos.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h
-itos.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h
-itos.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h
-itos.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h
-itos.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h
-itos.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h
-
-makepath.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-makepath.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h
-makepath.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h
-makepath.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h
-makepath.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h
-makepath.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h
-makepath.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h
-makepath.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h
-
-netconn.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h
-netconn.o: ${topdir}/bashtypes.h
-
-netopen.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h ${topdir}/xmalloc.h
-netopen.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h
-netopen.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h
-netopen.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h
-netopen.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h
-netopen.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h
-netopen.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h
-netopen.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h
-netopen.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
-
-oslib.o: ${topdir}/bashtypes.h ${topdir}/bashansi.h ${BASHINCDIR}/maxpath.h
-oslib.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h
-oslib.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h
-oslib.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h
-oslib.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h
-oslib.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h
-oslib.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h
-oslib.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h
-oslib.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h
-oslib.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
-
-pathcanon.o: ${topdir}/bashtypes.h ${topdir}/bashansi.h ${BASHINCDIR}/maxpath.h
-pathcanon.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h
-pathcanon.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h
-pathcanon.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h
-pathcanon.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h
-pathcanon.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h
-pathcanon.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h
-pathcanon.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h
-pathcanon.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h
-pathcanon.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
-
-pathphys.o: ${topdir}/bashtypes.h ${topdir}/bashansi.h ${BASHINCDIR}/maxpath.h
-pathphys.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h
-pathphys.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h
-pathphys.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h
-pathphys.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h
-pathphys.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h
-pathphys.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h
-pathphys.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h
-pathphys.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h
-pathphys.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
-
-rename.o: ${topdir}/bashtypes.h ${BASHINCDIR}/stdc.h
-rename.o: ${BASHINCDIR}/posixstat.h
-
-setlinebuf.o: ${topdir}/xmalloc.h ${topdir}/bashansi.h
-setlinebuf.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/stdc.h
-
-eaccess.o: ${topdir}/bashtypes.h
-eaccess.o: ${BASHINCDIR}/posixstat.h
-eaccess.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-eaccess.o: ${BASHINCDIR}/filecntl.h
-eaccess.o: ${BASHINCDIR}/stdc.h
-eaccess.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h
-eaccess.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h
-eaccess.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h
-eaccess.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h
-eaccess.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h
-eaccess.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h
-eaccess.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h
-
-shquote.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h
-shquote.o: ${BASHINCDIR}/ansi_stdlib.h ${topdir}/xmalloc.h
-
-shtty.o: ${BASHINCDIR}/shtty.h
-shtty.o: ${BASHINCDIR}/stdc.h
-
-snprintf.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h ${topdir}/xmalloc.h
-snprintf.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
-snprintf.o: ${BASHINCDIR}/typemax.h
-
-spell.o: ${topdir}/bashtypes.h
-spell.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/posixdir.h
-spell.o: ${BASHINCDIR}/ansi_stdlib.h
-
-strcasecmp.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h
-strcasecmp.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
-
-strerror.o: ${topdir}/bashtypes.h
-strerror.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h
-strerror.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h
-strerror.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h
-strerror.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h
-strerror.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h
-strerror.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h
-strerror.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h
-
-strcasestr.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h
-strcasestr.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
-
-stringlist.o: ${topdir}/bashansi.h
-stringlist.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h
-stringlist.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h
-stringlist.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h
-stringlist.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h
-stringlist.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h
-stringlist.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h
-stringlist.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h
-
-stringvec.o: ${topdir}/bashansi.h ${BASHINCDIR}/chartypes.h
-stringvec.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h
-stringvec.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h
-stringvec.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h
-stringvec.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h
-stringvec.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h
-stringvec.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h
-stringvec.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h
-
-strnlen.o: ${BASHINCDIR}/stdc.h
-
-strpbrk.o: ${BASHINCDIR}/stdc.h
-
-strtod.o: ${topdir}/bashansi.h
-strtod.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
-
-strtoimax.o: ${BASHINCDIR}/stdc.h
-
-strtol.o: ${topdir}/bashansi.h
-strtol.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
-strtol.o: ${BASHINCDIR}/typemax.h
-
-strtoll.o: ${topdir}/bashansi.h
-strtoll.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
-strtoll.o: ${BASHINCDIR}/typemax.h
-
-strtoul.o: ${topdir}/bashansi.h
-strtoul.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
-strtoul.o: ${BASHINCDIR}/typemax.h
-
-strtoull.o: ${topdir}/bashansi.h
-strtoull.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
-strtoull.o: ${BASHINCDIR}/typemax.h
-
-strtoumax.o: ${BASHINCDIR}/stdc.h
-
-strtrans.o: ${topdir}/bashansi.h
-strtrans.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
-strtrans.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h
-strtrans.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h
-strtrans.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h
-strtrans.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h
-strtrans.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h
-strtrans.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h
-strtrans.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h
-
-times.o: ${BASHINCDIR}/systimes.h
-times.o: ${BASHINCDIR}/posixtime.h
-
-timeval.o: ${BASHINCDIR}/posixtime.h
-
-tmpfile.o: ${topdir}/bashtypes.h
-tmpfile.o: ${BASHINCDIR}/posixstat.h
-tmpfile.o: ${BASHINCDIR}/filecntl.h
-
-uconvert.o: ${topdir}/bashtypes.h
-
-ufuncs.o: ${topdir}/bashtypes.h
-
-clock.o: ${BASHINCDIR}/posixtime.h
-
-mailstat.o: ${topdir}/bashansi.h
-mailstat.o: ${topdir}/bashtypes.h
-mailstat.o: ${BASHINCDIR}/ansi_stdlib.h
-mailstat.o: ${BASHINCDIR}/posixstat.h
-mailstat.o: ${BASHINCDIR}/posixdir.h
-mailstat.o: ${BASHINCDIR}/maxpath.h
-
-fmtulong.o: ${topdir}/bashansi.h
-fmtulong.o: ${BASHINCDIR}/ansi_stdlib.h
-fmtulong.o: ${BASHINCDIR}/chartypes.h
-fmtulong.o: ${BASHINCDIR}/stdc.h
-fmtulong.o: ${BASHINCDIR}/typemax.h
-fmtulong.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h
-
-fmtullong.o: ${topdir}/bashansi.h
-fmtullong.o: ${BASHINCDIR}/ansi_stdlib.h
-fmtullong.o: ${BASHINCDIR}/chartypes.h
-fmtullong.o: ${BASHINCDIR}/stdc.h
-fmtullong.o: ${BASHINCDIR}/typemax.h
-fmtullong.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h
-
-fmtumax.o: ${topdir}/bashansi.h
-fmtumax.o: ${BASHINCDIR}/ansi_stdlib.h
-fmtumax.o: ${BASHINCDIR}/chartypes.h
-fmtumax.o: ${BASHINCDIR}/stdc.h
-fmtumax.o: ${BASHINCDIR}/typemax.h
-fmtumax.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h
-
-wcsdup.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-wcsdup.o: ${BASHINCDIR}/stdc.h
-wcsdup.o: ${topdir}/xmalloc.h
-
-mbschr.o: ${topdir}/bashansi.h
-mbschr.o: ${BASHINCDIR}/ansi_stdlib.h
-mbschr.o: ${BASHINCDIR}/shmbutil.h
-
-zgetline.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-zgetline.o: ${BASHINCDIR}/stdc.h
-zgetline.o: ${topdir}/xmalloc.h
-zgetline.o: ${topdir}/bashtypes.h
-
-mbscasecmp.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-mbscasecmp.o: ${BASHINCDIR}/stdc.h
-mbscasecmp.o: ${topdir}/xmalloc.h
-
-mbscmp.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-mbscmp.o: ${BASHINCDIR}/stdc.h
-mbscmp.o: ${topdir}/xmalloc.h
-
-casemod.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-casemod.o: ${BASHINCDIR}/stdc.h
-casemod.o: ${topdir}/xmalloc.h
-casemod.o: ${topdir}/bashtypes.h
-casemod.o: ${BASHINCDIR}/shmbutil.h
-casemod.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h
-
-fdprintf.o: ${BASHINCDIR}/stdc.h
-
-input_avail.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-input_avail.o: ${BASHINCDIR}/stdc.h
-input_avail.o: ${topdir}/xmalloc.h ${BASHINCDIR}/posixselect.h
-
-mktime.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
-mktime.o: ${BASHINCDIR}/stdc.h
-
diff --git a/lib/sh/casemod.c~ b/lib/sh/casemod.c~
deleted file mode 100644 (file)
index 5b1b04e..0000000
+++ /dev/null
@@ -1,243 +0,0 @@
-/* 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 <shmbutil.h>
-#include <chartypes.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));
-
-#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)
-    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, m;
-  mbstate_t state;
-#endif
-
-#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;
-         ADVANCE_CHAR (ret, end, start);
-         continue;
-       }
-
-      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;
-
-      if (MB_CUR_MAX == 1 || isascii (wc))
-       {
-         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];
-         else if (MB_NULLWCH (m))
-           wc = L'\0';
-         switch (nop)
-         {
-         default:
-         case CASE_NOOP:  nwc = wc; break;
-         case CASE_UPPER:  nwc = TOUPPER (wc); break;
-         case CASE_LOWER:  nwc = TOLOWER (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/lib/sh/fnxform.c~ b/lib/sh/fnxform.c~
deleted file mode 100644 (file)
index ecc7fd7..0000000
+++ /dev/null
@@ -1,200 +0,0 @@
-/* fnxform - use iconv(3) to transform strings to and from "filename" format */
-
-/* Copyright (C) 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/>.
-*/
-
-#include <config.h>
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-#include "bashansi.h"
-#include <stdio.h>
-#include "bashtypes.h"
-
-#include "stdc.h"
-#include "bashintl.h"
-#include <xmalloc.h>
-
-#if defined (HAVE_ICONV)
-#  include <iconv.h>
-#endif
-
-#if defined (HAVE_LOCALE_CHARSET)
-extern const char *locale_charset __P((void));
-#endif
-
-#if defined (HAVE_ICONV)
-static iconv_t conv_fromfs = (iconv_t)-1;
-static iconv_t conv_tofs = (iconv_t)-1;
-
-#define OUTLEN_MAX 4096
-
-static char *outbuf = 0;
-static size_t outlen = 0;
-
-static char *curencoding __P((void));
-static void init_tofs __P((void));
-static void init_fromfs __P((void));
-
-static char *
-curencoding ()
-{
-  char *loc;
-#if defined (HAVE_LOCALE_CHARSET)
-  loc = (char *)locale_charset ();
-  return loc;
-#else
-  char *dot, *mod;
-
-  loc = get_locale_var ("LC_CTYPE");
-  if (loc == 0 || *loc == 0)
-    return "";
-  dot = strchr (loc, '.');
-  if (dot == 0)
-    return loc;
-  mod = strchr (dot, '@');
-  if (mod)
-    *mod = '\0';
-  return dot;
-#endif
-}  
-
-static void
-init_tofs ()
-{
-  char *cur;
-
-  cur = curencoding ();
-  conv_tofs = iconv_open ("UTF-8-MAC", cur);
-}
-
-static void
-init_fromfs ()
-{
-  char *cur;
-
-  cur = curencoding ();
-  conv_fromfs = iconv_open (cur, "UTF-8-MAC");
-}
-
-char *
-fnx_tofs (string, len)
-     char *string;
-     size_t len;
-{
-#ifdef MACOSX
-  ICONV_CONST char *inbuf;
-  char *tempbuf;
-  size_t templen;
-  
-  if (conv_tofs == (iconv_t)-1)
-    init_tofs ();
-  if (conv_tofs == (iconv_t)-1)
-    return string;
-
-  /* Free and reallocate outbuf if it's *too* big */
-  if (outlen >= OUTLEN_MAX && len < OUTLEN_MAX - 8)
-    {
-      free (outbuf);
-      outbuf = 0;
-      outlen = 0;
-    }
-
-  inbuf = string;
-  if (outbuf == 0 || outlen < len + 8)
-    {
-      outlen = len + 8;
-      outbuf = outbuf ? xrealloc (outbuf, outlen + 1) : xmalloc (outlen + 1);
-    }
-  tempbuf = outbuf;
-  templen = outlen;
-
-  iconv (conv_tofs, NULL, NULL, NULL, NULL);
-
-  if (iconv (conv_tofs, &inbuf, &len, &tempbuf, &templen) == (size_t)-1)
-    return string;
-
-  *tempbuf = '\0';
-  return outbuf;
-#else
-  return string;
-#endif
-}
-
-char *
-fnx_fromfs (string, len)
-     char *string;
-     size_t len;
-{
-#ifdef MACOSX
-  ICONV_CONST char *inbuf;
-  char *tempbuf;
-  size_t templen;
-
-  if (conv_fromfs == (iconv_t)-1)
-    init_fromfs ();
-  if (conv_fromfs == (iconv_t)-1)
-    return string;
-
-itrace("fnx_fromfs: outlen = %d after init_fromfs", outlen);
-  /* Free and reallocate outbuf if it's *too* big */
-  if (outlen >= OUTLEN_MAX && len < OUTLEN_MAX - 8)
-    {
-      free (outbuf);
-      outbuf = 0;
-      outlen = 0;
-    }
-
-  inbuf = string;
-  if (outbuf == 0 || outlen < (len + 8))
-    {
-      outlen = len + 8;
-      outbuf = outbuf ? xrealloc (outbuf, outlen + 1) : xmalloc (outlen + 1);
-itrace("fnx_fromfs: increased outlen to %d", outlen);
-    }
-  tempbuf = outbuf;
-  templen = outlen;
-
-  iconv (conv_fromfs, NULL, NULL, NULL, NULL);
-
-  if (iconv (conv_fromfs, &inbuf, &len, &tempbuf, &templen) == (size_t)-1)
-    return string;
-
-  *tempbuf = '\0';
-  return outbuf;
-#else
-  return string;
-#endif
-}
-
-#else
-char *
-fnx_tofs (string)
-     char *string;
-{
-bar
-  return string;
-}
-
-char *
-fnx_fromfs (string)
-     char *string;
-{
-  return string;
-}
-#endif
diff --git a/lib/sh/fpurge.c.old b/lib/sh/fpurge.c.old
deleted file mode 100644 (file)
index a01c1bf..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/* fpurge - Flushing buffers of a FILE stream. */
-
-/* Copyright (C) 2007 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 "stdc.h"
-
-#include <stdio.h>
-
-/* Specification.  Same as in ../../externs.h.  */
-#define NEED_FPURGE_DECL
-#if HAVE_FPURGE
-#  define fpurge _bash_fpurge
-#endif
-extern int fpurge __P((FILE *stream));
-
-#if HAVE___FPURGE                   /* glibc >= 2.2, Solaris >= 7 */
-# include <stdio_ext.h>
-#endif
-#include <stdlib.h>
-
-int
-fpurge (FILE *fp)
-{
-#if HAVE___FPURGE                   /* glibc >= 2.2, Solaris >= 7 */
-
-  __fpurge (fp);
-  /* The __fpurge function does not have a return value.  */
-  return 0;
-
-#elif HAVE_FPURGE                   /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X */
-
-  /* Call the system's fpurge function.  */
-# undef fpurge
-# if !HAVE_DECL_FPURGE
-  extern int fpurge (FILE *);
-# endif
-  int result = fpurge (fp);
-# if defined __sferror || defined __DragonFly__        /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */
-  if (result == 0)
-    /* Correct the invariants that fpurge broke.
-       <stdio.h> on BSD systems says:
-         "The following always hold: if _flags & __SRD, _w is 0."
-       If this invariant is not fulfilled and the stream is read-write but
-       currently writing, subsequent putc or fputc calls will write directly
-       into the buffer, although they shouldn't be allowed to.  */
-    if ((fp->_flags & __SRD) != 0)
-      fp->_w = 0;
-# endif
-  return result;
-
-#else
-
-  /* Most systems provide FILE as a struct and the necessary bitmask in
-     <stdio.h>, because they need it for implementing getc() and putc() as
-     fast macros.  */
-# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Linux libc5 */
-  fp->_IO_read_end = fp->_IO_read_ptr;
-  fp->_IO_write_ptr = fp->_IO_write_base;
-  /* Avoid memory leak when there is an active ungetc buffer.  */
-  if (fp->_IO_save_base != NULL)
-    {
-      free (fp->_IO_save_base);
-      fp->_IO_save_base = NULL;
-    }
-  return 0;
-# elif defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */
-  fp->_p = fp->_bf._base;
-  fp->_r = 0;
-  fp->_w = ((fp->_flags & (__SLBF | __SNBF | __SRD)) == 0 /* fully buffered and not currently reading? */
-           ? fp->_bf._size
-           : 0);
-  /* Avoid memory leak when there is an active ungetc buffer.  */
-#  if defined __NetBSD__ || defined __OpenBSD__ /* NetBSD, OpenBSD */
-   /* See <http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup>
-      and <http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup> */
-#   define fp_ub ((struct { struct __sbuf _ub; } *) fp->_ext._base)->_ub
-#  else                                         /* FreeBSD, MacOS X, Cygwin */
-#   define fp_ub fp->_ub
-#  endif
-  if (fp_ub._base != NULL)
-    {
-      if (fp_ub._base != fp->_ubuf)
-       free (fp_ub._base);
-      fp_ub._base = NULL;
-    }
-  return 0;
-# elif defined _IOERR               /* AIX, HP-UX, IRIX, OSF/1, Solaris, mingw */
-  fp->_ptr = fp->_base;
-  if (fp->_ptr != NULL)
-    fp->_cnt = 0;
-  return 0;
-# elif defined __UCLIBC__           /* uClibc */
-#  ifdef __STDIO_BUFFERS
-  if (fp->__modeflags & __FLAG_WRITING)
-    fp->__bufpos = fp->__bufstart;
-  else if (fp->__modeflags & (__FLAG_READONLY | __FLAG_READING))
-    fp->__bufpos = fp->__bufread;
-#  endif
-  return 0;
-# else
- #error "Please port gnulib fpurge.c to your platform! Look at the definitions of fflush, setvbuf and ungetc on your system, then report this to bug-gnulib."
-# endif
-
-#endif
-}
diff --git a/lib/sh/fpurge.c~ b/lib/sh/fpurge.c~
deleted file mode 100644 (file)
index fa2ccf9..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/* fpurge - Flushing buffers of a FILE stream. */
-
-/* Copyright (C) 2007 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 "stdc.h"
-
-#include <stdio.h>
-
-/* Specification.  Same as in ../../externs.h.  */
-#define NEED_FPURGE_DECL
-#if HAVE_FPURGE
-#  define fpurge _bash_fpurge
-#endif
-extern int fpurge __P((FILE *stream));
-
-#if HAVE___FPURGE                   /* glibc >= 2.2, Haiku, Solaris >= 7 */
-# include <stdio_ext.h>
-#endif
-#include <stdlib.h>
-
-int
-fpurge (FILE *fp)
-{
-#if HAVE___FPURGE                   /* glibc >= 2.2, Haiku, Solaris >= 7 */
-
-  __fpurge (fp);
-  /* The __fpurge function does not have a return value.  */
-  return 0;
-
-#elif HAVE_FPURGE                   /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X */
-
-  /* Call the system's fpurge function.  */
-# undef fpurge
-# if !HAVE_DECL_FPURGE
-  extern int fpurge (FILE *);
-# endif
-  int result = fpurge (fp);
-# if defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */
-  if (result == 0)
-    /* Correct the invariants that fpurge broke.
-       <stdio.h> on BSD systems says:
-         "The following always hold: if _flags & __SRD, _w is 0."
-       If this invariant is not fulfilled and the stream is read-write but
-       currently writing, subsequent putc or fputc calls will write directly
-       into the buffer, although they shouldn't be allowed to.  */
-    if ((fp->_flags & __SRD) != 0)
-      fp->_w = 0;
-# endif
-  return result;
-
-#else
-
-  /* Most systems provide FILE as a struct and the necessary bitmask in
-     <stdio.h>, because they need it for implementing getc() and putc() as
-     fast macros.  */
-# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
-  fp->_IO_read_end = fp->_IO_read_ptr;
-  fp->_IO_write_ptr = fp->_IO_write_base;
-  /* Avoid memory leak when there is an active ungetc buffer.  */
-  if (fp->_IO_save_base != NULL)
-    {
-      free (fp->_IO_save_base);
-      fp->_IO_save_base = NULL;
-    }
-  return 0;
-# elif defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */
-  fp_->_p = fp_->_bf._base;
-  fp_->_r = 0;
-  fp_->_w = ((fp_->_flags & (__SLBF | __SNBF | __SRD)) == 0 /* fully buffered and not currently reading? */
-            ? fp_->_bf._size
-            : 0);
-  /* Avoid memory leak when there is an active ungetc buffer.  */
-  if (fp_ub._base != NULL)
-    {
-      if (fp_ub._base != fp_->_ubuf)
-       free (fp_ub._base);
-      fp_ub._base = NULL;
-    }
-  return 0;
-# elif defined __EMX__              /* emx+gcc */
-  fp->_ptr = fp->_buffer;
-  fp->_rcount = 0;
-  fp->_wcount = 0;
-  fp->_ungetc_count = 0;
-  return 0;
-# elif defined _IOERR               /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw */
-  fp->_ptr = fp->_base;
-  if (fp->_ptr != NULL)
-    fp->_cnt = 0;
-  return 0;
-# elif defined __UCLIBC__           /* uClibc */
-#  ifdef __STDIO_BUFFERS
-  if (fp->__modeflags & __FLAG_WRITING)
-    fp->__bufpos = fp->__bufstart;
-  else if (fp->__modeflags & (__FLAG_READONLY | __FLAG_READING))
-    fp->__bufpos = fp->__bufread;
-#  endif
-  return 0;
-# elif defined __QNX__              /* QNX */
-  fp->_Rback = fp->_Back + sizeof (fp->_Back);
-  fp->_Rsave = NULL;
-  if (fp->_Mode & 0x2000 /* _MWRITE */)
-    /* fp->_Buf <= fp->_Next <= fp->_Wend */
-    fp->_Next = fp->_Buf;
-  else
-    /* fp->_Buf <= fp->_Next <= fp->_Rend */
-    fp->_Rend = fp->_Next;
-  return 0;
-# elif defined __MINT__             /* Atari FreeMiNT */
-  if (fp->__pushed_back)
-    {
-      fp->__bufp = fp->__pushback_bufp;
-      fp->__pushed_back = 0;
-    }
-  /* Preserve the current file position.  */
-  if (fp->__target != -1)
-    fp->__target += fp->__bufp - fp->__buffer;
-  fp->__bufp = fp->__buffer;
-  /* Nothing in the buffer, next getc is nontrivial.  */
-  fp->__get_limit = fp->__bufp;
-  /* Nothing in the buffer, next putc is nontrivial.  */
-  fp->__put_limit = fp->__buffer;
-  return 0;
-# else
- #error "Please port gnulib fpurge.c to your platform! Look at the definitions of fflush, setvbuf and ungetc on your system, then report this to bug-gnulib."
-# endif
-
-#endif
-}
diff --git a/lib/sh/input_avail.c~ b/lib/sh/input_avail.c~
deleted file mode 100644 (file)
index 5e01f8f..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/* input_avail.c -- check whether or not data is available for reading on a
-                   specified file descriptor. */
-
-/* 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 (__TANDEM)
-#  include <floss.h>
-#endif
-
-#if defined (HAVE_CONFIG_H)
-#  include <config.h>
-#endif
-
-#include <sys/types.h>
-#include <fcntl.h>
-#if defined (HAVE_SYS_FILE_H)
-#  include <sys/file.h>
-#endif /* HAVE_SYS_FILE_H */
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#include "bashansi.h"
-
-#if defined (HAVE_SELECT)
-#  if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX)
-#    include <sys/time.h>
-#  endif
-#endif /* HAVE_SELECT */
-#if defined (HAVE_SYS_SELECT_H)
-#  include <sys/select.h>
-#endif
-
-#if defined (FIONREAD_IN_SYS_IOCTL)
-#  include <sys/ioctl.h>
-#endif
-
-#include <stdio.h>
-#include <errno.h>
-
-#if !defined (errno)
-extern int errno;
-#endif /* !errno */
-
-#if !defined (O_NDELAY) && defined (O_NONBLOCK)
-#  define O_NDELAY O_NONBLOCK  /* Posix style */
-#endif
-
-/* Return >= 1 if select/FIONREAD indicates data available for reading on
-   file descriptor FD; 0 if no data available.  Return -1 on error. */
-int
-input_avail (fd)
-     int fd;
-{
-  int result, chars_avail;
-#if defined(HAVE_SELECT)
-  fd_set readfds, exceptfds;
-  struct timeval timeout;
-#endif
-
-  if (fd < 0)
-    return -1;
-
-  chars_avail = 0;
-
-#if defined (HAVE_SELECT)
-  FD_ZERO (&readfds);
-  FD_ZERO (&exceptfds);
-  FD_SET (fd, &readfds);
-  FD_SET (fd, &exceptfds);
-  timeout.tv_sec = 0;
-  timeout.tv_usec = 0;
-  result = select (fd + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout);
-  return ((result <= 0) ? 0 : 1);
-
-#endif
-
-  result = -1;
-#if defined (FIONREAD)
-  errno = 0;
-  result = ioctl (fd, FIONREAD, &chars_avail);
-  if (result == -1 && errno == EIO)
-    return -1;
-  return (chars_avail);
-#endif
-
-  return 0;
-}
diff --git a/lib/sh/mbscasecmp.c~ b/lib/sh/mbscasecmp.c~
deleted file mode 100644 (file)
index bd6e44a..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/* mbscasecmp - case-insensitive multibyte string comparison. */
-
-/* Copyright (C) 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/>.
-*/
-
-#include <config.h>
-
-#if !defined (HAVE_MBSCASECMP) && defined (HANDLE_MULTIBYTE)
-
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-
-#include <wchar.h>
-#include <wctype.h>
-
-/* Compare MBS1 and MBS2.  */
-int
-mbscasecmp (mbs1, mbs2)
-    const char *mbs1;
-    const char *mbs2;
-{
-  int len1, len2;
-  wchar_t c1, c2, l1, l2;
-
-  len1 = len2 = 0;
-  /* Reset multibyte characters to their initial state.         */
-  (void) mblen ((char *) NULL, 0);
-
-  do
-    {
-      len1 = mbtowc (&c1, mbs1, MB_CUR_MAX);
-      len2 = mbtowc (&c2, mbs2, MB_CUR_MAX);
-
-      if (len1 == 0)
-       return len2 == 0 ? 0 : -1;
-      else if (len2 == 0)
-       return 1;
-      else if (len1 > 0 && len2 < 0)
-        return -1;
-      else if (len1 < 0 && len2 > 0)
-        return 1;
-      else if (len1 < 0 && len2 < 0)
-       {
-         len1 = strlen (mbs1);
-         len2 = strlen (mbs2);
-         return (len1 == len2 ? memcmp (mbs1, mbs2, len1)
-                              : ((len1 < len2) ? (memcmp (mbs1, mbs2, len1) > 0 ? 1 : -1)
-                                               : (memcmp (mbs1, mbs2, len2) >= 0 ? 1 : -1)));
-       }
-
-      l1 = towlower (c1);
-      l2 = towlower (c2);
-      mbs1 += len1;
-      mbs2 += len2;
-    }
-  while (l1 == l2);
-
-  return l1 - l2;
-}
-
-#endif
diff --git a/lib/sh/mbschr.c~ b/lib/sh/mbschr.c~
deleted file mode 100644 (file)
index 58b4641..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/* xstrchr.c - strchr(3) that handles multibyte characters. */
-
-/* Copyright (C) 2002 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>
-
-#ifdef HAVE_STDLIB_H
-#  include <stdlib.h>
-#endif
-
-#include "bashansi.h"
-#include "shmbutil.h"
-
-#undef xstrchr
-
-/* In some locales, the non-first byte of some multibyte characters have
-   the same value as some ascii character.  Faced with these strings, a
-   legacy strchr() might return the wrong value. */
-
-char *
-#if defined (PROTOTYPES)
-xstrchr (const char *s, int c)
-#else
-xstrchr (s, c)
-     const char *s;
-     int c;
-#endif
-{
-#if HANDLE_MULTIBYTE
-  char *pos;
-  mbstate_t state;
-  size_t strlength, mblength;
-
-  /* The locale encodings with said weird property are BIG5, BIG5-HKSCS,
-     GBK, GB18030, SHIFT_JIS, and JOHAB.  They exhibit the problem only
-     when c >= 0x30.  We can therefore use the faster bytewise search if
-     c <= 0x30. */
-  if ((unsigned char)c >= '0' && MB_CUR_MAX > 1)
-    {
-      pos = (char *)s;
-      memset (&state, '\0', sizeof(mbstate_t));
-      strlength = strlen (s);
-
-      while (strlength > 0)
-       {
-         mblength = mbrlen (pos, strlength, &state);
-         if (mblength == (size_t)-2 || mblength == (size_t)-1 || mblength == (size_t)0)
-           mblength = 1;
-
-         if (mblength == 1 && c == (unsigned char)*pos)
-           return pos;
-
-         strlength -= mblength;
-         pos += mblength;
-       }
-
-      return ((char *)NULL);
-    }
-  else
-#endif
-  return (strchr (s, c));
-}
diff --git a/lib/sh/mbscmp.c~ b/lib/sh/mbscmp.c~
deleted file mode 100644 (file)
index e6cf951..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/* mbscmp - multibyte string comparison. */
-
-/* Copyright (C) 1995 Free Software Foundation, Inc.
-
-   This file is part of GNU Bash, the Bourne Again SHell.
-
-   Bash is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   Bash is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with Bash.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <config.h>
-
-#if !defined (HAVE_MBSCMP) && defined (HANDLE_MULTIBYTE)
-
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-
-/* Compare MBS1 and MBS2.  */
-int
-mbscmp (mbs1, mbs2)
-    const char *mbs1;
-    const char *mbs2;
-{
-  int len1, len2;
-  wchar_t c1, c2;
-
-  len1 = len2 = 0;
-  /* Reset multibyte characters to their initial state.         */
-  (void) mblen ((char *) NULL, 0);
-
-  do
-    {
-      len1 = mbtowc ((wchar_t *) &c1, mbs1, MB_CUR_MAX);
-      len2 = mbtowc ((wchar_t *) &c2, mbs2, MB_CUR_MAX);
-
-      if (len1 == 0)
-       return len2 == 0 ? 0 : -1;
-      else if (len2 == 0)
-       return 1;
-      else if (len1 > 0 && len2 < 0)
-        return -1;
-      else if (len1 < 0 && len2 > 0)
-        return 1;
-      else if (len1 < 0 && len2 < 0)
-       {
-         len1 = strlen (mbs1);
-         len2 = strlen (mbs2);
-         return (len1 == len2 ? memcmp (mbs1, mbs2, len1)
-                              : ((len1 < len2) ? (memcmp (mbs1, mbs2, len1) > 0 ? 1 : -1)
-                                               : (memcmp (mbs1, mbs2, len2) >= 0 ? 1 : -1)));
-       }
-
-      mbs1 += len1;
-      mbs2 += len2;
-    }
-  while (c1 == c2);
-
-  return c1 - c2;
-}
-
-#endif
diff --git a/lib/sh/snprintf.c~ b/lib/sh/snprintf.c~
deleted file mode 100644 (file)
index 868d87a..0000000
+++ /dev/null
@@ -1,2171 +0,0 @@
-/* snprintf - formatted output to strings, with bounds checking and allocation */
-
-/*
- build a test version with
-   gcc -g -DDRIVER -I../.. -I../../include -o test-snprintf snprintf.c fmtu*long.o
-*/
-/*
-   Unix snprintf implementation.
-   derived from inetutils/libinetutils/snprintf.c Version 1.1
-
-   Copyright (C) 2001,2006 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/>.
-   
-   Revision History:
-
-   1.1:
-      *  added changes from Miles Bader
-      *  corrected a bug with %f
-      *  added support for %#g
-      *  added more comments :-)
-   1.0:
-      *  supporting must ANSI syntaxic_sugars
-   0.0:
-      *  support %s %c %d
-
- THANKS(for the patches and ideas):
-     Miles Bader
-     Cyrille Rustom
-     Jacek Slabocewiz
-     Mike Parker(mouse)
-
-*/
-
-/*
- * Currently doesn't handle (and bash/readline doesn't use):
- *     * *M$ width, precision specifications
- *     * %N$ numbered argument conversions
- *     * inf, nan floating values imperfect (if isinf(), isnan() not in libc)
- *     * support for `F' is imperfect with ldfallback(), since underlying
- *       printf may not handle it -- should ideally have another autoconf test
- */
-
-#define FLOATING_POINT
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-/* GCC 4.2 on Snow Leopard doesn't like the snprintf prototype */
-#if defined(DEBUG) && !defined (MACOSX)
-#  undef HAVE_SNPRINTF
-#  undef HAVE_ASPRINTF
-
-#  define HAVE_SNPRINTF 0
-#  define HAVE_ASPRINTF 0
-#endif
-
-#if defined(DRIVER) && !defined(HAVE_CONFIG_H)
-#define HAVE_LONG_LONG
-#define HAVE_LONG_DOUBLE
-#ifdef __linux__
-#define HAVE_PRINTF_A_FORMAT
-#endif
-#define HAVE_ISINF_IN_LIBC
-#define HAVE_ISNAN_IN_LIBC
-#define PREFER_STDARG
-#define HAVE_STRINGIZE
-#define HAVE_LIMITS_H
-#define HAVE_STDDEF_H
-#define HAVE_LOCALE_H
-#define intmax_t long
-#endif
-
-#if !HAVE_SNPRINTF || !HAVE_ASPRINTF
-
-#include <bashtypes.h>
-
-#if defined(PREFER_STDARG)
-#  include <stdarg.h>
-#else
-#  include <varargs.h>
-#endif
-
-#ifdef HAVE_LIMITS_H
-#  include <limits.h>
-#endif
-#include <bashansi.h>
-#ifdef HAVE_STDDEF_H
-#  include <stddef.h>
-#endif
-#include <chartypes.h>
-
-#ifdef HAVE_STDINT_H
-#  include <stdint.h>
-#endif
-
-#ifdef FLOATING_POINT
-#  include <float.h>   /* for manifest constants */
-#  include <stdio.h>   /* for sprintf */
-#endif
-
-#include <typemax.h>
-
-#ifdef HAVE_LOCALE_H
-#  include <locale.h>
-#endif
-
-#include "stdc.h"
-#include <shmbutil.h>
-
-#ifndef DRIVER
-#  include "shell.h"
-#else
-#  define FL_PREFIX     0x01    /* add 0x, 0X, or 0 prefix as appropriate */
-#  define FL_ADDBASE    0x02    /* add base# prefix to converted value */
-#  define FL_HEXUPPER   0x04    /* use uppercase when converting to hex */
-#  define FL_UNSIGNED   0x08    /* don't add any sign */
-extern char *fmtulong __P((unsigned long int, int, char *, size_t, int));
-extern char *fmtullong __P((unsigned long long int, int, char *, size_t, int));
-#endif
-
-#ifndef FREE
-#  define FREE(x)      if (x) free (x)
-#endif
-
-/* Bound on length of the string representing an integer value of type T.
-   Subtract one for the sign bit if T is signed;
-   302 / 1000 is log10 (2) rounded up;
-   add one for integer division truncation;
-   add one more for a minus sign if t is signed.  */
-#define INT_STRLEN_BOUND(t) \
-  ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 \
-     + 1 + TYPE_SIGNED (t))
-
-/* conversion flags */
-#define PF_ALTFORM     0x00001         /* # */
-#define PF_HEXPREFIX   0x00002         /* 0[Xx] */
-#define PF_LADJUST     0x00004         /* - */
-#define PF_ZEROPAD     0x00008         /* 0 */
-#define PF_PLUS                0x00010         /* + */
-#define PF_SPACE       0x00020         /* ' ' */
-#define PF_THOUSANDS   0x00040         /* ' */
-
-#define PF_DOT         0x00080         /* `.precision' */
-#define PF_STAR_P      0x00100         /* `*' after precision */
-#define PF_STAR_W      0x00200         /* `*' before or without precision */
-
-/* length modifiers */
-#define PF_SIGNEDCHAR  0x00400         /* hh */
-#define PF_SHORTINT    0x00800         /* h */
-#define PF_LONGINT     0x01000         /* l */
-#define PF_LONGLONG    0x02000         /* ll */
-#define PF_LONGDBL     0x04000         /* L */
-#define PF_INTMAX_T    0x08000         /* j */
-#define PF_SIZE_T      0x10000         /* z */
-#define PF_PTRDIFF_T   0x20000         /* t */
-
-#define PF_ALLOCBUF    0x40000         /* for asprintf, vasprintf */
-
-#define PFM_SN         0x01            /* snprintf, vsnprintf */
-#define PFM_AS         0x02            /* asprintf, vasprintf */
-
-#define ASBUFSIZE      128
-
-#define x_digs "0123456789abcdef"
-#define X_digs "0123456789ABCDEF"
-
-static char intbuf[INT_STRLEN_BOUND(unsigned long) + 1];
-
-static int decpoint;
-static int thoussep;
-static char *grouping;
-
-/* 
- * For the FLOATING POINT FORMAT :
- *  the challenge was finding a way to
- *  manipulate the Real numbers without having
- *  to resort to mathematical function(it
- *  would require to link with -lm) and not
- *  going down to the bit pattern(not portable)
- *
- *  so a number, a real is:
-
-      real = integral + fraction
-
-      integral = ... + a(2)*10^2 + a(1)*10^1 + a(0)*10^0
-      fraction = b(1)*10^-1 + b(2)*10^-2 + ...
-
-      where:
-       0 <= a(i) => 9 
-       0 <= b(i) => 9 
-    from then it was simple math
- */
-
-/*
- * size of the buffer for the integral part
- * and the fraction part 
- */
-#define MAX_INT  99 + 1 /* 1 for the null */
-#define MAX_FRACT 307 + 1
-
-/* 
- * These functions use static buffers to store the results,
- * and so are not reentrant
- */
-#define itoa(n) fmtulong(n, 10, intbuf, sizeof(intbuf), 0);
-#define dtoa(n, p, f) numtoa(n, 10, p, f)
-
-#define SWAP_INT(a,b) {int t; t = (a); (a) = (b); (b) = t;}
-
-#define GETARG(type)   (va_arg(args, type))
-
-/* Macros that do proper sign extension and handle length modifiers.  Used
-   for the integer conversion specifiers. */
-#define GETSIGNED(p) \
-  (((p)->flags & PF_LONGINT) \
-       ? GETARG (long) \
-       : (((p)->flags & PF_SHORTINT) ? (long)(short)GETARG (int) \
-                                     : (long)GETARG (int)))
-
-#define GETUNSIGNED(p) \
-  (((p)->flags & PF_LONGINT) \
-       ? GETARG (unsigned long) \
-       : (((p)->flags & PF_SHORTINT) ? (unsigned long)(unsigned short)GETARG (int) \
-                                     : (unsigned long)GETARG (unsigned int)))
-
-
-#ifdef HAVE_LONG_DOUBLE
-#define GETLDOUBLE(p) GETARG (long double)
-#endif
-#define GETDOUBLE(p) GETARG (double)
-
-#define SET_SIZE_FLAGS(p, type) \
-  if (sizeof (type) > sizeof (int)) \
-    (p)->flags |= PF_LONGINT; \
-  if (sizeof (type) > sizeof (long)) \
-    (p)->flags |= PF_LONGLONG;
-
-/* this struct holds everything we need */
-struct DATA
-{
-  int length;
-  char *base;          /* needed for [v]asprintf */
-  char *holder;
-  int counter;
-  const char *pf;
-
-/* FLAGS */
-  int flags;
-  int justify;
-  int width, precision;
-  char pad;
-};
-
-/* the floating point stuff */
-#ifdef FLOATING_POINT
-static double pow_10 __P((int));
-static int log_10 __P((double));
-static double integral __P((double, double *));
-static char *numtoa __P((double, int, int, char **));
-#endif
-
-static void init_data __P((struct DATA *, char *, size_t, const char *, int));
-static void init_conv_flag __P((struct DATA *));
-
-/* for the format */
-#ifdef FLOATING_POINT
-static void floating __P((struct DATA *, double));
-static void exponent __P((struct DATA *, double));
-#endif
-static void number __P((struct DATA *, unsigned long, int));
-#ifdef HAVE_LONG_LONG
-static void lnumber __P((struct DATA *, unsigned long long, int));
-#endif
-static void pointer __P((struct DATA *, unsigned long));
-static void strings __P((struct DATA *, char *));
-
-#ifdef FLOATING_POINT
-#  define FALLBACK_FMTSIZE     32
-#  define FALLBACK_BASE                4096
-#  define LFALLBACK_BASE       5120
-#  ifdef HAVE_LONG_DOUBLE
-static void ldfallback __P((struct DATA *, const char *, const char *, long double));
-#  endif
-static void dfallback __P((struct DATA *, const char *, const char *, double));
-#endif
-
-static char *groupnum __P((char *));
-
-#ifdef DRIVER
-static void memory_error_and_abort ();
-static void *xmalloc __P((size_t));
-static void *xrealloc __P((void *, size_t));
-static void xfree __P((void *));
-#else
-#  include <xmalloc.h>
-#endif
-
-/* those are defines specific to snprintf to hopefully
- * make the code clearer :-)
- */
-#define RIGHT 1
-#define LEFT  0
-#define NOT_FOUND -1
-#define FOUND 1
-#define MAX_FIELD 15
-
-/* round off to the precision */
-#define ROUND(d, p) \
-           (d < 0.) ? \
-            d - pow_10(-(p)->precision) * 0.5 : \
-            d + pow_10(-(p)->precision) * 0.5
-
-/* set default precision */
-#define DEF_PREC(p) \
-           if ((p)->precision == NOT_FOUND) \
-             (p)->precision = 6
-
-/* put a char.  increment the number of chars written even if we've exceeded
-   the vsnprintf/snprintf buffer size (for the return value) */
-#define PUT_CHAR(c, p) \
-       do \
-         { \
-           if (((p)->flags & PF_ALLOCBUF) && ((p)->counter >= (p)->length - 1)) \
-             { \
-               (p)->length += ASBUFSIZE; \
-               (p)->base = (char *)xrealloc((p)->base, (p)->length); \
-               (p)->holder = (p)->base + (p)->counter; /* in case reallocated */ \
-             } \
-           if ((p)->counter < (p)->length) \
-             *(p)->holder++ = (c); \
-           (p)->counter++; \
-         } \
-       while (0)
-
-/* Output a string.  P->WIDTH has already been adjusted for padding. */
-#define PUT_STRING(string, len, p) \
-       do \
-         { \
-           PAD_RIGHT (p); \
-           while ((len)-- > 0) \
-             { \
-               PUT_CHAR (*(string), (p)); \
-               (string)++; \
-             } \
-           PAD_LEFT (p); \
-         } \
-       while (0)
-
-#define PUT_PLUS(d, p, zero) \
-           if ((d) > zero && (p)->justify == RIGHT) \
-             PUT_CHAR('+', p)
-
-#define PUT_SPACE(d, p, zero) \
-           if (((p)->flags & PF_SPACE) && (d) > zero) \
-             PUT_CHAR(' ', p)
-
-/* pad right */ 
-#define PAD_RIGHT(p) \
-           if ((p)->width > 0 && (p)->justify != LEFT) \
-             for (; (p)->width > 0; (p)->width--) \
-                PUT_CHAR((p)->pad, p)
-
-/* pad left */
-#define PAD_LEFT(p) \
-           if ((p)->width > 0 && (p)->justify == LEFT) \
-             for (; (p)->width > 0; (p)->width--) \
-                PUT_CHAR((p)->pad, p)
-
-/* pad with zeros from decimal precision */
-#define PAD_ZERO(p) \
-       if ((p)->precision > 0) \
-         for (; (p)->precision > 0; (p)->precision--) \
-           PUT_CHAR('0', p)
-
-/* if width and prec. in the args */
-#define STAR_ARGS(p) \
-       do { \
-           if ((p)->flags & PF_STAR_W) \
-             { \
-               (p)->width = GETARG (int); \
-               if ((p)->width < 0) \
-                 { \
-                   (p)->flags |= PF_LADJUST; \
-                   (p)->justify = LEFT; \
-                   (p)->width = -(p)->width; \
-                 } \
-             } \
-           if ((p)->flags & PF_STAR_P) \
-             { \
-               (p)->precision = GETARG (int); \
-               if ((p)->precision < 0) \
-                 { \
-                   (p)->flags &= ~PF_STAR_P; \
-                   (p)->precision = NOT_FOUND; \
-                 } \
-             } \
-       } while (0)
-
-#if defined (HAVE_LOCALE_H) && defined (HAVE_LOCALECONV)
-#  define GETLOCALEDATA(d, t, g) \
-      do \
-       { \
-         struct lconv *lv; \
-         if ((d) == 0) { \
-         (d) = '.'; (t) = -1; (g) = 0; /* defaults */ \
-         lv = localeconv(); \
-         if (lv) \
-           { \
-             if (lv->decimal_point && lv->decimal_point[0]) \
-               (d) = lv->decimal_point[0]; \
-             if (lv->thousands_sep && lv->thousands_sep[0]) \
-               (t) = lv->thousands_sep[0]; \
-             (g) = lv->grouping ? lv->grouping : ""; \
-             if (*(g) == '\0' || *(g) == CHAR_MAX || (t) == -1) (g) = 0; \
-           } \
-         } \
-       } \
-      while (0);
-#else
-#  define GETLOCALEDATA(d, t, g) \
-      ( (d) = '.', (t) = ',', g = "\003" )
-#endif
-
-#ifdef FLOATING_POINT
-/*
- * Find the nth power of 10
- */
-static double
-pow_10(n)
-     int n;
-{ 
-  double P;
-
-  /* handle common cases with fast switch statement. */
-  switch (n)
-    {
-    case -3:   return .001;
-    case -2:   return .01;
-    case -1:   return .1;
-    case 0:    return 1.;
-    case 1:    return 10.;
-    case 2:    return 100.;
-    case 3:    return 1000.;
-    }
-
-  if (n < 0)
-    {
-      P = .0001;
-      for (n += 4; n < 0; n++)
-       P /= 10.;
-    }
-  else
-    {
-      P = 10000.;
-      for (n -= 4; n > 0; n--)
-       P *= 10.;
-    }
-
-  return P;
-}
-
-/*
- * Find the integral part of the log in base 10 
- * Note: this not a real log10()
-        I just need and approximation(integerpart) of x in:
-         10^x ~= r
- * log_10(200) = 2;
- * log_10(250) = 2;
- *
- * NOTE: do not call this with r == 0 -- an infinite loop results.
- */
-static int
-log_10(r)
-     double r;
-{ 
-  int i = 0;
-  double result = 1.;
-
-  if (r < 0.)
-    r = -r;
-
-  if (r < 1.)
-    {
-      while (result >= r)
-       {
-         result /= 10.;
-         i++;
-       }
-      return (-i);
-    }
-  else
-    {
-      while (result <= r)
-       {
-         result *= 10.;
-         i++;
-       }
-      return (i - 1);
-    }
-}
-
-/*
- * This function return the fraction part of a double
- * and set in ip the integral part.
- * In many ways it resemble the modf() found on most Un*x
- */
-static double
-integral(real, ip)
-     double real;
-     double *ip;
-{ 
-  int j;
-  double i, s, p;
-  double real_integral = 0.;
-
-  /* take care of the obvious */
-  /* equal to zero ? */
-  if (real == 0.)
-    {
-      *ip = 0.;
-      return (0.);
-    }
-
-  /* negative number ? */
-  if (real < 0.)
-    real = -real;
-
-  /* a fraction ? */
-  if ( real < 1.)
-    {
-      *ip = 0.;
-      return real;
-    }
-
-  /* the real work :-) */
-  for (j = log_10(real); j >= 0; j--)
-    {
-      p = pow_10(j);
-      s = (real - real_integral)/p;
-      i = 0.;
-      while (i + 1. <= s)
-       i++;
-      real_integral += i*p;
-    }
-  *ip = real_integral;
-  return (real - real_integral);
-}
-
-#define PRECISION 1.e-6
-/* 
- * return an ascii representation of the integral part of the number
- * and set fract to be an ascii representation of the fraction part
- * the container for the fraction and the integral part or staticly
- * declare with fix size 
- */
-static char *
-numtoa(number, base, precision, fract)
-     double number;
-     int base, precision;
-     char **fract;
-{
-  register int i, j;
-  double ip, fp; /* integer and fraction part */
-  double fraction;
-  int digits = MAX_INT - 1;
-  static char integral_part[MAX_INT];
-  static char fraction_part[MAX_FRACT];
-  double sign;
-  int ch;
-
-  /* taking care of the obvious case: 0.0 */
-  if (number == 0.)
-    { 
-      integral_part[0] = '0';
-      integral_part[1] = '\0';
-      /* The fractional part has to take the precision into account */
-      for (ch = 0; ch < precision-1; ch++)
-       fraction_part[ch] = '0';
-      fraction_part[ch] = '0';
-      fraction_part[ch+1] = '\0';
-      if (fract)
-       *fract = fraction_part;
-      return integral_part;
-    }
-
-  /* for negative numbers */
-  if ((sign = number) < 0.)
-    {
-      number = -number;
-      digits--; /* sign consume one digit */
-    }
-
-  fraction = integral(number, &ip);
-  number = ip;
-
-  /* do the integral part */
-  if (ip == 0.)
-    {
-      integral_part[0] = '0';
-      i = 1;
-    }
-  else
-    {
-      for ( i = 0; i < digits && number != 0.; ++i)
-       {
-         number /= base;
-         fp = integral(number, &ip);
-         ch = (int)((fp + PRECISION)*base); /* force to round */
-         integral_part[i] = (ch <= 9) ? ch + '0' : ch + 'a' - 10;
-         if (! ISXDIGIT((unsigned char)integral_part[i]))
-           break;      /* bail out overflow !! */
-         number = ip;
-        }
-    }
-     
-  /* Oh No !! out of bound, ho well fill it up ! */
-  if (number != 0.)
-    for (i = 0; i < digits; ++i)
-      integral_part[i] = '9';
-
-  /* put the sign ? */
-  if (sign < 0.)
-    integral_part[i++] = '-';
-
-  integral_part[i] = '\0';
-
-  /* reverse every thing */
-  for ( i--, j = 0; j < i; j++, i--)
-    SWAP_INT(integral_part[i], integral_part[j]);  
-
-  /* the fractional part */
-  for (i=0, fp=fraction; precision > 0 && i < MAX_FRACT ; i++, precision--)
-    {
-      fraction_part[i] = (int)((fp + PRECISION)*10. + '0');
-      if (! DIGIT(fraction_part[i])) /* underflow ? */
-       break;
-      fp = (fp*10.0) - (double)(long)((fp + PRECISION)*10.);
-    }
-  fraction_part[i] = '\0';
-
-  if (fract != (char **)0)
-    *fract = fraction_part;
-
-  return integral_part;
-}
-#endif
-
-/* for %d and friends, it puts in holder
- * the representation with the right padding
- */
-static void
-number(p, d, base)
-     struct DATA *p;
-     unsigned long d;
-     int base;
-{
-  char *tmp, *t;
-  long sd;
-  int flags;
-
-  /* An explicit precision turns off the zero-padding flag. */
-  if ((p->flags & PF_ZEROPAD) && p->precision >= 0 && (p->flags & PF_DOT))
-    p->flags &= ~PF_ZEROPAD;
-
-  sd = d;      /* signed for ' ' padding in base 10 */
-  flags = 0;
-  flags = (*p->pf == 'x' || *p->pf == 'X' || *p->pf == 'o' || *p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0;
-  if (*p->pf == 'X')
-    flags |= FL_HEXUPPER;
-
-  tmp = fmtulong (d, base, intbuf, sizeof(intbuf), flags);
-  t = 0;
-  if ((p->flags & PF_THOUSANDS))
-    {
-      GETLOCALEDATA(decpoint, thoussep, grouping);
-      if (grouping && (t = groupnum (tmp)))
-        tmp = t;
-    }
-
-  p->width -= strlen(tmp);
-  PAD_RIGHT(p);
-
-  if ((p->flags & PF_DOT) && p->precision > 0)
-    {
-      p->precision -= strlen(tmp);
-      PAD_ZERO(p);
-    }
-
-  switch (base)
-    {
-    case 10:
-      PUT_PLUS(sd, p, 0);
-      PUT_SPACE(sd, p, 0);
-      break;
-    case 8:
-      if (p->flags & PF_ALTFORM)
-       PUT_CHAR('0', p);
-      break;
-    case 16:
-      if (p->flags & PF_ALTFORM)
-       {
-         PUT_CHAR('0', p);
-         PUT_CHAR(*p->pf, p);
-       }
-      break;
-    }
-
-  while (*tmp)
-    {
-      PUT_CHAR(*tmp, p);
-      tmp++;
-    }
-
-  PAD_LEFT(p);
-  FREE (t);
-}
-
-#ifdef HAVE_LONG_LONG
-/*
- * identical to number() but works for `long long'
- */
-static void
-lnumber(p, d, base)
-     struct DATA *p;
-     unsigned long long d;
-     int base;
-{
-  char *tmp, *t;
-  long long sd;
-  int flags;
-
-  /* An explicit precision turns off the zero-padding flag. */
-  if ((p->flags & PF_ZEROPAD) && p->precision >= 0 && (p->flags & PF_DOT))
-    p->flags &= ~PF_ZEROPAD;
-
-  sd = d;      /* signed for ' ' padding in base 10 */
-  flags = (*p->pf == 'x' || *p->pf == 'X' || *p->pf == 'o' || *p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0;
-  if (*p->pf == 'X')
-    flags |= FL_HEXUPPER;
-
-  tmp = fmtullong (d, base, intbuf, sizeof(intbuf), flags);
-  t = 0;
-  if ((p->flags & PF_THOUSANDS))
-    {
-      GETLOCALEDATA(decpoint, thoussep, grouping);
-      if (grouping && (t = groupnum (tmp)))
-        tmp = t;
-    }
-
-  p->width -= strlen(tmp);
-  PAD_RIGHT(p);
-
-  if ((p->flags & PF_DOT) && p->precision > 0)
-    {
-      p->precision -= strlen(tmp);
-      PAD_ZERO(p);
-    }
-
-  switch (base)
-    {
-    case 10:
-      PUT_PLUS(sd, p, 0);
-      PUT_SPACE(sd, p, 0);
-      break;
-    case 8:
-      if (p->flags & PF_ALTFORM)
-       PUT_CHAR('0', p);
-      break;
-    case 16:
-      if (p->flags & PF_ALTFORM)
-       {
-         PUT_CHAR('0', p);
-         PUT_CHAR(*p->pf, p);
-       }
-      break;
-    }
-
-  while (*tmp)
-    {
-      PUT_CHAR(*tmp, p);
-      tmp++;
-    }
-
-  PAD_LEFT(p);
-  FREE (t);
-}
-#endif
-
-static void
-pointer(p, d)
-     struct DATA *p;
-     unsigned long d;
-{
-  char *tmp;
-
-  tmp = fmtulong(d, 16, intbuf, sizeof(intbuf), 0);
-  p->width -= strlen(tmp);
-  PAD_RIGHT(p);
-
-  /* prefix '0x' for pointers */
-  PUT_CHAR('0', p);
-  PUT_CHAR('x', p);
-
-  while (*tmp)
-    {
-      PUT_CHAR(*tmp, p);
-      tmp++;
-    }
-
-  PAD_LEFT(p);
-}
-
-/* %s strings */
-static void
-strings(p, tmp)
-     struct DATA *p;
-     char *tmp;
-{
-  size_t len;
-
-  len = strlen(tmp);
-  if (p->precision != NOT_FOUND) /* the smallest number */
-    len = (len < p->precision ? len : p->precision);
-  p->width -= len;
-
-  PUT_STRING (tmp, len, p);
-}
-
-#if HANDLE_MULTIBYTE
-/* %ls wide-character strings */
-static void
-wstrings(p, tmp)
-     struct DATA *p;
-     wchar_t *tmp;
-{
-  size_t len;
-  mbstate_t mbs;
-  char *os;
-  const wchar_t *ws;
-
-  memset (&mbs, '\0', sizeof (mbstate_t));
-  ws = (const wchar_t *)tmp;
-
-  os = (char *)NULL;
-  if (p->precision != NOT_FOUND)
-    {
-      os = (char *)xmalloc (p->precision + 1);
-      len = wcsrtombs (os, &ws, p->precision, &mbs);
-    }
-  else
-    {
-      len = wcsrtombs (NULL, &ws, 0, &mbs);
-      if (len != (size_t)-1)
-        {
-         memset (&mbs, '\0', sizeof (mbstate_t));
-         os = (char *)xmalloc (len + 1);
-         (void)wcsrtombs (os, &ws, len + 1, &mbs);
-        }
-    }
-  if (len == (size_t)-1)
-    {
-      /* invalid multibyte sequence; bail now. */
-      FREE (os);      
-      return;
-    }
-
-  p->width -= len;
-  PUT_STRING (os, len, p);
-  free (os);
-}
-
-static void
-wchars (p, wc)
-     struct DATA *p;
-     wint_t wc;
-{
-  char *lbuf, *l;
-  mbstate_t mbs;
-  size_t len;
-
-  lbuf = (char *)malloc (MB_CUR_MAX+1);
-  if (lbuf == 0)
-    return;
-  memset (&mbs, '\0', sizeof (mbstate_t));
-  len = wcrtomb (lbuf, wc, &mbs);
-  if (len == (size_t)-1)
-    /* conversion failed; bail now. */
-    return;
-  p->width -= len;
-  l = lbuf;
-  PUT_STRING (l, len, p);
-  free (lbuf);
-}
-#endif /* HANDLE_MULTIBYTE */
-
-#ifdef FLOATING_POINT
-
-#ifndef HAVE_ISINF_IN_LIBC
-/* Half-assed versions, since we don't want to link with libm. */
-static int
-isinf(d)
-     double d;
-{
-#ifdef DBL_MAX
-  if (d < DBL_MIN)
-    return -1;
-  else if (d > DBL_MAX)
-    return 1;
-  else
-#endif
-    return 0;
-}
-#endif
-
-#ifndef HAVE_ISNAN_IN_LIBC
-static int
-isnan(d)
-     double d;
-{
-  return 0;
-}
-#endif
-
-/* Check for [+-]infinity and NaN.  If MODE == 1, we check for Infinity, else
-   (mode == 2) we check for NaN.  This does the necessary printing.  Returns
-   1 if Inf or Nan, 0 if not. */
-static int
-chkinfnan(p, d, mode)
-     struct DATA *p;
-     double d;
-     int mode;         /* == 1 for inf, == 2 for nan */
-{
-  int i;
-  char *tmp;
-  char *big, *small;
-
-  i = (mode == 1) ? isinf(d) : isnan(d);
-  if (i == 0)
-    return 0;
-  big = (mode == 1) ? "INF" : "NAN";
-  small = (mode == 1) ? "inf" : "nan";
-
-  tmp = (*p->pf == 'F' || *p->pf == 'G' || *p->pf == 'E') ? big : small;
-
-  if (i < 0)
-    PUT_CHAR('-', p);
-
-  while (*tmp)
-    {
-      PUT_CHAR (*tmp, p);
-      tmp++;
-    }
-
-  return 1;
-}
-
-/* %f %F %g %G floating point representation */
-static void
-floating(p, d)
-     struct DATA *p;
-     double d;
-{
-  char *tmp, *tmp2, *t;
-  int i;
-
-  if (d != 0 && (chkinfnan(p, d, 1) || chkinfnan(p, d, 2)))
-    return;    /* already printed nan or inf */
-
-  GETLOCALEDATA(decpoint, thoussep, grouping);
-  DEF_PREC(p);
-  d = ROUND(d, p);
-  tmp = dtoa(d, p->precision, &tmp2);
-  t = 0;
-  if ((p->flags & PF_THOUSANDS) && grouping && (t = groupnum (tmp)))
-    tmp = t;
-
-  if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0)
-    {
-      /* smash the trailing zeros unless altform */
-      for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--)
-        tmp2[i] = '\0'; 
-      if (tmp2[0] == '\0')
-       p->precision = 0;
-    }
-
-  /* calculate the padding. 1 for the dot */
-  p->width = p->width -
-           ((d > 0. && p->justify == RIGHT) ? 1:0) -
-           ((p->flags & PF_SPACE) ? 1:0) -
-           strlen(tmp) - p->precision -
-           ((p->precision != 0 || (p->flags & PF_ALTFORM)) ? 1 : 0);   /* radix char */
-  PAD_RIGHT(p);  
-  PUT_PLUS(d, p, 0.);
-  PUT_SPACE(d, p, 0.);
-
-  while (*tmp)
-    {
-      PUT_CHAR(*tmp, p);       /* the integral */
-      tmp++;
-    }
-  FREE (t);
-
-  if (p->precision != 0 || (p->flags & PF_ALTFORM))
-    PUT_CHAR(decpoint, p);  /* put the '.' */
-
-  for (; *tmp2; tmp2++)
-    PUT_CHAR(*tmp2, p); /* the fraction */
-  
-  PAD_LEFT(p);
-} 
-
-/* %e %E %g %G exponent representation */
-static void
-exponent(p, d)
-     struct DATA *p;
-     double d;
-{
-  char *tmp, *tmp2;
-  int j, i;
-
-  if (d != 0 && (chkinfnan(p, d, 1) || chkinfnan(p, d, 2)))
-    return;    /* already printed nan or inf */
-
-  GETLOCALEDATA(decpoint, thoussep, grouping);
-  DEF_PREC(p);
-  if (d == 0.)
-    j = 0;
-  else
-    {
-      j = log_10(d);
-      d = d / pow_10(j);  /* get the Mantissa */
-      d = ROUND(d, p);           
-    }
-  tmp = dtoa(d, p->precision, &tmp2);
-
-  /* 1 for unit, 1 for the '.', 1 for 'e|E',
-   * 1 for '+|-', 2 for 'exp' */
-  /* calculate how much padding need */
-  p->width = p->width - 
-            ((d > 0. && p->justify == RIGHT) ? 1:0) -
-            ((p->flags & PF_SPACE) ? 1:0) - p->precision - 6;
-
-  PAD_RIGHT(p);
-  PUT_PLUS(d, p, 0.);
-  PUT_SPACE(d, p, 0.);
-
-  while (*tmp)
-    {
-      PUT_CHAR(*tmp, p);
-      tmp++;
-    }
-
-  if (p->precision != 0 || (p->flags & PF_ALTFORM))
-      PUT_CHAR(decpoint, p);  /* the '.' */
-
-  if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0)
-    /* smash the trailing zeros unless altform */
-    for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--)
-      tmp2[i] = '\0'; 
-
-  for (; *tmp2; tmp2++)
-    PUT_CHAR(*tmp2, p); /* the fraction */
-
-  /* the exponent put the 'e|E' */
-  if (*p->pf == 'g' || *p->pf == 'e')
-    PUT_CHAR('e', p);
-  else
-    PUT_CHAR('E', p);
-
-  /* the sign of the exp */
-  if (j >= 0)
-    PUT_CHAR('+', p);
-  else
-    {
-      PUT_CHAR('-', p);
-      j = -j;
-    }
-
-   tmp = itoa(j);
-   /* pad out to at least two spaces.  pad with `0' if the exponent is a
-      single digit. */
-   if (j <= 9)
-     PUT_CHAR('0', p);
-
-   /* the exponent */
-   while (*tmp)
-     {
-       PUT_CHAR(*tmp, p);
-       tmp++;
-     }
-
-   PAD_LEFT(p);
-}
-#endif
-
-/* Return a new string with the digits in S grouped according to the locale's
-   grouping info and thousands separator.  If no grouping should be performed,
-   this returns NULL; the caller needs to check for it. */
-static char *
-groupnum (s)
-     char *s;
-{
-  char *se, *ret, *re, *g;
-  int len, slen;
-
-  if (grouping == 0 || *grouping <= 0 || *grouping == CHAR_MAX)
-    return ((char *)NULL);
-
-  /* find min grouping to size returned string */
-  for (len = *grouping, g = grouping; *g; g++)
-      if (*g > 0 && *g < len)
-       len = *g;
-
-  slen = strlen (s);
-  len = slen / len + 1;
-  ret = (char *)xmalloc (slen + len + 1);
-  re = ret + slen + len;
-  *re = '\0';
-
-  g = grouping;
-  se = s + slen;
-  len = *g;
-
-  while (se > s)
-    {
-      *--re = *--se;
-
-      /* handle `-' inserted by numtoa() and the fmtu* family here. */
-      if (se > s && se[-1] == '-')
-       continue;
-
-      /* begin new group. */
-      if (--len == 0 && se > s)
-       {
-         *--re = thoussep;
-         len = *++g;           /* was g++, but that uses first char twice (glibc bug, too) */
-         if (*g == '\0')
-           len = *--g;         /* use previous grouping */
-         else if (*g == CHAR_MAX)
-           {
-             do
-               *--re = *--se;
-             while (se > s);
-             break;
-           }
-       }
-    }
-
-  if (re > ret)
-#ifdef HAVE_MEMMOVE
-    memmove (ret, re, strlen (re) + 1);
-#else
-    strcpy (ret, re);
-#endif
-   
-  return ret;
-}
-
-/* initialize the conversion specifiers */
-static void
-init_conv_flag (p)
-     struct DATA *p;
-{
-  p->flags &= PF_ALLOCBUF;             /* preserve PF_ALLOCBUF flag */
-  p->precision = p->width = NOT_FOUND;
-  p->justify = NOT_FOUND;
-  p->pad = ' ';
-}
-
-static void
-init_data (p, string, length, format, mode)
-     struct DATA *p;
-     char *string;
-     size_t length;
-     const char *format;
-     int mode;
-{
-  p->length = length - 1; /* leave room for '\0' */
-  p->holder = p->base = string;
-  p->pf = format;
-  p->counter = 0;
-  p->flags = (mode == PFM_AS) ? PF_ALLOCBUF : 0;
-}
-
-static int
-#if defined (__STDC__)
-vsnprintf_internal(struct DATA *data, char *string, size_t length, const char *format, va_list args)
-#else
-vsnprintf_internal(data, string, length, format, args)
-     struct DATA *data;
-     char *string;
-     size_t length;
-     const char *format;
-     va_list args;
-#endif
-{
-  double d; /* temporary holder */
-#ifdef HAVE_LONG_DOUBLE
-  long double ld;      /* for later */
-#endif
-  unsigned long ul;
-#ifdef HAVE_LONG_LONG
-  unsigned long long ull;
-#endif
-  int state, i, c, n;
-  char *s;
-#if HANDLE_MULTIBYTE
-  wchar_t *ws;
-  wint_t wc;
-#endif
-  const char *convstart;
-  int negprec;
-
-  /* Sanity check, the string length must be >= 0.  C99 actually says that
-     LENGTH can be zero here, in the case of snprintf/vsnprintf (it's never
-     0 in the case of asprintf/vasprintf), and the return value is the number
-     of characters that would have been written. */
-  if (length < 0)
-    return -1;
-
-  if (format == 0)
-    return 0;
-
-  /* Reset these for each call because the locale might have changed. */
-  decpoint = thoussep = 0;
-  grouping = 0;
-
-  negprec = 0;
-  for (; c = *(data->pf); data->pf++)
-    {
-      if (c != '%')
-       {
-         PUT_CHAR (c, data);
-         continue;
-       }
-
-      convstart = data->pf;
-      init_conv_flag (data); /* initialise format flags */
-
-      state = 1;
-      for (state = 1; state && *data->pf; )
-       {
-         c = *(++data->pf);
-             /* fmtend = data->pf */
-#if defined (FLOATING_POINT) && defined (HAVE_LONG_DOUBLE)
-         if (data->flags & PF_LONGDBL)
-           {
-             switch (c)
-               {
-               case 'f': case 'F':
-               case 'e': case 'E':
-               case 'g': case 'G':
-#  ifdef HAVE_PRINTF_A_FORMAT
-               case 'a': case 'A':
-#  endif
-                 STAR_ARGS (data);
-                 ld = GETLDOUBLE (data);
-                 ldfallback (data, convstart, data->pf, ld);
-                 goto conv_break;
-               }
-           }
-#endif /* FLOATING_POINT && HAVE_LONG_DOUBLE */
-
-         switch (c)
-           {
-             /* Parse format flags */
-             case '\0': /* a NULL here ? ? bail out */
-               *data->holder = '\0';
-               return data->counter;
-               break;
-             case '#':
-               data->flags |= PF_ALTFORM;
-               continue;
-             case '0':
-               data->flags |= PF_ZEROPAD;
-               data->pad = '0';
-               continue;
-             case '*':
-               if (data->flags & PF_DOT)
-                 data->flags |= PF_STAR_P;
-               else
-                 data->flags |= PF_STAR_W;
-               continue;
-             case '-':
-               if ((data->flags & PF_DOT) == 0)
-                 {
-                   data->flags |= PF_LADJUST;
-                   data->justify = LEFT;
-                 }
-               else
-                 negprec = 1;
-               continue;
-             case ' ':
-               if ((data->flags & PF_PLUS) == 0)
-                 data->flags |= PF_SPACE;
-               continue;
-             case '+':
-               if ((data->flags & PF_DOT) == 0)
-                 {
-                   data->flags |= PF_PLUS;
-                   data->justify = RIGHT;
-                 }
-               continue;
-             case '\'':
-               data->flags |= PF_THOUSANDS;
-               continue;
-
-             case '1': case '2': case '3':
-             case '4': case '5': case '6':
-             case '7': case '8': case '9':
-               n = 0;
-               do
-                 {
-                   n = n * 10 + TODIGIT(c);
-                   c = *(++data->pf);
-                 }
-               while (DIGIT(c));
-               data->pf--;             /* went too far */
-               if (n < 0)
-                 n = 0;
-               if (data->flags & PF_DOT)
-                 data->precision = negprec ? NOT_FOUND : n;
-               else
-                 data->width = n;
-               continue;
-
-             /* optional precision */
-             case '.':
-               data->flags |= PF_DOT;
-               data->precision = 0;
-               continue;
-
-             /* length modifiers */
-             case 'h':
-               data->flags |= (data->flags & PF_SHORTINT) ? PF_SIGNEDCHAR : PF_SHORTINT;
-               continue;
-             case 'l':
-               data->flags |= (data->flags & PF_LONGINT) ? PF_LONGLONG : PF_LONGINT;
-               continue;
-             case 'L':
-               data->flags |= PF_LONGDBL;
-               continue;
-             case 'q':
-               data->flags |= PF_LONGLONG;
-               continue;
-             case 'j':
-               data->flags |= PF_INTMAX_T;
-               SET_SIZE_FLAGS(data, intmax_t);
-               continue;
-             case 'z':
-               data->flags |= PF_SIZE_T;
-               SET_SIZE_FLAGS(data, size_t);
-               continue;
-             case 't':
-               data->flags |= PF_PTRDIFF_T;
-               SET_SIZE_FLAGS(data, ptrdiff_t);
-               continue;
-               
-             /* Conversion specifiers */
-#ifdef FLOATING_POINT
-             case 'f':  /* float, double */
-             case 'F':
-               STAR_ARGS(data);
-               d = GETDOUBLE(data);
-               floating(data, d);
-conv_break:            
-               state = 0;
-               break;
-             case 'g': 
-             case 'G':
-               STAR_ARGS(data);
-               DEF_PREC(data);
-               d = GETDOUBLE(data);
-               i = (d != 0.) ? log_10(d) : -1;
-               /*
-                * for '%g|%G' ANSI: use f if exponent
-                * is in the range or [-4,p] exclusively
-                * else use %e|%E
-                */
-               if (-4 < i && i < data->precision)
-                 {
-                   /* reset precision */
-                   data->precision -= i + 1;
-                   floating(data, d);
-                 }
-               else
-                 {
-                   /* reduce precision by 1 because of leading digit before
-                      decimal point in e format. */
-                   data->precision--;
-                   exponent(data, d);
-                 }
-               state = 0;
-               break;
-             case 'e':
-             case 'E':  /* Exponent double */
-               STAR_ARGS(data);
-               d = GETDOUBLE(data);
-               exponent(data, d);
-               state = 0;
-               break;
-#  ifdef HAVE_PRINTF_A_FORMAT
-             case 'a':
-             case 'A':
-               STAR_ARGS(data);
-               d = GETDOUBLE(data);
-               dfallback(data, convstart, data->pf, d);
-               state = 0;
-               break;
-#  endif /* HAVE_PRINTF_A_FORMAT */
-#endif /* FLOATING_POINT */
-             case 'U':
-               data->flags |= PF_LONGINT;
-               /* FALLTHROUGH */
-             case 'u':
-               STAR_ARGS(data);
-#ifdef HAVE_LONG_LONG
-               if (data->flags & PF_LONGLONG)
-                 {
-                   ull = GETARG (unsigned long long);
-                   lnumber(data, ull, 10);
-                 }
-               else
-#endif
-                 {
-                   ul = GETUNSIGNED(data);
-                   number(data, ul, 10);
-                 }
-               state = 0;
-               break;
-             case 'D':
-               data->flags |= PF_LONGINT;
-               /* FALLTHROUGH */
-             case 'd':  /* decimal */
-             case 'i':
-               STAR_ARGS(data);
-#ifdef HAVE_LONG_LONG
-               if (data->flags & PF_LONGLONG)
-                 {
-                   ull = GETARG (long long);
-                   lnumber(data, ull, 10);
-                 }
-               else
-#endif
-                 {
-                   ul = GETSIGNED(data);
-                   number(data, ul, 10);
-                 }
-               state = 0;
-               break;
-             case 'o':  /* octal */
-               STAR_ARGS(data);
-#ifdef HAVE_LONG_LONG
-               if (data->flags & PF_LONGLONG)
-                 {
-                   ull = GETARG (unsigned long long);
-                   lnumber(data, ull, 8);
-                 }
-               else
-#endif
-                 {
-                   ul = GETUNSIGNED(data);
-                   number(data, ul, 8);
-                 }
-               state = 0;
-               break;
-             case 'x': 
-             case 'X':  /* hexadecimal */
-               STAR_ARGS(data);
-#ifdef HAVE_LONG_LONG
-               if (data->flags & PF_LONGLONG)
-                 {
-                   ull = GETARG (unsigned long long);
-                   lnumber(data, ull, 16);
-                 }
-               else
-#endif
-                 {
-                   ul = GETUNSIGNED(data);
-                   number(data, ul, 16);
-                 }
-               state = 0;
-               break;
-             case 'p':
-               STAR_ARGS(data);
-               ul = (unsigned long)GETARG (void *);
-               pointer(data, ul);
-               state = 0;
-               break;
-#if HANDLE_MULTIBYTE
-             case 'C':
-               data->flags |= PF_LONGINT;
-               /* FALLTHROUGH */
-#endif
-             case 'c': /* character */
-               STAR_ARGS(data);
-#if HANDLE_MULTIBYTE
-               if (data->flags & PF_LONGINT)
-                 {
-                   wc = GETARG (wint_t);
-                   wchars (data, wc);
-                 }
-               else
-#endif
-                 {             
-                   ul = GETARG (int);
-                   PUT_CHAR(ul, data);
-                 }
-               state = 0;
-               break;
-#if HANDLE_MULTIBYTE
-             case 'S':
-               data->flags |= PF_LONGINT;
-               /* FALLTHROUGH */
-#endif
-             case 's':  /* string */
-               STAR_ARGS(data);
-#if HANDLE_MULTIBYTE
-               if (data->flags & PF_LONGINT)
-                 {
-                   ws = GETARG (wchar_t *);
-                   wstrings (data, ws);
-                 }
-               else
-#endif
-                 {
-                   s = GETARG (char *);
-                   strings(data, s);
-                 }
-               state = 0;
-               break;
-             case 'n':
-#ifdef HAVE_LONG_LONG
-               if (data->flags & PF_LONGLONG)
-                 *(GETARG (long long *)) = data->counter;
-               else
-#endif
-               if (data->flags & PF_LONGINT)
-                 *(GETARG (long *)) = data->counter;
-               else if (data->flags & PF_SHORTINT)
-                 *(GETARG (short *)) = data->counter;
-               else
-                 *(GETARG (int *)) = data->counter;
-               state = 0;
-               break;
-             case '%':  /* nothing just % */
-               PUT_CHAR('%', data);
-               state = 0;
-               break;
-             default:
-               /* is this an error ? maybe bail out */
-               state = 0;
-               break;
-       } /* end switch */
-      } /* end of `%' for loop */
-    } /* end of format string for loop */
-
-  if (data->length >= 0)
-    *data->holder = '\0'; /* the end ye ! */
-
-  return data->counter;
-}
-
-#if defined (FLOATING_POINT) && defined (HAVE_LONG_DOUBLE)
-/*
- * Printing floating point numbers accurately is an art.  I'm not good
- * at it.  Fall back to sprintf for long double formats.
- */
-static void
-ldfallback (data, fs, fe, ld)
-     struct DATA *data;
-     const char *fs, *fe;
-     long double ld;
-{
-  register char *x;
-  char fmtbuf[FALLBACK_FMTSIZE], *obuf;
-  int fl;
-
-  fl = LFALLBACK_BASE + (data->precision < 6 ? 6 : data->precision) + 2;
-  obuf = (char *)xmalloc (fl);
-  fl = fe - fs + 1;
-  strncpy (fmtbuf, fs, fl);
-  fmtbuf[fl] = '\0';
-
-  if ((data->flags & PF_STAR_W) && (data->flags & PF_STAR_P))
-    sprintf (obuf, fmtbuf, data->width, data->precision, ld);
-  else if (data->flags & PF_STAR_W)
-    sprintf (obuf, fmtbuf, data->width, ld);
-  else if (data->flags & PF_STAR_P)
-    sprintf (obuf, fmtbuf, data->precision, ld);
-  else
-    sprintf (obuf, fmtbuf, ld);
-
-  for (x = obuf; *x; x++)
-    PUT_CHAR (*x, data);    
-  xfree (obuf);
-}
-#endif /* FLOATING_POINT && HAVE_LONG_DOUBLE */
-
-#ifdef FLOATING_POINT
-/* Used for %a, %A if the libc printf supports them. */
-static void
-dfallback (data, fs, fe, d)
-     struct DATA *data;
-     const char *fs, *fe;
-     double d;
-{
-  register char *x;
-  char fmtbuf[FALLBACK_FMTSIZE], obuf[FALLBACK_BASE];
-  int fl;
-
-  fl = fe - fs + 1;
-  strncpy (fmtbuf, fs, fl);
-  fmtbuf[fl] = '\0';
-
-  if ((data->flags & PF_STAR_W) && (data->flags & PF_STAR_P))
-    sprintf (obuf, fmtbuf, data->width, data->precision, d);
-  else if (data->flags & PF_STAR_W)
-    sprintf (obuf, fmtbuf, data->width, d);
-  else if (data->flags & PF_STAR_P)
-    sprintf (obuf, fmtbuf, data->precision, d);
-  else
-    sprintf (obuf, fmtbuf, d);
-
-  for (x = obuf; *x; x++)
-    PUT_CHAR (*x, data);    
-}
-#endif /* FLOATING_POINT */
-
-#if !HAVE_SNPRINTF
-
-int
-#if defined (__STDC__)
-vsnprintf(char *string, size_t length, const char *format, va_list args)
-#else
-vsnprintf(string, length, format, args)
-     char *string;
-     size_t length;
-     const char *format;
-     va_list args;
-#endif
-{
-  struct DATA data;
-
-  if (string == 0 && length != 0)
-    return 0;
-  init_data (&data, string, length, format, PFM_SN);
-  return (vsnprintf_internal(&data, string, length, format, args));
-}
-
-int
-#if defined(PREFER_STDARG)
-snprintf(char *string, size_t length, const char * format, ...)
-#else
-snprintf(string, length, format, va_alist)
-     char *string;
-     size_t length;
-     const char *format;
-     va_dcl
-#endif
-{
-  struct DATA data;
-  int rval;
-  va_list args;
-
-  SH_VA_START(args, format);
-
-  if (string == 0 && length != 0)
-    return 0;
-  init_data (&data, string, length, format, PFM_SN);
-  rval = vsnprintf_internal (&data, string, length, format, args);
-
-  va_end(args);
-
-  return rval;
-}
-
-#endif /* HAVE_SNPRINTF */
-
-#if !HAVE_ASPRINTF
-
-int
-#if defined (__STDC__)
-vasprintf(char **stringp, const char *format, va_list args)
-#else
-vasprintf(stringp, format, args)
-     char **stringp;
-     const char *format;
-     va_list args;
-#endif
-{
-  struct DATA data;
-  char *string;
-  int r;
-
-  string = (char *)xmalloc(ASBUFSIZE);
-  init_data (&data, string, ASBUFSIZE, format, PFM_AS);
-  r = vsnprintf_internal(&data, string, ASBUFSIZE, format, args);
-  *stringp = data.base;                /* not string in case reallocated */
-  return r;
-}
-
-int
-#if defined(PREFER_STDARG)
-asprintf(char **stringp, const char * format, ...)
-#else
-asprintf(stringp, format, va_alist)
-     char **stringp;
-     const char *format;
-     va_dcl
-#endif
-{
-  int rval;
-  va_list args;
-
-  SH_VA_START(args, format);
-
-  rval = vasprintf (stringp, format, args);
-
-  va_end(args);
-
-  return rval;
-}
-
-#endif /* HAVE_ASPRINTF */
-
-static void
-fake_snprintf_asprintf_symbol()
-{
-       ;
-}
-#endif
-
-#ifdef DRIVER
-
-static void
-memory_error_and_abort ()
-{
-  write (2, "out of virtual memory\n", 22);
-  abort ();
-}
-
-static void *
-xmalloc(bytes)
-     size_t bytes;
-{
-  void *ret;
-
-  ret = malloc(bytes);
-  if (ret == 0)
-    memory_error_and_abort ();
-  return ret;
-}
-
-static void *
-xrealloc (pointer, bytes)
-     void *pointer;
-     size_t bytes;
-{
-  void *ret;
-
-  ret = pointer ? realloc(pointer, bytes) : malloc(bytes);
-  if (ret == 0)
-    memory_error_and_abort ();
-  return ret;
-}
-
-static void
-xfree(x)
-     void *x;
-{
-  if (x)
-    free (x);
-}
-
-/* set of small tests for snprintf() */
-main()
-{
-  char holder[100];
-  char *h;
-  int i, si, ai;
-
-#ifdef HAVE_LOCALE_H
-  setlocale(LC_ALL, "");
-#endif
-
-#if 1
-  si = snprintf((char *)NULL, 0, "abcde\n");
-  printf("snprintf returns %d with NULL first argument and size of 0\n", si);
-  si = snprintf(holder, 0, "abcde\n");
-  printf("snprintf returns %d with non-NULL first argument and size of 0\n", si);
-  si = snprintf((char *)NULL, 16, "abcde\n");
-  printf("snprintf returns %d with NULL first argument and non-zero size\n", si);
-  
-/*
-  printf("Suite of test for snprintf:\n");
-  printf("a_format\n");
-  printf("printf() format\n");
-  printf("snprintf() format\n\n");
-*/
-/* Checking the field widths */
-
-  printf("/%%ld %%ld/, 336, 336\n");
-  snprintf(holder, sizeof holder, "/%ld %ld/\n", 336, 336);
-  asprintf(&h, "/%ld %ld/\n", 336, 336);
-  printf("/%ld %ld/\n", 336, 336);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%d/, 336\n");
-  snprintf(holder, sizeof holder, "/%d/\n", 336);
-  asprintf(&h, "/%d/\n", 336);
-  printf("/%d/\n", 336);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%2d/, 336\n");
-  snprintf(holder, sizeof holder, "/%2d/\n", 336);
-  asprintf(&h, "/%2d/\n", 336);
-  printf("/%2d/\n", 336);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%10d/, 336\n");
-  snprintf(holder, sizeof holder, "/%10d/\n", 336);
-  asprintf(&h, "/%10d/\n", 336);
-  printf("/%10d/\n", 336);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%-10d/, 336\n");
-  snprintf(holder, sizeof holder, "/%-10d/\n", 336);
-  asprintf(&h, "/%-10d/\n", 336);
-  printf("/%-10d/\n", 336);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-
-/* floating points */
-
-  printf("/%%f/, 1234.56\n");
-  snprintf(holder, sizeof holder, "/%f/\n", 1234.56);
-  asprintf(&h, "/%f/\n", 1234.56);
-  printf("/%f/\n", 1234.56);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%e/, 1234.56\n");
-  snprintf(holder, sizeof holder, "/%e/\n", 1234.56);
-  asprintf(&h, "/%e/\n", 1234.56);
-  printf("/%e/\n", 1234.56);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%4.2f/, 1234.56\n");
-  snprintf(holder, sizeof holder, "/%4.2f/\n", 1234.56);
-  asprintf(&h, "/%4.2f/\n", 1234.56);
-  printf("/%4.2f/\n", 1234.56);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%3.1f/, 1234.56\n");
-  snprintf(holder, sizeof holder, "/%3.1f/\n", 1234.56);
-  asprintf(&h, "/%3.1f/\n", 1234.56);
-  printf("/%3.1f/\n", 1234.56);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%10.3f/, 1234.56\n");
-  snprintf(holder, sizeof holder, "/%10.3f/\n", 1234.56);
-  asprintf(&h, "/%10.3f/\n", 1234.56);
-  printf("/%10.3f/\n", 1234.56);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%10.3e/, 1234.56\n");
-  snprintf(holder, sizeof holder, "/%10.3e/\n", 1234.56);
-  asprintf(&h, "/%10.3e/\n", 1234.56);
-  printf("/%10.3e/\n", 1234.56);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%+4.2f/, 1234.56\n");
-  snprintf(holder, sizeof holder, "/%+4.2f/\n", 1234.56);
-  asprintf(&h, "/%+4.2f/\n", 1234.56);
-  printf("/%+4.2f/\n", 1234.56);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%010.2f/, 1234.56\n");
-  snprintf(holder, sizeof holder, "/%010.2f/\n", 1234.56);
-  asprintf(&h, "/%010.2f/\n", 1234.56);
-  printf("/%010.2f/\n", 1234.56);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-#define BLURB "Outstanding acting !"
-/* strings precisions */
-
-  printf("/%%2s/, \"%s\"\n", BLURB);
-  snprintf(holder, sizeof holder, "/%2s/\n", BLURB);
-  asprintf(&h, "/%2s/\n", BLURB);
-  printf("/%2s/\n", BLURB);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%22s/ %s\n", BLURB);
-  snprintf(holder, sizeof holder, "/%22s/\n", BLURB);
-  asprintf(&h, "/%22s/\n", BLURB);
-  printf("/%22s/\n", BLURB);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%22.5s/ %s\n", BLURB);
-  snprintf(holder, sizeof holder, "/%22.5s/\n", BLURB);
-  asprintf(&h, "/%22.5s/\n", BLURB);
-  printf("/%22.5s/\n", BLURB);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%-22.5s/ %s\n", BLURB);
-  snprintf(holder, sizeof holder, "/%-22.5s/\n", BLURB);
-  asprintf(&h, "/%-22.5s/\n", BLURB);
-  printf("/%-22.5s/\n", BLURB);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-/* see some flags */
-
-  printf("%%x %%X %%#x, 31, 31, 31\n");
-  snprintf(holder, sizeof holder, "%x %X %#x\n", 31, 31, 31);
-  asprintf(&h, "%x %X %#x\n", 31, 31, 31);
-  printf("%x %X %#x\n", 31, 31, 31);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("**%%d**%% d**%% d**, 42, 42, -42\n");
-  snprintf(holder, sizeof holder, "**%d**% d**% d**\n", 42, 42, -42);
-  asprintf(&h, "**%d**% d**% d**\n", 42, 42, -42);
-  printf("**%d**% d**% d**\n", 42, 42, -42);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-/* other flags */
-
-  printf("/%%g/, 31.4\n");
-  snprintf(holder, sizeof holder, "/%g/\n", 31.4);
-  asprintf(&h, "/%g/\n", 31.4);
-  printf("/%g/\n", 31.4);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%.6g/, 31.4\n");
-  snprintf(holder, sizeof holder, "/%.6g/\n", 31.4);
-  asprintf(&h, "/%.6g/\n", 31.4);
-  printf("/%.6g/\n", 31.4);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%.1G/, 31.4\n");
-  snprintf(holder, sizeof holder, "/%.1G/\n", 31.4);
-  asprintf(&h, "/%.1G/\n", 31.4);
-  printf("/%.1G/\n", 31.4);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%.1G/, 3100000000.4\n");
-  snprintf(holder, sizeof holder, "/%.1G/\n", 3100000000.4);  
-  asprintf(&h, "/%.1G/\n", 3100000000.4);  
-  printf("/%.1G/\n", 3100000000.4); 
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("abc%%n\n");
-  printf("abc%n", &i); printf("%d\n", i);
-  snprintf(holder, sizeof holder, "abc%n", &i);
-  printf("%s", holder); printf("%d\n\n", i);
-  asprintf(&h, "abc%n", &i);
-  printf("%s", h); printf("%d\n\n", i);
-  
-  printf("%%*.*s --> 10.10\n");
-  snprintf(holder, sizeof holder, "%*.*s\n", 10, 10, BLURB);
-  asprintf(&h, "%*.*s\n", 10, 10, BLURB);
-  printf("%*.*s\n", 10, 10, BLURB);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("%%%%%%%%\n");
-  snprintf(holder, sizeof holder, "%%%%\n");
-  asprintf(&h, "%%%%\n");
-  printf("%%%%\n");
-  printf("%s", holder);
-  printf("%s\n", h);
-
-#define BIG "Hello this is a too big string for the buffer"
-/*  printf("A buffer to small of 10, trying to put this:\n");*/
-  printf("<%%>, %s\n", BIG); 
-  i = snprintf(holder, 10, "%s\n", BIG);
-  i = asprintf(&h, "%s", BIG);
-  printf("<%s>\n", BIG);
-  printf("<%s>\n", holder);
-  printf("<%s>\n\n", h);
-
-  printf ("<%%p> vsnprintf\n");
-  i = snprintf(holder, 100, "%p", vsnprintf);
-  i = asprintf(&h, "%p", vsnprintf);
-  printf("<%p>\n", vsnprintf);
-  printf("<%s>\n", holder);  
-  printf("<%s>\n\n", h);
-
-  printf ("<%%lu> LONG_MAX+1\n");
-  i = snprintf(holder, 100, "%lu", (unsigned long)(LONG_MAX)+1);
-  i = asprintf(&h, "%lu", (unsigned long)(LONG_MAX)+1);
-  printf("<%lu>\n", (unsigned long)(LONG_MAX)+1);
-  printf("<%s>\n", holder);
-  printf("<%s>\n\n", h);
-
-#ifdef HAVE_LONG_LONG
-  printf ("<%%llu> LLONG_MAX+1\n");
-  i = snprintf(holder, 100, "%llu", (unsigned long long)(LLONG_MAX)+1);
-  i = asprintf(&h, "%llu", (unsigned long long)(LLONG_MAX)+1);
-  printf("<%llu>\n", (unsigned long long)(LLONG_MAX)+1);
-  printf("<%s>\n", holder);
-  printf("<%s>\n\n", h);
-#endif
-
-#ifdef HAVE_LONG_DOUBLE
-  printf ("<%%6.2LE> 42.42\n");
-  i = snprintf(holder, 100, "%6.2LE", (long double)42.42);
-  i = asprintf(&h, "%6.2LE", (long double)42.42);
-  printf ("<%6.2LE>\n", (long double)42.42);
-  printf ("<%s>\n", holder);
-  printf ("<%s>\n\n", h);
-#endif
-
-#ifdef HAVE_PRINTF_A_FORMAT
-  printf ("<%%6.2A> 42.42\n");
-  i = snprintf(holder, 100, "%6.2A", 42.42);
-  i = asprintf(&h, "%6.2A", 42.42);
-  printf ("<%6.2A>\n", 42.42);
-  printf ("<%s>\n", holder);
-  printf ("<%s>\n\n", h);
-
-  printf ("<%%6.2LA> 42.42\n");
-  i = snprintf(holder, 100, "%6.2LA", (long double)42.42);
-  i = asprintf(&h, "%6.2LA", (long double)42.42);
-  printf ("<%6.2LA>\n", (long double)42.42);
-  printf ("<%s>\n", holder);
-  printf ("<%s>\n\n", h);
-#endif
-
-  printf ("<%%.10240f> DBL_MAX\n");
-  si = snprintf(holder, 100, "%.10240f", DBL_MAX);
-  ai = asprintf(&h, "%.10240f", DBL_MAX);
-  printf ("<%.10240f>\n", DBL_MAX);
-  printf ("<%d> <%s>\n", si, holder);
-  printf ("<%d> <%s>\n\n", ai, h);
-
-  printf ("<%%.10240Lf> LDBL_MAX\n");
-  si = snprintf(holder, 100, "%.10240Lf", (long double)LDBL_MAX);
-  ai = asprintf(&h, "%.10240Lf", (long double)LDBL_MAX);
-  printf ("<%.10240Lf>\n", (long double)LDBL_MAX);
-  printf ("<%d> <%s>\n", si, holder);
-  printf ("<%d> <%s>\n\n", ai, h);
-
-  /* huh? */
-  printf("/%%g/, 421.2345\n");
-  snprintf(holder, sizeof holder, "/%g/\n", 421.2345);
-  asprintf(&h, "/%g/\n", 421.2345);
-  printf("/%g/\n", 421.2345);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%g/, 4214.2345\n");
-  snprintf(holder, sizeof holder, "/%g/\n", 4214.2345);
-  asprintf(&h, "/%g/\n", 4214.2345);
-  printf("/%g/\n", 4214.2345);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%.5g/, 4214.2345\n");
-  snprintf(holder, sizeof holder, "/%.5g/\n", 4214.2345);
-  asprintf(&h, "/%.5g/\n", 4214.2345);
-  printf("/%.5g/\n", 4214.2345);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%.4g/, 4214.2345\n");
-  snprintf(holder, sizeof holder, "/%.4g/\n", 4214.2345);
-  asprintf(&h, "/%.4g/\n", 4214.2345);
-  printf("/%.4g/\n", 4214.2345);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%'ld %%'ld/, 12345, 1234567\n");
-  snprintf(holder, sizeof holder, "/%'ld %'ld/\n", 12345, 1234567);
-  asprintf(&h, "/%'ld %'ld/\n", 12345, 1234567);
-  printf("/%'ld %'ld/\n", 12345, 1234567);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%'ld %%'ld/, 336, 3336\n");
-  snprintf(holder, sizeof holder, "/%'ld %'ld/\n", 336, 3336);
-  asprintf(&h, "/%'ld %'ld/\n", 336, 3336);
-  printf("/%'ld %'ld/\n", 336, 3336);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%'ld %%'ld/, -42786, -142786\n");
-  snprintf(holder, sizeof holder, "/%'ld %'ld/\n", -42786, -142786);
-  asprintf(&h, "/%'ld %'ld/\n", -42786, -142786);
-  printf("/%'ld %'ld/\n", -42786, -142786);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%'f %%'f/, 421.2345, 421234.56789\n");
-  snprintf(holder, sizeof holder, "/%'f %'f/\n", 421.2345, 421234.56789);
-  asprintf(&h, "/%'f %'f/\n", 421.2345, 421234.56789);
-  printf("/%'f %'f/\n", 421.2345, 421234.56789);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%'f %%'f/, -421.2345, -421234.56789\n");
-  snprintf(holder, sizeof holder, "/%'f %'f/\n", -421.2345, -421234.56789);
-  asprintf(&h, "/%'f %'f/\n", -421.2345, -421234.56789);
-  printf("/%'f %'f/\n", -421.2345, -421234.56789);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%'g %%'g/, 421.2345, 421234.56789\n");
-  snprintf(holder, sizeof holder, "/%'g %'g/\n", 421.2345, 421234.56789);
-  asprintf(&h, "/%'g %'g/\n", 421.2345, 421234.56789);
-  printf("/%'g %'g/\n", 421.2345, 421234.56789);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  printf("/%%'g %%'g/, -421.2345, -421234.56789\n");
-  snprintf(holder, sizeof holder, "/%'g %'g/\n", -421.2345, -421234.56789);
-  asprintf(&h, "/%'g %'g/\n", -421.2345, -421234.56789);
-  printf("/%'g %'g/\n", -421.2345, -421234.56789);
-  printf("%s", holder);
-  printf("%s\n", h);
-#endif
-
-  printf("/%%'g/, 4213455.8392\n");
-  snprintf(holder, sizeof holder, "/%'g/\n", 4213455.8392);
-  asprintf(&h, "/%'g/\n", 4213455.8392);
-  printf("/%'g/\n", 4213455.8392);
-  printf("%s", holder);
-  printf("%s\n", h);
-
-  exit (0);
-}
-#endif
diff --git a/lib/sh/strcasestr.c~ b/lib/sh/strcasestr.c~
deleted file mode 100644 (file)
index fefd351..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/* strindex.c - Find if one string appears as a substring of another string,
-               without regard to case. */
-
-/* Copyright (C) 2000 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 <bashansi.h>
-#include <chartypes.h>
-
-#include <stdc.h>
-
-/* Determine if s2 occurs in s1.  If so, return a pointer to the
-   match in s1.  The compare is case insensitive.  This is a
-   case-insensitive strstr(3). */
-char *
-strcasestr (s1, s2)
-     const char *s1;
-     const char *s2;
-{
-  register int i, l, len, c;
-
-  c = TOLOWER ((unsigned char)s2[0]);
-  len = strlen (s1);
-  l = strlen (s2);
-  for (i = 0; (len - i) >= l; i++)
-    if ((TOLOWER ((unsigned char)s1[i]) == c) && (strncasecmp (s1 + i, s2, l) == 0))
-      return ((char *)s1 + i);
-  return ((char *)0);
-}
diff --git a/lib/sh/strtoimax.c~ b/lib/sh/strtoimax.c~
deleted file mode 100644 (file)
index 834cb24..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/* strtoimax - convert string representation of a number into an intmax_t value. */
-
-/* Copyright 1999-2005 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/>.
-*/
-
-/* Written by Paul Eggert.  Modified by Chet Ramey for Bash. */
-
-#if HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#if HAVE_INTTYPES_H
-#  include <inttypes.h>
-#endif
-
-#if HAVE_STDINT_H
-#  include <stdint.h>
-#endif
-
-#if HAVE_STDLIB_H
-#  include <stdlib.h>
-#endif
-
-#include <stdc.h>
-
-/* Verify a requirement at compile-time (unlike assert, which is runtime).  */
-#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; }
-
-#ifndef HAVE_DECL_STRTOL
-"this configure-time declaration test was not run"
-#endif
-#if !HAVE_DECL_STRTOL
-extern long strtol __P((const char *, char **, int));
-#endif
-
-#ifndef HAVE_DECL_STRTOLL
-"this configure-time declaration test was not run"
-#endif
-#if !HAVE_DECL_STRTOLL && HAVE_LONG_LONG
-extern long long strtoll __P((const char *, char **, int));
-#endif
-
-#ifdef strtoimax
-#undef strtoimax
-#endif
-
-intmax_t
-strtoimax (ptr, endptr, base)
-     const char *ptr;
-     char **endptr;
-     int base;
-{
-#if HAVE_LONG_LONG
-  verify(size_is_that_of_long_or_long_long,
-        (sizeof (intmax_t) == sizeof (long) ||
-         sizeof (intmax_t) == sizeof (long long)));
-
-  if (sizeof (intmax_t) != sizeof (long))
-    return (strtoll (ptr, endptr, base));
-#else
-  verify (size_is_that_of_long, sizeof (intmax_t) == sizeof (long));
-#endif
-
-  return (strtol (ptr, endptr, base));
-}
-
-#ifdef TESTING
-# include <stdio.h>
-int
-main ()
-{
-  char *p, *endptr;
-  intmax_t x;
-#if HAVE_LONG_LONG
-  long long y;
-#endif
-  long z;
-  
-  printf ("sizeof intmax_t: %d\n", sizeof (intmax_t));
-
-#if HAVE_LONG_LONG
-  printf ("sizeof long long: %d\n", sizeof (long long));
-#endif
-  printf ("sizeof long: %d\n", sizeof (long));
-
-  x = strtoimax("42", &endptr, 10);
-#if HAVE_LONG_LONG
-  y = strtoll("42", &endptr, 10);
-#else
-  y = -1;
-#endif
-  z = strtol("42", &endptr, 10);
-
-  printf ("%lld %lld %ld\n", x, y, z);
-
-  exit (0);
-}
-#endif
diff --git a/lib/sh/strtoumax.c~ b/lib/sh/strtoumax.c~
deleted file mode 100644 (file)
index 9599da5..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/* strtoumax - convert string representation of a number into an uintmax_t value. */
-
-/* Copyright 1999-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/>.
-*/
-/* Written by Paul Eggert.  Modified by Chet Ramey for Bash. */
-
-#if HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#if HAVE_INTTYPES_H
-#  include <inttypes.h>
-#endif
-
-#if HAVE_STDINT_H
-#  include <stdint.h>
-#endif
-
-#if HAVE_STDLIB_H
-#  include <stdlib.h>
-#endif
-
-#include <stdc.h>
-
-/* Verify a requirement at compile-time (unlike assert, which is runtime).  */
-#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; }
-
-#ifndef HAVE_DECL_STRTOUL
-"this configure-time declaration test was not run"
-#endif
-#if !HAVE_DECL_STRTOUL
-extern unsigned long strtoul __P((const char *, char **, int));
-#endif
-
-#ifndef HAVE_DECL_STRTOULL
-"this configure-time declaration test was not run"
-#endif
-#if !HAVE_DECL_STRTOULL && HAVE_UNSIGNED_LONG_LONG
-extern unsigned long long strtoull __P((const char *, char **, int));
-#endif
-
-#ifdef strtoumax
-#undef strtoumax
-#endif
-
-uintmax_t
-strtoumax (ptr, endptr, base)
-     const char *ptr;
-     char **endptr;
-     int base;
-{
-#if HAVE_UNSIGNED_LONG_LONG
-  verify (size_is_that_of_unsigned_long_or_unsigned_long_long,
-         (sizeof (uintmax_t) == sizeof (unsigned long) ||
-          sizeof (uintmax_t) == sizeof (unsigned long long)));
-
-  if (sizeof (uintmax_t) != sizeof (unsigned long))
-    return (strtoull (ptr, endptr, base));
-#else
-  verify (size_is_that_of_unsigned_long, sizeof (uintmax_t) == sizeof (unsigned long));
-#endif
-
-  return (strtoul (ptr, endptr, base));
-}
-
-#ifdef TESTING
-# include <stdio.h>
-int
-main ()
-{
-  char *p, *endptr;
-  uintmax_t x;
-#if HAVE_UNSIGNED_LONG_LONG
-  unsigned long long y;
-#endif
-  unsigned long z;
-
-  printf ("sizeof uintmax_t: %d\n", sizeof (uintmax_t));
-
-#if HAVE_UNSIGNED_LONG_LONG
-  printf ("sizeof unsigned long long: %d\n", sizeof (unsigned long long));
-#endif
-  printf ("sizeof unsigned long: %d\n", sizeof (unsigned long));
-
-  x = strtoumax("42", &endptr, 10);
-#if HAVE_LONG_LONG
-  y = strtoull("42", &endptr, 10);
-#else
-  y = 0;
-#endif
-  z = strtoul("42", &endptr, 10);
-
-  printf ("%llu %llu %lu\n", x, y, z);
-
-  exit (0);
-}
-#endif
diff --git a/lib/sh/uconvert.c~ b/lib/sh/uconvert.c~
deleted file mode 100644 (file)
index 1009565..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/* uconvert - convert string representations of decimal numbers into whole
-             number/fractional value pairs. */
-
-/* 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/>.
-*/
-
-#include "config.h"
-
-#include "bashtypes.h"
-
-#if defined (TIME_WITH_SYS_TIME)
-#  include <sys/time.h>
-#  include <time.h>
-#else
-#  if defined (HAVE_SYS_TIME_H)
-#    include <sys/time.h>
-#  else
-#    include <time.h>
-#  endif
-#endif
-
-#if defined (HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
-
-#include <stdio.h>
-#include "chartypes.h"
-
-#include "shell.h"
-#include "builtins.h"
-
-#define DECIMAL        '.'             /* XXX - should use locale */
-
-#define RETURN(x) \
-do { \
-  if (ip) *ip = ipart * mult; \
-  if (up) *up = upart; \
-  return (x); \
-} while (0)
-
-/*
- * An incredibly simplistic floating point converter.
- */
-static int multiplier[7] = { 1, 100000, 10000, 1000, 100, 10, 1 };
-
-/* Take a decimal number int-part[.[micro-part]] and convert it to the whole
-   and fractional portions.  The fractional portion is returned in
-   millionths (micro); callers are responsible for multiplying appropriately.
-   Return 1 if value converted; 0 if invalid integer for either whole or
-   fractional parts. */
-int
-uconvert(s, ip, up)
-     char *s;
-     long *ip, *up;
-{
-  int n, mult;
-  long ipart, upart;
-  char *p;
-
-  ipart = upart = 0;
-  mult = 1;
-
-  if (s && (*s == '-' || *s == '+'))
-    {
-      mult = (*s == '-') ? -1 : 1;
-      p = s + 1;
-    }
-  else
-    p = s;
-
-  for ( ; p && *p; p++)
-    {
-      if (*p == DECIMAL)               /* decimal point */
-       break;
-      if (DIGIT(*p) == 0)
-       RETURN(0);
-      ipart = (ipart * 10) + (*p - '0');
-    }
-
-  if (*p == 0)
-    RETURN(1);
-
-  if (*p == DECIMAL)
-    p++;
-
-  /* Look for up to six digits past a decimal point. */
-  for (n = 0; n < 6 && p[n]; n++)
-    {
-      if (DIGIT(p[n]) == 0)
-       RETURN(0);
-      upart = (upart * 10) + (p[n] - '0');
-    }
-
-  /* Now convert to millionths */
-  upart *= multiplier[n];
-
-  if (n == 6 && p[6] >= '5' && p[6] <= '9')
-    upart++;                   /* round up 1 */
-
-  RETURN(1);
-}
diff --git a/lib/sh/winsize.c~ b/lib/sh/winsize.c~
deleted file mode 100644 (file)
index 81ebb37..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/* winsize.c - handle window size changes and information. */
-
-/* Copyright (C) 2005 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 <stdc.h>
-
-#include "bashtypes.h"
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include <sys/ioctl.h>
-
-#if !defined (STRUCT_WINSIZE_IN_SYS_IOCTL)
-/* For struct winsize on SCO */
-/*   sys/ptem.h has winsize but needs mblk_t from sys/stream.h */
-#  if defined (HAVE_SYS_PTEM_H) && defined (TIOCGWINSZ) && defined (SIGWINCH)
-#    if defined (HAVE_SYS_STREAM_H)
-#      include <sys/stream.h>
-#    endif
-#    include <sys/ptem.h>
-#  endif /* HAVE_SYS_PTEM_H && TIOCGWINSZ && SIGWINCH */
-#endif /* !STRUCT_WINSIZE_IN_SYS_IOCTL */
-
-#include <stdio.h>
-
-/* Return the fd from which we are actually getting input. */
-#define input_tty() (shell_tty != -1) ? shell_tty : fileno (stderr)
-
-#if !defined (errno)
-extern int errno;
-#endif /* !errno */
-
-extern int shell_tty;
-
-#if defined (READLINE)
-extern void rl_set_screen_size __P((int, int));
-#endif
-extern void sh_set_lines_and_columns __P((int, int));
-
-void
-get_new_window_size (from_sig, rp, cp)
-     int from_sig;
-     int *rp, *cp;
-{
-#if defined (TIOCGWINSZ)
-  struct winsize win;
-  int tty;
-
-  tty = input_tty ();
-  if (tty >= 0 && (ioctl (tty, TIOCGWINSZ, &win) == 0) &&
-      win.ws_row > 0 && win.ws_col > 0)
-    {
-      sh_set_lines_and_columns (win.ws_row, win.ws_col);
-#if defined (READLINE)
-      rl_set_screen_size (win.ws_row, win.ws_col);
-      if (rp)
-       *rp = win.ws_row;
-      if (cp)
-       *cp = win.ws_col;
-#endif
-    }
-#endif
-}
diff --git a/lib/sh/xstrchr.c~ b/lib/sh/xstrchr.c~
deleted file mode 100644 (file)
index 6dd4d8e..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/* xstrchr.c - strchr(3) that handles multibyte characters. */
-
-/* Copyright (C) 2002 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>
-
-#ifdef HAVE_STDLIB_H
-#  include <stdlib.h>
-#endif
-
-#include "bashansi.h"
-#include "shmbutil.h"
-
-#undef xstrchr
-
-/* In some locales, the non-first byte of some multibyte characters have
-   the same value as some ascii character.  Faced with these strings, a
-   legacy strchr() might return the wrong value. */
-
-char *
-#if defined (PROTOTYPES)
-xstrchr (const char *s, int c)
-#else
-xstrchr (s, c)
-     const char *s;
-     int c;
-#endif
-{
-#if HANDLE_MULTIBYTE
-  char *pos;
-  mbstate_t state;
-  size_t strlength, mblength;
-
-  /* The locale encodings with said weird property are BIG5, BIG5-HKSCS,
-     GBK, GB18030, SHIFT_JIS, and JOHAB.  They exhibit the problem only
-     when c >= 0x30.  We can therefore use the faster bytewise search if
-     c <= 0x30. */
-  if ((unsigned char)c >= '0' && MB_CUR_MAX > 1)
-    {
-      pos = (char *)s;
-      memset (&state, '\0', sizeof(mbstate_t));
-      strlength = strlen (s);
-
-      while (strlength > 0)
-       {
-         mblength = mbrlen (pos, strlength, &state);
-         if (mblength == (size_t)-2 || mblength == (size_t)-1 || mblength == (size_t)0)
-           mblength = 1;
-
-         if (c == (unsigned char)*pos)
-           return pos;
-
-         strlength -= mblength;
-         pos += mblength;
-       }
-
-      return ((char *)NULL);
-    }
-  else
-#endif
-  return (strchr (s, c));
-}
diff --git a/make_cmd.c~ b/make_cmd.c~
deleted file mode 100644 (file)
index 3c20241..0000000
+++ /dev/null
@@ -1,886 +0,0 @@
-/* make_cmd.c -- Functions for making instances of the various
-   parser constructs. */
-
-/* Copyright (C) 1989-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/>.
-*/
-
-#include "config.h"
-
-#include <stdio.h>
-#include "bashtypes.h"
-#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H)
-#  include <sys/file.h>
-#endif
-#include "filecntl.h"
-#include "bashansi.h"
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include "bashintl.h"
-
-#include "parser.h"
-#include "syntax.h"
-#include "command.h"
-#include "general.h"
-#include "error.h"
-#include "flags.h"
-#include "make_cmd.h"
-#include "dispose_cmd.h"
-#include "variables.h"
-#include "subst.h"
-#include "input.h"
-#include "ocache.h"
-#include "externs.h"
-
-#if defined (JOB_CONTROL)
-#include "jobs.h"
-#endif
-
-#include "shmbutil.h"
-
-extern int line_number, current_command_line_count, parser_state;
-extern int last_command_exit_value;
-
-/* Object caching */
-sh_obj_cache_t wdcache = {0, 0, 0};
-sh_obj_cache_t wlcache = {0, 0, 0};
-
-#define WDCACHESIZE    60
-#define WLCACHESIZE    60
-
-static COMMAND *make_for_or_select __P((enum command_type, WORD_DESC *, WORD_LIST *, COMMAND *, int));
-#if defined (ARITH_FOR_COMMAND)
-static WORD_LIST *make_arith_for_expr __P((char *));
-#endif
-static COMMAND *make_until_or_while __P((enum command_type, COMMAND *, COMMAND *));
-
-void
-cmd_init ()
-{
-  ocache_create (wdcache, WORD_DESC, WDCACHESIZE);
-  ocache_create (wlcache, WORD_LIST, WLCACHESIZE);
-}
-
-WORD_DESC *
-alloc_word_desc ()
-{
-  WORD_DESC *temp;
-
-  ocache_alloc (wdcache, WORD_DESC, temp);
-  temp->flags = 0;
-  temp->word = 0;
-  return temp;
-}
-
-WORD_DESC *
-make_bare_word (string)
-     const char *string;
-{
-  WORD_DESC *temp;
-
-  temp = alloc_word_desc ();
-
-  if (*string)
-    temp->word = savestring (string);
-  else
-    {
-      temp->word = (char *)xmalloc (1);
-      temp->word[0] = '\0';
-    }
-
-  return (temp);
-}
-
-WORD_DESC *
-make_word_flags (w, string)
-     WORD_DESC *w;
-     const char *string;
-{
-  register int i;
-  size_t slen;
-  DECLARE_MBSTATE;
-
-  i = 0;
-  slen = strlen (string);
-  while (i < slen)
-    {
-      switch (string[i])
-       {
-       case '$':
-         w->flags |= W_HASDOLLAR;
-         break;
-       case '\\':
-         break;        /* continue the loop */
-       case '\'':
-       case '`':
-       case '"':
-         w->flags |= W_QUOTED;
-         break;
-       }
-
-      ADVANCE_CHAR (string, slen, i);
-    }
-
-  return (w);
-}
-
-WORD_DESC *
-make_word (string)
-     const char *string;
-{
-  WORD_DESC *temp;
-
-  temp = make_bare_word (string);
-  return (make_word_flags (temp, string));
-}
-
-WORD_DESC *
-make_word_from_token (token)
-     int token;
-{
-  char tokenizer[2];
-
-  tokenizer[0] = token;
-  tokenizer[1] = '\0';
-
-  return (make_word (tokenizer));
-}
-
-WORD_LIST *
-make_word_list (word, wlink)
-     WORD_DESC *word;
-     WORD_LIST *wlink;
-{
-  WORD_LIST *temp;
-
-  ocache_alloc (wlcache, WORD_LIST, temp);
-
-  temp->word = word;
-  temp->next = wlink;
-  return (temp);
-}
-
-COMMAND *
-make_command (type, pointer)
-     enum command_type type;
-     SIMPLE_COM *pointer;
-{
-  COMMAND *temp;
-
-  temp = (COMMAND *)xmalloc (sizeof (COMMAND));
-  temp->type = type;
-  temp->value.Simple = pointer;
-  temp->value.Simple->flags = temp->flags = 0;
-  temp->redirects = (REDIRECT *)NULL;
-  return (temp);
-}
-
-COMMAND *
-command_connect (com1, com2, connector)
-     COMMAND *com1, *com2;
-     int connector;
-{
-  CONNECTION *temp;
-
-  temp = (CONNECTION *)xmalloc (sizeof (CONNECTION));
-  temp->connector = connector;
-  temp->first = com1;
-  temp->second = com2;
-  return (make_command (cm_connection, (SIMPLE_COM *)temp));
-}
-
-static COMMAND *
-make_for_or_select (type, name, map_list, action, lineno)
-     enum command_type type;
-     WORD_DESC *name;
-     WORD_LIST *map_list;
-     COMMAND *action;
-     int lineno;
-{
-  FOR_COM *temp;
-
-  temp = (FOR_COM *)xmalloc (sizeof (FOR_COM));
-  temp->flags = 0;
-  temp->name = name;
-  temp->line = lineno;
-  temp->map_list = map_list;
-  temp->action = action;
-  return (make_command (type, (SIMPLE_COM *)temp));
-}
-
-COMMAND *
-make_for_command (name, map_list, action, lineno)
-     WORD_DESC *name;
-     WORD_LIST *map_list;
-     COMMAND *action;
-     int lineno;
-{
-  return (make_for_or_select (cm_for, name, map_list, action, lineno));
-}
-
-COMMAND *
-make_select_command (name, map_list, action, lineno)
-     WORD_DESC *name;
-     WORD_LIST *map_list;
-     COMMAND *action;
-     int lineno;
-{
-#if defined (SELECT_COMMAND)
-  return (make_for_or_select (cm_select, name, map_list, action, lineno));
-#else
-  last_command_exit_value = 2;
-  return ((COMMAND *)NULL);
-#endif
-}
-
-#if defined (ARITH_FOR_COMMAND)
-static WORD_LIST *
-make_arith_for_expr (s)
-     char *s;
-{
-  WORD_LIST *result;
-  WORD_DESC *wd;
-
-  if (s == 0 || *s == '\0')
-    return ((WORD_LIST *)NULL);
-  wd = make_word (s);
-  wd->flags |= W_NOGLOB|W_NOSPLIT|W_QUOTED|W_DQUOTE;   /* no word splitting or globbing */
-  result = make_word_list (wd, (WORD_LIST *)NULL);
-  return result;
-}
-#endif
-
-/* Note that this function calls dispose_words on EXPRS, since it doesn't
-   use the word list directly.  We free it here rather than at the caller
-   because no other function in this file requires that the caller free
-   any arguments. */
-COMMAND *
-make_arith_for_command (exprs, action, lineno)
-     WORD_LIST *exprs;
-     COMMAND *action;
-     int lineno;
-{
-#if defined (ARITH_FOR_COMMAND)
-  ARITH_FOR_COM *temp;
-  WORD_LIST *init, *test, *step;
-  char *s, *t, *start;
-  int nsemi;
-
-  init = test = step = (WORD_LIST *)NULL;
-  /* Parse the string into the three component sub-expressions. */
-  start = t = s = exprs->word->word;
-  for (nsemi = 0; ;)
-    {
-      /* skip whitespace at the start of each sub-expression. */
-      while (whitespace (*s))
-       s++;
-      start = s;
-      /* skip to the semicolon or EOS */
-      while (*s && *s != ';')
-       s++;
-
-      t = (s > start) ? substring (start, 0, s - start) : (char *)NULL;
-
-      nsemi++;
-      switch (nsemi)
-       {
-       case 1:
-         init = make_arith_for_expr (t);
-         break;
-       case 2:
-         test = make_arith_for_expr (t);
-         break;
-       case 3:
-         step = make_arith_for_expr (t);
-         break;
-       }
-
-      FREE (t);
-      if (*s == '\0')
-       break;
-      s++;     /* skip over semicolon */
-    }
-
-  if (nsemi != 3)
-    {
-      if (nsemi < 3)
-       parser_error (lineno, _("syntax error: arithmetic expression required"));
-      else
-       parser_error (lineno, _("syntax error: `;' unexpected"));
-      parser_error (lineno, _("syntax error: `((%s))'"), exprs->word->word);
-      last_command_exit_value = 2;
-      return ((COMMAND *)NULL);
-    }
-
-  temp = (ARITH_FOR_COM *)xmalloc (sizeof (ARITH_FOR_COM));
-  temp->flags = 0;
-  temp->line = lineno;
-  temp->init = init ? init : make_arith_for_expr ("1");
-  temp->test = test ? test : make_arith_for_expr ("1");
-  temp->step = step ? step : make_arith_for_expr ("1");
-  temp->action = action;
-
-  dispose_words (exprs);
-  return (make_command (cm_arith_for, (SIMPLE_COM *)temp));
-#else
-  dispose_words (exprs);
-  last_command_exit_value = 2;
-  return ((COMMAND *)NULL);
-#endif /* ARITH_FOR_COMMAND */
-}
-
-COMMAND *
-make_group_command (command)
-     COMMAND *command;
-{
-  GROUP_COM *temp;
-
-  temp = (GROUP_COM *)xmalloc (sizeof (GROUP_COM));
-  temp->command = command;
-  return (make_command (cm_group, (SIMPLE_COM *)temp));
-}
-
-COMMAND *
-make_case_command (word, clauses, lineno)
-     WORD_DESC *word;
-     PATTERN_LIST *clauses;
-     int lineno;
-{
-  CASE_COM *temp;
-
-  temp = (CASE_COM *)xmalloc (sizeof (CASE_COM));
-  temp->flags = 0;
-  temp->line = lineno;
-  temp->word = word;
-  temp->clauses = REVERSE_LIST (clauses, PATTERN_LIST *);
-  return (make_command (cm_case, (SIMPLE_COM *)temp));
-}
-
-PATTERN_LIST *
-make_pattern_list (patterns, action)
-     WORD_LIST *patterns;
-     COMMAND *action;
-{
-  PATTERN_LIST *temp;
-
-  temp = (PATTERN_LIST *)xmalloc (sizeof (PATTERN_LIST));
-  temp->patterns = REVERSE_LIST (patterns, WORD_LIST *);
-  temp->action = action;
-  temp->next = NULL;
-  temp->flags = 0;
-  return (temp);
-}
-
-COMMAND *
-make_if_command (test, true_case, false_case)
-     COMMAND *test, *true_case, *false_case;
-{
-  IF_COM *temp;
-
-  temp = (IF_COM *)xmalloc (sizeof (IF_COM));
-  temp->flags = 0;
-  temp->test = test;
-  temp->true_case = true_case;
-  temp->false_case = false_case;
-  return (make_command (cm_if, (SIMPLE_COM *)temp));
-}
-
-static COMMAND *
-make_until_or_while (which, test, action)
-     enum command_type which;
-     COMMAND *test, *action;
-{
-  WHILE_COM *temp;
-
-  temp = (WHILE_COM *)xmalloc (sizeof (WHILE_COM));
-  temp->flags = 0;
-  temp->test = test;
-  temp->action = action;
-  return (make_command (which, (SIMPLE_COM *)temp));
-}
-
-COMMAND *
-make_while_command (test, action)
-     COMMAND *test, *action;
-{
-  return (make_until_or_while (cm_while, test, action));
-}
-
-COMMAND *
-make_until_command (test, action)
-     COMMAND *test, *action;
-{
-  return (make_until_or_while (cm_until, test, action));
-}
-
-COMMAND *
-make_arith_command (exp)
-     WORD_LIST *exp;
-{
-#if defined (DPAREN_ARITHMETIC)
-  COMMAND *command;
-  ARITH_COM *temp;
-
-  command = (COMMAND *)xmalloc (sizeof (COMMAND));
-  command->value.Arith = temp = (ARITH_COM *)xmalloc (sizeof (ARITH_COM));
-
-  temp->flags = 0;
-  temp->line = line_number;
-  temp->exp = exp;
-
-  command->type = cm_arith;
-  command->redirects = (REDIRECT *)NULL;
-  command->flags = 0;
-
-  return (command);
-#else
-  last_command_exit_value = 2;
-  return ((COMMAND *)NULL);
-#endif
-}
-
-#if defined (COND_COMMAND)
-struct cond_com *
-make_cond_node (type, op, left, right)
-     int type;
-     WORD_DESC *op;
-     struct cond_com *left, *right;
-{
-  COND_COM *temp;
-
-  temp = (COND_COM *)xmalloc (sizeof (COND_COM));
-  temp->flags = 0;
-  temp->line = line_number;
-  temp->type = type;
-  temp->op = op;
-  temp->left = left;
-  temp->right = right;
-
-  return (temp);
-}
-#endif
-
-COMMAND *
-make_cond_command (cond_node)
-     COND_COM *cond_node;
-{
-#if defined (COND_COMMAND)
-  COMMAND *command;
-
-  command = (COMMAND *)xmalloc (sizeof (COMMAND));
-  command->value.Cond = cond_node;
-
-  command->type = cm_cond;
-  command->redirects = (REDIRECT *)NULL;
-  command->flags = 0;
-  command->line = cond_node ? cond_node->line : 0;
-
-  return (command);
-#else
-  last_command_exit_value = 2;
-  return ((COMMAND *)NULL);
-#endif
-}
-
-COMMAND *
-make_bare_simple_command ()
-{
-  COMMAND *command;
-  SIMPLE_COM *temp;
-
-  command = (COMMAND *)xmalloc (sizeof (COMMAND));
-  command->value.Simple = temp = (SIMPLE_COM *)xmalloc (sizeof (SIMPLE_COM));
-
-  temp->flags = 0;
-  temp->line = line_number;
-  temp->words = (WORD_LIST *)NULL;
-  temp->redirects = (REDIRECT *)NULL;
-
-  command->type = cm_simple;
-  command->redirects = (REDIRECT *)NULL;
-  command->flags = 0;
-
-  return (command);
-}
-
-/* Return a command which is the connection of the word or redirection
-   in ELEMENT, and the command * or NULL in COMMAND. */
-COMMAND *
-make_simple_command (element, command)
-     ELEMENT element;
-     COMMAND *command;
-{
-  /* If we are starting from scratch, then make the initial command
-     structure.  Also note that we have to fill in all the slots, since
-     malloc doesn't return zeroed space. */
-  if (command == 0)
-    {
-      command = make_bare_simple_command ();
-      parser_state |= PST_REDIRLIST;
-    }
-
-  if (element.word)
-    {
-      command->value.Simple->words = make_word_list (element.word, command->value.Simple->words);
-      parser_state &= ~PST_REDIRLIST;
-    }
-  else if (element.redirect)
-    {
-      REDIRECT *r = element.redirect;
-      /* Due to the way <> is implemented, there may be more than a single
-        redirection in element.redirect.  We just follow the chain as far
-        as it goes, and hook onto the end. */
-      while (r->next)
-       r = r->next;
-      r->next = command->value.Simple->redirects;
-      command->value.Simple->redirects = element.redirect;
-    }
-
-  return (command);
-}
-
-/* Because we are Bourne compatible, we read the input for this
-   << or <<- redirection now, from wherever input is coming from.
-   We store the input read into a WORD_DESC.  Replace the text of
-   the redirectee.word with the new input text.  If <<- is on,
-   then remove leading TABS from each line. */
-void
-make_here_document (temp, lineno)
-     REDIRECT *temp;
-     int lineno;
-{
-  int kill_leading, redir_len;
-  char *redir_word, *document, *full_line;
-  int document_index, document_size, delim_unquoted;
-
-  if (temp->instruction != r_deblank_reading_until &&
-      temp->instruction != r_reading_until)
-    {
-      internal_error (_("make_here_document: bad instruction type %d"), temp->instruction);
-      return;
-    }
-
-  kill_leading = temp->instruction == r_deblank_reading_until;
-
-  document = (char *)NULL;
-  document_index = document_size = 0;
-
-  /* Quote removal is the only expansion performed on the delimiter
-     for here documents, making it an extremely special case. */
-  redir_word = string_quote_removal (temp->redirectee.filename->word, 0);
-
-  /* redirection_expand will return NULL if the expansion results in
-     multiple words or no words.  Check for that here, and just abort
-     this here document if it does. */
-  if (redir_word)
-    redir_len = strlen (redir_word);
-  else
-    {
-      temp->here_doc_eof = (char *)xmalloc (1);
-      temp->here_doc_eof[0] = '\0';
-      goto document_done;
-    }
-
-  free (temp->redirectee.filename->word);
-  temp->here_doc_eof = redir_word;
-
-  /* Read lines from wherever lines are coming from.
-     For each line read, if kill_leading, then kill the
-     leading tab characters.
-     If the line matches redir_word exactly, then we have
-     manufactured the document.  Otherwise, add the line to the
-     list of lines in the document. */
-
-  /* If the here-document delimiter was quoted, the lines should
-     be read verbatim from the input.  If it was not quoted, we
-     need to perform backslash-quoted newline removal. */
-  delim_unquoted = (temp->redirectee.filename->flags & W_QUOTED) == 0;
-  while (full_line = read_secondary_line (delim_unquoted))
-    {
-      register char *line;
-      int len;
-
-      line = full_line;
-      line_number++;
-
-      /* If set -v is in effect, echo the line read.  read_secondary_line/
-        read_a_line leaves the newline at the end, so don't print another. */
-      if (echo_input_at_read)
-       fprintf (stderr, "%s", line);
-
-      if (kill_leading && *line)
-       {
-         /* Hack:  To be compatible with some Bourne shells, we
-            check the word before stripping the whitespace.  This
-            is a hack, though. */
-         if (STREQN (line, redir_word, redir_len) && line[redir_len] == '\n')
-           goto document_done;
-
-         while (*line == '\t')
-           line++;
-       }
-
-      if (*line == 0)
-       continue;
-
-      if (STREQN (line, redir_word, redir_len) && line[redir_len] == '\n')
-       goto document_done;
-
-      len = strlen (line);
-      if (len + document_index >= document_size)
-       {
-         document_size = document_size ? 2 * (document_size + len) : len + 2;
-         document = (char *)xrealloc (document, document_size);
-       }
-
-      /* len is guaranteed to be > 0 because of the check for line
-        being an empty string before the call to strlen. */
-      FASTCOPY (line, document + document_index, len);
-      document_index += len;
-    }
-
-  if (full_line == 0)
-    internal_warning (_("here-document at line %d delimited by end-of-file (wanted `%s')"), lineno, redir_word);
-
-document_done:
-  if (document)
-    document[document_index] = '\0';
-  else
-    {
-      document = (char *)xmalloc (1);
-      document[0] = '\0';
-    }
-  temp->redirectee.filename->word = document;
-}
-
-/* Generate a REDIRECT from SOURCE, DEST, and INSTRUCTION.
-   INSTRUCTION is the instruction type, SOURCE is a file descriptor,
-   and DEST is a file descriptor or a WORD_DESC *. */
-REDIRECT *
-make_redirection (source, instruction, dest_and_filename)
-     REDIRECTEE source;
-     enum r_instruction instruction;
-     REDIRECTEE dest_and_filename;
-{
-  REDIRECT *temp;
-  WORD_DESC *w;
-  int wlen;
-  intmax_t lfd;
-
-  temp = (REDIRECT *)xmalloc (sizeof (REDIRECT));
-
-  /* First do the common cases. */
-  temp->redirector = source;
-  temp->redirectee = dest_and_filename;
-  temp->instruction = instruction;
-  temp->flags = temp->rflags = 0;
-  temp->next = (REDIRECT *)NULL;
-
-  switch (instruction)
-    {
-
-    case r_output_direction:           /* >foo */
-    case r_output_force:               /* >| foo */
-    case r_err_and_out:                        /* &>filename */
-      temp->flags = O_TRUNC | O_WRONLY | O_CREAT;
-      break;
-
-    case r_appending_to:               /* >>foo */
-    case r_append_err_and_out:         /* &>> filename */
-      temp->flags = O_APPEND | O_WRONLY | O_CREAT;
-      break;
-
-    case r_input_direction:            /* <foo */
-    case r_inputa_direction:           /* foo & makes this. */
-      temp->flags = O_RDONLY;
-      break;
-
-    case r_input_output:               /* <>foo */
-      temp->flags = O_RDWR | O_CREAT;
-      break;
-
-    case r_deblank_reading_until:      /* <<-foo */
-    case r_reading_until:              /* << foo */
-    case r_reading_string:             /* <<< foo */
-    case r_close_this:                 /* <&- */
-    case r_duplicating_input:          /* 1<&2 */
-    case r_duplicating_output:         /* 1>&2 */
-      break;
-
-    /* the parser doesn't pass these. */
-    case r_move_input:                 /* 1<&2- */
-    case r_move_output:                        /* 1>&2- */
-    case r_move_input_word:            /* 1<&$foo- */
-    case r_move_output_word:           /* 1>&$foo- */
-      break;
-
-    /* The way the lexer works we have to do this here. */
-    case r_duplicating_input_word:     /* 1<&$foo */
-    case r_duplicating_output_word:    /* 1>&$foo */
-      w = dest_and_filename.filename;
-      wlen = strlen (w->word) - 1;
-      if (w->word[wlen] == '-')                /* Yuck */
-        {
-          w->word[wlen] = '\0';
-         if (all_digits (w->word) && legal_number (w->word, &lfd) && lfd == (int)lfd)
-           {
-             dispose_word (w);
-             temp->instruction = (instruction == r_duplicating_input_word) ? r_move_input : r_move_output;
-             temp->redirectee.dest = lfd;
-           }
-         else
-           temp->instruction = (instruction == r_duplicating_input_word) ? r_move_input_word : r_move_output_word;
-        }
-          
-      break;
-
-    default:
-      programming_error (_("make_redirection: redirection instruction `%d' out of range"), instruction);
-      abort ();
-      break;
-    }
-  return (temp);
-}
-
-COMMAND *
-make_function_def (name, command, lineno, lstart)
-     WORD_DESC *name;
-     COMMAND *command;
-     int lineno, lstart;
-{
-  FUNCTION_DEF *temp;
-#if defined (ARRAY_VARS)
-  SHELL_VAR *bash_source_v;
-  ARRAY *bash_source_a;
-#endif
-
-  temp = (FUNCTION_DEF *)xmalloc (sizeof (FUNCTION_DEF));
-  temp->command = command;
-  temp->name = name;
-  temp->line = lineno;
-  temp->flags = 0;
-  command->line = lstart;
-
-  /* Information used primarily for debugging. */
-  temp->source_file = 0;
-#if defined (ARRAY_VARS)
-  GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
-  if (bash_source_a && array_num_elements (bash_source_a) > 0)
-    temp->source_file = array_reference (bash_source_a, 0);
-#endif
-#if defined (DEBUGGER)
-  bind_function_def (name->word, temp);
-#endif
-
-  temp->source_file = 0;
-  return (make_command (cm_function_def, (SIMPLE_COM *)temp));
-}
-
-COMMAND *
-make_subshell_command (command)
-     COMMAND *command;
-{
-  SUBSHELL_COM *temp;
-
-  temp = (SUBSHELL_COM *)xmalloc (sizeof (SUBSHELL_COM));
-  temp->command = command;
-  temp->flags = CMD_WANT_SUBSHELL;
-  return (make_command (cm_subshell, (SIMPLE_COM *)temp));
-}
-
-COMMAND *
-make_coproc_command (name, command)
-     char *name;
-     COMMAND *command;
-{
-  COPROC_COM *temp;
-
-  temp = (COPROC_COM *)xmalloc (sizeof (COPROC_COM));
-  temp->name = savestring (name);
-  temp->command = command;
-  temp->flags = CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
-  return (make_command (cm_coproc, (SIMPLE_COM *)temp));
-}
-
-/* Reverse the word list and redirection list in the simple command
-   has just been parsed.  It seems simpler to do this here the one
-   time then by any other method that I can think of. */
-COMMAND *
-clean_simple_command (command)
-     COMMAND *command;
-{
-  if (command->type != cm_simple)
-    command_error ("clean_simple_command", CMDERR_BADTYPE, command->type, 0);
-  else
-    {
-      command->value.Simple->words =
-       REVERSE_LIST (command->value.Simple->words, WORD_LIST *);
-      command->value.Simple->redirects =
-       REVERSE_LIST (command->value.Simple->redirects, REDIRECT *);
-    }
-
-  parser_state &= ~PST_REDIRLIST;
-  return (command);
-}
-
-/* The Yacc grammar productions have a problem, in that they take a
-   list followed by an ampersand (`&') and do a simple command connection,
-   making the entire list effectively asynchronous, instead of just
-   the last command.  This means that when the list is executed, all
-   the commands have stdin set to /dev/null when job control is not
-   active, instead of just the last.  This is wrong, and needs fixing
-   up.  This function takes the `&' and applies it to the last command
-   in the list.  This is done only for lists connected by `;'; it makes
-   `;' bind `tighter' than `&'. */
-COMMAND *
-connect_async_list (command, command2, connector)
-     COMMAND *command, *command2;
-     int connector;
-{
-  COMMAND *t, *t1, *t2;
-
-  t1 = command;
-  t = command->value.Connection->second;
-
-  if (!t || (command->flags & CMD_WANT_SUBSHELL) ||
-      command->value.Connection->connector != ';')
-    {
-      t = command_connect (command, command2, connector);
-      return t;
-    }
-
-  /* This is just defensive programming.  The Yacc precedence rules
-     will generally hand this function a command where t points directly
-     to the command we want (e.g. given a ; b ; c ; d &, t1 will point
-     to the `a ; b ; c' list and t will be the `d').  We only want to do
-     this if the list is not being executed as a unit in the background
-     with `( ... )', so we have to check for CMD_WANT_SUBSHELL.  That's
-     the only way to tell. */
-  while (((t->flags & CMD_WANT_SUBSHELL) == 0) && t->type == cm_connection &&
-        t->value.Connection->connector == ';')
-    {
-      t1 = t;
-      t = t->value.Connection->second;
-    }
-  /* Now we have t pointing to the last command in the list, and
-     t1->value.Connection->second == t. */
-  t2 = command_connect (t, command2, connector);
-  t1->value.Connection->second = t2;
-  return command;
-}
diff --git a/make_cmd.h~ b/make_cmd.h~
deleted file mode 100644 (file)
index 9c969f7..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/* make_cmd.h -- Declarations of functions found in make_cmd.c */
-
-/* Copyright (C) 1993-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 (_MAKE_CMD_H_)
-#define _MAKE_CMD_H_
-
-#include "stdc.h"
-
-extern void cmd_init __P((void));
-
-extern WORD_DESC *alloc_word_desc __P((void));
-extern WORD_DESC *make_bare_word __P((const char *));
-extern WORD_DESC *make_word_flags __P((WORD_DESC *, const char *));
-extern WORD_DESC *make_word __P((const char *));
-extern WORD_DESC *make_word_from_token __P((int));
-
-extern WORD_LIST *make_word_list __P((WORD_DESC *, WORD_LIST *));
-
-#define add_string_to_list(s, l) make_word_list (make_word(s), (l))
-
-extern COMMAND *make_command __P((enum command_type, SIMPLE_COM *));
-extern COMMAND *command_connect __P((COMMAND *, COMMAND *, int));
-extern COMMAND *make_for_command __P((WORD_DESC *, WORD_LIST *, COMMAND *, int));
-extern COMMAND *make_group_command __P((COMMAND *));
-extern COMMAND *make_case_command __P((WORD_DESC *, PATTERN_LIST *, int));
-extern PATTERN_LIST *make_pattern_list __P((WORD_LIST *, COMMAND *));
-extern COMMAND *make_if_command __P((COMMAND *, COMMAND *, COMMAND *));
-extern COMMAND *make_while_command __P((COMMAND *, COMMAND *));
-extern COMMAND *make_until_command __P((COMMAND *, COMMAND *));
-extern COMMAND *make_bare_simple_command __P((void));
-extern COMMAND *make_simple_command __P((ELEMENT, COMMAND *));
-extern void make_here_document __P((REDIRECT *, int));
-extern REDIRECT *make_redirection __P((REDIRECTEE, enum r_instruction, REDIRECTEE));
-extern COMMAND *make_function_def __P((WORD_DESC *, COMMAND *, int, int));
-extern COMMAND *clean_simple_command __P((COMMAND *));
-
-extern COMMAND *make_arith_command __P((WORD_LIST *));
-
-extern COMMAND *make_select_command __P((WORD_DESC *, WORD_LIST *, COMMAND *, int));
-
-#if defined (COND_COMMAND)
-extern COND_COM *make_cond_node __P((int, WORD_DESC *, COND_COM *, COND_COM *));
-extern COMMAND *make_cond_command __P((COND_COM *));
-#endif
-
-extern COMMAND *make_arith_for_command __P((WORD_LIST *, COMMAND *, int));
-
-extern COMMAND *make_subshell_command __P((COMMAND *));
-extern COMMAND *make_coproc_command __P((char *, COMMAND *));
-
-extern COMMAND *connect_async_list __P((COMMAND *, COMMAND *, int));
-
-#endif /* !_MAKE_CMD_H */
diff --git a/parse.y.diff b/parse.y.diff
deleted file mode 100644 (file)
index ece54ba..0000000
+++ /dev/null
@@ -1,326 +0,0 @@
-*** ../bash-4.0/parse.y        2009-01-08 08:29:12.000000000 -0500
---- parse.y    2009-03-06 20:32:35.000000000 -0500
-***************
-*** 1616,1623 ****
-    int *ret;
-  
-!   ret = (int *)xmalloc (3 * sizeof (int));
-    ret[0] = last_read_token;
-    ret[1] = token_before_that;
-    ret[2] = two_tokens_ago;
-    return ret;
-  }
---- 1616,1624 ----
-    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;
-  }
-***************
-*** 1632,1635 ****
---- 1633,1637 ----
-    token_before_that = ts[1];
-    two_tokens_ago = ts[2];
-+   current_token = ts[3];
-  }
-  
-***************
-*** 2669,2672 ****
---- 2671,2675 ----
-    word_desc_to_read = (WORD_DESC *)NULL;
-  
-+   current_token = '\n';              /* XXX */
-    last_read_token = '\n';
-    token_to_read = '\n';
-***************
-*** 2916,2919 ****
---- 2919,2923 ----
-  #define P_COMMAND    0x08    /* parsing a command, so look for comments */
-  #define P_BACKQUOTE  0x10    /* parsing a backquoted command substitution */
-+ #define P_ARRAYSUB   0x20    /* parsing a [...] array subscript for assignment */
-  
-  /* Lexical state while parsing a grouping construct or $(...). */
-***************
-*** 2928,2931 ****
---- 2932,2936 ----
-  #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) == '|')
-***************
-*** 2963,2967 ****
-    int retind, retsize, rflags;
-  
-! /* itrace("parse_matched_pair: open = %c close = %c flags = %d", open, close, flags); */
-    count = 1;
-    tflags = 0;
---- 2968,2972 ----
-    int retind, retsize, rflags;
-  
-! /*itrace("parse_matched_pair: open = %c close = %c flags = %d", open, close, flags); */
-    count = 1;
-    tflags = 0;
-***************
-*** 3130,3133 ****
---- 3135,3140 ----
-             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
-***************
-*** 3146,3149 ****
---- 3153,3157 ----
-       /* check for $(), $[], or ${} inside quoted string. */
-       {
-+ parse_dollar_word:
-         if (open == ch)       /* undo previous increment */
-           count--;
-***************
-*** 3180,3184 ****
-       int *lenp, flags;
-  {
-!   int count, ch, peekc, tflags, lex_rwlen, lex_firstind;
-    int nestlen, ttranslen, start_lineno;
-    char *ret, *nestret, *ttrans, *heredelim;
---- 3188,3192 ----
-       int *lenp, flags;
-  {
-!   int count, ch, peekc, tflags, lex_rwlen, lex_wlen, lex_firstind;
-    int nestlen, ttranslen, start_lineno;
-    char *ret, *nestret, *ttrans, *heredelim;
-***************
-*** 3201,3205 ****
-  
-    start_lineno = line_number;
-!   lex_rwlen = 0;
-  
-    heredelim = 0;
---- 3209,3213 ----
-  
-    start_lineno = line_number;
-!   lex_rwlen = lex_wlen = 0;
-  
-    heredelim = 0;
-***************
-*** 3268,3271 ****
---- 3276,3319 ----
-       }
-  
-+       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 || ch == CTLNUL)
-+          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) && lex_rwlen == 0)
-***************
-*** 3317,3321 ****
-             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;
---- 3365,3369 ----
-             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;
-***************
-*** 3325,3330 ****
-           {
-             shell_ungetc (peekc);
--            tflags |= LEX_RESWDOK;
-  /*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch);*/
-             lex_rwlen = 0;
-             continue;
---- 3373,3378 ----
-           {
-             shell_ungetc (peekc);
-  /*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch);*/
-+            tflags |= LEX_RESWDOK;
-             lex_rwlen = 0;
-             continue;
-***************
-*** 3365,3369 ****
-             tflags &= ~LEX_RESWDOK;
-           }
-!        else if (shellbreak (ch) == 0)
-  {
-             tflags &= ~LEX_RESWDOK;
---- 3413,3419 ----
-             tflags &= ~LEX_RESWDOK;
-           }
-!        else if MBTEST((tflags & LEX_CKCOMMENT) && ch == '#' && (lex_rwlen == 0 || ((tflags & LEX_INWORD) && lex_wlen == 0)))
-!          ;   /* don't turn off LEX_RESWDOK if we're starting a comment */
-!        else if MBTEST(shellbreak (ch) == 0)
-  {
-             tflags &= ~LEX_RESWDOK;
-***************
-*** 3372,3375 ****
---- 3422,3426 ----
-       }
-  
-+       /* Might be the start of a here-doc delimiter */
-        if MBTEST((tflags & LEX_INCOMMENT) == 0 && (tflags & LEX_CKCASE) && ch == '<')
-       {
-***************
-*** 3395,3428 ****
-             else
-               shell_ungetc (peekc);
-!            tflags |= LEX_HEREDELIM;
-!            lex_firstind = -1;
-             continue;
-           }
-         else
-!          ch = peekc;         /* fall through and continue XXX - this skips comments if peekc == '#' */
-       }
-!       /* 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 || ch == CTLNUL)
-!          ret[retind++] = CTLESC;
-!        ret[retind++] = ch;
-!        continue;
-!      }
-!       else if MBTEST(ch == CTLESC || ch == CTLNUL)   /* special shell escapes */
-       {
-         RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
---- 3446,3466 ----
-             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);
-***************
-*** 4249,4253 ****
-                     (token_index == 0 && (parser_state&PST_COMPASSIGN))))
-          {
-!        ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
-         if (ttok == &matched_pair_error)
-           return -1;          /* Bail immediately. */
---- 4287,4291 ----
-                     (token_index == 0 && (parser_state&PST_COMPASSIGN))))
-          {
-!        ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARRAYSUB);
-         if (ttok == &matched_pair_error)
-           return -1;          /* Bail immediately. */
-***************
-*** 4450,4453 ****
---- 4488,4492 ----
-      case AND_AND:
-      case BANG:
-+     case BAR_AND:
-      case DO:
-      case DONE:
-***************
-*** 5184,5188 ****
-        if (interactive && EOF_Reached)
-       EOF_Reached = 0;
-!       last_command_exit_value = EX_USAGE;
-        return;
-      }
---- 5223,5227 ----
-        if (interactive && EOF_Reached)
-       EOF_Reached = 0;
-!       last_command_exit_value = EX_BADUSAGE;
-        return;
-      }
-***************
-*** 5199,5203 ****
-       print_offending_line ();
-  
-!       last_command_exit_value = EX_USAGE;
-        return;
-      }
---- 5238,5242 ----
-       print_offending_line ();
-  
-!       last_command_exit_value = EX_BADUSAGE;
-        return;
-      }
-***************
-*** 5230,5234 ****
-      }
-  
-!   last_command_exit_value = EX_USAGE;
-  }
-  
---- 5269,5273 ----
-      }
-  
-!   last_command_exit_value = EX_BADUSAGE;
-  }
-  
diff --git a/parse.y.new b/parse.y.new
deleted file mode 100644 (file)
index 7498738..0000000
+++ /dev/null
@@ -1,5671 +0,0 @@
-/* parse.y - Yacc grammar for bash. */
-
-/* Copyright (C) 1989-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/>.
-*/
-
-%{
-#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 "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 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 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 number of lines read from input while creating the current command. */
-int current_command_line_count;
-
-/* The token that currently denotes the end of parse. */
-int shell_eof_token;
-
-/* The token currently being read. */
-int current_token;
-
-/* 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 int shell_input_line_index;
-static int shell_input_line_size;      /* Amount allocated for shell_input_line. */
-static int 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 current parser state. */
-static int parser_state;
-
-/* 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;
-
-/* 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 redir;
-%}
-
-%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
-
-/* More general tokens. yylex () knows how to make these. */
-%token <word> WORD ASSIGNMENT_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
-                       {
-                         redir.filename = $2;
-                         $$ = make_redirection (1, r_output_direction, redir);
-                       }
-       |       '<' WORD
-                       {
-                         redir.filename = $2;
-                         $$ = make_redirection (0, r_input_direction, redir);
-                       }
-       |       NUMBER '>' WORD
-                       {
-                         redir.filename = $3;
-                         $$ = make_redirection ($1, r_output_direction, redir);
-                       }
-       |       NUMBER '<' WORD
-                       {
-                         redir.filename = $3;
-                         $$ = make_redirection ($1, r_input_direction, redir);
-                       }
-       |       GREATER_GREATER WORD
-                       {
-                         redir.filename = $2;
-                         $$ = make_redirection (1, r_appending_to, redir);
-                       }
-       |       NUMBER GREATER_GREATER WORD
-                       {
-                         redir.filename = $3;
-                         $$ = make_redirection ($1, r_appending_to, redir);
-                       }
-       |       LESS_LESS WORD
-                       {
-                         redir.filename = $2;
-                         $$ = make_redirection (0, r_reading_until, redir);
-                         redir_stack[need_here_doc++] = $$;
-                       }
-       |       NUMBER LESS_LESS WORD
-                       {
-                         redir.filename = $3;
-                         $$ = make_redirection ($1, r_reading_until, redir);
-                         redir_stack[need_here_doc++] = $$;
-                       }
-       |       LESS_LESS_LESS WORD
-                       {
-                         redir.filename = $2;
-                         $$ = make_redirection (0, r_reading_string, redir);
-                       }
-       |       NUMBER LESS_LESS_LESS WORD
-                       {
-                         redir.filename = $3;
-                         $$ = make_redirection ($1, r_reading_string, redir);
-                       }
-       |       LESS_AND NUMBER
-                       {
-                         redir.dest = $2;
-                         $$ = make_redirection (0, r_duplicating_input, redir);
-                       }
-       |       NUMBER LESS_AND NUMBER
-                       {
-                         redir.dest = $3;
-                         $$ = make_redirection ($1, r_duplicating_input, redir);
-                       }
-       |       GREATER_AND NUMBER
-                       {
-                         redir.dest = $2;
-                         $$ = make_redirection (1, r_duplicating_output, redir);
-                       }
-       |       NUMBER GREATER_AND NUMBER
-                       {
-                         redir.dest = $3;
-                         $$ = make_redirection ($1, r_duplicating_output, redir);
-                       }
-       |       LESS_AND WORD
-                       {
-                         redir.filename = $2;
-                         $$ = make_redirection (0, r_duplicating_input_word, redir);
-                       }
-       |       NUMBER LESS_AND WORD
-                       {
-                         redir.filename = $3;
-                         $$ = make_redirection ($1, r_duplicating_input_word, redir);
-                       }
-       |       GREATER_AND WORD
-                       {
-                         redir.filename = $2;
-                         $$ = make_redirection (1, r_duplicating_output_word, redir);
-                       }
-       |       NUMBER GREATER_AND WORD
-                       {
-                         redir.filename = $3;
-                         $$ = make_redirection ($1, r_duplicating_output_word, redir);
-                       }
-       |       LESS_LESS_MINUS WORD
-                       {
-                         redir.filename = $2;
-                         $$ = make_redirection
-                           (0, r_deblank_reading_until, redir);
-                         redir_stack[need_here_doc++] = $$;
-                       }
-       |       NUMBER LESS_LESS_MINUS WORD
-                       {
-                         redir.filename = $3;
-                         $$ = make_redirection
-                           ($1, r_deblank_reading_until, redir);
-                         redir_stack[need_here_doc++] = $$;
-                       }
-       |       GREATER_AND '-'
-                       {
-                         redir.dest = 0;
-                         $$ = make_redirection (1, r_close_this, redir);
-                       }
-       |       NUMBER GREATER_AND '-'
-                       {
-                         redir.dest = 0;
-                         $$ = make_redirection ($1, r_close_this, redir);
-                       }
-       |       LESS_AND '-'
-                       {
-                         redir.dest = 0;
-                         $$ = make_redirection (0, r_close_this, redir);
-                       }
-       |       NUMBER LESS_AND '-'
-                       {
-                         redir.dest = 0;
-                         $$ = make_redirection ($1, r_close_this, redir);
-                       }
-       |       AND_GREATER WORD
-                       {
-                         redir.filename = $2;
-                         $$ = make_redirection (1, r_err_and_out, redir);
-                       }
-       |       AND_GREATER_GREATER WORD
-                       {
-                         redir.filename = $2;
-                         $$ = make_redirection (1, r_append_err_and_out, redir);
-                       }
-       |       NUMBER LESS_GREATER WORD
-                       {
-                         redir.filename = $3;
-                         $$ = make_redirection ($1, r_input_output, redir);
-                       }
-       |       LESS_GREATER WORD
-                       {
-                         redir.filename = $2;
-                         $$ = make_redirection (0, r_input_output, redir);
-                       }
-       |       GREATER_BAR WORD
-                       {
-                         redir.filename = $2;
-                         $$ = make_redirection (1, r_output_force, redir);
-                       }
-       |       NUMBER GREATER_BAR WORD
-                       {
-                         redir.filename = $3;
-                         $$ = make_redirection ($1, r_output_force, redir);
-                       }
-       ;
-
-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
-                       {
-                         if ($2)
-                           $2->flags |= CMD_INVERT_RETURN;
-                         $$ = $2;
-                       }
-       |       timespec pipeline
-                       {
-                         if ($2)
-                           $2->flags |= $1;
-                         $$ = $2;
-                       }
-       |       timespec BANG pipeline
-                       {
-                         if ($3)
-                           $3->flags |= $1|CMD_INVERT_RETURN;
-                         $$ = $3;
-                       }
-       |       BANG timespec pipeline
-                       {
-                         if ($3)
-                           $3->flags |= $2|CMD_INVERT_RETURN;
-                         $$ = $3;
-                       }
-       |       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';
-                       }
-                       
-       ;
-
-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;
-                         REDIRECT *r;
-
-                         tc = $1;
-                         rd.dest = 1;
-                         r = make_redirection (2, r_duplicating_output, rd);
-                         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; }
-       ;
-%%
-
-/* 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 *)NULL;
-      if (signal_is_ignored (SIGINT) == 0)
-       {
-         old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler);
-         interrupt_immediately++;
-       }
-      terminate_immediately = 1;
-
-      current_readline_line = readline (current_readline_prompt ?
-                                         current_readline_prompt : "");
-
-      terminate_immediately = 0;
-      if (signal_is_ignored (SIGINT) == 0 && old_sigint)
-       {
-         interrupt_immediately--;
-         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 (interactive)
-       {
-         interrupt_immediately++;
-         terminate_immediately++;
-       }
-      result = getc_with_restart (bash_input.location.file);
-      if (interactive)
-       {
-         interrupt_immediately--;
-         terminate_immediately--;
-       }
-    }
-  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;
-
-#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
-  int saved_line_size, saved_line_index, 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 = 0, c, peekc, pass_next;
-
-#if defined (READLINE)
-  if (no_line_editing && SHOULD_PROMPT ())
-#else
-  if (SHOULD_PROMPT ())
-#endif
-    print_prompt ();
-
-  pass_next = 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)
-       {
-         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 (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 */
-  { "-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;
-  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++;
-
-    restart_read:
-
-      /* Allow immediate exit if interrupted during input. */
-      QUIT;
-
-      i = 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;
-           }
-
-         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;
-           }
-
-         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)
-               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 ();
-             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_len + 3 > shell_input_line_size)
-           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 ();
-       }
-    }
-
-  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. */
-  if (!uc && (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++;
-       goto restart_read;
-    }
-
-  if (!uc && 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 && 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) || \
-   ((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 (r[l -1] != ' ')
-    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)
-  switch (last_read_token)
-    {
-    case 0:
-    case ';':
-    case '\n':
-    case AND_AND:
-    case OR_OR:
-    case '&':
-    case DO:
-    case THEN:
-    case ELSE:
-    case '{':          /* } */
-    case '(':          /* ) */
-      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 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);
-#endif
-
-#if 0
-#if defined (COMMAND_TIMING)
-  if (STREQ (token, "time") && ((parser_state & PST_CASEPAT) == 0) && time_command_acceptable ())
-    return (TIME);
-#endif /* COMMAND_TIMING */
-#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;
-
-  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   0x01
-#define P_ALLOWESC     0x02
-#define P_DQUOTE       0x04
-#define P_COMMAND      0x08    /* parsing a command, so look for comments */
-#define P_BACKQUOTE    0x10    /* parsing a backquoted command substitution */
-#define P_ARRAYSUB     0x20    /* parsing a [...] array subscript for assignment */
-
-/* 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;
-
-/* itrace("parse_matched_pair: open = %c close = %c flags = %d", 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 || ch == CTLNUL)
-           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;
-
-#if 0
-      /* The big hammer.  Single quotes aren't special in double quotes.  The
-         problem is that Posix says 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." */
-      if MBTEST(open == '{' && (flags & P_DQUOTE) && ch == '\'')       /* } */
-       continue;
-#endif
-
-      /* 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 ((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|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;
-  return ret;
-}
-
-/* Not exactly right yet, should handle shell metacharacters better.  If
-   any changes are made to this test, make analogous changes to subst.c:
-   extract_delimited_string(). */
-#define COMMENT_BEGIN(x)       ((x) == '#' && (retind == 0 || ret[retind-1] == '\n' || shellblank (ret[retind - 1])))
-
-/* 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_firstind;
-  int nestlen, ttranslen, start_lineno;
-  char *ret, *nestret, *ttrans, *heredelim;
-  int retind, retsize, rflags, hdlen;
-
-/*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 = 0;
-
-  heredelim = 0;
-  lex_firstind = -1;
-
-  while (count)
-    {
-comsub_readchar:
-      ch = shell_getc (qc != '\'' && (tflags & 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);*/
-                 lex_firstind = -1;
-               }
-             else
-               lex_firstind = retind + 1;
-           }
-       }
-
-      /* Possible reprompting. */
-      if (ch == '\n' && SHOULD_PROMPT ())
-       prompt_again ();
-
-      /* 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')
-           tflags &= ~LEX_INCOMMENT;
-
-         continue;
-       }
-
-      /* Skip whitespace */
-      if MBTEST(shellblank (ch) && 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;
-         else if (lex_firstind >= 0 && (tflags & LEX_PASSNEXT) == 0 && shellbreak (ch))
-           {
-             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;
-           }
-       }
-
-      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 || ch == CTLNUL)
-           ret[retind++] = CTLESC;
-         ret[retind++] = ch;
-         continue;
-       }
-
-      /* 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))
-       {
-         /* 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);
-             tflags |= LEX_RESWDOK;
-/*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch);*/
-             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", line_number);*/
-}
-             else if (STREQN (ret + retind - 4, "esac", 4))
-{
-               tflags &= ~LEX_INCASE;
-/*itrace("parse_comsub:%d: found `esac', lex_incase -> 0", line_number);*/
-}              
-             tflags &= ~LEX_RESWDOK;
-           }
-         else if MBTEST((tflags & LEX_CKCOMMENT) && COMMENT_BEGIN(ch))
-           ;   /* don't turn off LEX_RESWDOK if we're starting a comment */
-         else if MBTEST(shellbreak (ch) == 0)
-{
-             tflags &= ~LEX_RESWDOK;
-/*itrace("parse_comsub:%d: found `%c', lex_reswordok -> 0", line_number, ch);*/
-}
-       }
-
-      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 - this skips comments if peekc == '#' */
-       }
-      else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && COMMENT_BEGIN(ch))
-       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
-      /* XXX - could check for here doc delimiter if count == 0 */
-      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++;
-
-      /* 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|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;
-}
-
-/* XXX - this needs to handle functionality like subst.c:no_longjmp_on_fatal_error;
-   maybe extract_command_subst should handle it. */
-char *
-xparse_dolparen (base, string, indp, flags)
-     char *base;
-     char *string;
-     int *indp;
-     int flags;
-{
-  sh_parser_state_t ps;
-  int orig_ind, nc, sflags;
-  char *ret, *s, *ep, *ostring;
-
-  /*yydebug = 1;*/
-  orig_ind = *indp;
-  ostring = string;
-
-  sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE;
-  if (flags & SX_NOLONGJMP)
-    sflags |= SEVAL_NOLONGJMP;
-  save_parser_state (&ps);
-
-  /*(*/
-  parser_state |= PST_CMDSUBST|PST_EOFTOKEN;   /* allow instant ')' */ /*(*/
-  shell_eof_token = ')';
-  parse_string (string, "command substitution", sflags, &ep);
-
-  restore_parser_state (&ps);
-  reset_parser ();
-  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 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 */
-      tok = read_token (READ);
-      parser_state &= ~PST_REGEXP;
-      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;
-
-  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 + 2,
-                                     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);
-             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 + 2,
-                                     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 + 2,
-                                     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 == '$')
-           {
-             ttok = (char *)xmalloc (3);
-             ttok[0] = ttok[1] = '$';
-             ttok[2] = '\0';
-             RESIZE_MALLOCED_BUFFER (token, token_index, 3,
-                                     token_buffer_size,
-                                     TOKEN_DEFAULT_GROW_SIZE);
-             strcpy (token + token_index, ttok);
-             token_index += 2;
-             dollar_present = 1;
-             all_digit_token = 0;
-             FREE (ttok);
-             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);
-
-             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)
-       token[token_index++] = CTLESC;
-
-    got_escaped_character:
-
-      all_digit_token &= DIGIT (character);
-      dollar_present |= character == '$';
-
-      token[token_index++] = character;
-
-      RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
-                             TOKEN_DEFAULT_GROW_SIZE);
-
-    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:
-
-  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;
-       else
-         yylval.number = -1;
-       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 (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;
-
-  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 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
-      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;
-}
-
-#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. */
-char *
-history_delimiting_chars ()
-{
-  register int i;
-
-  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). */
-  if (parser_state & PST_HEREDOC)
-    return (current_command_line_count == 2 ? "\n" : "");
-
-  /* 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 `()' */
-
-  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;
-#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);
-             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';
-
-#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)
-                         strcpy (t_string, t + 1);
-                     }
-                 }
-#undef ROOT_PATH
-#undef DOUBLE_SLASH_ROOT
-               else
-                 /* polite_directory_format is guaranteed to return a string
-                    no longer than PATH_MAX - 1 characters. */
-                 strcpy (t_string, polite_directory_format (t_string));
-
-               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;
-      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;
-    }
-  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;
-
-  if (message)
-    {
-      parser_error (line_number, "%s", message);
-      if (interactive && EOF_Reached)
-       EOF_Reached = 0;
-      last_command_exit_value = 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)))
-    {
-      parser_error (line_number, _("syntax error near unexpected token `%s'"), msg);
-      free (msg);
-
-      if (interactive == 0)
-       print_offending_line ();
-
-      last_command_exit_value = 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 = 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;
-  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 defined (ARRAY_VARS)
-  SHELL_VAR *v;
-#endif
-
-  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->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)
-  v = find_variable ("PIPESTATUS");
-  if (v && array_p (v) && array_cell (v))
-    ps->pipestatus = array_copy (array_cell (v));
-  else
-    ps->pipestatus = (ARRAY *)NULL;
-#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;
-
-  return (ps);
-}
-
-void
-restore_parser_state (ps)
-     sh_parser_state_t *ps;
-{
-#if defined (ARRAY_VARS)
-  SHELL_VAR *v;
-#endif
-
-  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;
-
-  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)
-  v = find_variable ("PIPESTATUS");
-  if (v && array_p (v) && array_cell (v))
-    {
-      array_dispose (array_cell (v));
-      var_setarray (v, 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;
-}
-
-/************************************************
- *                                             *
- *     MULTIBYTE CHARACTER HANDLING            *
- *                                             *
- ************************************************/
-
-#if defined (HANDLE_MULTIBYTE)
-static void
-set_line_mbstate ()
-{
-  int i, previ, len, c;
-  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)
-       {
-         int 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) */
-         int j;
-         for (j = i; j < len; j++)
-           shell_input_line_property[j] = 1;
-         break;
-       }
-
-      shell_input_line_property[i] = mbclen;
-    }
-}
-#endif /* HANDLE_MULTIBYTE */
diff --git a/parse.y.save b/parse.y.save
deleted file mode 100644 (file)
index e7a0251..0000000
+++ /dev/null
@@ -1,5708 +0,0 @@
-/* parse.y - Yacc grammar for bash. */
-
-/* Copyright (C) 1989-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/>.
-*/
-
-%{
-#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 "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 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 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 number of lines read from input while creating the current command. */
-int current_command_line_count;
-
-/* The token that currently denotes the end of parse. */
-int shell_eof_token;
-
-/* The token currently being read. */
-int current_token;
-
-/* 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 int shell_input_line_index;
-static int shell_input_line_size;      /* Amount allocated for shell_input_line. */
-static int 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 current parser state. */
-static int parser_state;
-
-/* 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;
-
-/* 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 redir;
-%}
-
-%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
-
-/* More general tokens. yylex () knows how to make these. */
-%token <word> WORD ASSIGNMENT_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
-                       {
-                         redir.filename = $2;
-                         $$ = make_redirection (1, r_output_direction, redir);
-                       }
-       |       '<' WORD
-                       {
-                         redir.filename = $2;
-                         $$ = make_redirection (0, r_input_direction, redir);
-                       }
-       |       NUMBER '>' WORD
-                       {
-                         redir.filename = $3;
-                         $$ = make_redirection ($1, r_output_direction, redir);
-                       }
-       |       NUMBER '<' WORD
-                       {
-                         redir.filename = $3;
-                         $$ = make_redirection ($1, r_input_direction, redir);
-                       }
-       |       GREATER_GREATER WORD
-                       {
-                         redir.filename = $2;
-                         $$ = make_redirection (1, r_appending_to, redir);
-                       }
-       |       NUMBER GREATER_GREATER WORD
-                       {
-                         redir.filename = $3;
-                         $$ = make_redirection ($1, r_appending_to, redir);
-                       }
-       |       LESS_LESS WORD
-                       {
-                         redir.filename = $2;
-                         $$ = make_redirection (0, r_reading_until, redir);
-                         redir_stack[need_here_doc++] = $$;
-                       }
-       |       NUMBER LESS_LESS WORD
-                       {
-                         redir.filename = $3;
-                         $$ = make_redirection ($1, r_reading_until, redir);
-                         redir_stack[need_here_doc++] = $$;
-                       }
-       |       LESS_LESS_LESS WORD
-                       {
-                         redir.filename = $2;
-                         $$ = make_redirection (0, r_reading_string, redir);
-                       }
-       |       NUMBER LESS_LESS_LESS WORD
-                       {
-                         redir.filename = $3;
-                         $$ = make_redirection ($1, r_reading_string, redir);
-                       }
-       |       LESS_AND NUMBER
-                       {
-                         redir.dest = $2;
-                         $$ = make_redirection (0, r_duplicating_input, redir);
-                       }
-       |       NUMBER LESS_AND NUMBER
-                       {
-                         redir.dest = $3;
-                         $$ = make_redirection ($1, r_duplicating_input, redir);
-                       }
-       |       GREATER_AND NUMBER
-                       {
-                         redir.dest = $2;
-                         $$ = make_redirection (1, r_duplicating_output, redir);
-                       }
-       |       NUMBER GREATER_AND NUMBER
-                       {
-                         redir.dest = $3;
-                         $$ = make_redirection ($1, r_duplicating_output, redir);
-                       }
-       |       LESS_AND WORD
-                       {
-                         redir.filename = $2;
-                         $$ = make_redirection (0, r_duplicating_input_word, redir);
-                       }
-       |       NUMBER LESS_AND WORD
-                       {
-                         redir.filename = $3;
-                         $$ = make_redirection ($1, r_duplicating_input_word, redir);
-                       }
-       |       GREATER_AND WORD
-                       {
-                         redir.filename = $2;
-                         $$ = make_redirection (1, r_duplicating_output_word, redir);
-                       }
-       |       NUMBER GREATER_AND WORD
-                       {
-                         redir.filename = $3;
-                         $$ = make_redirection ($1, r_duplicating_output_word, redir);
-                       }
-       |       LESS_LESS_MINUS WORD
-                       {
-                         redir.filename = $2;
-                         $$ = make_redirection
-                           (0, r_deblank_reading_until, redir);
-                         redir_stack[need_here_doc++] = $$;
-                       }
-       |       NUMBER LESS_LESS_MINUS WORD
-                       {
-                         redir.filename = $3;
-                         $$ = make_redirection
-                           ($1, r_deblank_reading_until, redir);
-                         redir_stack[need_here_doc++] = $$;
-                       }
-       |       GREATER_AND '-'
-                       {
-                         redir.dest = 0;
-                         $$ = make_redirection (1, r_close_this, redir);
-                       }
-       |       NUMBER GREATER_AND '-'
-                       {
-                         redir.dest = 0;
-                         $$ = make_redirection ($1, r_close_this, redir);
-                       }
-       |       LESS_AND '-'
-                       {
-                         redir.dest = 0;
-                         $$ = make_redirection (0, r_close_this, redir);
-                       }
-       |       NUMBER LESS_AND '-'
-                       {
-                         redir.dest = 0;
-                         $$ = make_redirection ($1, r_close_this, redir);
-                       }
-       |       AND_GREATER WORD
-                       {
-                         redir.filename = $2;
-                         $$ = make_redirection (1, r_err_and_out, redir);
-                       }
-       |       AND_GREATER_GREATER WORD
-                       {
-                         redir.filename = $2;
-                         $$ = make_redirection (1, r_append_err_and_out, redir);
-                       }
-       |       NUMBER LESS_GREATER WORD
-                       {
-                         redir.filename = $3;
-                         $$ = make_redirection ($1, r_input_output, redir);
-                       }
-       |       LESS_GREATER WORD
-                       {
-                         redir.filename = $2;
-                         $$ = make_redirection (0, r_input_output, redir);
-                       }
-       |       GREATER_BAR WORD
-                       {
-                         redir.filename = $2;
-                         $$ = make_redirection (1, r_output_force, redir);
-                       }
-       |       NUMBER GREATER_BAR WORD
-                       {
-                         redir.filename = $3;
-                         $$ = make_redirection ($1, r_output_force, redir);
-                       }
-       ;
-
-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
-                       {
-                         if ($2)
-                           $2->flags |= CMD_INVERT_RETURN;
-                         $$ = $2;
-                       }
-       |       timespec pipeline
-                       {
-                         if ($2)
-                           $2->flags |= $1;
-                         $$ = $2;
-                       }
-       |       timespec BANG pipeline
-                       {
-                         if ($3)
-                           $3->flags |= $1|CMD_INVERT_RETURN;
-                         $$ = $3;
-                       }
-       |       BANG timespec pipeline
-                       {
-                         if ($3)
-                           $3->flags |= $2|CMD_INVERT_RETURN;
-                         $$ = $3;
-                       }
-       |       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';
-                       }
-                       
-       ;
-
-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;
-                         REDIRECT *r;
-
-                         tc = $1->type == cm_simple ? (COMMAND *)$1->value.Simple : $1;
-                         rd.dest = 1;
-                         r = make_redirection (2, r_duplicating_output, rd);
-                         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; }
-       ;
-%%
-
-/* 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 *)NULL;
-      if (signal_is_ignored (SIGINT) == 0)
-       {
-         old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler);
-         interrupt_immediately++;
-       }
-      terminate_immediately = 1;
-
-      current_readline_line = readline (current_readline_prompt ?
-                                         current_readline_prompt : "");
-
-      terminate_immediately = 0;
-      if (signal_is_ignored (SIGINT) == 0 && old_sigint)
-       {
-         interrupt_immediately--;
-         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 (interactive)
-       {
-         interrupt_immediately++;
-         terminate_immediately++;
-       }
-      result = getc_with_restart (bash_input.location.file);
-      if (interactive)
-       {
-         interrupt_immediately--;
-         terminate_immediately--;
-       }
-    }
-  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;
-
-#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
-  int saved_line_size, saved_line_index, 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 = 0, c, peekc, pass_next;
-
-#if defined (READLINE)
-  if (no_line_editing && SHOULD_PROMPT ())
-#else
-  if (SHOULD_PROMPT ())
-#endif
-    print_prompt ();
-
-  pass_next = 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)
-       {
-         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 (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 */
-  { "-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;
-  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++;
-
-    restart_read:
-
-      /* Allow immediate exit if interrupted during input. */
-      QUIT;
-
-      i = 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;
-           }
-
-         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;
-           }
-
-         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)
-               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 ();
-             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_len + 3 > shell_input_line_size)
-           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 ();
-       }
-    }
-
-  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. */
-  if (!uc && (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++;
-       goto restart_read;
-    }
-
-  if (!uc && 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 && 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) || \
-   ((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 (r[l -1] != ' ')
-    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)
-  switch (last_read_token)
-    {
-    case 0:
-    case ';':
-    case '\n':
-    case AND_AND:
-    case OR_OR:
-    case '&':
-    case DO:
-    case THEN:
-    case ELSE:
-    case '{':          /* } */
-    case '(':          /* ) */
-      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 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);
-#endif
-
-#if 0
-#if defined (COMMAND_TIMING)
-  if (STREQ (token, "time") && ((parser_state & PST_CASEPAT) == 0) && time_command_acceptable ())
-    return (TIME);
-#endif /* COMMAND_TIMING */
-#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;
-
-  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   0x01
-#define P_ALLOWESC     0x02
-#define P_DQUOTE       0x04
-#define P_COMMAND      0x08    /* parsing a command, so look for comments */
-#define P_BACKQUOTE    0x10    /* parsing a backquoted command substitution */
-#define P_ARRAYSUB     0x20    /* parsing a [...] array subscript for assignment */
-
-/* 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;
-
-/*itrace("parse_matched_pair: open = %c close = %c flags = %d", 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 || ch == CTLNUL)
-           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;
-
-#if 0
-      /* The big hammer.  Single quotes aren't special in double quotes.  The
-         problem is that Posix says 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." */
-      if MBTEST(open == '{' && (flags & P_DQUOTE) && ch == '\'')       /* } */
-       continue;
-#endif
-
-      /* 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 ((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|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;
-  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;
-
-/*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_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);*/
-                 lex_firstind = -1;
-               }
-             else
-               lex_firstind = retind + 1;
-           }
-       }
-
-      /* Possible reprompting. */
-      if (ch == '\n' && SHOULD_PROMPT ())
-       prompt_again ();
-
-      /* 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 || ch == CTLNUL)
-           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) && 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;
-         else if (lex_firstind >= 0 && (tflags & LEX_PASSNEXT) == 0 && shellbreak (ch))
-           {
-             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))
-       {
-         /* 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 */
-         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);*/
-}
-       }
-
-      /* 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|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;
-}
-
-/* XXX - this needs to handle functionality like subst.c:no_longjmp_on_fatal_error;
-   maybe extract_command_subst should handle it. */
-char *
-xparse_dolparen (base, string, indp, flags)
-     char *base;
-     char *string;
-     int *indp;
-     int flags;
-{
-  sh_parser_state_t ps;
-  int orig_ind, nc, sflags;
-  char *ret, *s, *ep, *ostring;
-
-  /*yydebug = 1;*/
-  orig_ind = *indp;
-  ostring = string;
-
-  sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE;
-  if (flags & SX_NOLONGJMP)
-    sflags |= SEVAL_NOLONGJMP;
-  save_parser_state (&ps);
-
-  /*(*/
-  parser_state |= PST_CMDSUBST|PST_EOFTOKEN;   /* allow instant ')' */ /*(*/
-  shell_eof_token = ')';
-  parse_string (string, "command substitution", sflags, &ep);
-
-  restore_parser_state (&ps);
-  reset_parser ();
-  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 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 */
-      tok = read_token (READ);
-      parser_state &= ~PST_REGEXP;
-      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;
-
-  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 + 2,
-                                     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);
-             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 + 2,
-                                     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 + 2,
-                                     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 == '$')
-           {
-             ttok = (char *)xmalloc (3);
-             ttok[0] = ttok[1] = '$';
-             ttok[2] = '\0';
-             RESIZE_MALLOCED_BUFFER (token, token_index, 3,
-                                     token_buffer_size,
-                                     TOKEN_DEFAULT_GROW_SIZE);
-             strcpy (token + token_index, ttok);
-             token_index += 2;
-             dollar_present = 1;
-             all_digit_token = 0;
-             FREE (ttok);
-             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);
-
-             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)
-       token[token_index++] = CTLESC;
-
-    got_escaped_character:
-
-      all_digit_token &= DIGIT (character);
-      dollar_present |= character == '$';
-
-      token[token_index++] = character;
-
-      RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
-                             TOKEN_DEFAULT_GROW_SIZE);
-
-    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:
-
-  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;
-       else
-         yylval.number = -1;
-       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 (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;
-
-  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 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
-      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;
-}
-
-#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. */
-char *
-history_delimiting_chars ()
-{
-  register int i;
-
-  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). */
-  if (parser_state & PST_HEREDOC)
-    return (current_command_line_count == 2 ? "\n" : "");
-
-  /* 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 `()' */
-
-  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;
-#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);
-             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';
-
-#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)
-                         strcpy (t_string, t + 1);
-                     }
-                 }
-#undef ROOT_PATH
-#undef DOUBLE_SLASH_ROOT
-               else
-                 /* polite_directory_format is guaranteed to return a string
-                    no longer than PATH_MAX - 1 characters. */
-                 strcpy (t_string, polite_directory_format (t_string));
-
-               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;
-      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;
-    }
-  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;
-
-  if (message)
-    {
-      parser_error (line_number, "%s", message);
-      if (interactive && EOF_Reached)
-       EOF_Reached = 0;
-      last_command_exit_value = 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)))
-    {
-      parser_error (line_number, _("syntax error near unexpected token `%s'"), msg);
-      free (msg);
-
-      if (interactive == 0)
-       print_offending_line ();
-
-      last_command_exit_value = 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 = 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;
-  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 defined (ARRAY_VARS)
-  SHELL_VAR *v;
-#endif
-
-  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->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)
-  v = find_variable ("PIPESTATUS");
-  if (v && array_p (v) && array_cell (v))
-    ps->pipestatus = array_copy (array_cell (v));
-  else
-    ps->pipestatus = (ARRAY *)NULL;
-#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;
-
-  return (ps);
-}
-
-void
-restore_parser_state (ps)
-     sh_parser_state_t *ps;
-{
-#if defined (ARRAY_VARS)
-  SHELL_VAR *v;
-#endif
-
-  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;
-
-  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)
-  v = find_variable ("PIPESTATUS");
-  if (v && array_p (v) && array_cell (v))
-    {
-      array_dispose (array_cell (v));
-      var_setarray (v, 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;
-}
-
-/************************************************
- *                                             *
- *     MULTIBYTE CHARACTER HANDLING            *
- *                                             *
- ************************************************/
-
-#if defined (HANDLE_MULTIBYTE)
-static void
-set_line_mbstate ()
-{
-  int i, previ, len, c;
-  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)
-       {
-         int 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) */
-         int j;
-         for (j = i; j < len; j++)
-           shell_input_line_property[j] = 1;
-         break;
-       }
-
-      shell_input_line_property[i] = mbclen;
-    }
-}
-#endif /* HANDLE_MULTIBYTE */
diff --git a/parse.y.save1 b/parse.y.save1
deleted file mode 100644 (file)
index 505b9d0..0000000
+++ /dev/null
@@ -1,5896 +0,0 @@
-/* parse.y - Yacc grammar for bash. */
-
-/* Copyright (C) 1989-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/>.
-*/
-
-%{
-#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 "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 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 int shell_input_line_index;
-static int shell_input_line_size;      /* Amount allocated for shell_input_line. */
-static int 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;
-%}
-
-%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
-
-/* 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
-                       {
-                         if ($2)
-                           $2->flags |= CMD_INVERT_RETURN;
-                         $$ = $2;
-                       }
-       |       timespec pipeline
-                       {
-                         if ($2)
-                           $2->flags |= $1;
-                         $$ = $2;
-                       }
-       |       timespec BANG pipeline
-                       {
-                         if ($3)
-                           $3->flags |= $1|CMD_INVERT_RETURN;
-                         $$ = $3;
-                       }
-       |       BANG timespec pipeline
-                       {
-                         if ($3)
-                           $3->flags |= $2|CMD_INVERT_RETURN;
-                         $$ = $3;
-                       }
-       |       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';
-                       }
-                       
-       ;
-
-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; }
-       ;
-%%
-
-/* 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 *)NULL;
-      if (signal_is_ignored (SIGINT) == 0)
-       {
-         old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler);
-         interrupt_immediately++;
-       }
-      terminate_immediately = 1;
-
-      current_readline_line = readline (current_readline_prompt ?
-                                         current_readline_prompt : "");
-
-      terminate_immediately = 0;
-      if (signal_is_ignored (SIGINT) == 0 && old_sigint)
-       {
-         interrupt_immediately--;
-         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 (interactive)
-       {
-         interrupt_immediately++;
-         terminate_immediately++;
-       }
-      result = getc_with_restart (bash_input.location.file);
-      if (interactive)
-       {
-         interrupt_immediately--;
-         terminate_immediately--;
-       }
-    }
-  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;
-
-#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
-  int saved_line_size, saved_line_index, 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 = 0, c, peekc, pass_next;
-
-#if defined (READLINE)
-  if (no_line_editing && SHOULD_PROMPT ())
-#else
-  if (SHOULD_PROMPT ())
-#endif
-    print_prompt ();
-
-  pass_next = 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)
-       {
-         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 */
-  { "-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;
-  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++;
-
-    restart_read:
-
-      /* Allow immediate exit if interrupted during input. */
-      QUIT;
-
-      i = 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;
-           }
-
-         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;
-           }
-
-         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)
-               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 ();
-             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_len + 3 > shell_input_line_size)
-           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 ();
-       }
-    }
-
-  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. */
-  if (!uc && (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++;
-       goto restart_read;
-    }
-
-  if (!uc && 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 && 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 (r[l -1] != ' ')
-    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)
-  switch (last_read_token)
-    {
-    case 0:
-    case ';':
-    case '\n':
-    case AND_AND:
-    case OR_OR:
-    case '&':
-    case DO:
-    case THEN:
-    case ELSE:
-    case '{':          /* } */
-    case '(':          /* ) */
-      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 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);
-#endif
-
-#if 0
-#if defined (COMMAND_TIMING)
-  if (STREQ (token, "time") && ((parser_state & PST_CASEPAT) == 0) && time_command_acceptable ())
-    return (TIME);
-#endif /* COMMAND_TIMING */
-#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;
-
-  /* Reset to global value of extended glob */
-  if (parser_state & PST_EXTPAT)
-{
-/*itrace("reset_parser: parser_state includes PST_EXTPAT");*/
-    extended_glob = global_extglob;
-}
-
-  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   0x01
-#define P_ALLOWESC     0x02
-#define P_DQUOTE       0x04
-#define P_COMMAND      0x08    /* parsing a command, so look for comments */
-#define P_BACKQUOTE    0x10    /* parsing a backquoted command substitution */
-#define P_ARRAYSUB     0x20    /* parsing a [...] array subscript for assignment */
-
-/* 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;
-
-/*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 || ch == CTLNUL)
-           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;
-
-#if 0
-      /* The big hammer.  Single quotes aren't special in double quotes.  The
-         problem is that Posix says 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." */
-      if MBTEST(open == '{' && (flags & P_DQUOTE) && ch == '\'')       /* } */
-       continue;
-#endif
-
-      /* 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 ((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|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;
-
-/*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_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 || ch == CTLNUL)
-           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) && 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;
-         else if (heredelim && ch == '\n')
-           {
-             tflags |= LEX_INHEREDOC;
-             tflags &= ~LEX_HEREDELIM;
-             lex_firstind = retind + 1;
-           }
-         else if (heredelim == 0 && lex_firstind >= 0 && (tflags & LEX_PASSNEXT) == 0 && shellbreak (ch))
-           {
-             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 */
-         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);*/
-}
-       }
-
-      /* 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|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;
-}
-
-/* XXX - this needs to handle functionality like subst.c:no_longjmp_on_fatal_error;
-   maybe extract_command_subst should handle it. */
-char *
-xparse_dolparen (base, string, indp, flags)
-     char *base;
-     char *string;
-     int *indp;
-     int flags;
-{
-  sh_parser_state_t ps;
-  int orig_ind, nc, sflags;
-  char *ret, *s, *ep, *ostring;
-
-  /*yydebug = 1;*/
-  orig_ind = *indp;
-  ostring = string;
-
-  sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE;
-  if (flags & SX_NOLONGJMP)
-    sflags |= SEVAL_NOLONGJMP;
-  save_parser_state (&ps);
-
-  /*(*/
-  parser_state |= PST_CMDSUBST|PST_EOFTOKEN;   /* allow instant ')' */ /*(*/
-  shell_eof_token = ')';
-  parse_string (string, "command substitution", sflags, &ep);
-
-  restore_parser_state (&ps);
-  reset_parser ();
-  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 + 2,
-                                     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);
-             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 + 2,
-                                     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 + 2,
-                                     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 == '$')
-           {
-             ttok = (char *)xmalloc (3);
-             ttok[0] = ttok[1] = '$';
-             ttok[2] = '\0';
-             RESIZE_MALLOCED_BUFFER (token, token_index, 3,
-                                     token_buffer_size,
-                                     TOKEN_DEFAULT_GROW_SIZE);
-             strcpy (token + token_index, ttok);
-             token_index += 2;
-             dollar_present = 1;
-             all_digit_token = 0;
-             FREE (ttok);
-             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);
-
-             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)
-       token[token_index++] = CTLESC;
-
-    got_escaped_character:
-
-      all_digit_token &= DIGIT (character);
-      dollar_present |= character == '$';
-
-      token[token_index++] = character;
-
-      RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
-                             TOKEN_DEFAULT_GROW_SIZE);
-
-    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:
-
-  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;
-       else
-         yylval.number = -1;
-       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 (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 (legal_identifier (token+1))
-       {
-         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 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
-      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;
-}
-
-#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. */
-char *
-history_delimiting_chars ()
-{
-  register int i;
-
-  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). */
-  if (parser_state & PST_HEREDOC)
-    return (current_command_line_count == 2 ? "\n" : "");
-
-  /* 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 `()' */
-
-  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);
-             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)
-                         strcpy (t_string, t + 1);
-                     }
-                 }
-#undef ROOT_PATH
-#undef DOUBLE_SLASH_ROOT
-               else
-                 /* polite_directory_format is guaranteed to return a string
-                    no longer than PATH_MAX - 1 characters. */
-                 strcpy (t_string, polite_directory_format (t_string));
-
-               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;
-
-  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)))
-    {
-      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;
-  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 defined (ARRAY_VARS)
-  SHELL_VAR *v;
-#endif
-
-  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->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)
-  v = find_variable ("PIPESTATUS");
-  if (v && array_p (v) && array_cell (v))
-    ps->pipestatus = array_copy (array_cell (v));
-  else
-    ps->pipestatus = (ARRAY *)NULL;
-#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;
-
-  return (ps);
-}
-
-void
-restore_parser_state (ps)
-     sh_parser_state_t *ps;
-{
-#if defined (ARRAY_VARS)
-  SHELL_VAR *v;
-#endif
-
-  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;
-
-  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)
-  v = find_variable ("PIPESTATUS");
-  if (v && array_p (v) && array_cell (v))
-    {
-      array_dispose (array_cell (v));
-      var_setarray (v, 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;
-}
-
-/************************************************
- *                                             *
- *     MULTIBYTE CHARACTER HANDLING            *
- *                                             *
- ************************************************/
-
-#if defined (HANDLE_MULTIBYTE)
-static void
-set_line_mbstate ()
-{
-  int i, previ, len, c;
-  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)
-       {
-         int 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) */
-         int j;
-         for (j = i; j < len; j++)
-           shell_input_line_property[j] = 1;
-         break;
-       }
-
-      shell_input_line_property[i] = mbclen;
-    }
-}
-#endif /* HANDLE_MULTIBYTE */
diff --git a/parse.y~ b/parse.y~
deleted file mode 100644 (file)
index 146512b..0000000
--- a/parse.y~
+++ /dev/null
@@ -1,5887 +0,0 @@
-/* parse.y - Yacc grammar for bash. */
-
-/* Copyright (C) 1989-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/>.
-*/
-
-%{
-#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 "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 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 int shell_input_line_index;
-static int shell_input_line_size;      /* Amount allocated for shell_input_line. */
-static int 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;
-%}
-
-%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
-
-/* 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
-                       {
-                         if ($2)
-                           $2->flags |= CMD_INVERT_RETURN;
-                         $$ = $2;
-                       }
-       |       timespec pipeline
-                       {
-                         if ($2)
-                           $2->flags |= $1;
-                         $$ = $2;
-                       }
-       |       timespec BANG pipeline
-                       {
-                         if ($3)
-                           $3->flags |= $1|CMD_INVERT_RETURN;
-                         $$ = $3;
-                       }
-       |       BANG timespec pipeline
-                       {
-                         if ($3)
-                           $3->flags |= $2|CMD_INVERT_RETURN;
-                         $$ = $3;
-                       }
-       |       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';
-                       }
-                       
-       ;
-
-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; }
-       ;
-%%
-
-/* 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 *)NULL;
-      if (signal_is_ignored (SIGINT) == 0)
-       {
-         old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler);
-         interrupt_immediately++;
-       }
-      terminate_immediately = 1;
-
-      current_readline_line = readline (current_readline_prompt ?
-                                         current_readline_prompt : "");
-
-      terminate_immediately = 0;
-      if (signal_is_ignored (SIGINT) == 0 && old_sigint)
-       {
-         interrupt_immediately--;
-         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 (interactive)
-       {
-         interrupt_immediately++;
-         terminate_immediately++;
-       }
-      result = getc_with_restart (bash_input.location.file);
-      if (interactive)
-       {
-         interrupt_immediately--;
-         terminate_immediately--;
-       }
-    }
-  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;
-
-#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
-  int saved_line_size, saved_line_index, 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 = 0, c, peekc, pass_next;
-
-#if defined (READLINE)
-  if (no_line_editing && SHOULD_PROMPT ())
-#else
-  if (SHOULD_PROMPT ())
-#endif
-    print_prompt ();
-
-  pass_next = 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)
-       {
-         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 */
-  { "-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;
-  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++;
-
-    restart_read:
-
-      /* Allow immediate exit if interrupted during input. */
-      QUIT;
-
-      i = 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;
-           }
-
-         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;
-           }
-
-         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)
-               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 ();
-             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_len + 3 > shell_input_line_size)
-           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 ();
-       }
-    }
-
-  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. */
-  if (!uc && (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++;
-       goto restart_read;
-    }
-
-  if (!uc && 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 && 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 (r[l -1] != ' ')
-    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)
-  switch (last_read_token)
-    {
-    case 0:
-    case ';':
-    case '\n':
-    case AND_AND:
-    case OR_OR:
-    case '&':
-    case DO:
-    case THEN:
-    case ELSE:
-    case '{':          /* } */
-    case '(':          /* ) */
-      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 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);
-#endif
-
-#if 0
-#if defined (COMMAND_TIMING)
-  if (STREQ (token, "time") && ((parser_state & PST_CASEPAT) == 0) && time_command_acceptable ())
-    return (TIME);
-#endif /* COMMAND_TIMING */
-#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;
-
-  /* Reset to global value of extended glob */
-  if (parser_state & PST_EXTPAT)
-{
-/*itrace("reset_parser: parser_state includes PST_EXTPAT");*/
-    extended_glob = global_extglob;
-}
-
-  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   0x01
-#define P_ALLOWESC     0x02
-#define P_DQUOTE       0x04
-#define P_COMMAND      0x08    /* parsing a command, so look for comments */
-#define P_BACKQUOTE    0x10    /* parsing a backquoted command substitution */
-#define P_ARRAYSUB     0x20    /* parsing a [...] array subscript for assignment */
-
-/* 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;
-
-/*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 || ch == CTLNUL)
-           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;
-
-#if 0
-      /* The big hammer.  Single quotes aren't special in double quotes.  The
-         problem is that Posix says 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." */
-      if MBTEST(open == '{' && (flags & P_DQUOTE) && ch == '\'')       /* } */
-       continue;
-#endif
-
-      /* 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 ((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|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;
-
-/*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_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);*/
-                 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);*/
-             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 || ch == CTLNUL)
-           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) && 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;
-         else if (lex_firstind >= 0 && (tflags & LEX_PASSNEXT) == 0 && shellbreak (ch))
-           {
-             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 */
-         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);*/
-}
-       }
-
-      /* 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|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;
-}
-
-/* XXX - this needs to handle functionality like subst.c:no_longjmp_on_fatal_error;
-   maybe extract_command_subst should handle it. */
-char *
-xparse_dolparen (base, string, indp, flags)
-     char *base;
-     char *string;
-     int *indp;
-     int flags;
-{
-  sh_parser_state_t ps;
-  int orig_ind, nc, sflags;
-  char *ret, *s, *ep, *ostring;
-
-  /*yydebug = 1;*/
-  orig_ind = *indp;
-  ostring = string;
-
-  sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE;
-  if (flags & SX_NOLONGJMP)
-    sflags |= SEVAL_NOLONGJMP;
-  save_parser_state (&ps);
-
-  /*(*/
-  parser_state |= PST_CMDSUBST|PST_EOFTOKEN;   /* allow instant ')' */ /*(*/
-  shell_eof_token = ')';
-  parse_string (string, "command substitution", sflags, &ep);
-
-  restore_parser_state (&ps);
-  reset_parser ();
-  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 + 2,
-                                     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);
-             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 + 2,
-                                     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 + 2,
-                                     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 == '$')
-           {
-             ttok = (char *)xmalloc (3);
-             ttok[0] = ttok[1] = '$';
-             ttok[2] = '\0';
-             RESIZE_MALLOCED_BUFFER (token, token_index, 3,
-                                     token_buffer_size,
-                                     TOKEN_DEFAULT_GROW_SIZE);
-             strcpy (token + token_index, ttok);
-             token_index += 2;
-             dollar_present = 1;
-             all_digit_token = 0;
-             FREE (ttok);
-             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);
-
-             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)
-       token[token_index++] = CTLESC;
-
-    got_escaped_character:
-
-      all_digit_token &= DIGIT (character);
-      dollar_present |= character == '$';
-
-      token[token_index++] = character;
-
-      RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
-                             TOKEN_DEFAULT_GROW_SIZE);
-
-    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:
-
-  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;
-       else
-         yylval.number = -1;
-       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 (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 (legal_identifier (token+1))
-       {
-         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 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
-      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;
-}
-
-#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. */
-char *
-history_delimiting_chars ()
-{
-  register int i;
-
-  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). */
-  if (parser_state & PST_HEREDOC)
-    return (current_command_line_count == 2 ? "\n" : "");
-
-  /* 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 `()' */
-
-  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);
-             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)
-                         strcpy (t_string, t + 1);
-                     }
-                 }
-#undef ROOT_PATH
-#undef DOUBLE_SLASH_ROOT
-               else
-                 /* polite_directory_format is guaranteed to return a string
-                    no longer than PATH_MAX - 1 characters. */
-                 strcpy (t_string, polite_directory_format (t_string));
-
-               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;
-
-  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)))
-    {
-      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;
-  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 defined (ARRAY_VARS)
-  SHELL_VAR *v;
-#endif
-
-  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->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)
-  v = find_variable ("PIPESTATUS");
-  if (v && array_p (v) && array_cell (v))
-    ps->pipestatus = array_copy (array_cell (v));
-  else
-    ps->pipestatus = (ARRAY *)NULL;
-#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;
-
-  return (ps);
-}
-
-void
-restore_parser_state (ps)
-     sh_parser_state_t *ps;
-{
-#if defined (ARRAY_VARS)
-  SHELL_VAR *v;
-#endif
-
-  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;
-
-  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)
-  v = find_variable ("PIPESTATUS");
-  if (v && array_p (v) && array_cell (v))
-    {
-      array_dispose (array_cell (v));
-      var_setarray (v, 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;
-}
-
-/************************************************
- *                                             *
- *     MULTIBYTE CHARACTER HANDLING            *
- *                                             *
- ************************************************/
-
-#if defined (HANDLE_MULTIBYTE)
-static void
-set_line_mbstate ()
-{
-  int i, previ, len, c;
-  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)
-       {
-         int 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) */
-         int j;
-         for (j = i; j < len; j++)
-           shell_input_line_property[j] = 1;
-         break;
-       }
-
-      shell_input_line_property[i] = mbclen;
-    }
-}
-#endif /* HANDLE_MULTIBYTE */
diff --git a/parser.h~ b/parser.h~
deleted file mode 100644 (file)
index 5e71a96..0000000
--- a/parser.h~
+++ /dev/null
@@ -1,63 +0,0 @@
-/* parser.h -- Everything you wanted to know about the parser, but were
-   afraid to ask. */
-
-/* Copyright (C) 1995, 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 (_PARSER_H_)
-#  define _PARSER_H_
-
-#  include "command.h"
-#  include "input.h"
-
-/* Possible states for the parser that require it to do special things. */
-#define PST_CASEPAT    0x00001         /* in a case pattern list */
-#define PST_ALEXPNEXT  0x00002         /* expand next word for aliases */
-#define PST_ALLOWOPNBRC        0x00004         /* allow open brace for function def */
-#define PST_NEEDCLOSBRC        0x00008         /* need close brace */
-#define PST_DBLPAREN   0x00010         /* double-paren parsing */
-#define PST_SUBSHELL   0x00020         /* ( ... ) subshell */
-#define PST_CMDSUBST   0x00040         /* $( ... ) command substitution */
-#define PST_CASESTMT   0x00080         /* parsing a case statement */
-#define PST_CONDCMD    0x00100         /* parsing a [[...]] command */
-#define PST_CONDEXPR   0x00200         /* parsing the guts of [[...]] */
-#define PST_ARITHFOR   0x00400         /* parsing an arithmetic for command */
-#define PST_ALEXPAND   0x00800         /* OK to expand aliases - unused */
-#define PST_CMDTOKEN   0x01000         /* command token OK - unused */
-#define PST_COMPASSIGN 0x02000         /* parsing x=(...) compound assignment */
-#define PST_ASSIGNOK   0x04000         /* assignment statement ok in this context */
-#define PST_EOFTOKEN   0x08000         /* yylex checks against shell_eof_token */
-#define PST_REGEXP     0x10000         /* parsing an ERE/BRE as a single word */
-#define PST_HEREDOC    0x20000         /* reading body of here-document */
-#define PST_REPARSE    0x40000         /* re-parsing in parse_string_to_word_list */
-#define PST_REDIRLIST  0x80000         /* parsing a list of redirctions preceding a simple command name */
-
-/* Definition of the delimiter stack.  Needed by parse.y and bashhist.c. */
-struct dstack {
-/* DELIMITERS is a stack of the nested delimiters that we have
-   encountered so far. */
-  char *delimiters;
-
-/* Offset into the stack of delimiters. */
-  int delimiter_depth;
-
-/* How many slots are allocated to DELIMITERS. */
-  int delimiter_space;
-};
-
-#endif /* _PARSER_H_ */
diff --git a/patchlevel.h~ b/patchlevel.h~
deleted file mode 100644 (file)
index c10ac99..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* patchlevel.h -- current bash patch level */
-
-/* Copyright (C) 2001-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 (_PATCHLEVEL_H_)
-#define _PATCHLEVEL_H_
-
-/* It's important that there be no other strings in this file that match the
-   regexp `^#define[   ]*PATCHLEVEL', since that's what support/mkversion.sh
-   looks for to find the patch level (for the sccs version string). */
-
-#define PATCHLEVEL 33
-
-#endif /* _PATCHLEVEL_H_ */
diff --git a/pathexp.c~ b/pathexp.c~
deleted file mode 100644 (file)
index ece200d..0000000
+++ /dev/null
@@ -1,486 +0,0 @@
-/* pathexp.c -- The shell interface to the globbing library. */
-
-/* Copyright (C) 1995-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/>.
-*/
-
-#include "config.h"
-
-#include "bashtypes.h"
-#include <stdio.h>
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include "bashansi.h"
-
-#include "shell.h"
-#include "pathexp.h"
-#include "flags.h"
-
-#include "shmbutil.h"
-#include "bashintl.h"
-
-#include <glob/strmatch.h>
-
-static int glob_name_is_acceptable __P((const char *));
-static void ignore_globbed_names __P((char **, sh_ignore_func_t *));
-               
-#if defined (USE_POSIX_GLOB_LIBRARY)
-#  include <glob.h>
-typedef int posix_glob_errfunc_t __P((const char *, int));
-#else
-#  include <glob/glob.h>
-#endif
-
-/* Control whether * matches .files in globbing. */
-int glob_dot_filenames;
-
-/* Control whether the extended globbing features are enabled. */
-int extended_glob = 0;
-
-/* Control enabling special handling of `**' */
-int glob_star = 0;
-
-/* Return nonzero if STRING has any unquoted special globbing chars in it.  */
-int
-unquoted_glob_pattern_p (string)
-     register char *string;
-{
-  register int c;
-  char *send;
-  int open;
-
-  DECLARE_MBSTATE;
-
-  open = 0;
-  send = string + strlen (string);
-
-  while (c = *string++)
-    {
-      switch (c)
-       {
-       case '?':
-       case '*':
-         return (1);
-
-       case '[':
-         open++;
-         continue;
-
-       case ']':
-         if (open)
-           return (1);
-         continue;
-
-       case '+':
-       case '@':
-       case '!':
-         if (*string == '(')   /*)*/
-           return (1);
-         continue;
-
-       case CTLESC:
-       case '\\':
-         if (*string++ == '\0')
-           return (0);
-       }
-
-      /* Advance one fewer byte than an entire multibyte character to
-        account for the auto-increment in the loop above. */
-#ifdef HANDLE_MULTIBYTE
-      string--;
-      ADVANCE_CHAR_P (string, send - string);
-      string++;
-#else
-      ADVANCE_CHAR_P (string, send - string);
-#endif
-    }
-  return (0);
-}
-
-/* Return 1 if C is a character that is `special' in a POSIX ERE and needs to
-   be quoted to match itself. */
-static inline int
-ere_char (c)
-     int c;
-{
-  switch (c)
-    {
-    case '.':
-    case '[':
-    case '\\':
-    case '(':
-    case ')':
-    case '*':
-    case '+':
-    case '?':
-    case '{':
-    case '|':
-    case '^':
-    case '$':
-      return 1;
-    default: 
-      return 0;
-    }
-  return (0);
-}
-
-int
-glob_char_p (s)
-     const char *s;
-{
-  switch (*s)
-    {
-    case '*':
-    case '[':
-    case ']':
-    case '?':
-    case '\\':
-      return 1;
-    case '+':
-    case '@':
-    case '!':
-      if (s[1] == '(')        /*(*/
-       return 1;
-      break;
-    }
-  return 0;
-}
-
-/* PATHNAME can contain characters prefixed by CTLESC; this indicates
-   that the character is to be quoted.  We quote it here in the style
-   that the glob library recognizes.  If flags includes QGLOB_CVTNULL,
-   we change quoted null strings (pathname[0] == CTLNUL) into empty
-   strings (pathname[0] == 0).  If this is called after quote removal
-   is performed, (flags & QGLOB_CVTNULL) should be 0; if called when quote
-   removal has not been done (for example, before attempting to match a
-   pattern while executing a case statement), flags should include
-   QGLOB_CVTNULL.  If flags includes QGLOB_FILENAME, appropriate quoting
-   to match a filename should be performed. */
-char *
-quote_string_for_globbing (pathname, qflags)
-     const char *pathname;
-     int qflags;
-{
-  char *temp;
-  register int i, j;
-
-  temp = (char *)xmalloc (strlen (pathname) + 1);
-
-  if ((qflags & QGLOB_CVTNULL) && QUOTED_NULL (pathname))
-    {
-      temp[0] = '\0';
-      return temp;
-    }
-
-  for (i = j = 0; pathname[i]; i++)
-    {
-      if (pathname[i] == CTLESC)
-       {
-         if ((qflags & QGLOB_FILENAME) && pathname[i+1] == '/')
-           continue;
-         if ((qflags & QGLOB_REGEXP) && ere_char (pathname[i+1]) == 0)
-           continue;
-         temp[j++] = '\\';
-         i++;
-         if (pathname[i] == '\0')
-           break;
-       }
-      else if (pathname[i] == '\\')
-       {
-         temp[j++] = '\\';
-         i++;
-         if (pathname[i] == '\0')
-           break;
-       }
-      temp[j++] = pathname[i];
-    }
-  temp[j] = '\0';
-
-  return (temp);
-}
-
-char *
-quote_globbing_chars (string)
-     char *string;
-{
-  size_t slen;
-  char *temp, *s, *t, *send;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string);
-  send = string + slen;
-
-  temp = (char *)xmalloc (slen * 2 + 1);
-  for (t = temp, s = string; *s; )
-    {
-      if (glob_char_p (s))
-       *t++ = '\\';
-
-      /* Copy a single (possibly multibyte) character from s to t,
-         incrementing both. */
-      COPY_CHAR_P (t, s, send);
-    }
-  *t = '\0';
-  return temp;
-}
-
-/* Call the glob library to do globbing on PATHNAME. */
-char **
-shell_glob_filename (pathname)
-     const char *pathname;
-{
-#if defined (USE_POSIX_GLOB_LIBRARY)
-  register int i;
-  char *temp, **results;
-  glob_t filenames;
-  int glob_flags;
-
-  temp = quote_string_for_globbing (pathname, QGLOB_FILENAME);
-
-  filenames.gl_offs = 0;
-
-#  if defined (GLOB_PERIOD)
-  glob_flags = glob_dot_filenames ? GLOB_PERIOD : 0;
-#  else
-  glob_flags = 0;
-#  endif /* !GLOB_PERIOD */
-
-  glob_flags |= (GLOB_ERR | GLOB_DOOFFS);
-
-  i = glob (temp, glob_flags, (posix_glob_errfunc_t *)NULL, &filenames);
-
-  free (temp);
-
-  if (i == GLOB_NOSPACE || i == GLOB_ABORTED)
-    return ((char **)NULL);
-  else if (i == GLOB_NOMATCH)
-    filenames.gl_pathv = (char **)NULL;
-  else if (i != 0)             /* other error codes not in POSIX.2 */
-    filenames.gl_pathv = (char **)NULL;
-
-  results = filenames.gl_pathv;
-
-  if (results && ((GLOB_FAILED (results)) == 0))
-    {
-      if (should_ignore_glob_matches ())
-       ignore_glob_matches (results);
-      if (results && results[0])
-       strvec_sort (results);
-      else
-       {
-         FREE (results);
-         results = (char **)NULL;
-       }
-    }
-
-  return (results);
-
-#else /* !USE_POSIX_GLOB_LIBRARY */
-
-  char *temp, **results;
-
-  noglob_dot_filenames = glob_dot_filenames == 0;
-
-  temp = quote_string_for_globbing (pathname, QGLOB_FILENAME);
-  results = glob_filename (temp, glob_star ? GX_GLOBSTAR : 0);
-  free (temp);
-
-  if (results && ((GLOB_FAILED (results)) == 0))
-    {
-      if (should_ignore_glob_matches ())
-       ignore_glob_matches (results);
-      if (results && results[0])
-       strvec_sort (results);
-      else
-       {
-         FREE (results);
-         results = (char **)&glob_error_return;
-       }
-    }
-
-  return (results);
-#endif /* !USE_POSIX_GLOB_LIBRARY */
-}
-
-/* Stuff for GLOBIGNORE. */
-
-static struct ignorevar globignore =
-{
-  "GLOBIGNORE",
-  (struct ign *)0,
-  0,
-  (char *)0,
-  (sh_iv_item_func_t *)0,
-};
-
-/* Set up to ignore some glob matches because the value of GLOBIGNORE
-   has changed.  If GLOBIGNORE is being unset, we also need to disable
-   the globbing of filenames beginning with a `.'. */
-void
-setup_glob_ignore (name)
-     char *name;
-{
-  char *v;
-
-  v = get_string_value (name);
-  setup_ignore_patterns (&globignore);
-
-  if (globignore.num_ignores)
-    glob_dot_filenames = 1;
-  else if (v == 0)
-    glob_dot_filenames = 0;
-}
-
-int
-should_ignore_glob_matches ()
-{
-  return globignore.num_ignores;
-}
-
-/* Return 0 if NAME matches a pattern in the globignore.ignores list. */
-static int
-glob_name_is_acceptable (name)
-     const char *name;
-{
-  struct ign *p;
-  int flags;
-
-  /* . and .. are never matched */
-  if (name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')))
-    return (0);
-
-  flags = FNM_PATHNAME | FNMATCH_EXTFLAG;
-  for (p = globignore.ignores; p->val; p++)
-    {
-      if (strmatch (p->val, (char *)name, flags) != FNM_NOMATCH)
-       return (0);
-    }
-  return (1);
-}
-
-/* Internal function to test whether filenames in NAMES should be
-   ignored.  NAME_FUNC is a pointer to a function to call with each
-   name.  It returns non-zero if the name is acceptable to the particular
-   ignore function which called _ignore_names; zero if the name should
-   be removed from NAMES. */
-
-static void
-ignore_globbed_names (names, name_func)
-     char **names;
-     sh_ignore_func_t *name_func;
-{
-  char **newnames;
-  int n, i;
-
-  for (i = 0; names[i]; i++)
-    ;
-  newnames = strvec_create (i + 1);
-
-  for (n = i = 0; names[i]; i++)
-    {
-      if ((*name_func) (names[i]))
-       newnames[n++] = names[i];
-      else
-       free (names[i]);
-    }
-
-  newnames[n] = (char *)NULL;
-
-  if (n == 0)
-    {
-      names[0] = (char *)NULL;
-      free (newnames);
-      return;
-    }
-
-  /* Copy the acceptable names from NEWNAMES back to NAMES and set the
-     new array end. */
-  for (n = 0; newnames[n]; n++)
-    names[n] = newnames[n];
-  names[n] = (char *)NULL;
-  free (newnames);
-}
-
-void
-ignore_glob_matches (names)
-     char **names;
-{
-  if (globignore.num_ignores == 0)
-    return;
-
-  ignore_globbed_names (names, glob_name_is_acceptable);
-}
-
-void
-setup_ignore_patterns (ivp)
-     struct ignorevar *ivp;
-{
-  int numitems, maxitems, ptr;
-  char *colon_bit, *this_ignoreval;
-  struct ign *p;
-
-  this_ignoreval = get_string_value (ivp->varname);
-
-  /* If nothing has changed then just exit now. */
-  if ((this_ignoreval && ivp->last_ignoreval && STREQ (this_ignoreval, ivp->last_ignoreval)) ||
-      (!this_ignoreval && !ivp->last_ignoreval))
-    return;
-
-  /* Oops.  The ignore variable has changed.  Re-parse it. */
-  ivp->num_ignores = 0;
-
-  if (ivp->ignores)
-    {
-      for (p = ivp->ignores; p->val; p++)
-       free(p->val);
-      free (ivp->ignores);
-      ivp->ignores = (struct ign *)NULL;
-    }
-
-  if (ivp->last_ignoreval)
-    {
-      free (ivp->last_ignoreval);
-      ivp->last_ignoreval = (char *)NULL;
-    }
-
-  if (this_ignoreval == 0 || *this_ignoreval == '\0')
-    return;
-
-  ivp->last_ignoreval = savestring (this_ignoreval);
-
-  numitems = maxitems = ptr = 0;
-
-  while (colon_bit = extract_colon_unit (this_ignoreval, &ptr))
-    {
-      if (numitems + 1 >= maxitems)
-       {
-         maxitems += 10;
-         ivp->ignores = (struct ign *)xrealloc (ivp->ignores, maxitems * sizeof (struct ign));
-       }
-      ivp->ignores[numitems].val = colon_bit;
-      ivp->ignores[numitems].len = strlen (colon_bit);
-      ivp->ignores[numitems].flags = 0;
-      if (ivp->item_func)
-       (*ivp->item_func) (&ivp->ignores[numitems]);
-      numitems++;
-    }
-  ivp->ignores[numitems].val = (char *)NULL;
-  ivp->num_ignores = numitems;
-}
diff --git a/pcomplete.c~ b/pcomplete.c~
deleted file mode 100644 (file)
index 6bd07c3..0000000
+++ /dev/null
@@ -1,1546 +0,0 @@
-/* pcomplete.c - functions to generate lists of matches for programmable completion. */
-
-/* Copyright (C) 1999-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/>.
-*/
-
-#include <config.h>
-
-#if defined (PROGRAMMABLE_COMPLETION)
-
-#include "bashtypes.h"
-#include "posixstat.h"
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include <signal.h>
-
-#if defined (PREFER_STDARG)
-#  include <stdarg.h>
-#else
-#  include <varargs.h>
-#endif
-
-#include <stdio.h>
-#include "bashansi.h"
-#include "bashintl.h"
-
-#include "shell.h"
-#include "pcomplete.h"
-#include "alias.h"
-#include "bashline.h"
-#include "execute_cmd.h"
-#include "pathexp.h"
-
-#if defined (JOB_CONTROL)
-#  include "jobs.h"
-#endif
-
-#if !defined (NSIG)
-#  include "trap.h"
-#endif
-
-#include "builtins.h"
-#include "builtins/common.h"
-
-#include <glob/glob.h>
-#include <glob/strmatch.h>
-
-#include <readline/rlconf.h>
-#include <readline/readline.h>
-#include <readline/history.h>
-
-#define PCOMP_RETRYFAIL        256
-
-#ifdef STRDUP
-#  undef STRDUP
-#endif
-#define STRDUP(x)      ((x) ? savestring (x) : (char *)NULL)
-
-typedef SHELL_VAR **SVFUNC ();
-
-#ifndef HAVE_STRPBRK
-extern char *strpbrk __P((char *, char *));
-#endif
-
-extern int array_needs_making;
-extern STRING_INT_ALIST word_token_alist[];
-extern char *signal_names[];
-
-#if defined (DEBUG)
-#if defined (PREFER_STDARG)
-static void debug_printf (const char *, ...)  __attribute__((__format__ (printf, 1, 2)));
-#endif
-#endif /* DEBUG */
-
-static int it_init_joblist __P((ITEMLIST *, int));
-
-static int it_init_aliases __P((ITEMLIST *));
-static int it_init_arrayvars __P((ITEMLIST *));
-static int it_init_bindings __P((ITEMLIST *));
-static int it_init_builtins __P((ITEMLIST *));
-static int it_init_disabled __P((ITEMLIST *));
-static int it_init_enabled __P((ITEMLIST *));
-static int it_init_exported __P((ITEMLIST *));
-static int it_init_functions __P((ITEMLIST *));
-static int it_init_hostnames __P((ITEMLIST *));
-static int it_init_jobs __P((ITEMLIST *));
-static int it_init_running __P((ITEMLIST *));
-static int it_init_stopped __P((ITEMLIST *));
-static int it_init_keywords __P((ITEMLIST *));
-static int it_init_signals __P((ITEMLIST *));
-static int it_init_variables __P((ITEMLIST *));
-static int it_init_setopts __P((ITEMLIST *));
-static int it_init_shopts __P((ITEMLIST *));
-
-static int shouldexp_filterpat __P((char *));
-static char *preproc_filterpat __P((char *, char *));
-
-static void init_itemlist_from_varlist __P((ITEMLIST *, SVFUNC *));
-
-static STRINGLIST *gen_matches_from_itemlist __P((ITEMLIST *, const char *));
-static STRINGLIST *gen_action_completions __P((COMPSPEC *, const char *));
-static STRINGLIST *gen_globpat_matches __P((COMPSPEC *, const char *));
-static STRINGLIST *gen_wordlist_matches __P((COMPSPEC *, const char *));
-static STRINGLIST *gen_shell_function_matches __P((COMPSPEC *, const char *,
-                                                  char *, int, WORD_LIST *,
-                                                  int, int, int *));
-static STRINGLIST *gen_command_matches __P((COMPSPEC *, const char *, char *,
-                                           int, WORD_LIST *, int, int));
-
-static STRINGLIST *gen_progcomp_completions __P((const char *, const char *,
-                                                const char *,
-                                                int, int, int *, int *,
-                                                COMPSPEC **));
-
-static char *pcomp_filename_completion_function __P((const char *, int));
-
-#if defined (ARRAY_VARS)
-static SHELL_VAR *bind_comp_words __P((WORD_LIST *));
-#endif
-static void bind_compfunc_variables __P((char *, int, WORD_LIST *, int, int));
-static void unbind_compfunc_variables __P((int));
-static WORD_LIST *build_arg_list __P((char *, const char *, WORD_LIST *, int));
-static WORD_LIST *command_line_to_word_list __P((char *, int, int, int *, int *));
-
-#ifdef DEBUG
-static int progcomp_debug = 0;
-#endif
-
-int prog_completion_enabled = 1;
-
-/* These are used to manage the arrays of strings for possible completions. */
-ITEMLIST it_aliases = { 0, it_init_aliases, (STRINGLIST *)0 };
-ITEMLIST it_arrayvars  = { LIST_DYNAMIC, it_init_arrayvars, (STRINGLIST *)0 };
-ITEMLIST it_bindings  = { 0, it_init_bindings, (STRINGLIST *)0 };
-ITEMLIST it_builtins  = { 0, it_init_builtins, (STRINGLIST *)0 };
-ITEMLIST it_commands = { LIST_DYNAMIC };       /* unused */
-ITEMLIST it_directories = { LIST_DYNAMIC };    /* unused */
-ITEMLIST it_disabled = { 0, it_init_disabled, (STRINGLIST *)0 };
-ITEMLIST it_enabled = { 0, it_init_enabled, (STRINGLIST *)0 };
-ITEMLIST it_exports  = { LIST_DYNAMIC, it_init_exported, (STRINGLIST *)0 };
-ITEMLIST it_files = { LIST_DYNAMIC };          /* unused */
-ITEMLIST it_functions  = { 0, it_init_functions, (STRINGLIST *)0 };
-ITEMLIST it_hostnames  = { LIST_DYNAMIC, it_init_hostnames, (STRINGLIST *)0 };
-ITEMLIST it_groups = { LIST_DYNAMIC };         /* unused */
-ITEMLIST it_jobs = { LIST_DYNAMIC, it_init_jobs, (STRINGLIST *)0 };
-ITEMLIST it_keywords = { 0, it_init_keywords, (STRINGLIST *)0 };
-ITEMLIST it_running = { LIST_DYNAMIC, it_init_running, (STRINGLIST *)0 };
-ITEMLIST it_services = { LIST_DYNAMIC };       /* unused */
-ITEMLIST it_setopts = { 0, it_init_setopts, (STRINGLIST *)0 };
-ITEMLIST it_shopts = { 0, it_init_shopts, (STRINGLIST *)0 };
-ITEMLIST it_signals = { 0, it_init_signals, (STRINGLIST *)0 };
-ITEMLIST it_stopped = { LIST_DYNAMIC, it_init_stopped, (STRINGLIST *)0 };
-ITEMLIST it_users = { LIST_DYNAMIC };          /* unused */
-ITEMLIST it_variables = { LIST_DYNAMIC, it_init_variables, (STRINGLIST *)0 };
-
-COMPSPEC *pcomp_curcs;
-const char *pcomp_curcmd;
-
-#ifdef DEBUG
-/* Debugging code */
-static void
-#if defined (PREFER_STDARG)
-debug_printf (const char *format, ...)
-#else
-debug_printf (format, va_alist)
-     const char *format;
-     va_dcl
-#endif
-{
-  va_list args;
-
-  if (progcomp_debug == 0)
-    return;
-
-  SH_VA_START (args, format);
-
-  fprintf (stdout, "DEBUG: ");
-  vfprintf (stdout, format, args);
-  fprintf (stdout, "\n");
-
-  rl_on_new_line ();
-
-  va_end (args);
-}
-#endif
-
-/* Functions to manage the item lists */
-
-void
-set_itemlist_dirty (it)
-     ITEMLIST *it;
-{
-  it->flags |= LIST_DIRTY;
-}
-
-void
-initialize_itemlist (itp)
-     ITEMLIST *itp;
-{
-  (*itp->list_getter) (itp);
-  itp->flags |= LIST_INITIALIZED;
-  itp->flags &= ~LIST_DIRTY;
-}
-
-void
-clean_itemlist (itp)
-     ITEMLIST *itp;
-{
-  STRINGLIST *sl;
-
-  sl = itp->slist;
-  if (sl)
-    {
-      if ((itp->flags & (LIST_DONTFREEMEMBERS|LIST_DONTFREE)) == 0)
-       strvec_flush (sl->list);
-      if ((itp->flags & LIST_DONTFREE) == 0)
-       free (sl->list);
-      free (sl);
-    }
-  itp->slist = (STRINGLIST *)NULL;
-  itp->flags &= ~(LIST_DONTFREE|LIST_DONTFREEMEMBERS|LIST_INITIALIZED|LIST_DIRTY);
-}
-
-
-static int
-shouldexp_filterpat (s)
-     char *s;
-{
-  register char *p;
-
-  for (p = s; p && *p; p++)
-    {
-      if (*p == '\\')
-       p++;
-      else if (*p == '&')
-       return 1;
-    }
-  return 0;
-}
-
-/* Replace any instance of `&' in PAT with TEXT.  Backslash may be used to
-   quote a `&' and inhibit substitution.  Returns a new string.  This just
-   calls stringlib.c:strcreplace(). */
-static char *
-preproc_filterpat (pat, text)
-     char *pat;
-     char *text;
-{
-  char *ret;
-
-  ret = strcreplace (pat, '&', text, 1);
-  return ret;
-}
-       
-/* Remove any match of FILTERPAT from SL.  A `&' in FILTERPAT is replaced by
-   TEXT.  A leading `!' in FILTERPAT negates the pattern; in this case
-   any member of SL->list that does *not* match will be removed.  This returns
-   a new STRINGLIST with the matching members of SL *copied*.  Any
-   non-matching members of SL->list are *freed*. */   
-STRINGLIST *
-filter_stringlist (sl, filterpat, text)
-     STRINGLIST *sl;
-     char *filterpat, *text;
-{
-  int i, m, not;
-  STRINGLIST *ret;
-  char *npat, *t;
-
-  if (sl == 0 || sl->list == 0 || sl->list_len == 0)
-    return sl;
-
-  npat = shouldexp_filterpat (filterpat) ? preproc_filterpat (filterpat, text) : filterpat;
-
-  not = (npat[0] == '!');
-  t = not ? npat + 1 : npat;
-
-  ret = strlist_create (sl->list_size);
-  for (i = 0; i < sl->list_len; i++)
-    {
-      m = strmatch (t, sl->list[i], FNMATCH_EXTFLAG);
-      if ((not && m == FNM_NOMATCH) || (not == 0 && m != FNM_NOMATCH))
-       free (sl->list[i]);
-      else
-       ret->list[ret->list_len++] = sl->list[i];
-    }
-
-  ret->list[ret->list_len] = (char *)NULL;
-  if (npat != filterpat)
-    free (npat);
-
-  return ret;
-}
-
-/* Turn an array of strings returned by rl_completion_matches into a STRINGLIST.
-   This understands how rl_completion_matches sets matches[0] (the lcd of the
-   strings in the list, unless it's the only match). */
-STRINGLIST *
-completions_to_stringlist (matches)
-     char **matches;
-{
-  STRINGLIST *sl;
-  int mlen, i, n;
-
-  mlen = (matches == 0) ? 0 : strvec_len (matches);
-  sl = strlist_create (mlen + 1);
-
-  if (matches == 0 || matches[0] == 0)
-    return sl;
-
-  if (matches[1] == 0)
-    {
-      sl->list[0] = STRDUP (matches[0]);
-      sl->list[sl->list_len = 1] = (char *)NULL;
-      return sl;
-    }
-
-  for (i = 1, n = 0; i < mlen; i++, n++)
-    sl->list[n] = STRDUP (matches[i]);
-  sl->list_len = n;
-  sl->list[n] = (char *)NULL;
-
-  return sl;
-}
-
-/* Functions to manage the various ITEMLISTs that we populate internally.
-   The caller is responsible for setting ITP->flags correctly. */
-
-static int
-it_init_aliases (itp)
-     ITEMLIST *itp;
-{
-#ifdef ALIAS
-  alias_t **alias_list;
-  register int i, n;
-  STRINGLIST *sl;
-
-  alias_list = all_aliases ();
-  if (alias_list == 0)
-    {
-      itp->slist = (STRINGLIST *)NULL;
-      return 0;
-    }
-  for (n = 0; alias_list[n]; n++)
-    ;
-  sl = strlist_create (n+1);
-  for (i = 0; i < n; i++)
-    sl->list[i] = STRDUP (alias_list[i]->name);
-  sl->list[n] = (char *)NULL;
-  sl->list_size = sl->list_len = n;
-  itp->slist = sl;
-#else
-  itp->slist = (STRINGLIST *)NULL;
-#endif
-  return 1;
-}
-
-static void
-init_itemlist_from_varlist (itp, svfunc)
-     ITEMLIST *itp;
-     SVFUNC *svfunc;
-{
-  SHELL_VAR **vlist;
-  STRINGLIST *sl;
-  register int i, n;
-
-  vlist = (*svfunc) ();
-  if (vlist == 0)
-    {
-      itp->slist = (STRINGLIST *)NULL;
-      return;
-    }    
-  for (n = 0; vlist[n]; n++)
-    ;
-  sl = strlist_create (n+1);
-  for (i = 0; i < n; i++)
-    sl->list[i] = savestring (vlist[i]->name);
-  sl->list[sl->list_len = n] = (char *)NULL;
-  itp->slist = sl;
-}
-
-static int
-it_init_arrayvars (itp)
-     ITEMLIST *itp;
-{
-#if defined (ARRAY_VARS)
-  init_itemlist_from_varlist (itp, all_array_variables);
-  return 1;
-#else
-  return 0;
-#endif
-}
-
-static int
-it_init_bindings (itp)
-     ITEMLIST *itp;
-{
-  char **blist;
-  STRINGLIST *sl;
-
-  /* rl_funmap_names allocates blist, but not its members */
-  blist = (char **)rl_funmap_names (); /* XXX fix const later */
-  sl = strlist_create (0);
-  sl->list = blist;
-  sl->list_size = 0;
-  sl->list_len = strvec_len (sl->list);
-  itp->flags |= LIST_DONTFREEMEMBERS;
-  itp->slist = sl;
-
-  return 0;
-}
-
-static int
-it_init_builtins (itp)
-     ITEMLIST *itp;
-{
-  STRINGLIST *sl;
-  register int i, n;
-
-  sl = strlist_create (num_shell_builtins);
-  for (i = n = 0; i < num_shell_builtins; i++)
-    if (shell_builtins[i].function)
-      sl->list[n++] = shell_builtins[i].name;
-  sl->list[sl->list_len = n] = (char *)NULL;
-  itp->flags |= LIST_DONTFREEMEMBERS;
-  itp->slist = sl;
-  return 0;
-}
-
-static int
-it_init_enabled (itp)
-     ITEMLIST *itp;
-{
-  STRINGLIST *sl;
-  register int i, n;
-
-  sl = strlist_create (num_shell_builtins);
-  for (i = n = 0; i < num_shell_builtins; i++)
-    {
-      if (shell_builtins[i].function && (shell_builtins[i].flags & BUILTIN_ENABLED))
-       sl->list[n++] = shell_builtins[i].name;
-    }
-  sl->list[sl->list_len = n] = (char *)NULL;
-  itp->flags |= LIST_DONTFREEMEMBERS;
-  itp->slist = sl;
-  return 0;
-}
-
-static int
-it_init_disabled (itp)
-     ITEMLIST *itp;
-{
-  STRINGLIST *sl;
-  register int i, n;
-
-  sl = strlist_create (num_shell_builtins);
-  for (i = n = 0; i < num_shell_builtins; i++)
-    {
-      if (shell_builtins[i].function && ((shell_builtins[i].flags & BUILTIN_ENABLED) == 0))
-       sl->list[n++] = shell_builtins[i].name;
-    }
-  sl->list[sl->list_len = n] = (char *)NULL;
-  itp->flags |= LIST_DONTFREEMEMBERS;
-  itp->slist = sl;
-  return 0;
-}
-
-static int
-it_init_exported (itp)
-     ITEMLIST *itp;
-{
-  init_itemlist_from_varlist (itp, all_exported_variables);
-  return 0;
-}
-
-static int
-it_init_functions (itp)
-     ITEMLIST *itp;
-{
-  init_itemlist_from_varlist (itp, all_visible_functions);
-  return 0;
-}
-
-static int
-it_init_hostnames (itp)
-     ITEMLIST *itp;
-{
-  STRINGLIST *sl;
-
-  sl = strlist_create (0);
-  sl->list = get_hostname_list ();
-  sl->list_len = sl->list ? strvec_len (sl->list) : 0;
-  sl->list_size = sl->list_len;
-  itp->slist = sl;
-  itp->flags |= LIST_DONTFREEMEMBERS|LIST_DONTFREE;
-  return 0;
-}
-
-static int
-it_init_joblist (itp, jstate)
-     ITEMLIST *itp;
-     int jstate;
-{
-#if defined (JOB_CONTROL)
-  STRINGLIST *sl;
-  register int i;
-  register PROCESS *p;
-  char *s, *t;
-  JOB *j;
-  JOB_STATE ws;                /* wanted state */
-
-  ws = JNONE;
-  if (jstate == 0)
-    ws = JRUNNING;
-  else if (jstate == 1)
-    ws = JSTOPPED;
-
-  sl = strlist_create (js.j_jobslots);
-  for (i = js.j_jobslots - 1; i >= 0; i--)
-    {
-      j = get_job_by_jid (i);
-      if (j == 0)
-       continue;
-      p = j->pipe;
-      if (jstate == -1 || JOBSTATE(i) == ws)
-       {
-         s = savestring (p->command);
-         t = strpbrk (s, " \t\n");
-         if (t)
-           *t = '\0';
-         sl->list[sl->list_len++] = s;
-       }
-    }
-  itp->slist = sl;
-#else
-  itp->slist = (STRINGLIST *)NULL;
-#endif
-  return 0;
-}
-
-static int
-it_init_jobs (itp)
-     ITEMLIST *itp;
-{
-  return (it_init_joblist (itp, -1));
-}
-
-static int
-it_init_running (itp)
-     ITEMLIST *itp;
-{
-  return (it_init_joblist (itp, 0));
-}
-
-static int
-it_init_stopped (itp)
-     ITEMLIST *itp;
-{
-  return (it_init_joblist (itp, 1));
-}
-
-static int
-it_init_keywords (itp)
-     ITEMLIST *itp;
-{
-  STRINGLIST *sl;
-  register int i, n;
-
-  for (n = 0; word_token_alist[n].word; n++)
-    ;
-  sl = strlist_create (n);
-  for (i = 0; i < n; i++)
-    sl->list[i] = word_token_alist[i].word;
-  sl->list[sl->list_len = i] = (char *)NULL;
-  itp->flags |= LIST_DONTFREEMEMBERS;
-  itp->slist = sl;
-  return 0;
-}
-
-static int
-it_init_signals (itp)
-     ITEMLIST *itp;
-{
-  STRINGLIST *sl;
-
-  sl = strlist_create (0);
-  sl->list = signal_names;
-  sl->list_len = strvec_len (sl->list);
-  itp->flags |= LIST_DONTFREE;
-  itp->slist = sl;
-  return 0;
-}
-
-static int
-it_init_variables (itp)
-     ITEMLIST *itp;
-{
-  init_itemlist_from_varlist (itp, all_visible_variables);
-  return 0;
-}
-
-static int
-it_init_setopts (itp)
-     ITEMLIST *itp;
-{
-  STRINGLIST *sl;
-
-  sl = strlist_create (0);
-  sl->list = get_minus_o_opts ();
-  sl->list_len = strvec_len (sl->list);
-  itp->slist = sl;
-  itp->flags |= LIST_DONTFREEMEMBERS;
-  return 0;
-}
-
-static int
-it_init_shopts (itp)
-     ITEMLIST *itp;
-{
-  STRINGLIST *sl;
-
-  sl = strlist_create (0);
-  sl->list = get_shopt_options ();
-  sl->list_len = strvec_len (sl->list);
-  itp->slist = sl;
-  itp->flags |= LIST_DONTFREEMEMBERS;
-  return 0;
-}
-
-/* Generate a list of all matches for TEXT using the STRINGLIST in itp->slist
-   as the list of possibilities.  If the itemlist has been marked dirty or
-   it should be regenerated every time, destroy the old STRINGLIST and make a
-   new one before trying the match.  TEXT is dequoted before attempting a
-   match. */
-static STRINGLIST *
-gen_matches_from_itemlist (itp, text)
-     ITEMLIST *itp;
-     const char *text;
-{
-  STRINGLIST *ret, *sl;
-  int tlen, i, n;
-  char *ntxt;
-
-  if ((itp->flags & (LIST_DIRTY|LIST_DYNAMIC)) ||
-      (itp->flags & LIST_INITIALIZED) == 0)
-    {
-      if (itp->flags & (LIST_DIRTY|LIST_DYNAMIC))
-       clean_itemlist (itp);
-      if ((itp->flags & LIST_INITIALIZED) == 0)
-       initialize_itemlist (itp);
-    }
-  if (itp->slist == 0)
-    return ((STRINGLIST *)NULL);
-  ret = strlist_create (itp->slist->list_len+1);
-  sl = itp->slist;
-
-  ntxt = bash_dequote_text (text);
-  tlen = STRLEN (ntxt);
-
-  for (i = n = 0; i < sl->list_len; i++)
-    {
-      if (tlen == 0 || STREQN (sl->list[i], ntxt, tlen))
-       ret->list[n++] = STRDUP (sl->list[i]);
-    }
-  ret->list[ret->list_len = n] = (char *)NULL;
-
-  FREE (ntxt);
-  return ret;
-}
-
-/* A wrapper for rl_filename_completion_function that dequotes the filename
-   before attempting completions. */
-static char *
-pcomp_filename_completion_function (text, state)
-     const char *text;
-     int state;
-{
-  static char *dfn;    /* dequoted filename */
-  int qc;
-
-  if (state == 0)
-    {
-      FREE (dfn);
-      /* remove backslashes quoting special characters in filenames. */
-#if 1
-      if (RL_ISSTATE (RL_STATE_COMPLETING) && rl_filename_dequoting_function)
-#else
-      if (rl_filename_dequoting_function)
-#endif
-       {
-         /* Use rl_completion_quote_character because any single or
-            double quotes have been removed by the time TEXT makes it
-            here, and we don't want to remove backslashes inside
-            quoted strings. */
-         dfn = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character);
-       }
-      else
-       dfn = savestring (text);
-    }
-
-  return (rl_filename_completion_function (dfn, state));
-}
-
-#define GEN_COMPS(bmap, flag, it, text, glist, tlist) \
-  do { \
-    if (bmap & flag) \
-      { \
-       tlist = gen_matches_from_itemlist (it, text); \
-       if (tlist) \
-         { \
-           glist = strlist_append (glist, tlist); \
-           strlist_dispose (tlist); \
-         } \
-      } \
-  } while (0)
-
-#define GEN_XCOMPS(bmap, flag, text, func, cmatches, glist, tlist) \
-  do { \
-    if (bmap & flag) \
-      { \
-       cmatches = rl_completion_matches (text, func); \
-       tlist = completions_to_stringlist (cmatches); \
-       glist = strlist_append (glist, tlist); \
-       strvec_dispose (cmatches); \
-       strlist_dispose (tlist); \
-      } \
-  } while (0)
-
-/* Functions to generate lists of matches from the actions member of CS. */
-
-static STRINGLIST *
-gen_action_completions (cs, text)
-     COMPSPEC *cs;
-     const char *text;
-{
-  STRINGLIST *ret, *tmatches;
-  char **cmatches;     /* from rl_completion_matches ... */
-  unsigned long flags;
-
-  ret = tmatches = (STRINGLIST *)NULL;
-  flags = cs->actions;
-
-  GEN_COMPS (flags, CA_ALIAS, &it_aliases, text, ret, tmatches);
-  GEN_COMPS (flags, CA_ARRAYVAR, &it_arrayvars, text, ret, tmatches);
-  GEN_COMPS (flags, CA_BINDING, &it_bindings, text, ret, tmatches);
-  GEN_COMPS (flags, CA_BUILTIN, &it_builtins, text, ret, tmatches);
-  GEN_COMPS (flags, CA_DISABLED, &it_disabled, text, ret, tmatches);
-  GEN_COMPS (flags, CA_ENABLED, &it_enabled, text, ret, tmatches);
-  GEN_COMPS (flags, CA_EXPORT, &it_exports, text, ret, tmatches);
-  GEN_COMPS (flags, CA_FUNCTION, &it_functions, text, ret, tmatches);
-  GEN_COMPS (flags, CA_HOSTNAME, &it_hostnames, text, ret, tmatches);
-  GEN_COMPS (flags, CA_JOB, &it_jobs, text, ret, tmatches);
-  GEN_COMPS (flags, CA_KEYWORD, &it_keywords, text, ret, tmatches);
-  GEN_COMPS (flags, CA_RUNNING, &it_running, text, ret, tmatches);
-  GEN_COMPS (flags, CA_SETOPT, &it_setopts, text, ret, tmatches);
-  GEN_COMPS (flags, CA_SHOPT, &it_shopts, text, ret, tmatches);
-  GEN_COMPS (flags, CA_SIGNAL, &it_signals, text, ret, tmatches);
-  GEN_COMPS (flags, CA_STOPPED, &it_stopped, text, ret, tmatches);
-  GEN_COMPS (flags, CA_VARIABLE, &it_variables, text, ret, tmatches);
-
-  GEN_XCOMPS(flags, CA_COMMAND, text, command_word_completion_function, cmatches, ret, tmatches);
-  GEN_XCOMPS(flags, CA_FILE, text, pcomp_filename_completion_function, cmatches, ret, tmatches);
-  GEN_XCOMPS(flags, CA_USER, text, rl_username_completion_function, cmatches, ret, tmatches);
-  GEN_XCOMPS(flags, CA_GROUP, text, bash_groupname_completion_function, cmatches, ret, tmatches);
-  GEN_XCOMPS(flags, CA_SERVICE, text, bash_servicename_completion_function, cmatches, ret, tmatches);
-
-  /* And lastly, the special case for directories */
-  if (flags & CA_DIRECTORY)
-    {
-      rl_completion_mark_symlink_dirs = 1;     /* override user preference */
-      cmatches = bash_directory_completion_matches (text);
-      tmatches = completions_to_stringlist (cmatches);
-      ret = strlist_append (ret, tmatches);
-      strvec_dispose (cmatches);
-      strlist_dispose (tmatches);
-    }
-
-  return ret;
-}
-
-/* Generate a list of matches for CS->globpat.  Unresolved: should this use
-   TEXT as a match prefix, or just go without?  Currently, the code does not
-   use TEXT, just globs CS->globpat and returns the results.  If we do decide
-   to use TEXT, we should call quote_string_for_globbing before the call to
-   glob_filename. */
-static STRINGLIST *
-gen_globpat_matches (cs, text)
-      COMPSPEC *cs;
-      const char *text;
-{
-  STRINGLIST *sl;
-
-  sl = strlist_create (0);
-  sl->list = glob_filename (cs->globpat, 0);
-  if (GLOB_FAILED (sl->list))
-    sl->list = (char **)NULL;
-  if (sl->list)
-    sl->list_len = sl->list_size = strvec_len (sl->list);
-  return sl;
-}
-
-/* Perform the shell word expansions on CS->words and return the results.
-   Again, this ignores TEXT. */
-static STRINGLIST *
-gen_wordlist_matches (cs, text)
-     COMPSPEC *cs;
-     const char *text;
-{
-  WORD_LIST *l, *l2;
-  STRINGLIST *sl;
-  int nw, tlen;
-  char *ntxt;          /* dequoted TEXT to use in comparisons */
-
-  if (cs->words == 0 || cs->words[0] == '\0')
-    return ((STRINGLIST *)NULL);
-
-  /* This used to be a simple expand_string(cs->words, 0), but that won't
-     do -- there's no way to split a simple list into individual words
-     that way, since the shell semantics say that word splitting is done
-     only on the results of expansion. */
-  l = split_at_delims (cs->words, strlen (cs->words), (char *)NULL, -1, 0, (int *)NULL, (int *)NULL);
-  if (l == 0)
-    return ((STRINGLIST *)NULL);
-  /* This will jump back to the top level if the expansion fails... */
-  l2 = expand_words_shellexp (l);
-  dispose_words (l);
-
-  nw = list_length (l2);
-  sl = strlist_create (nw + 1);
-
-  ntxt = bash_dequote_text (text);
-  tlen = STRLEN (ntxt);
-
-  for (nw = 0, l = l2; l; l = l->next)
-    {
-      if (tlen == 0 || STREQN (l->word->word, ntxt, tlen))
-       sl->list[nw++] = STRDUP (l->word->word);
-    }
-  sl->list[sl->list_len = nw] = (char *)NULL;
-
-  dispose_words (l2);
-  FREE (ntxt);
-  return sl;
-}
-
-#ifdef ARRAY_VARS
-
-static SHELL_VAR *
-bind_comp_words (lwords)
-     WORD_LIST *lwords;
-{
-  SHELL_VAR *v;
-
-  v = find_variable ("COMP_WORDS");
-  if (v == 0)
-    v = make_new_array_variable ("COMP_WORDS");
-  if (readonly_p (v))
-    VUNSETATTR (v, att_readonly);
-  if (array_p (v) == 0)
-    v = convert_var_to_array (v);
-  v = assign_array_var_from_word_list (v, lwords, 0);
-
-  VUNSETATTR (v, att_invisible);
-  return v;
-}
-#endif /* ARRAY_VARS */
-
-static void
-bind_compfunc_variables (line, ind, lwords, cw, exported)
-     char *line;
-     int ind;
-     WORD_LIST *lwords;
-     int cw, exported;
-{
-  char ibuf[INT_STRLEN_BOUND(int) + 1];
-  char *value;
-  SHELL_VAR *v;
-
-  /* Set the variables that the function expects while it executes.  Maybe
-     these should be in the function environment (temporary_env). */
-  v = bind_variable ("COMP_LINE", line, 0);
-  if (v && exported)
-    VSETATTR(v, att_exported);
-
-  value = inttostr (ind, ibuf, sizeof(ibuf));
-  v = bind_int_variable ("COMP_POINT", value);
-  if (v && exported)
-    VSETATTR(v, att_exported);
-
-  value = inttostr (rl_completion_type, ibuf, sizeof (ibuf));
-  v = bind_int_variable ("COMP_TYPE", value);
-  if (v && exported)
-    VSETATTR(v, att_exported);
-
-  value = inttostr (rl_completion_invoking_key, ibuf, sizeof (ibuf));
-  v = bind_int_variable ("COMP_KEY", value);
-  if (v && exported)
-    VSETATTR(v, att_exported);
-
-  /* Since array variables can't be exported, we don't bother making the
-     array of words. */
-  if (exported == 0)
-    {
-#ifdef ARRAY_VARS
-      v = bind_comp_words (lwords);
-      value = inttostr (cw, ibuf, sizeof(ibuf));
-      bind_int_variable ("COMP_CWORD", value);
-#endif
-    }
-  else
-    array_needs_making = 1;
-}
-
-static void
-unbind_compfunc_variables (exported)
-     int exported;
-{
-  unbind_variable ("COMP_LINE");
-  unbind_variable ("COMP_POINT");
-  unbind_variable ("COMP_TYPE");
-  unbind_variable ("COMP_KEY");
-#ifdef ARRAY_VARS
-  unbind_variable ("COMP_WORDS");
-  unbind_variable ("COMP_CWORD");
-#endif
-  if (exported)
-    array_needs_making = 1;
-}
-
-/* Build the list of words to pass to a function or external command
-   as arguments.  When the function or command is invoked,
-
-       $0 == function or command being invoked
-       $1 == command name
-       $2 == word to be completed (possibly null)
-       $3 == previous word
-
-   Functions can access all of the words in the current command line
-   with the COMP_WORDS array.  External commands cannot; they have to
-   make do  with the COMP_LINE and COMP_POINT variables. */
-
-static WORD_LIST *
-build_arg_list (cmd, text, lwords, ind)
-     char *cmd;
-     const char *text;
-     WORD_LIST *lwords;
-     int ind;
-{
-  WORD_LIST *ret, *cl, *l;
-  WORD_DESC *w;
-  int i;
-
-  ret = (WORD_LIST *)NULL;
-  w = make_word (cmd);
-  ret = make_word_list (w, (WORD_LIST *)NULL);
-
-  w = (lwords && lwords->word) ? copy_word (lwords->word) : make_word ("");
-  cl = ret->next = make_word_list (w, (WORD_LIST *)NULL);
-
-  w = make_word (text);
-  cl->next = make_word_list (w, (WORD_LIST *)NULL);
-  cl = cl->next;
-
-  /* Search lwords for current word */
-  for (l = lwords, i = 1; l && i < ind-1; l = l->next, i++)
-    ;
-  w = (l && l->word) ? copy_word (l->word) : make_word ("");
-  cl->next = make_word_list (w, (WORD_LIST *)NULL);
-
-  return ret;
-}
-
-/* Build a command string with
-       $0 == cs->funcname      (function to execute for completion list)
-       $1 == command name      (command being completed)
-       $2 = word to be completed (possibly null)
-       $3 = previous word
-   and run in the current shell.  The function should put its completion
-   list into the array variable COMPREPLY.  We build a STRINGLIST
-   from the results and return it.
-
-   Since the shell function should return its list of matches in an array
-   variable, this does nothing if arrays are not compiled into the shell. */
-
-static STRINGLIST *
-gen_shell_function_matches (cs, text, line, ind, lwords, nw, cw, foundp)
-     COMPSPEC *cs;
-     const char *text;
-     char *line;
-     int ind;
-     WORD_LIST *lwords;
-     int nw, cw;
-     int *foundp;
-{
-  char *funcname;
-  STRINGLIST *sl;
-  SHELL_VAR *f, *v;
-  WORD_LIST *cmdlist;
-  int fval, found;
-  sh_parser_state_t ps;
-  sh_parser_state_t * restrict pps;
-#if defined (ARRAY_VARS)
-  ARRAY *a;
-#endif
-
-  found = 0;
-  if (foundp)
-    *foundp = found;
-
-  funcname = cs->funcname;
-  f = find_function (funcname);
-  if (f == 0)
-    {
-      internal_error (_("completion: function `%s' not found"), funcname);
-      rl_ding ();
-      rl_on_new_line ();
-      return ((STRINGLIST *)NULL);
-    }
-
-#if !defined (ARRAY_VARS)
-  return ((STRINGLIST *)NULL);
-#else
-
-  /* We pass cw - 1 because command_line_to_word_list returns indices that are
-     1-based, while bash arrays are 0-based. */
-  bind_compfunc_variables (line, ind, lwords, cw - 1, 0);
-
-  cmdlist = build_arg_list (funcname, text, lwords, cw);
-
-  pps = &ps;
-  save_parser_state (pps);
-  begin_unwind_frame ("gen-shell-function-matches");
-  add_unwind_protect (restore_parser_state, (char *)pps);
-  add_unwind_protect (dispose_words, (char *)cmdlist);
-  add_unwind_protect (unbind_compfunc_variables, (char *)0);
-
-  fval = execute_shell_function (f, cmdlist);  
-
-  discard_unwind_frame ("gen-shell-function-matches");
-  restore_parser_state (pps);
-
-  found = fval != EX_NOTFOUND;
-  if (fval == EX_RETRYFAIL)
-    found |= PCOMP_RETRYFAIL;
-  if (foundp)
-    *foundp = found;
-
-  /* Now clean up and destroy everything. */
-  dispose_words (cmdlist);
-  unbind_compfunc_variables (0);
-
-  /* The list of completions is returned in the array variable COMPREPLY. */
-  v = find_variable ("COMPREPLY");
-  if (v == 0)
-    return ((STRINGLIST *)NULL);
-  if (array_p (v) == 0)
-    v = convert_var_to_array (v);
-
-  VUNSETATTR (v, att_invisible);
-
-  a = array_cell (v);
-  if (found == 0 || (found & PCOMP_RETRYFAIL) || a == 0 || array_empty (a))
-    sl = (STRINGLIST *)NULL;
-  else
-    {
-      /* XXX - should we filter the list of completions so only those matching
-        TEXT are returned?  Right now, we do not. */
-      sl = strlist_create (0);
-      sl->list = array_to_argv (a);
-      sl->list_len = sl->list_size = array_num_elements (a);
-    }
-
-  /* XXX - should we unbind COMPREPLY here? */
-  unbind_variable ("COMPREPLY");
-
-  return (sl);
-#endif
-}
-
-/* Build a command string with
-       $0 == cs->command       (command to execute for completion list)
-       $1 == command name      (command being completed)
-       $2 = word to be completed (possibly null)
-       $3 = previous word
-   and run in with command substitution.  Parse the results, one word
-   per line, with backslashes allowed to escape newlines.  Build a
-   STRINGLIST from the results and return it. */
-
-static STRINGLIST *
-gen_command_matches (cs, text, line, ind, lwords, nw, cw)
-     COMPSPEC *cs;
-     const char *text;
-     char *line;
-     int ind;
-     WORD_LIST *lwords;
-     int nw, cw;
-{
-  char *csbuf, *cscmd, *t;
-  int cmdlen, cmdsize, n, ws, we;
-  WORD_LIST *cmdlist, *cl;
-  WORD_DESC *tw;
-  STRINGLIST *sl;
-
-  bind_compfunc_variables (line, ind, lwords, cw, 1);
-  cmdlist = build_arg_list (cs->command, text, lwords, cw);
-
-  /* Estimate the size needed for the buffer. */
-  n = strlen (cs->command);
-  cmdsize = n + 1;
-  for (cl = cmdlist->next; cl; cl = cl->next)
-    cmdsize += STRLEN (cl->word->word) + 3;
-  cmdsize += 2;
-
-  /* allocate the string for the command and fill it in. */
-  cscmd = (char *)xmalloc (cmdsize + 1);
-
-  strcpy (cscmd, cs->command);                 /* $0 */
-  cmdlen = n;
-  cscmd[cmdlen++] = ' ';
-  for (cl = cmdlist->next; cl; cl = cl->next)   /* $1, $2, $3, ... */
-    {
-      t = sh_single_quote (cl->word->word ? cl->word->word : "");
-      n = strlen (t);
-      RESIZE_MALLOCED_BUFFER (cscmd, cmdlen, n + 2, cmdsize, 64);
-      strcpy (cscmd + cmdlen, t);
-      cmdlen += n;
-      if (cl->next)
-       cscmd[cmdlen++] = ' ';
-      free (t);
-    }
-  cscmd[cmdlen] = '\0';
-
-  tw = command_substitute (cscmd, 0);
-  csbuf = tw ? tw->word : (char *)NULL;
-  dispose_word_desc (tw);
-
-  /* Now clean up and destroy everything. */
-  dispose_words (cmdlist);
-  free (cscmd);
-  unbind_compfunc_variables (1);
-
-  if (csbuf == 0 || *csbuf == '\0')
-    {
-      FREE (csbuf);
-      return ((STRINGLIST *)NULL);
-    }
-
-  /* Now break CSBUF up at newlines, with backslash allowed to escape a
-     newline, and put the individual words into a STRINGLIST. */
-  sl = strlist_create (16);
-  for (ws = 0; csbuf[ws]; )
-    {
-      we = ws;
-      while (csbuf[we] && csbuf[we] != '\n')
-       {
-         if (csbuf[we] == '\\' && csbuf[we+1] == '\n')
-           we++;
-         we++;
-       }
-      t = substring (csbuf, ws, we);
-      if (sl->list_len >= sl->list_size - 1)
-       strlist_resize (sl, sl->list_size + 16);
-      sl->list[sl->list_len++] = t;
-      while (csbuf[we] == '\n') we++;
-      ws = we;
-    }
-  sl->list[sl->list_len] = (char *)NULL;
-
-  free (csbuf);
-  return (sl);
-}
-
-static WORD_LIST *
-command_line_to_word_list (line, llen, sentinel, nwp, cwp)
-     char *line;
-     int llen, sentinel, *nwp, *cwp;
-{
-  WORD_LIST *ret;
-  char *delims;
-
-#if 0
-  delims = "()<>;&| \t\n";     /* shell metacharacters break words */
-#else
-  delims = rl_completer_word_break_characters;
-#endif
-  ret = split_at_delims (line, llen, delims, sentinel, SD_NOQUOTEDELIMS, nwp, cwp);
-  return (ret);
-}
-
-/* Evaluate COMPSPEC *cs and return all matches for WORD. */
-
-STRINGLIST *
-gen_compspec_completions (cs, cmd, word, start, end, foundp)
-     COMPSPEC *cs;
-     const char *cmd;
-     const char *word;
-     int start, end;
-     int *foundp;
-{
-  STRINGLIST *ret, *tmatches;
-  char *line;
-  int llen, nw, cw, found, foundf;
-  WORD_LIST *lwords;
-  COMPSPEC *tcs;
-
-  found = 1;
-
-#ifdef DEBUG
-  debug_printf ("gen_compspec_completions (%s, %s, %d, %d)", cmd, word, start, end);
-  debug_printf ("gen_compspec_completions: %s -> %p", cmd, cs);
-#endif
-  ret = gen_action_completions (cs, word);
-#ifdef DEBUG
-  if (ret && progcomp_debug)
-    {
-      debug_printf ("gen_action_completions (%p, %s) -->", cs, word);
-      strlist_print (ret, "\t");
-      rl_on_new_line ();
-    }
-#endif
-
-  /* Now we start generating completions based on the other members of CS. */
-  if (cs->globpat)
-    {
-      tmatches = gen_globpat_matches (cs, word);
-      if (tmatches)
-       {
-#ifdef DEBUG
-         if (progcomp_debug)
-           {
-             debug_printf ("gen_globpat_matches (%p, %s) -->", cs, word);
-             strlist_print (tmatches, "\t");
-             rl_on_new_line ();
-           }
-#endif
-         ret = strlist_append (ret, tmatches);
-         strlist_dispose (tmatches);
-         rl_filename_completion_desired = 1;
-       }
-    }
-
-  if (cs->words)
-    {
-      tmatches = gen_wordlist_matches (cs, word);
-      if (tmatches)
-       {
-#ifdef DEBUG
-         if (progcomp_debug)
-           {
-             debug_printf ("gen_wordlist_matches (%p, %s) -->", cs, word);
-             strlist_print (tmatches, "\t");
-             rl_on_new_line ();
-           }
-#endif
-         ret = strlist_append (ret, tmatches);
-         strlist_dispose (tmatches);
-       }
-    }
-
-  lwords = (WORD_LIST *)NULL;
-  line = (char *)NULL;
-  if (cs->command || cs->funcname)
-    {
-      /* If we have a command or function to execute, we need to first break
-        the command line into individual words, find the number of words,
-        and find the word in the list containing the word to be completed. */
-      line = substring (rl_line_buffer, start, end);
-      llen = end - start;
-
-#ifdef DEBUG
-      debug_printf ("command_line_to_word_list (%s, %d, %d, %p, %p)",
-               line, llen, rl_point - start, &nw, &cw);
-#endif
-      lwords = command_line_to_word_list (line, llen, rl_point - start, &nw, &cw);
-#ifdef DEBUG
-      if (lwords == 0 && llen > 0)
-       debug_printf ("ERROR: command_line_to_word_list returns NULL");
-      else if (progcomp_debug)
-       {
-         debug_printf ("command_line_to_word_list -->");
-         printf ("\t");
-         print_word_list (lwords, "!");
-         printf ("\n");
-         fflush(stdout);
-         rl_on_new_line ();
-       }
-#endif
-    }
-
-  if (cs->funcname)
-    {
-      foundf = 0;
-      tmatches = gen_shell_function_matches (cs, word, line, rl_point - start, lwords, nw, cw, &foundf);
-      if (foundf != 0)
-       found = foundf;
-      if (tmatches)
-       {
-#ifdef DEBUG
-         if (progcomp_debug)
-           {
-             debug_printf ("gen_shell_function_matches (%p, %s, %p, %d, %d) -->", cs, word, lwords, nw, cw);
-             strlist_print (tmatches, "\t");
-             rl_on_new_line ();
-           }
-#endif
-         ret = strlist_append (ret, tmatches);
-         strlist_dispose (tmatches);
-       }
-    }
-
-  if (cs->command)
-    {
-      tmatches = gen_command_matches (cs, word, line, rl_point - start, lwords, nw, cw);
-      if (tmatches)
-       {
-#ifdef DEBUG
-         if (progcomp_debug)
-           {
-             debug_printf ("gen_command_matches (%p, %s, %p, %d, %d) -->", cs, word, lwords, nw, cw);
-             strlist_print (tmatches, "\t");
-             rl_on_new_line ();
-           }
-#endif
-         ret = strlist_append (ret, tmatches);
-         strlist_dispose (tmatches);
-       }
-    }
-
-  if (cs->command || cs->funcname)
-    {
-      if (lwords)
-       dispose_words (lwords);
-      FREE (line);
-    }
-
-  if (foundp)
-    *foundp = found;
-
-  if (found == 0 || (found & PCOMP_RETRYFAIL))
-    {
-      strlist_dispose (ret);
-      return NULL;
-    }
-
-  if (cs->filterpat)
-    {
-      tmatches = filter_stringlist (ret, cs->filterpat, word);
-#ifdef DEBUG
-      if (progcomp_debug)
-       {
-         debug_printf ("filter_stringlist (%p, %s, %s) -->", ret, cs->filterpat, word);
-         strlist_print (tmatches, "\t");
-         rl_on_new_line ();
-       }
-#endif
-      if (ret && ret != tmatches)
-       {
-         FREE (ret->list);
-         free (ret);
-       }
-      ret = tmatches;
-    }
-
-  if (cs->prefix || cs->suffix)
-    ret = strlist_prefix_suffix (ret, cs->prefix, cs->suffix);
-
-  /* If no matches have been generated and the user has specified that
-      directory completion should be done as a default, call
-      gen_action_completions again to generate a list of matching directory
-      names. */
-  if ((ret == 0 || ret->list_len == 0) && (cs->options & COPT_DIRNAMES))
-    {
-      tcs = compspec_create ();
-      tcs->actions = CA_DIRECTORY;
-      ret = gen_action_completions (tcs, word);
-      compspec_dispose (tcs);
-    }
-  else if (cs->options & COPT_PLUSDIRS)
-    {
-      tcs = compspec_create ();
-      tcs->actions = CA_DIRECTORY;
-      tmatches = gen_action_completions (tcs, word);
-      ret = strlist_append (ret, tmatches);
-      strlist_dispose (tmatches);
-      compspec_dispose (tcs);
-    }
-
-  return (ret);
-}
-
-void
-pcomp_set_readline_variables (flags, nval)
-     int flags, nval;
-{
-  /* If the user specified that the compspec returns filenames, make
-     sure that readline knows it. */
-  if (flags & COPT_FILENAMES)
-    rl_filename_completion_desired = nval;
-  /* If the user doesn't want a space appended, tell readline. */
-  if (flags & COPT_NOSPACE)
-    rl_completion_suppress_append = nval;
-}
-
-/* Set or unset FLAGS in the options word of the current compspec.
-   SET_OR_UNSET is 1 for setting, 0 for unsetting. */
-void
-pcomp_set_compspec_options (cs, flags, set_or_unset)
-     COMPSPEC *cs;
-     int flags, set_or_unset;
-{
-  if (cs == 0 && ((cs = pcomp_curcs) == 0))
-    return;
-  if (set_or_unset)
-    cs->options |= flags;
-  else
-    cs->options &= ~flags;
-}
-
-static STRINGLIST *
-gen_progcomp_completions (ocmd, cmd, word, start, end, foundp, retryp, lastcs)
-     const char *ocmd;
-     const char *cmd;
-     const char *word;
-     int start, end;
-     int *foundp, *retryp;
-     COMPSPEC **lastcs;
-{
-  COMPSPEC *cs, *oldcs;
-  const char *oldcmd;
-  STRINGLIST *ret;
-
-  cs = progcomp_search (ocmd);
-
-  if (cs == 0 || cs == *lastcs)
-    return (NULL);
-
-  if (*lastcs)
-    compspec_dispose (*lastcs);
-  cs->refcount++;      /* XXX */
-  *lastcs = cs;
-
-  cs = compspec_copy (cs);
-
-  oldcs = pcomp_curcs;
-  oldcmd = pcomp_curcmd;
-
-  pcomp_curcs = cs;
-  pcomp_curcmd = cmd;
-
-  ret = gen_compspec_completions (cs, cmd, word, start, end, foundp);
-
-  pcomp_curcs = oldcs;
-  pcomp_curcmd = oldcmd;
-
-  /* We need to conditionally handle setting *retryp here */
-  if (retryp)
-    *retryp = foundp && (*foundp & PCOMP_RETRYFAIL);           
-
-  if (foundp)
-    {
-      *foundp &= ~PCOMP_RETRYFAIL;
-      *foundp |= cs->options;
-    }
-
-  compspec_dispose (cs);
-  return ret;  
-}
-
-/* The driver function for the programmable completion code.  Returns a list
-   of matches for WORD, which is an argument to command CMD.  START and END
-   bound the command currently being completed in rl_line_buffer. */
-char **
-programmable_completions (cmd, word, start, end, foundp)
-     const char *cmd;
-     const char *word;
-     int start, end, *foundp;
-{
-  COMPSPEC *cs, *lastcs;
-  STRINGLIST *ret;
-  char **rmatches, *t;
-  int found, retry, count;
-
-  lastcs = 0;
-  found = count = 0;
-
-  do
-    {
-      retry = 0;
-
-      /* We look at the basename of CMD if the full command does not have
-        an associated COMPSPEC. */
-      ret = gen_progcomp_completions (cmd, cmd, word, start, end, &found, &retry, &lastcs);
-      if (found == 0)
-       {
-         t = strrchr (cmd, '/');
-         if (t && *(++t))
-           ret = gen_progcomp_completions (t, cmd, word, start, end, &found, &retry, &lastcs);
-       }
-
-      if (found == 0)
-       ret = gen_progcomp_completions (DEFAULTCMD, cmd, word, start, end, &found, &retry, &lastcs);
-
-      count++;
-
-      if (count > 32)
-       {
-         internal_warning ("programmable_completion: %s: possible retry loop", cmd);
-         break;
-       }
-    }
-  while (retry);
-
-  if (ret)
-    {
-      rmatches = ret->list;
-      free (ret);
-    }
-  else
-    rmatches = (char **)NULL;
-
-  if (foundp)
-    *foundp = found;
-
-  if (lastcs)  /* XXX - should be while? */
-    compspec_dispose (lastcs);
-
-  return (rmatches);
-}
-
-#endif /* PROGRAMMABLE_COMPLETION */
diff --git a/po/LINGUAS~ b/po/LINGUAS~
deleted file mode 100644 (file)
index e60ea35..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-# Set of available languages.
-en@quot en@boldquot af bg ca cs de eo es et fi fr hu id ja lt nl pl pt_BR ro ru sk sv tr vi zh_TW
diff --git a/po/POTFILES.in~ b/po/POTFILES.in~
deleted file mode 100644 (file)
index 6d9afbf..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-# List of source files containing translatable strings.
-# Copyright (C) 2004 Free Software Foundation, Inc.
-
-arrayfunc.c
-bashhist.c
-bashline.c
-braces.c
-builtins/bind.def
-builtins/break.def
-builtins/caller.def
-builtins/cd.def
-builtins/common.c
-builtins/complete.def
-builtins/declare.def
-builtins/enable.def
-builtins/evalfile.c
-builtins/exec.def
-builtins/exit.def
-builtins/fc.def
-builtins/fg_bg.def
-builtins/getopt.c
-builtins/hash.def
-builtins/help.def
-builtins/history.def
-builtins/inlib.def
-builtins/jobs.def
-builtins/kill.def
-builtins/let.def
-builtins/mapfile.def
-builtins/mkbuiltins.c
-builtins/printf.def
-builtins/pushd.def
-builtins/read.def
-builtins/return.def
-builtins/set.def
-builtins/setattr.def
-builtins/shift.def
-builtins/shopt.def
-builtins/source.def
-builtins/suspend.def
-builtins/type.def
-builtins/ulimit.def
-builtins/umask.def
-error.c
-eval.c
-execute_cmd.c
-expr.c
-general.c
-input.c
-jobs.c
-lib/malloc/malloc.c
-lib/malloc/stats.c
-lib/malloc/table.c
-lib/malloc/watch.c
-lib/sh/fmtulong.c
-lib/sh/netopen.c
-mailcheck.c
-make_cmd.c
-nojobs.c
-parse.y
-pcomplete.c
-pcomplib.c
-print_cmd.c
-redir.c
-shell.c
-sig.c
-siglist.c
-subst.c
-test.c
-trap.c
-variables.c
-version.c
-xmalloc.c
-
-# Apparently gettext's defaults cannot handle files that exist outside of the
-# source directory, like in the build directory
-#../builtins/builtins.c
diff --git a/print_cmd.c~ b/print_cmd.c~
deleted file mode 100644 (file)
index d24dc0a..0000000
+++ /dev/null
@@ -1,1533 +0,0 @@
-/* print_command -- A way to make readable commands from a command tree. */
-
-/* Copyright (C) 1989-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/>.
-*/
-
-#include "config.h"
-
-#include <stdio.h>
-
-#if defined (HAVE_UNISTD_H)
-#  ifdef _MINIX
-#    include <sys/types.h>
-#  endif
-#  include <unistd.h>
-#endif
-
-#if defined (PREFER_STDARG)
-#  include <stdarg.h>
-#else
-#  include <varargs.h>
-#endif
-
-#include "bashansi.h"
-#include "bashintl.h"
-
-#include "shell.h"
-#include "flags.h"
-#include <y.tab.h>     /* use <...> so we pick it up from the build directory */
-
-#include "shmbutil.h"
-
-#include "builtins/common.h"
-
-#if !HAVE_DECL_PRINTF
-extern int printf __P((const char *, ...));    /* Yuck.  Double yuck. */
-#endif
-
-extern int indirection_level;
-extern int last_command_exit_value;
-
-static int indentation;
-static int indentation_amount = 4;
-
-#if defined (PREFER_STDARG)
-typedef void PFUNC __P((const char *, ...));
-
-static void cprintf __P((const char *, ...))  __attribute__((__format__ (printf, 1, 2)));
-static void xprintf __P((const char *, ...))  __attribute__((__format__ (printf, 1, 2)));
-#else
-#define PFUNC VFunction
-static void cprintf ();
-static void xprintf ();
-#endif
-
-static void reset_locals __P((void));
-static void newline __P((char *));
-static void indent __P((int));
-static void semicolon __P((void));
-static void the_printed_command_resize __P((int));
-
-static void make_command_string_internal __P((COMMAND *));
-static void _print_word_list __P((WORD_LIST *, char *, PFUNC *));
-static void command_print_word_list __P((WORD_LIST *, char *));
-static void print_case_clauses __P((PATTERN_LIST *));
-static void print_redirection_list __P((REDIRECT *));
-static void print_redirection __P((REDIRECT *));
-static void print_heredoc_header __P((REDIRECT *));
-static void print_heredoc_body __P((REDIRECT *));
-static void print_heredocs __P((REDIRECT *));
-static void print_deferred_heredocs __P((const char *));
-
-static void print_for_command __P((FOR_COM *));
-#if defined (ARITH_FOR_COMMAND)
-static void print_arith_for_command __P((ARITH_FOR_COM *));
-#endif
-#if defined (SELECT_COMMAND)
-static void print_select_command __P((SELECT_COM *));
-#endif
-static void print_group_command __P((GROUP_COM *));
-static void print_case_command __P((CASE_COM *));
-static void print_while_command __P((WHILE_COM *));
-static void print_until_command __P((WHILE_COM *));
-static void print_until_or_while __P((WHILE_COM *, char *));
-static void print_if_command __P((IF_COM *));
-#if defined (COND_COMMAND)
-static void print_cond_node __P((COND_COM *));
-#endif
-static void print_function_def __P((FUNCTION_DEF *));
-
-#define PRINTED_COMMAND_INITIAL_SIZE 64
-#define PRINTED_COMMAND_GROW_SIZE 128
-
-char *the_printed_command = (char *)NULL;
-int the_printed_command_size = 0;
-int command_string_index = 0;
-
-int xtrace_fd = -1;
-FILE *xtrace_fp = 0;
-
-#define CHECK_XTRACE_FP        xtrace_fp = (xtrace_fp ? xtrace_fp : stderr)
-
-/* Non-zero means the stuff being printed is inside of a function def. */
-static int inside_function_def;
-static int skip_this_indent;
-static int was_heredoc;
-static int printing_connection;
-static REDIRECT *deferred_heredocs;
-
-/* The depth of the group commands that we are currently printing.  This
-   includes the group command that is a function body. */
-static int group_command_nesting;
-
-/* A buffer to indicate the indirection level (PS4) when set -x is enabled. */
-static char indirection_string[100];
-
-/* Print COMMAND (a command tree) on standard output. */
-void
-print_command (command)
-     COMMAND *command;
-{
-  command_string_index = 0;
-  printf ("%s", make_command_string (command));
-}
-
-/* Make a string which is the printed representation of the command
-   tree in COMMAND.  We return this string.  However, the string is
-   not consed, so you have to do that yourself if you want it to
-   remain around. */
-char *
-make_command_string (command)
-     COMMAND *command;
-{
-  command_string_index = was_heredoc = 0;
-  deferred_heredocs = 0;
-  make_command_string_internal (command);
-  return (the_printed_command);
-}
-
-/* The internal function.  This is the real workhorse. */
-static void
-make_command_string_internal (command)
-     COMMAND *command;
-{
-  char s[3], *op;
-
-  if (command == 0)
-    cprintf ("");
-  else
-    {
-      if (skip_this_indent)
-       skip_this_indent--;
-      else
-       indent (indentation);
-
-      if (command->flags & CMD_TIME_PIPELINE)
-       {
-         cprintf ("time ");
-         if (command->flags & CMD_TIME_POSIX)
-           cprintf ("-p ");
-       }
-
-      if (command->flags & CMD_INVERT_RETURN)
-       cprintf ("! ");
-
-      switch (command->type)
-       {
-       case cm_for:
-         print_for_command (command->value.For);
-         break;
-
-#if defined (ARITH_FOR_COMMAND)
-       case cm_arith_for:
-         print_arith_for_command (command->value.ArithFor);
-         break;
-#endif
-
-#if defined (SELECT_COMMAND)
-       case cm_select:
-         print_select_command (command->value.Select);
-         break;
-#endif
-
-       case cm_case:
-         print_case_command (command->value.Case);
-         break;
-
-       case cm_while:
-         print_while_command (command->value.While);
-         break;
-
-       case cm_until:
-         print_until_command (command->value.While);
-         break;
-
-       case cm_if:
-         print_if_command (command->value.If);
-         break;
-
-#if defined (DPAREN_ARITHMETIC)
-       case cm_arith:
-         print_arith_command (command->value.Arith->exp);
-         break;
-#endif
-
-#if defined (COND_COMMAND)
-       case cm_cond:
-         print_cond_command (command->value.Cond);
-         break;
-#endif
-
-       case cm_simple:
-         print_simple_command (command->value.Simple);
-         break;
-
-       case cm_connection:
-
-         skip_this_indent++;
-         printing_connection++;
-         make_command_string_internal (command->value.Connection->first);
-
-         switch (command->value.Connection->connector)
-           {
-           case '&':
-           case '|':
-             {
-               char c = command->value.Connection->connector;
-
-               s[0] = ' ';
-               s[1] = c;
-               s[2] = '\0';
-               
-               print_deferred_heredocs (s);
-
-               if (c != '&' || command->value.Connection->second)
-                 {
-                   cprintf (" ");
-                   skip_this_indent++;
-                 }
-             }
-             break;
-
-           case AND_AND:
-             print_deferred_heredocs (" && ");
-             if (command->value.Connection->second)
-               skip_this_indent++;
-             break;
-
-           case OR_OR:
-             print_deferred_heredocs (" || ");
-             if (command->value.Connection->second)
-               skip_this_indent++;
-             break;
-
-           case ';':
-             if (deferred_heredocs == 0)
-               {
-                 if (was_heredoc == 0)
-                   cprintf (";");
-                 else
-                   was_heredoc = 0;
-               }
-             else
-               print_deferred_heredocs (inside_function_def ? "" : ";");
-
-             if (inside_function_def)
-               cprintf ("\n");
-             else
-               {
-                 cprintf (" ");
-                 if (command->value.Connection->second)
-                   skip_this_indent++;
-               }
-             break;
-
-           default:
-             cprintf (_("print_command: bad connector `%d'"),
-                      command->value.Connection->connector);
-             break;
-           }
-
-         make_command_string_internal (command->value.Connection->second);
-         if (deferred_heredocs)
-           print_deferred_heredocs ("");
-         printing_connection--;                  
-         break;
-
-       case cm_function_def:
-         print_function_def (command->value.Function_def);
-         break;
-
-       case cm_group:
-         print_group_command (command->value.Group);
-         break;
-
-       case cm_subshell:
-         cprintf ("( ");
-         skip_this_indent++;
-         make_command_string_internal (command->value.Subshell->command);
-         cprintf (" )");
-         break;
-
-       case cm_coproc:
-         cprintf ("coproc %s ", command->value.Coproc->name);
-         skip_this_indent++;
-         make_command_string_internal (command->value.Coproc->command);
-         break;
-
-       default:
-         command_error ("print_command", CMDERR_BADTYPE, command->type, 0);
-         break;
-       }
-
-
-      if (command->redirects)
-       {
-         cprintf (" ");
-         print_redirection_list (command->redirects);
-       }
-    }
-}
-
-static void
-_print_word_list (list, separator, pfunc)
-     WORD_LIST *list;
-     char *separator;
-     PFUNC *pfunc;
-{
-  WORD_LIST *w;
-
-  for (w = list; w; w = w->next)
-    (*pfunc) ("%s%s", w->word->word, w->next ? separator : "");
-}
-
-void
-print_word_list (list, separator)
-     WORD_LIST *list;
-     char *separator;
-{
-  _print_word_list (list, separator, xprintf);
-}
-
-void
-xtrace_set (fd, fp)
-     int fd;
-     FILE *fp;
-{
-  if (fd >= 0 && sh_validfd (fd) == 0)
-    {
-      internal_error (_("xtrace_set: %d: invalid file descriptor"), fd);
-      return;
-    }
-  if (fp == 0)
-    {
-      internal_error (_("xtrace_set: NULL file pointer"));
-      return;
-    }
-  if (fd >= 0 && fileno (fp) != fd)
-    internal_warning (_("xtrace fd (%d) != fileno xtrace fp (%d)"), fd, fileno (fp));
-  
-  xtrace_fd = fd;
-  xtrace_fp = fp;
-}
-
-void
-xtrace_init ()
-{
-  xtrace_set (-1, stderr);
-}
-
-void
-xtrace_reset ()
-{
-  if (xtrace_fd >= 0 && xtrace_fp)
-    {
-      fflush (xtrace_fp);
-      fclose (xtrace_fp);
-    }
-  else if (xtrace_fd >= 0)
-    close (xtrace_fd);
-
-  xtrace_fd = -1;
-  xtrace_fp = stderr;
-}
-
-void
-xtrace_fdchk (fd)
-     int fd;
-{
-  if (fd == xtrace_fd)
-    xtrace_reset ();
-}
-
-/* Return a string denoting what our indirection level is. */
-
-char *
-indirection_level_string ()
-{
-  register int i, j;
-  char *ps4;
-  char ps4_firstc[MB_LEN_MAX+1];
-  int ps4_firstc_len, ps4_len;
-
-  indirection_string[0] = '\0';
-  ps4 = get_string_value ("PS4");
-
-  if (ps4 == 0 || *ps4 == '\0')
-    return (indirection_string);
-
-  change_flag ('x', FLAG_OFF);
-  ps4 = decode_prompt_string (ps4);
-  change_flag ('x', FLAG_ON);
-
-  if (ps4 == 0 || *ps4 == '\0')
-    return (indirection_string);
-
-#if defined (HANDLE_MULTIBYTE)
-  ps4_len = strnlen (ps4, MB_CUR_MAX);
-  ps4_firstc_len = MBLEN (ps4, ps4_len);
-  if (ps4_firstc_len == 1 || ps4_firstc_len == 0 || MB_INVALIDCH (ps4_firstc_len))
-    {
-      ps4_firstc[0] = ps4[0];
-      ps4_firstc[ps4_firstc_len = 1] = '\0';
-    }
-  else
-    memcpy (ps4_firstc, ps4, ps4_firstc_len);
-#else
-  ps4_firstc[0] = ps4[0];
-  ps4_firstc[ps4_firstc_len = 1] = '\0';
-#endif
-      
-  for (i = j = 0; ps4_firstc[0] && j < indirection_level && i < 99; i += ps4_firstc_len, j++)
-    {
-      if (ps4_firstc_len == 1)
-       indirection_string[i] = ps4_firstc[0];
-      else
-       memcpy (indirection_string+i, ps4_firstc, ps4_firstc_len);
-    }      
-
-  for (j = ps4_firstc_len; *ps4 && ps4[j] && i < 99; i++, j++)
-    indirection_string[i] = ps4[j];
-
-  indirection_string[i] = '\0';
-  free (ps4);
-  return (indirection_string);
-}
-
-void
-xtrace_print_assignment (name, value, assign_list, xflags)
-     char *name, *value;
-     int assign_list, xflags;
-{
-  char *nval;
-
-  CHECK_XTRACE_FP;
-
-  if (xflags)
-    fprintf (xtrace_fp, "%s", indirection_level_string ());
-
-  /* VALUE should not be NULL when this is called. */
-  if (*value == '\0' || assign_list)
-    nval = value;
-  else if (sh_contains_shell_metas (value))
-    nval = sh_single_quote (value);
-  else if (ansic_shouldquote (value))
-    nval = ansic_quote (value, 0, (int *)0);
-  else
-    nval = value;
-
-  if (assign_list)
-    fprintf (xtrace_fp, "%s=(%s)\n", name, nval);
-  else
-    fprintf (xtrace_fp, "%s=%s\n", name, nval);
-
-  if (nval != value)
-    FREE (nval);
-
-  fflush (xtrace_fp);
-}
-
-/* A function to print the words of a simple command when set -x is on. */
-void
-xtrace_print_word_list (list, xtflags)
-     WORD_LIST *list;
-     int xtflags;
-{
-  WORD_LIST *w;
-  char *t, *x;
-
-  CHECK_XTRACE_FP;
-
-  if (xtflags)
-    fprintf (xtrace_fp, "%s", indirection_level_string ());
-
-  for (w = list; w; w = w->next)
-    {
-      t = w->word->word;
-      if (t == 0 || *t == '\0')
-       fprintf (xtrace_fp, "''%s", w->next ? " " : "");
-      else if (sh_contains_shell_metas (t))
-       {
-         x = sh_single_quote (t);
-         fprintf (xtrace_fp, "%s%s", x, w->next ? " " : "");
-         free (x);
-       }
-      else if (ansic_shouldquote (t))
-       {
-         x = ansic_quote (t, 0, (int *)0);
-         fprintf (xtrace_fp, "%s%s", x, w->next ? " " : "");
-         free (x);
-       }
-      else
-       fprintf (xtrace_fp, "%s%s", t, w->next ? " " : "");
-    }
-  fprintf (xtrace_fp, "\n");
-  fflush (xtrace_fp);
-}
-
-static void
-command_print_word_list (list, separator)
-     WORD_LIST *list;
-     char *separator;
-{
-  _print_word_list (list, separator, cprintf);
-}
-
-void
-print_for_command_head (for_command)
-     FOR_COM *for_command;
-{
-  cprintf ("for %s in ", for_command->name->word);
-  command_print_word_list (for_command->map_list, " ");
-}
-
-void
-xtrace_print_for_command_head (for_command)
-     FOR_COM *for_command;
-{
-  CHECK_XTRACE_FP;
-  fprintf (xtrace_fp, "%s", indirection_level_string ());
-  fprintf (xtrace_fp, "for %s in ", for_command->name->word);
-  xtrace_print_word_list (for_command->map_list, 0);
-}
-
-static void
-print_for_command (for_command)
-     FOR_COM *for_command;
-{
-  print_for_command_head (for_command);
-
-  cprintf (";");
-  newline ("do\n");
-  indentation += indentation_amount;
-  make_command_string_internal (for_command->action);
-  semicolon ();
-  indentation -= indentation_amount;
-  newline ("done");
-}
-
-#if defined (ARITH_FOR_COMMAND)
-static void
-print_arith_for_command (arith_for_command)
-     ARITH_FOR_COM *arith_for_command;
-{
-  cprintf ("for ((");
-  command_print_word_list (arith_for_command->init, " ");
-  cprintf ("; ");
-  command_print_word_list (arith_for_command->test, " ");
-  cprintf ("; ");
-  command_print_word_list (arith_for_command->step, " ");
-  cprintf ("))");
-  newline ("do\n");
-  indentation += indentation_amount;
-  make_command_string_internal (arith_for_command->action);
-  semicolon ();
-  indentation -= indentation_amount;
-  newline ("done");
-}
-#endif /* ARITH_FOR_COMMAND */
-
-#if defined (SELECT_COMMAND)
-void
-print_select_command_head (select_command)
-     SELECT_COM *select_command;
-{
-  cprintf ("select %s in ", select_command->name->word);
-  command_print_word_list (select_command->map_list, " ");
-}
-
-void
-xtrace_print_select_command_head (select_command)
-     SELECT_COM *select_command;
-{
-  CHECK_XTRACE_FP;
-  fprintf (xtrace_fp, "%s", indirection_level_string ());
-  fprintf (xtrace_fp, "select %s in ", select_command->name->word);
-  xtrace_print_word_list (select_command->map_list, 0);
-}
-
-static void
-print_select_command (select_command)
-     SELECT_COM *select_command;
-{
-  print_select_command_head (select_command);
-
-  cprintf (";");
-  newline ("do\n");
-  indentation += indentation_amount;
-  make_command_string_internal (select_command->action);
-  semicolon ();
-  indentation -= indentation_amount;
-  newline ("done");
-}
-#endif /* SELECT_COMMAND */
-
-static void
-print_group_command (group_command)
-     GROUP_COM *group_command;
-{
-  group_command_nesting++;
-  cprintf ("{ ");
-
-  if (inside_function_def == 0)
-    skip_this_indent++;
-  else
-    {
-      /* This is a group command { ... } inside of a function
-        definition, and should be printed as a multiline group
-        command, using the current indentation. */
-      cprintf ("\n");
-      indentation += indentation_amount;
-    }
-
-  make_command_string_internal (group_command->command);
-
-  if (inside_function_def)
-    {
-      cprintf ("\n");
-      indentation -= indentation_amount;
-      indent (indentation);
-    }
-  else
-    {
-      semicolon ();
-      cprintf (" ");
-    }
-
-  cprintf ("}");
-
-  group_command_nesting--;
-}
-
-void
-print_case_command_head (case_command)
-     CASE_COM *case_command;
-{
-  cprintf ("case %s in ", case_command->word->word);
-}
-
-void
-xtrace_print_case_command_head (case_command)
-     CASE_COM *case_command;
-{
-  CHECK_XTRACE_FP;
-  fprintf (xtrace_fp, "%s", indirection_level_string ());
-  fprintf (xtrace_fp, "case %s in\n", case_command->word->word);
-}
-
-static void
-print_case_command (case_command)
-     CASE_COM *case_command;
-{
-  print_case_command_head (case_command);
-
-  if (case_command->clauses)
-    print_case_clauses (case_command->clauses);
-  newline ("esac");
-}
-
-static void
-print_case_clauses (clauses)
-     PATTERN_LIST *clauses;
-{
-  indentation += indentation_amount;
-  while (clauses)
-    {
-      newline ("");
-      command_print_word_list (clauses->patterns, " | ");
-      cprintf (")\n");
-      indentation += indentation_amount;
-      make_command_string_internal (clauses->action);
-      indentation -= indentation_amount;
-      if (clauses->flags & CASEPAT_FALLTHROUGH)
-       newline (";&");
-      else if (clauses->flags & CASEPAT_TESTNEXT)
-       newline (";;&");
-      else
-       newline (";;");
-      clauses = clauses->next;
-    }
-  indentation -= indentation_amount;
-}
-
-static void
-print_while_command (while_command)
-     WHILE_COM *while_command;
-{
-  print_until_or_while (while_command, "while");
-}
-
-static void
-print_until_command (while_command)
-     WHILE_COM *while_command;
-{
-  print_until_or_while (while_command, "until");
-}
-
-static void
-print_until_or_while (while_command, which)
-     WHILE_COM *while_command;
-     char *which;
-{
-  cprintf ("%s ", which);
-  skip_this_indent++;
-  make_command_string_internal (while_command->test);
-  semicolon ();
-  cprintf (" do\n");   /* was newline ("do\n"); */
-  indentation += indentation_amount;
-  make_command_string_internal (while_command->action);
-  indentation -= indentation_amount;
-  semicolon ();
-  newline ("done");
-}
-
-static void
-print_if_command (if_command)
-     IF_COM *if_command;
-{
-  cprintf ("if ");
-  skip_this_indent++;
-  make_command_string_internal (if_command->test);
-  semicolon ();
-  cprintf (" then\n");
-  indentation += indentation_amount;
-  make_command_string_internal (if_command->true_case);
-  indentation -= indentation_amount;
-
-  if (if_command->false_case)
-    {
-      semicolon ();
-      newline ("else\n");
-      indentation += indentation_amount;
-      make_command_string_internal (if_command->false_case);
-      indentation -= indentation_amount;
-    }
-  semicolon ();
-  newline ("fi");
-}
-
-#if defined (DPAREN_ARITHMETIC)
-void
-print_arith_command (arith_cmd_list)
-     WORD_LIST *arith_cmd_list;
-{
-  cprintf ("((");
-  command_print_word_list (arith_cmd_list, " ");
-  cprintf ("))");
-}
-#endif
-
-#if defined (COND_COMMAND)
-static void
-print_cond_node (cond)
-     COND_COM *cond;
-{
-  if (cond->flags & CMD_INVERT_RETURN)
-    cprintf ("! ");
-
-  if (cond->type == COND_EXPR)
-    {
-      cprintf ("( ");
-      print_cond_node (cond->left);
-      cprintf (" )");
-    }
-  else if (cond->type == COND_AND)
-    {
-      print_cond_node (cond->left);
-      cprintf (" && ");
-      print_cond_node (cond->right);
-    }
-  else if (cond->type == COND_OR)
-    {
-      print_cond_node (cond->left);
-      cprintf (" || ");
-      print_cond_node (cond->right);
-    }
-  else if (cond->type == COND_UNARY)
-    {
-      cprintf ("%s", cond->op->word);
-      cprintf (" ");
-      print_cond_node (cond->left);
-    }
-  else if (cond->type == COND_BINARY)
-    {
-      print_cond_node (cond->left);
-      cprintf (" ");
-      cprintf ("%s", cond->op->word);
-      cprintf (" ");
-      print_cond_node (cond->right);
-    }
-  else if (cond->type == COND_TERM)
-    {
-      cprintf ("%s", cond->op->word);          /* need to add quoting here */
-    }
-}
-
-void
-print_cond_command (cond)
-     COND_COM *cond;
-{
-  cprintf ("[[ ");
-  print_cond_node (cond);
-  cprintf (" ]]");
-}
-
-#ifdef DEBUG
-void
-debug_print_cond_command (cond)
-     COND_COM *cond;
-{
-  fprintf (stderr, "DEBUG: ");
-  command_string_index = 0;
-  print_cond_command (cond);
-  fprintf (stderr, "%s\n", the_printed_command);
-}
-#endif
-
-void
-xtrace_print_cond_term (type, invert, op, arg1, arg2)
-     int type, invert;
-     WORD_DESC *op;
-     char *arg1, *arg2;
-{
-  CHECK_XTRACE_FP;
-  command_string_index = 0;
-  fprintf (xtrace_fp, "%s", indirection_level_string ());
-  fprintf (xtrace_fp, "[[ ");
-  if (invert)
-    fprintf (xtrace_fp, "! ");
-
-  if (type == COND_UNARY)
-    {
-      fprintf (xtrace_fp, "%s ", op->word);
-      fprintf (xtrace_fp, "%s", (arg1 && *arg1) ? arg1 : "''");
-    }
-  else if (type == COND_BINARY)
-    {
-      fprintf (xtrace_fp, "%s", (arg1 && *arg1) ? arg1 : "''");
-      fprintf (xtrace_fp, " %s ", op->word);
-      fprintf (xtrace_fp, "%s", (arg2 && *arg2) ? arg2 : "''");
-    }
-
-  fprintf (xtrace_fp, " ]]\n");
-
-  fflush (xtrace_fp);
-}        
-#endif /* COND_COMMAND */
-
-#if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
-/* A function to print the words of an arithmetic command when set -x is on. */
-void
-xtrace_print_arith_cmd (list)
-     WORD_LIST *list;
-{
-  WORD_LIST *w;
-
-  CHECK_XTRACE_FP;
-  fprintf (xtrace_fp, "%s", indirection_level_string ());
-  fprintf (xtrace_fp, "(( ");
-  for (w = list; w; w = w->next)
-    fprintf (xtrace_fp, "%s%s", w->word->word, w->next ? " " : "");
-  fprintf (xtrace_fp, " ))\n");
-
-  fflush (xtrace_fp);
-}
-#endif
-
-void
-print_simple_command (simple_command)
-     SIMPLE_COM *simple_command;
-{
-  command_print_word_list (simple_command->words, " ");
-
-  if (simple_command->redirects)
-    {
-      cprintf (" ");
-      print_redirection_list (simple_command->redirects);
-    }
-}
-
-static void
-print_heredocs (heredocs)
-     REDIRECT *heredocs;
-{
-  REDIRECT *hdtail;
-
-  cprintf (" "); 
-  for (hdtail = heredocs; hdtail; hdtail = hdtail->next)
-    {
-      print_redirection (hdtail);
-      cprintf ("\n");
-    }
-  was_heredoc = 1;
-}
-
-/* Print heredocs that are attached to the command before the connector
-   represented by CSTRING.  The parsing semantics require us to print the
-   here-doc delimiters, then the connector (CSTRING), then the here-doc
-   bodies.  We don't print the connector if it's a `;', but we use it to
-   note not to print an extra space after the last heredoc body and
-   newline. */
-static void
-print_deferred_heredocs (cstring)
-     const char *cstring;
-{
-  REDIRECT *hdtail;    
-
-  for (hdtail = deferred_heredocs; hdtail; hdtail = hdtail->next)
-    {
-      cprintf (" ");
-      print_heredoc_header (hdtail);
-    }
-  if (cstring[0] != ';' || cstring[1])
-    cprintf ("%s", cstring); 
-  if (deferred_heredocs)
-    cprintf ("\n");
-  for (hdtail = deferred_heredocs; hdtail; hdtail = hdtail->next)
-    {
-      print_heredoc_body (hdtail);
-      cprintf ("\n");
-    }
-  if (deferred_heredocs)
-    {
-      if (cstring && cstring[0] && (cstring[0] != ';' || cstring[1]))
-       cprintf (" ");  /* make sure there's at least one space */
-      dispose_redirects (deferred_heredocs);
-      was_heredoc = 1;
-    }
-  deferred_heredocs = (REDIRECT *)NULL;
-}
-      
-static void
-print_redirection_list (redirects)
-     REDIRECT *redirects;
-{
-  REDIRECT *heredocs, *hdtail, *newredir;
-
-  heredocs = (REDIRECT *)NULL;
-  hdtail = heredocs;
-
-  was_heredoc = 0;
-  while (redirects)
-    {
-      /* Defer printing the here documents until we've printed the
-        rest of the redirections. */
-      if (redirects->instruction == r_reading_until || redirects->instruction == r_deblank_reading_until)
-       {
-         newredir = copy_redirect (redirects);
-         newredir->next = (REDIRECT *)NULL;
-         if (heredocs)
-           {
-             hdtail->next = newredir;
-             hdtail = newredir;
-           }
-         else
-           hdtail = heredocs = newredir;
-       }
-      else if (redirects->instruction == r_duplicating_output_word && redirects->redirector.dest == 1)
-       {
-         /* Temporarily translate it as the execution code does. */
-         redirects->instruction = r_err_and_out;
-         print_redirection (redirects);
-         redirects->instruction = r_duplicating_output_word;
-       }
-      else
-       print_redirection (redirects);
-
-      redirects = redirects->next;
-      if (redirects)
-       cprintf (" ");
-    }
-
-  /* Now that we've printed all the other redirections (on one line),
-     print the here documents. */
-  if (heredocs && printing_connection)
-    deferred_heredocs = heredocs;
-  else if (heredocs)
-    {
-      print_heredocs (heredocs);
-      dispose_redirects (heredocs);
-    }
-}
-
-static void
-print_heredoc_header (redirect)
-     REDIRECT *redirect;
-{
-  int kill_leading;
-  char *x;
-
-  kill_leading = redirect->instruction == r_deblank_reading_until;
-
-  /* Here doc header */
-  if (redirect->rflags & REDIR_VARASSIGN)
-    cprintf ("{%s}", redirect->redirector.filename->word);
-  else if (redirect->redirector.dest != 0)
-    cprintf ("%d", redirect->redirector.dest);
-
-  /* If the here document delimiter is quoted, single-quote it. */
-  if (redirect->redirectee.filename->flags & W_QUOTED)
-    {
-      x = sh_single_quote (redirect->here_doc_eof);
-      cprintf ("<<%s%s", kill_leading ? "-" : "", x);
-      free (x);
-    }
-  else
-    cprintf ("<<%s%s", kill_leading ? "-" : "", redirect->here_doc_eof);
-}
-
-static void
-print_heredoc_body (redirect)
-     REDIRECT *redirect;
-{
-  /* Here doc body */
-  cprintf ("%s%s", redirect->redirectee.filename->word, redirect->here_doc_eof);
-}
-
-static void
-print_redirection (redirect)
-     REDIRECT *redirect;
-{
-  int kill_leading, redirector, redir_fd;
-  WORD_DESC *redirectee, *redir_word;
-
-  kill_leading = 0;
-  redirectee = redirect->redirectee.filename;
-  redir_fd = redirect->redirectee.dest;
-
-  redir_word = redirect->redirector.filename;
-  redirector = redirect->redirector.dest;
-
-  switch (redirect->instruction)
-    {
-    case r_input_direction:
-      if (redirect->rflags & REDIR_VARASSIGN)
-       cprintf ("{%s}", redir_word->word);
-      else if (redirector != 0)
-       cprintf ("%d", redirector);
-      cprintf ("< %s", redirectee->word);
-      break;
-
-    case r_output_direction:
-      if (redirect->rflags & REDIR_VARASSIGN)
-       cprintf ("{%s}", redir_word->word);
-      else if (redirector != 1)
-       cprintf ("%d", redirector);
-      cprintf ("> %s", redirectee->word);
-      break;
-
-    case r_inputa_direction:   /* Redirection created by the shell. */
-      cprintf ("&");
-      break;
-
-    case r_output_force:
-      if (redirect->rflags & REDIR_VARASSIGN)
-       cprintf ("{%s}", redir_word->word);
-      else if (redirector != 1)
-       cprintf ("%d", redirector);
-      cprintf (">|%s", redirectee->word);
-      break;
-
-    case r_appending_to:
-      if (redirect->rflags & REDIR_VARASSIGN)
-       cprintf ("{%s}", redir_word->word);
-      else if (redirector != 1)
-       cprintf ("%d", redirector);
-      cprintf (">> %s", redirectee->word);
-      break;
-
-    case r_input_output:
-      if (redirect->rflags & REDIR_VARASSIGN)
-       cprintf ("{%s}", redir_word->word);
-      else if (redirector != 1)
-       cprintf ("%d", redirector);
-      cprintf ("<> %s", redirectee->word);
-      break;
-
-    case r_deblank_reading_until:
-    case r_reading_until:
-      print_heredoc_header (redirect);
-      cprintf ("\n");
-      print_heredoc_body (redirect);
-      break;
-
-    case r_reading_string:
-      if (redirect->rflags & REDIR_VARASSIGN)
-       cprintf ("{%s}", redir_word->word);
-      else if (redirector != 0)
-       cprintf ("%d", redirector);
-      if (ansic_shouldquote (redirect->redirectee.filename->word))
-       {
-         char *x;
-         x = ansic_quote (redirect->redirectee.filename->word, 0, (int *)0);
-         cprintf ("<<< %s", x);
-         free (x);
-       }
-      else
-       cprintf ("<<< %s", redirect->redirectee.filename->word);
-      break;
-
-    case r_duplicating_input:
-      if (redirect->rflags & REDIR_VARASSIGN)
-       cprintf ("{%s}<&%d", redir_word->word, redir_fd);
-      else
-       cprintf ("%d<&%d", redirector, redir_fd);
-      break;
-
-    case r_duplicating_output:
-      if (redirect->rflags & REDIR_VARASSIGN)
-       cprintf ("{%s}>&%d", redir_word->word, redir_fd);
-      else
-       cprintf ("%d>&%d", redirector, redir_fd);
-      break;
-
-    case r_duplicating_input_word:
-      if (redirect->rflags & REDIR_VARASSIGN)
-       cprintf ("{%s}<&%s", redir_word->word, redirectee->word);
-      else
-       cprintf ("%d<&%s", redirector, redirectee->word);
-      break;
-
-    case r_duplicating_output_word:
-      if (redirect->rflags & REDIR_VARASSIGN)
-       cprintf ("{%s}>&%s", redir_word->word, redirectee->word);
-      else
-       cprintf ("%d>&%s", redirector, redirectee->word);
-      break;
-
-    case r_move_input:
-      if (redirect->rflags & REDIR_VARASSIGN)
-       cprintf ("{%s}<&%d-", redir_word->word, redir_fd);
-      else
-       cprintf ("%d<&%d-", redirector, redir_fd);
-      break;
-
-    case r_move_output:
-      if (redirect->rflags & REDIR_VARASSIGN)
-       cprintf ("{%s}>&%d-", redir_word->word, redir_fd);
-      else
-       cprintf ("%d>&%d-", redirector, redir_fd);
-      break;
-
-    case r_move_input_word:
-      if (redirect->rflags & REDIR_VARASSIGN)
-       cprintf ("{%s}<&%s-", redir_word->word, redirectee->word);
-      else
-       cprintf ("%d<&%s-", redirector, redirectee->word);
-      break;
-
-    case r_move_output_word:
-      if (redirect->rflags & REDIR_VARASSIGN)
-       cprintf ("{%s}>&%s-", redir_word->word, redirectee->word);
-      else
-       cprintf ("%d>&%s-", redirector, redirectee->word);
-      break;
-
-    case r_close_this:
-      if (redirect->rflags & REDIR_VARASSIGN)
-       cprintf ("{%s}>&-", redir_word->word);
-      else
-       cprintf ("%d>&-", redirector);
-      break;
-
-    case r_err_and_out:
-      cprintf ("&>%s", redirectee->word);
-      break;
-
-    case r_append_err_and_out:
-      cprintf ("&>>%s", redirectee->word);
-      break;
-    }
-}
-
-static void
-reset_locals ()
-{
-  inside_function_def = 0;
-  indentation = 0;
-  printing_connection = 0;
-  deferred_heredocs = 0;
-}
-
-static void
-print_function_def (func)
-     FUNCTION_DEF *func;
-{
-  COMMAND *cmdcopy;
-  REDIRECT *func_redirects;
-
-  func_redirects = NULL;
-  cprintf ("function %s () \n", func->name->word);
-  add_unwind_protect (reset_locals, 0);
-
-  indent (indentation);
-  cprintf ("{ \n");
-
-  inside_function_def++;
-  indentation += indentation_amount;
-
-  cmdcopy = copy_command (func->command);
-  if (cmdcopy->type == cm_group)
-    {
-      func_redirects = cmdcopy->redirects;
-      cmdcopy->redirects = (REDIRECT *)NULL;
-    }
-  make_command_string_internal (cmdcopy->type == cm_group
-                                       ? cmdcopy->value.Group->command
-                                       : cmdcopy);
-
-  remove_unwind_protect ();
-  indentation -= indentation_amount;
-  inside_function_def--;
-
-  if (func_redirects)
-    { /* { */
-      newline ("} ");
-      print_redirection_list (func_redirects);
-      cmdcopy->redirects = func_redirects;
-    }
-  else
-    newline ("}");
-
-  dispose_command (cmdcopy);
-}
-
-/* Return the string representation of the named function.
-   NAME is the name of the function.
-   COMMAND is the function body.  It should be a GROUP_COM.
-   flags&FUNC_MULTILINE is non-zero to pretty-print, or zero for all on one line.
-   flags&FUNC_EXTERNAL means convert from internal to external form
-  */
-char *
-named_function_string (name, command, flags)
-     char *name;
-     COMMAND *command;
-     int flags;
-{
-  char *result;
-  int old_indent, old_amount;
-  COMMAND *cmdcopy;
-  REDIRECT *func_redirects;
-
-  old_indent = indentation;
-  old_amount = indentation_amount;
-  command_string_index = was_heredoc = 0;
-  deferred_heredocs = 0;
-
-  if (name && *name)
-    cprintf ("%s ", name);
-
-  cprintf ("() ");
-
-  if ((flags & FUNC_MULTILINE) == 0)
-    {
-      indentation = 1;
-      indentation_amount = 0;
-    }
-  else
-    {
-      cprintf ("\n");
-      indentation += indentation_amount;
-    }
-
-  inside_function_def++;
-
-  cprintf ((flags & FUNC_MULTILINE) ? "{ \n" : "{ ");
-
-  cmdcopy = copy_command (command);
-  /* Take any redirections specified in the function definition (which should
-     apply to the function as a whole) and save them for printing later. */
-  func_redirects = (REDIRECT *)NULL;
-  if (cmdcopy->type == cm_group)
-    {
-      func_redirects = cmdcopy->redirects;
-      cmdcopy->redirects = (REDIRECT *)NULL;
-    }
-  make_command_string_internal (cmdcopy->type == cm_group
-                                       ? cmdcopy->value.Group->command
-                                       : cmdcopy);
-
-  indentation = old_indent;
-  indentation_amount = old_amount;
-  inside_function_def--;
-
-  if (func_redirects)
-    { /* { */
-      newline ("} ");
-      print_redirection_list (func_redirects);
-      cmdcopy->redirects = func_redirects;
-    }
-  else
-    newline ("}");
-
-  result = the_printed_command;
-
-  if ((flags & FUNC_MULTILINE) == 0)
-    {
-#if 0
-      register int i;
-      for (i = 0; result[i]; i++)
-       if (result[i] == '\n')
-         {
-           strcpy (result + i, result + i + 1);
-           --i;
-         }
-#else
-      if (result[2] == '\n')   /* XXX -- experimental */
-       strcpy (result + 2, result + 3);
-#endif
-    }
-
-  dispose_command (cmdcopy);
-
-  if (flags & FUNC_EXTERNAL)
-    result = remove_quoted_escapes (result);
-
-  return (result);
-}
-
-static void
-newline (string)
-     char *string;
-{
-  cprintf ("\n");
-  indent (indentation);
-  if (string && *string)
-    cprintf ("%s", string);
-}
-
-static char *indentation_string;
-static int indentation_size;
-
-static void
-indent (amount)
-     int amount;
-{
-  register int i;
-
-  RESIZE_MALLOCED_BUFFER (indentation_string, 0, amount, indentation_size, 16);
-
-  for (i = 0; amount > 0; amount--)
-    indentation_string[i++] = ' ';
-  indentation_string[i] = '\0';
-  cprintf (indentation_string);
-}
-
-static void
-semicolon ()
-{
-  if (command_string_index > 0 &&
-       (the_printed_command[command_string_index - 1] == '&' ||
-       the_printed_command[command_string_index - 1] == '\n'))
-    return;
-  cprintf (";");
-}
-
-/* How to make the string. */
-static void
-#if defined (PREFER_STDARG)
-cprintf (const char *control, ...)
-#else
-cprintf (control, va_alist)
-     const char *control;
-     va_dcl
-#endif
-{
-  register const char *s;
-  char char_arg[2], *argp, intbuf[INT_STRLEN_BOUND (int) + 1];
-  int digit_arg, arg_len, c;
-  va_list args;
-
-  SH_VA_START (args, control);
-
-  arg_len = strlen (control);
-  the_printed_command_resize (arg_len + 1);
-
-  char_arg[1] = '\0';
-  s = control;
-  while (s && *s)
-    {
-      c = *s++;
-      argp = (char *)NULL;
-      if (c != '%' || !*s)
-       {
-         char_arg[0] = c;
-         argp = char_arg;
-         arg_len = 1;
-       }
-      else
-       {
-         c = *s++;
-         switch (c)
-           {
-           case '%':
-             char_arg[0] = c;
-             argp = char_arg;
-             arg_len = 1;
-             break;
-
-           case 's':
-             argp = va_arg (args, char *);
-             arg_len = strlen (argp);
-             break;
-
-           case 'd':
-             /* Represent an out-of-range file descriptor with an out-of-range
-                integer value.  We can do this because the only use of `%d' in
-                the calls to cprintf is to output a file descriptor number for
-                a redirection. */
-             digit_arg = va_arg (args, int);
-             if (digit_arg < 0)
-               {
-                 sprintf (intbuf, "%u", (unsigned)-1);
-                 argp = intbuf;
-               }
-             else
-               argp = inttostr (digit_arg, intbuf, sizeof (intbuf));
-             arg_len = strlen (argp);
-             break;
-
-           case 'c':
-             char_arg[0] = va_arg (args, int);
-             argp = char_arg;
-             arg_len = 1;
-             break;
-
-           default:
-             programming_error (_("cprintf: `%c': invalid format character"), c);
-             /*NOTREACHED*/
-           }
-       }
-
-      if (argp && arg_len)
-       {
-         the_printed_command_resize (arg_len + 1);
-         FASTCOPY (argp, the_printed_command + command_string_index, arg_len);
-         command_string_index += arg_len;
-       }
-    }
-
-  the_printed_command[command_string_index] = '\0';
-}
-
-/* Ensure that there is enough space to stuff LENGTH characters into
-   THE_PRINTED_COMMAND. */
-static void
-the_printed_command_resize (length)
-     int length;
-{
-  if (the_printed_command == 0)
-    {
-      the_printed_command_size = (length + PRINTED_COMMAND_INITIAL_SIZE - 1) & ~(PRINTED_COMMAND_INITIAL_SIZE - 1);
-      the_printed_command = (char *)xmalloc (the_printed_command_size);
-      command_string_index = 0;
-    }
-  else if ((command_string_index + length) >= the_printed_command_size)
-    {
-      int new;
-      new = command_string_index + length + 1;
-
-      /* Round up to the next multiple of PRINTED_COMMAND_GROW_SIZE. */
-      new = (new + PRINTED_COMMAND_GROW_SIZE - 1) & ~(PRINTED_COMMAND_GROW_SIZE - 1);
-      the_printed_command_size = new;
-
-      the_printed_command = (char *)xrealloc (the_printed_command, the_printed_command_size);
-    }
-}
-
-#if defined (HAVE_VPRINTF)
-/* ``If vprintf is available, you may assume that vfprintf and vsprintf are
-     also available.'' */
-
-static void
-#if defined (PREFER_STDARG)
-xprintf (const char *format, ...)
-#else
-xprintf (format, va_alist)
-     const char *format;
-     va_dcl
-#endif
-{
-  va_list args;
-
-  SH_VA_START (args, format);
-
-  vfprintf (stdout, format, args);
-  va_end (args);
-}
-
-#else
-
-static void
-xprintf (format, arg1, arg2, arg3, arg4, arg5)
-     const char *format;
-{
-  printf (format, arg1, arg2, arg3, arg4, arg5);
-}
-
-#endif /* !HAVE_VPRINTF */
diff --git a/redir.c~ b/redir.c~
deleted file mode 100644 (file)
index 20fc683..0000000
--- a/redir.c~
+++ /dev/null
@@ -1,1175 +0,0 @@
-/* redir.c -- Functions to perform input and output redirection. */
-
-/* Copyright (C) 1997-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/>.
-*/
-
-#include "config.h"
-
-#if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX)
-  #pragma alloca
-#endif /* _AIX && RISC6000 && !__GNUC__ */
-
-#include <stdio.h>
-#include "bashtypes.h"
-#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H)
-#  include <sys/file.h>
-#endif
-#include "filecntl.h"
-#include "posixstat.h"
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include <errno.h>
-
-#if !defined (errno)
-extern int errno;
-#endif
-
-#include "bashansi.h"
-#include "bashintl.h"
-#include "memalloc.h"
-
-#define NEED_FPURGE_DECL
-
-#include "shell.h"
-#include "flags.h"
-#include "execute_cmd.h"
-#include "redir.h"
-
-#if defined (BUFFERED_INPUT)
-#  include "input.h"
-#endif
-
-#define SHELL_FD_BASE  10
-
-int expanding_redir;
-
-extern int posixly_correct;
-extern REDIRECT *redirection_undo_list;
-extern REDIRECT *exec_redirection_undo_list;
-
-/* Static functions defined and used in this file. */
-static void add_undo_close_redirect __P((int));
-static void add_exec_redirect __P((REDIRECT *));
-static int add_undo_redirect __P((int, enum r_instruction, int));
-static int expandable_redirection_filename __P((REDIRECT *));
-static int stdin_redirection __P((enum r_instruction, int));
-static int undoablefd __P((int));
-static int do_redirection_internal __P((REDIRECT *, int));
-
-static int write_here_document __P((int, WORD_DESC *));
-static int write_here_string __P((int, WORD_DESC *));
-static int here_document_to_fd __P((WORD_DESC *, enum r_instruction));
-
-static int redir_special_open __P((int, char *, int, int, enum r_instruction));
-static int noclobber_open __P((char *, int, int, enum r_instruction));
-static int redir_open __P((char *, int, int, enum r_instruction));
-
-/* Spare redirector used when translating [N]>&WORD[-] or [N]<&WORD[-] to
-   a new redirection and when creating the redirection undo list. */
-static REDIRECTEE rd;
-
-/* Set to errno when a here document cannot be created for some reason.
-   Used to print a reasonable error message. */
-static int heredoc_errno;
-
-void
-redirection_error (temp, error)
-     REDIRECT *temp;
-     int error;
-{
-  char *filename, *allocname;
-  int oflags;
-
-  allocname = 0;
-  if (temp->rflags & REDIR_VARASSIGN)
-    filename = savestring (temp->redirector.filename->word);
-  else if (temp->redirector.dest < 0)
-    /* This can happen when read_token_word encounters overflow, like in
-       exec 4294967297>x */
-    filename = _("file descriptor out of range");
-#ifdef EBADF
-  /* This error can never involve NOCLOBBER */
-  else if (error != NOCLOBBER_REDIRECT && temp->redirector.dest >= 0 && error == EBADF)
-    {
-      /* If we're dealing with two file descriptors, we have to guess about
-         which one is invalid; in the cases of r_{duplicating,move}_input and
-         r_{duplicating,move}_output we're here because dup2() failed. */
-      switch (temp->instruction)
-        {
-        case r_duplicating_input:
-        case r_duplicating_output:
-        case r_move_input:
-        case r_move_output:
-         filename = allocname = itos (temp->redirectee.dest);
-         break;
-       default:
-         filename = allocname = itos (temp->redirector.dest);
-         break;
-        }
-    }
-#endif
-  else if (expandable_redirection_filename (temp))
-    {
-      if (posixly_correct && interactive_shell == 0)
-       {
-         oflags = temp->redirectee.filename->flags;
-         temp->redirectee.filename->flags |= W_NOGLOB;
-       }
-      filename = allocname = redirection_expand (temp->redirectee.filename);
-      if (posixly_correct && interactive_shell == 0)
-       temp->redirectee.filename->flags = oflags;
-      if (filename == 0)
-       filename = temp->redirectee.filename->word;
-    }
-  else if (temp->redirectee.dest < 0)
-    filename = "file descriptor out of range";
-  else
-    filename = allocname = itos (temp->redirectee.dest);
-
-  switch (error)
-    {
-    case AMBIGUOUS_REDIRECT:
-      internal_error (_("%s: ambiguous redirect"), filename);
-      break;
-
-    case NOCLOBBER_REDIRECT:
-      internal_error (_("%s: cannot overwrite existing file"), filename);
-      break;
-
-#if defined (RESTRICTED_SHELL)
-    case RESTRICTED_REDIRECT:
-      internal_error (_("%s: restricted: cannot redirect output"), filename);
-      break;
-#endif /* RESTRICTED_SHELL */
-
-    case HEREDOC_REDIRECT:
-      internal_error (_("cannot create temp file for here-document: %s"), strerror (heredoc_errno));
-      break;
-
-    case BADVAR_REDIRECT:
-      internal_error (_("cannot assign fd to variable %s"), filename);
-      break;
-
-    default:
-      internal_error ("%s: %s", filename, strerror (error));
-      break;
-    }
-
-  FREE (allocname);
-}
-
-/* Perform the redirections on LIST.  If flags & RX_ACTIVE, then actually
-   make input and output file descriptors, otherwise just do whatever is
-   neccessary for side effecting.  flags & RX_UNDOABLE says to remember
-   how to undo the redirections later, if non-zero.  If flags & RX_CLEXEC
-   is non-zero, file descriptors opened in do_redirection () have their
-   close-on-exec flag set. */
-int
-do_redirections (list, flags)
-     REDIRECT *list;
-     int flags;
-{
-  int error;
-  REDIRECT *temp;
-
-  if (flags & RX_UNDOABLE)
-    {
-      if (redirection_undo_list)
-       {
-         dispose_redirects (redirection_undo_list);
-         redirection_undo_list = (REDIRECT *)NULL;
-       }
-      if (exec_redirection_undo_list)
-       dispose_exec_redirects ();
-    }
-
-  for (temp = list; temp; temp = temp->next)
-    {
-      error = do_redirection_internal (temp, flags);
-      if (error)
-       {
-         redirection_error (temp, error);
-         return (error);
-       }
-    }
-  return (0);
-}
-
-/* Return non-zero if the redirection pointed to by REDIRECT has a
-   redirectee.filename that can be expanded. */
-static int
-expandable_redirection_filename (redirect)
-     REDIRECT *redirect;
-{
-  switch (redirect->instruction)
-    {
-    case r_output_direction:
-    case r_appending_to:
-    case r_input_direction:
-    case r_inputa_direction:
-    case r_err_and_out:
-    case r_append_err_and_out:
-    case r_input_output:
-    case r_output_force:
-    case r_duplicating_input_word:
-    case r_duplicating_output_word:
-    case r_move_input_word:
-    case r_move_output_word:
-      return 1;
-
-    default:
-      return 0;
-    }
-}
-
-/* Expand the word in WORD returning a string.  If WORD expands to
-   multiple words (or no words), then return NULL. */
-char *
-redirection_expand (word)
-     WORD_DESC *word;
-{
-  char *result;
-  WORD_LIST *tlist1, *tlist2;
-  WORD_DESC *w;
-
-  w = copy_word (word);
-  if (posixly_correct)
-    w->flags |= W_NOSPLIT;
-
-  tlist1 = make_word_list (w, (WORD_LIST *)NULL);
-  expanding_redir = 1;
-  tlist2 = expand_words_no_vars (tlist1);
-  expanding_redir = 0;
-  dispose_words (tlist1);
-
-  if (!tlist2 || tlist2->next)
-    {
-      /* We expanded to no words, or to more than a single word.
-        Dispose of the word list and return NULL. */
-      if (tlist2)
-       dispose_words (tlist2);
-      return ((char *)NULL);
-    }
-  result = string_list (tlist2);  /* XXX savestring (tlist2->word->word)? */
-  dispose_words (tlist2);
-  return (result);
-}
-
-static int
-write_here_string (fd, redirectee)
-     int fd;
-     WORD_DESC *redirectee;
-{
-  char *herestr;
-  int herelen, n, e;
-
-  expanding_redir = 1;
-  herestr = expand_string_to_string (redirectee->word, 0);
-  expanding_redir = 0;
-  herelen = STRLEN (herestr);
-
-  n = write (fd, herestr, herelen);
-  if (n == herelen)
-    {
-      n = write (fd, "\n", 1);
-      herelen = 1;
-    }
-  e = errno;
-  FREE (herestr);
-  if (n != herelen)
-    {
-      if (e == 0)
-       e = ENOSPC;
-      return e;
-    }
-  return 0;
-}  
-
-/* Write the text of the here document pointed to by REDIRECTEE to the file
-   descriptor FD, which is already open to a temp file.  Return 0 if the
-   write is successful, otherwise return errno. */
-static int
-write_here_document (fd, redirectee)
-     int fd;
-     WORD_DESC *redirectee;
-{
-  char *document;
-  int document_len, fd2;
-  FILE *fp;
-  register WORD_LIST *t, *tlist;
-
-  /* Expand the text if the word that was specified had
-     no quoting.  The text that we expand is treated
-     exactly as if it were surrounded by double quotes. */
-
-  if (redirectee->flags & W_QUOTED)
-    {
-      document = redirectee->word;
-      document_len = strlen (document);
-      /* Set errno to something reasonable if the write fails. */
-      if (write (fd, document, document_len) < document_len)
-       {
-         if (errno == 0)
-           errno = ENOSPC;
-         return (errno);
-       }
-      else
-       return 0;
-    }
-
-  expanding_redir = 1;
-  tlist = expand_string (redirectee->word, Q_HERE_DOCUMENT);
-  expanding_redir = 0;
-
-  if (tlist)
-    {
-      /* Try using buffered I/O (stdio) and writing a word
-        at a time, letting stdio do the work of buffering
-        for us rather than managing our own strings.  Most
-        stdios are not particularly fast, however -- this
-        may need to be reconsidered later. */
-      if ((fd2 = dup (fd)) < 0 || (fp = fdopen (fd2, "w")) == NULL)
-       {
-         if (fd2 >= 0)
-           close (fd2);
-         return (errno);
-       }
-      errno = 0;
-      for (t = tlist; t; t = t->next)
-       {
-         /* This is essentially the body of
-            string_list_internal expanded inline. */
-         document = t->word->word;
-         document_len = strlen (document);
-         if (t != tlist)
-           putc (' ', fp);     /* separator */
-         fwrite (document, document_len, 1, fp);
-         if (ferror (fp))
-           {
-             if (errno == 0)
-               errno = ENOSPC;
-             fd2 = errno;
-             fclose(fp);
-             dispose_words (tlist);
-             return (fd2);
-           }
-       }
-      dispose_words (tlist);
-      if (fclose (fp) != 0)
-       {
-         if (errno == 0)
-           errno = ENOSPC;
-         return (errno);
-       }
-    }
-  return 0;
-}
-
-/* Create a temporary file holding the text of the here document pointed to
-   by REDIRECTEE, and return a file descriptor open for reading to the temp
-   file.  Return -1 on any error, and make sure errno is set appropriately. */
-static int
-here_document_to_fd (redirectee, ri)
-     WORD_DESC *redirectee;
-     enum r_instruction ri;
-{
-  char *filename;
-  int r, fd, fd2;
-
-  fd = sh_mktmpfd ("sh-thd", MT_USERANDOM|MT_USETMPDIR, &filename);
-
-  /* If we failed for some reason other than the file existing, abort */
-  if (fd < 0)
-    {
-      FREE (filename);
-      return (fd);
-    }
-
-  errno = r = 0;               /* XXX */
-  /* write_here_document returns 0 on success, errno on failure. */
-  if (redirectee->word)
-    r = (ri != r_reading_string) ? write_here_document (fd, redirectee)
-                                : write_here_string (fd, redirectee);
-
-  if (r)
-    {
-      close (fd);
-      unlink (filename);
-      free (filename);
-      errno = r;
-      return (-1);
-    }
-
-  /* In an attempt to avoid races, we close the first fd only after opening
-     the second. */
-  /* Make the document really temporary.  Also make it the input. */
-  fd2 = open (filename, O_RDONLY, 0600);
-
-  if (fd2 < 0)
-    {
-      r = errno;
-      unlink (filename);
-      free (filename);
-      close (fd);
-      errno = r;
-      return -1;
-    }
-
-  close (fd);
-  if (unlink (filename) < 0)
-    {
-      r = errno;
-#if defined (__CYGWIN__)
-      /* Under CygWin 1.1.0, the unlink will fail if the file is
-        open. This hack will allow the previous action of silently
-        ignoring the error, but will still leave the file there. This
-        needs some kind of magic. */
-      if (r == EACCES)
-       return (fd2);
-#endif /* __CYGWIN__ */
-      close (fd2);
-      free (filename);
-      errno = r;
-      return (-1);
-    }
-
-  free (filename);
-  return (fd2);
-}
-
-#define RF_DEVFD       1
-#define RF_DEVSTDERR   2
-#define RF_DEVSTDIN    3
-#define RF_DEVSTDOUT   4
-#define RF_DEVTCP      5
-#define RF_DEVUDP      6
-
-/* A list of pattern/value pairs for filenames that the redirection
-   code handles specially. */
-static STRING_INT_ALIST _redir_special_filenames[] = {
-#if !defined (HAVE_DEV_FD)
-  { "/dev/fd/[0-9]*", RF_DEVFD },
-#endif
-#if !defined (HAVE_DEV_STDIN)
-  { "/dev/stderr", RF_DEVSTDERR },
-  { "/dev/stdin", RF_DEVSTDIN },
-  { "/dev/stdout", RF_DEVSTDOUT },
-#endif
-#if defined (NETWORK_REDIRECTIONS)
-  { "/dev/tcp/*/*", RF_DEVTCP },
-  { "/dev/udp/*/*", RF_DEVUDP },
-#endif
-  { (char *)NULL, -1 }
-};
-
-static int
-redir_special_open (spec, filename, flags, mode, ri)
-     int spec;
-     char *filename;
-     int flags, mode;
-     enum r_instruction ri;
-{
-  int fd;
-#if !defined (HAVE_DEV_FD)
-  intmax_t lfd;
-#endif
-
-  fd = -1;
-  switch (spec)
-    {
-#if !defined (HAVE_DEV_FD)
-    case RF_DEVFD:
-      if (all_digits (filename+8) && legal_number (filename+8, &lfd) && lfd == (int)lfd)
-       {
-         fd = lfd;
-         fd = fcntl (fd, F_DUPFD, SHELL_FD_BASE);
-       }
-      else
-       fd = AMBIGUOUS_REDIRECT;
-      break;
-#endif
-
-#if !defined (HAVE_DEV_STDIN)
-    case RF_DEVSTDIN:
-      fd = fcntl (0, F_DUPFD, SHELL_FD_BASE);
-      break;
-    case RF_DEVSTDOUT:
-      fd = fcntl (1, F_DUPFD, SHELL_FD_BASE);
-      break;
-    case RF_DEVSTDERR:
-      fd = fcntl (2, F_DUPFD, SHELL_FD_BASE);
-      break;
-#endif
-
-#if defined (NETWORK_REDIRECTIONS)
-    case RF_DEVTCP:
-    case RF_DEVUDP:
-#if defined (HAVE_NETWORK)
-      fd = netopen (filename);
-#else
-      internal_warning (_("/dev/(tcp|udp)/host/port not supported without networking"));
-      fd = open (filename, flags, mode);
-#endif
-      break;
-#endif /* NETWORK_REDIRECTIONS */
-    }
-
-  return fd;
-}
-      
-/* Open FILENAME with FLAGS in noclobber mode, hopefully avoiding most
-   race conditions and avoiding the problem where the file is replaced
-   between the stat(2) and open(2). */
-static int
-noclobber_open (filename, flags, mode, ri)
-     char *filename;
-     int flags, mode;
-     enum r_instruction ri;
-{
-  int r, fd;
-  struct stat finfo, finfo2;
-
-  /* If the file exists and is a regular file, return an error
-     immediately. */
-  r = stat (filename, &finfo);
-  if (r == 0 && (S_ISREG (finfo.st_mode)))
-    return (NOCLOBBER_REDIRECT);
-
-  /* If the file was not present (r != 0), make sure we open it
-     exclusively so that if it is created before we open it, our open
-     will fail.  Make sure that we do not truncate an existing file.
-     Note that we don't turn on O_EXCL unless the stat failed -- if
-     the file was not a regular file, we leave O_EXCL off. */
-  flags &= ~O_TRUNC;
-  if (r != 0)
-    {
-      fd = open (filename, flags|O_EXCL, mode);
-      return ((fd < 0 && errno == EEXIST) ? NOCLOBBER_REDIRECT : fd);
-    }
-  fd = open (filename, flags, mode);
-
-  /* If the open failed, return the file descriptor right away. */
-  if (fd < 0)
-    return (errno == EEXIST ? NOCLOBBER_REDIRECT : fd);
-
-  /* OK, the open succeeded, but the file may have been changed from a
-     non-regular file to a regular file between the stat and the open.
-     We are assuming that the O_EXCL open handles the case where FILENAME
-     did not exist and is symlinked to an existing file between the stat
-     and open. */
-
-  /* If we can open it and fstat the file descriptor, and neither check
-     revealed that it was a regular file, and the file has not been replaced,
-     return the file descriptor. */
-  if ((fstat (fd, &finfo2) == 0) && (S_ISREG (finfo2.st_mode) == 0) &&
-      r == 0 && (S_ISREG (finfo.st_mode) == 0) &&
-      same_file (filename, filename, &finfo, &finfo2))
-    return fd;
-
-  /* The file has been replaced.  badness. */
-  close (fd);  
-  errno = EEXIST;
-  return (NOCLOBBER_REDIRECT);
-}
-
-static int
-redir_open (filename, flags, mode, ri)
-     char *filename;
-     int flags, mode;
-     enum r_instruction ri;
-{
-  int fd, r;
-
-  r = find_string_in_alist (filename, _redir_special_filenames, 1);
-  if (r >= 0)
-    return (redir_special_open (r, filename, flags, mode, ri));
-
-  /* If we are in noclobber mode, you are not allowed to overwrite
-     existing files.  Check before opening. */
-  if (noclobber && CLOBBERING_REDIRECT (ri))
-    {
-      fd = noclobber_open (filename, flags, mode, ri);
-      if (fd == NOCLOBBER_REDIRECT)
-       return (NOCLOBBER_REDIRECT);
-    }
-  else
-    {
-      fd = open (filename, flags, mode);
-#if defined (AFS)
-      if ((fd < 0) && (errno == EACCES))
-       {
-         fd = open (filename, flags & ~O_CREAT, mode);
-         errno = EACCES;       /* restore errno */
-       }
-#endif /* AFS */
-    }
-
-  return fd;
-}
-
-static int
-undoablefd (fd)
-     int fd;
-{
-  int clexec;
-
-  clexec = fcntl (fd, F_GETFD, 0);
-  if (clexec == -1 || (fd >= SHELL_FD_BASE && clexec == 1))
-    return 0;
-  return 1;
-}
-
-/* Do the specific redirection requested.  Returns errno or one of the
-   special redirection errors (*_REDIRECT) in case of error, 0 on success.
-   If flags & RX_ACTIVE is zero, then just do whatever is neccessary to
-   produce the appropriate side effects.   flags & RX_UNDOABLE, if non-zero,
-   says to remember how to undo each redirection.  If flags & RX_CLEXEC is
-   non-zero, then we set all file descriptors > 2 that we open to be
-   close-on-exec.  */
-static int
-do_redirection_internal (redirect, flags)
-     REDIRECT *redirect;
-     int flags;
-{
-  WORD_DESC *redirectee;
-  int redir_fd, fd, redirector, r, oflags;
-  intmax_t lfd;
-  char *redirectee_word;
-  enum r_instruction ri;
-  REDIRECT *new_redirect;
-  REDIRECTEE sd;
-
-  redirectee = redirect->redirectee.filename;
-  redir_fd = redirect->redirectee.dest;
-  redirector = redirect->redirector.dest;
-  ri = redirect->instruction;
-
-  if (redirect->flags & RX_INTERNAL)
-    flags |= RX_INTERNAL;
-
-  if (TRANSLATE_REDIRECT (ri))
-    {
-      /* We have [N]>&WORD[-] or [N]<&WORD[-].  Expand WORD, then translate
-        the redirection into a new one and continue. */
-      redirectee_word = redirection_expand (redirectee);
-
-      /* XXX - what to do with [N]<&$w- where w is unset or null?  ksh93
-              closes N. */
-      if (redirectee_word == 0)
-       return (AMBIGUOUS_REDIRECT);
-      else if (redirectee_word[0] == '-' && redirectee_word[1] == '\0')
-       {
-         sd.dest = redirector;
-         rd.dest = 0;
-         new_redirect = make_redirection (sd, r_close_this, rd);
-       }
-      else if (all_digits (redirectee_word))
-       {
-         sd.dest = redirector;
-         if (legal_number (redirectee_word, &lfd) && (int)lfd == lfd)
-           rd.dest = lfd;
-         else
-           rd.dest = -1;       /* XXX */
-         switch (ri)
-           {
-           case r_duplicating_input_word:
-             new_redirect = make_redirection (sd, r_duplicating_input, rd);
-             break;
-           case r_duplicating_output_word:
-             new_redirect = make_redirection (sd, r_duplicating_output, rd);
-             break;
-           case r_move_input_word:
-             new_redirect = make_redirection (sd, r_move_input, rd);
-             break;
-           case r_move_output_word:
-             new_redirect = make_redirection (sd, r_move_output, rd);
-             break;
-           }
-       }
-      else if (ri == r_duplicating_output_word && redirector == 1)
-       {
-         sd.dest = 1;
-         rd.filename = make_bare_word (redirectee_word);
-         new_redirect = make_redirection (sd, r_err_and_out, rd);
-       }
-      else
-       {
-         free (redirectee_word);
-         return (AMBIGUOUS_REDIRECT);
-       }
-
-      free (redirectee_word);
-
-      /* Set up the variables needed by the rest of the function from the
-        new redirection. */
-      if (new_redirect->instruction == r_err_and_out)
-       {
-         char *alloca_hack;
-
-         /* Copy the word without allocating any memory that must be
-            explicitly freed. */
-         redirectee = (WORD_DESC *)alloca (sizeof (WORD_DESC));
-         xbcopy ((char *)new_redirect->redirectee.filename,
-                (char *)redirectee, sizeof (WORD_DESC));
-
-         alloca_hack = (char *)
-           alloca (1 + strlen (new_redirect->redirectee.filename->word));
-         redirectee->word = alloca_hack;
-         strcpy (redirectee->word, new_redirect->redirectee.filename->word);
-       }
-      else
-       /* It's guaranteed to be an integer, and shouldn't be freed. */
-       redirectee = new_redirect->redirectee.filename;
-
-      redir_fd = new_redirect->redirectee.dest;
-      redirector = new_redirect->redirector.dest;
-      ri = new_redirect->instruction;
-
-      /* Overwrite the flags element of the old redirect with the new value. */
-      redirect->flags = new_redirect->flags;
-      dispose_redirects (new_redirect);
-    }
-
-  switch (ri)
-    {
-    case r_output_direction:
-    case r_appending_to:
-    case r_input_direction:
-    case r_inputa_direction:
-    case r_err_and_out:                /* command &>filename */
-    case r_append_err_and_out: /* command &>> filename */
-    case r_input_output:
-    case r_output_force:
-      if (posixly_correct && interactive_shell == 0)
-       {
-         oflags = redirectee->flags;
-         redirectee->flags |= W_NOGLOB;
-       }
-      redirectee_word = redirection_expand (redirectee);
-      if (posixly_correct && interactive_shell == 0)
-       redirectee->flags = oflags;
-
-      if (redirectee_word == 0)
-       return (AMBIGUOUS_REDIRECT);
-
-#if defined (RESTRICTED_SHELL)
-      if (restricted && (WRITE_REDIRECT (ri)))
-       {
-         free (redirectee_word);
-         return (RESTRICTED_REDIRECT);
-       }
-#endif /* RESTRICTED_SHELL */
-
-      fd = redir_open (redirectee_word, redirect->flags, 0666, ri);
-      free (redirectee_word);
-
-      if (fd == NOCLOBBER_REDIRECT)
-       return (fd);
-
-      if (fd < 0)
-       return (errno);
-
-      if (flags & RX_ACTIVE)
-       {
-         if (flags & RX_UNDOABLE)
-           {
-             /* Only setup to undo it if the thing to undo is active. */
-             if ((fd != redirector) && (fcntl (redirector, F_GETFD, 0) != -1))
-               add_undo_redirect (redirector, ri, -1);
-             else
-               add_undo_close_redirect (redirector);
-           }
-
-#if defined (BUFFERED_INPUT)
-         check_bash_input (redirector);
-#endif
-
-         /* Make sure there is no pending output before we change the state
-            of the underlying file descriptor, since the builtins use stdio
-            for output. */
-         if (redirector == 1 && fileno (stdout) == redirector)
-           {
-             fflush (stdout);
-             fpurge (stdout);
-           }
-         else if (redirector == 2 && fileno (stderr) == redirector)
-           {
-             fflush (stderr);
-             fpurge (stderr);
-           }
-
-         if ((fd != redirector) && (dup2 (fd, redirector) < 0))
-           return (errno);
-
-#if defined (BUFFERED_INPUT)
-         /* Do not change the buffered stream for an implicit redirection
-            of /dev/null to fd 0 for asynchronous commands without job
-            control (r_inputa_direction). */
-         if (ri == r_input_direction || ri == r_input_output)
-           duplicate_buffered_stream (fd, redirector);
-#endif /* BUFFERED_INPUT */
-
-         /*
-          * If we're remembering, then this is the result of a while, for
-          * or until loop with a loop redirection, or a function/builtin
-          * executing in the parent shell with a redirection.  In the
-          * function/builtin case, we want to set all file descriptors > 2
-          * to be close-on-exec to duplicate the effect of the old
-          * for i = 3 to NOFILE close(i) loop.  In the case of the loops,
-          * both sh and ksh leave the file descriptors open across execs.
-          * The Posix standard mentions only the exec builtin.
-          */
-         if ((flags & RX_CLEXEC) && (redirector > 2))
-           SET_CLOSE_ON_EXEC (redirector);
-       }
-
-      if (fd != redirector)
-       {
-#if defined (BUFFERED_INPUT)
-         if (INPUT_REDIRECT (ri))
-           close_buffered_fd (fd);
-         else
-#endif /* !BUFFERED_INPUT */
-           close (fd);         /* Don't close what we just opened! */
-       }
-
-      /* If we are hacking both stdout and stderr, do the stderr
-        redirection here. */
-      if (ri == r_err_and_out || ri == r_append_err_and_out)
-       {
-         if (flags & RX_ACTIVE)
-           {
-             if (flags & RX_UNDOABLE)
-               add_undo_redirect (2, ri, -1);
-             if (dup2 (1, 2) < 0)
-               return (errno);
-           }
-       }
-      break;
-
-    case r_reading_until:
-    case r_deblank_reading_until:
-    case r_reading_string:
-      /* REDIRECTEE is a pointer to a WORD_DESC containing the text of
-        the new input.  Place it in a temporary file. */
-      if (redirectee)
-       {
-         fd = here_document_to_fd (redirectee, ri);
-
-         if (fd < 0)
-           {
-             heredoc_errno = errno;
-             return (HEREDOC_REDIRECT);
-           }
-
-         if (flags & RX_ACTIVE)
-           {
-             if (flags & RX_UNDOABLE)
-               {
-                 /* Only setup to undo it if the thing to undo is active. */
-                 if ((fd != redirector) && (fcntl (redirector, F_GETFD, 0) != -1))
-                   add_undo_redirect (redirector, ri, -1);
-                 else
-                   add_undo_close_redirect (redirector);
-               }
-
-#if defined (BUFFERED_INPUT)
-             check_bash_input (redirector);
-#endif
-             if (fd != redirector && dup2 (fd, redirector) < 0)
-               {
-                 r = errno;
-                 close (fd);
-                 return (r);
-               }
-
-#if defined (BUFFERED_INPUT)
-             duplicate_buffered_stream (fd, redirector);
-#endif
-
-             if ((flags & RX_CLEXEC) && (redirector > 2))
-               SET_CLOSE_ON_EXEC (redirector);
-           }
-
-         if (fd != redirector)
-#if defined (BUFFERED_INPUT)
-           close_buffered_fd (fd);
-#else
-           close (fd);
-#endif
-       }
-      break;
-
-    case r_duplicating_input:
-    case r_duplicating_output:
-    case r_move_input:
-    case r_move_output:
-      if ((flags & RX_ACTIVE) && (redir_fd != redirector))
-       {
-         if (flags & RX_UNDOABLE)
-           {
-             /* Only setup to undo it if the thing to undo is active. */
-             if (fcntl (redirector, F_GETFD, 0) != -1)
-               add_undo_redirect (redirector, ri, redir_fd);
-             else
-               add_undo_close_redirect (redirector);
-           }
-#if defined (BUFFERED_INPUT)
-         check_bash_input (redirector);
-#endif
-         /* This is correct.  2>&1 means dup2 (1, 2); */
-         if (dup2 (redir_fd, redirector) < 0)
-           return (errno);
-
-#if defined (BUFFERED_INPUT)
-         if (ri == r_duplicating_input || ri == r_move_input)
-           duplicate_buffered_stream (redir_fd, redirector);
-#endif /* BUFFERED_INPUT */
-
-         /* First duplicate the close-on-exec state of redirectee.  dup2
-            leaves the flag unset on the new descriptor, which means it
-            stays open.  Only set the close-on-exec bit for file descriptors
-            greater than 2 in any case, since 0-2 should always be open
-            unless closed by something like `exec 2<&-'.  It should always
-            be safe to set fds > 2 to close-on-exec if they're being used to
-            save file descriptors < 2, since we don't need to preserve the
-            state of the close-on-exec flag for those fds -- they should
-            always be open. */
-         /* if ((already_set || set_unconditionally) && (ok_to_set))
-               set_it () */
-#if 0
-         if (((fcntl (redir_fd, F_GETFD, 0) == 1) || redir_fd < 2 || (flags & RX_CLEXEC)) &&
-              (redirector > 2))
-#else
-         if (((fcntl (redir_fd, F_GETFD, 0) == 1) || (redir_fd < 2 && (flags & RX_INTERNAL)) || (flags & RX_CLEXEC)) &&
-              (redirector > 2))
-#endif
-           SET_CLOSE_ON_EXEC (redirector);
-
-         /* When undoing saving of non-standard file descriptors (>=3) using
-            file descriptors >= SHELL_FD_BASE, we set the saving fd to be
-            close-on-exec and use a flag to decide how to set close-on-exec
-            when the fd is restored. */
-         if ((redirect->flags & RX_INTERNAL) && (redirect->flags & RX_SAVCLEXEC) && redirector >= 3 && redir_fd >= SHELL_FD_BASE)
-           SET_OPEN_ON_EXEC (redirector);
-           
-         /* dup-and-close redirection */
-         if (ri == r_move_input || ri == r_move_output)
-           {
-             xtrace_fdchk (redir_fd);
-
-             close (redir_fd);
-#if defined (COPROCESS_SUPPORT)
-             coproc_fdchk (redir_fd);  /* XXX - loses coproc fds */
-#endif
-           }
-       }
-      break;
-
-    case r_close_this:
-      if (flags & RX_ACTIVE)
-       {
-         if ((flags & RX_UNDOABLE) && (fcntl (redirector, F_GETFD, 0) != -1))
-           add_undo_redirect (redirector, ri, -1);
-
-#if defined (COPROCESS_SUPPORT)
-         coproc_fdchk (redirector);
-#endif
-         xtrace_fdchk (redirector);
-
-#if defined (BUFFERED_INPUT)
-         check_bash_input (redirector);
-         close_buffered_fd (redirector);
-#else /* !BUFFERED_INPUT */
-         close (redirector);
-#endif /* !BUFFERED_INPUT */
-       }
-      break;
-
-    case r_duplicating_input_word:
-    case r_duplicating_output_word:
-      break;
-    }
-  return (0);
-}
-
-/* Remember the file descriptor associated with the slot FD,
-   on REDIRECTION_UNDO_LIST.  Note that the list will be reversed
-   before it is executed.  Any redirections that need to be undone
-   even if REDIRECTION_UNDO_LIST is discarded by the exec builtin
-   are also saved on EXEC_REDIRECTION_UNDO_LIST.  FDBASE says where to
-   start the duplicating.  If it's less than SHELL_FD_BASE, we're ok,
-   and can use SHELL_FD_BASE (-1 == don't care).  If it's >= SHELL_FD_BASE,
-   we have to make sure we don't use fdbase to save a file descriptor,
-   since we're going to use it later (e.g., make sure we don't save fd 0
-   to fd 10 if we have a redirection like 0<&10).  If the value of fdbase
-   puts the process over its fd limit, causing fcntl to fail, we try
-   again with SHELL_FD_BASE. */
-static int
-add_undo_redirect (fd, ri, fdbase)
-     int fd;
-     enum r_instruction ri;
-     int fdbase;
-{
-  int new_fd, clexec_flag;
-  REDIRECT *new_redirect, *closer, *dummy_redirect;
-  REDIRECTEE sd;
-
-  new_fd = fcntl (fd, F_DUPFD, (fdbase < SHELL_FD_BASE) ? SHELL_FD_BASE : fdbase+1);
-  if (new_fd < 0)
-    new_fd = fcntl (fd, F_DUPFD, SHELL_FD_BASE);
-
-  if (new_fd < 0)
-    {
-      sys_error (_("redirection error: cannot duplicate fd"));
-      return (-1);
-    }
-
-  clexec_flag = fcntl (fd, F_GETFD, 0);
-
-  sd.dest = new_fd;
-  rd.dest = 0;
-  closer = make_redirection (sd, r_close_this, rd);
-  closer->flags |= RX_INTERNAL;
-  dummy_redirect = copy_redirects (closer);
-
-  sd.dest = fd;
-  rd.dest = new_fd;
-  if (fd == 0)
-    new_redirect = make_redirection (sd, r_duplicating_input, rd);
-  else
-    new_redirect = make_redirection (sd, r_duplicating_output, rd);
-  new_redirect->flags |= RX_INTERNAL;
-  if (clexec_flag == 0 && fd >= 3 && new_fd >= SHELL_FD_BASE)
-    new_redirect->flags |= RX_SAVCLEXEC;
-  new_redirect->next = closer;
-
-  closer->next = redirection_undo_list;
-  redirection_undo_list = new_redirect;
-
-  /* Save redirections that need to be undone even if the undo list
-     is thrown away by the `exec' builtin. */
-  add_exec_redirect (dummy_redirect);
-
-  /* experimental:  if we're saving a redirection to undo for a file descriptor
-     above SHELL_FD_BASE, add a redirection to be undone if the exec builtin
-     causes redirections to be discarded.  There needs to be a difference
-     between fds that are used to save other fds and then are the target of
-     user redirctions and fds that are just the target of user redirections.
-     We use the close-on-exec flag to tell the difference; fds > SHELL_FD_BASE
-     that have the close-on-exec flag set are assumed to be fds used internally
-     to save others. */
-  if (fd >= SHELL_FD_BASE && ri != r_close_this && clexec_flag)
-    {
-      sd.dest = fd;
-      rd.dest = new_fd;
-      new_redirect = make_redirection (sd, r_duplicating_output, rd);
-      new_redirect->flags |= RX_INTERNAL;
-
-      add_exec_redirect (new_redirect);
-    }
-
-  /* File descriptors used only for saving others should always be
-     marked close-on-exec.  Unfortunately, we have to preserve the
-     close-on-exec state of the file descriptor we are saving, since
-     fcntl (F_DUPFD) sets the new file descriptor to remain open
-     across execs.  If, however, the file descriptor whose state we
-     are saving is <= 2, we can just set the close-on-exec flag,
-     because file descriptors 0-2 should always be open-on-exec,
-     and the restore above in do_redirection() will take care of it. */
-  if (clexec_flag || fd < 3)
-    SET_CLOSE_ON_EXEC (new_fd);
-  else if (redirection_undo_list->flags & RX_SAVCLEXEC)
-    SET_CLOSE_ON_EXEC (new_fd);
-
-  return (0);
-}
-
-/* Set up to close FD when we are finished with the current command
-   and its redirections. */
-static void
-add_undo_close_redirect (fd)
-     int fd;
-{
-  REDIRECT *closer;
-  REDIRECTEE sd;
-
-  sd.dest = fd;
-  rd.dest = 0;
-  closer = make_redirection (sd, r_close_this, rd);
-  closer->flags |= RX_INTERNAL;
-  closer->next = redirection_undo_list;
-  redirection_undo_list = closer;
-}
-
-static void
-add_exec_redirect (dummy_redirect)
-     REDIRECT *dummy_redirect;
-{
-  dummy_redirect->next = exec_redirection_undo_list;
-  exec_redirection_undo_list = dummy_redirect;
-}
-
-/* Return 1 if the redirection specified by RI and REDIRECTOR alters the
-   standard input. */
-static int
-stdin_redirection (ri, redirector)
-     enum r_instruction ri;
-     int redirector;
-{
-  switch (ri)
-    {
-    case r_input_direction:
-    case r_inputa_direction:
-    case r_input_output:
-    case r_reading_until:
-    case r_deblank_reading_until:
-    case r_reading_string:
-      return (1);
-    case r_duplicating_input:
-    case r_duplicating_input_word:
-    case r_close_this:
-      return (redirector == 0);
-    case r_output_direction:
-    case r_appending_to:
-    case r_duplicating_output:
-    case r_err_and_out:
-    case r_append_err_and_out:
-    case r_output_force:
-    case r_duplicating_output_word:
-      return (0);
-    }
-  return (0);
-}
-
-/* Return non-zero if any of the redirections in REDIRS alter the standard
-   input. */
-int
-stdin_redirects (redirs)
-     REDIRECT *redirs;
-{
-  REDIRECT *rp;
-  int n;
-
-  for (n = 0, rp = redirs; rp; rp = rp->next)
-    n += stdin_redirection (rp->instruction, rp->redirector.dest);
-  return n;
-}
diff --git a/shell.c~ b/shell.c~
deleted file mode 100644 (file)
index 9f6e997..0000000
--- a/shell.c~
+++ /dev/null
@@ -1,1844 +0,0 @@
-/* shell.c -- GNU's idea of the POSIX shell specification. */
-
-/* Copyright (C) 1987-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/>.
-*/
-
-/*
-  Birthdate:
-  Sunday, January 10th, 1988.
-  Initial author: Brian Fox
-*/
-#define INSTALL_DEBUG_MODE
-
-#include "config.h"
-
-#include "bashtypes.h"
-#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H)
-#  include <sys/file.h>
-#endif
-#include "posixstat.h"
-#include "posixtime.h"
-#include "bashansi.h"
-#include <stdio.h>
-#include <signal.h>
-#include <errno.h>
-#include "filecntl.h"
-#include <pwd.h>
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include "bashintl.h"
-
-#define NEED_SH_SETLINEBUF_DECL                /* used in externs.h */
-
-#include "shell.h"
-#include "flags.h"
-#include "trap.h"
-#include "mailcheck.h"
-#include "builtins.h"
-#include "builtins/common.h"
-
-#if defined (JOB_CONTROL)
-#include "jobs.h"
-#endif /* JOB_CONTROL */
-
-#include "input.h"
-#include "execute_cmd.h"
-#include "findcmd.h"
-
-#if defined (USING_BASH_MALLOC) && defined (DEBUG) && !defined (DISABLE_MALLOC_WRAPPERS)
-#  include <malloc/shmalloc.h>
-#endif
-
-#if defined (HISTORY)
-#  include "bashhist.h"
-#  include <readline/history.h>
-#endif
-
-#if defined (READLINE)
-#  include "bashline.h"
-#endif
-
-#include <tilde/tilde.h>
-#include <glob/strmatch.h>
-
-#if defined (__OPENNT)
-#  include <opennt/opennt.h>
-#endif
-
-#if !defined (HAVE_GETPW_DECLS)
-extern struct passwd *getpwuid ();
-#endif /* !HAVE_GETPW_DECLS */
-
-#if !defined (errno)
-extern int errno;
-#endif
-
-#if defined (NO_MAIN_ENV_ARG)
-extern char **environ; /* used if no third argument to main() */
-#endif
-
-extern char *dist_version, *release_status;
-extern int patch_level, build_version;
-extern int shell_level;
-extern int subshell_environment;
-extern int last_command_exit_value;
-extern int line_number;
-extern int expand_aliases;
-extern int array_needs_making;
-extern int gnu_error_format;
-extern char *primary_prompt, *secondary_prompt;
-extern char *this_command_name;
-
-/* Non-zero means that this shell has already been run; i.e. you should
-   call shell_reinitialize () if you need to start afresh. */
-int shell_initialized = 0;
-
-COMMAND *global_command = (COMMAND *)NULL;
-
-/* Information about the current user. */
-struct user_info current_user =
-{
-  (uid_t)-1, (uid_t)-1, (gid_t)-1, (gid_t)-1,
-  (char *)NULL, (char *)NULL, (char *)NULL
-};
-
-/* The current host's name. */
-char *current_host_name = (char *)NULL;
-
-/* Non-zero means that this shell is a login shell.
-   Specifically:
-   0 = not login shell.
-   1 = login shell from getty (or equivalent fake out)
-  -1 = login shell from "--login" (or -l) flag.
-  -2 = both from getty, and from flag.
- */
-int login_shell = 0;
-
-/* Non-zero means that at this moment, the shell is interactive.  In
-   general, this means that the shell is at this moment reading input
-   from the keyboard. */
-int interactive = 0;
-
-/* Non-zero means that the shell was started as an interactive shell. */
-int interactive_shell = 0;
-
-/* Non-zero means to send a SIGHUP to all jobs when an interactive login
-   shell exits. */
-int hup_on_exit = 0;
-
-/* Non-zero means to list status of running and stopped jobs at shell exit */
-int check_jobs_at_exit = 0;
-
-/* Non-zero means to change to a directory name supplied as a command name */
-int autocd = 0;
-
-/* Tells what state the shell was in when it started:
-       0 = non-interactive shell script
-       1 = interactive
-       2 = -c command
-       3 = wordexp evaluation
-   This is a superset of the information provided by interactive_shell.
-*/
-int startup_state = 0;
-
-/* Special debugging helper. */
-int debugging_login_shell = 0;
-
-/* The environment that the shell passes to other commands. */
-char **shell_environment;
-
-/* Non-zero when we are executing a top-level command. */
-int executing = 0;
-
-/* The number of commands executed so far. */
-int current_command_number = 1;
-
-/* Non-zero is the recursion depth for commands. */
-int indirection_level = 0;
-
-/* The name of this shell, as taken from argv[0]. */
-char *shell_name = (char *)NULL;
-
-/* time in seconds when the shell was started */
-time_t shell_start_time;
-
-/* Are we running in an emacs shell window? */
-int running_under_emacs;
-
-/* Do we have /dev/fd? */
-#ifdef HAVE_DEV_FD
-int have_devfd = HAVE_DEV_FD;
-#else
-int have_devfd = 0;
-#endif
-
-/* The name of the .(shell)rc file. */
-static char *bashrc_file = "~/.bashrc";
-
-/* Non-zero means to act more like the Bourne shell on startup. */
-static int act_like_sh;
-
-/* Non-zero if this shell is being run by `su'. */
-static int su_shell;
-
-/* Non-zero if we have already expanded and sourced $ENV. */
-static int sourced_env;
-
-/* Is this shell running setuid? */
-static int running_setuid;
-
-/* Values for the long-winded argument names. */
-static int debugging;                  /* Do debugging things. */
-static int no_rc;                      /* Don't execute ~/.bashrc */
-static int no_profile;                 /* Don't execute .profile */
-static int do_version;                 /* Display interesting version info. */
-static int make_login_shell;           /* Make this shell be a `-bash' shell. */
-static int want_initial_help;          /* --help option */
-
-int debugging_mode = 0;                /* In debugging mode with --debugger */
-int no_line_editing = 0;       /* Don't do fancy line editing. */
-int dump_translatable_strings; /* Dump strings in $"...", don't execute. */
-int dump_po_strings;           /* Dump strings in $"..." in po format */
-int wordexp_only = 0;          /* Do word expansion only */
-int protected_mode = 0;                /* No command substitution with --wordexp */
-
-#if defined (STRICT_POSIX)
-int posixly_correct = 1;       /* Non-zero means posix.2 superset. */
-#else
-int posixly_correct = 0;       /* Non-zero means posix.2 superset. */
-#endif
-
-
-/* Some long-winded argument names.  These are obviously new. */
-#define Int 1
-#define Charp 2
-static const struct {
-  const char *name;
-  int type;
-  int *int_value;
-  char **char_value;
-} long_args[] = {
-  { "debug", Int, &debugging, (char **)0x0 },
-#if defined (DEBUGGER)
-  { "debugger", Int, &debugging_mode, (char **)0x0 },
-#endif
-  { "dump-po-strings", Int, &dump_po_strings, (char **)0x0 },
-  { "dump-strings", Int, &dump_translatable_strings, (char **)0x0 },
-  { "help", Int, &want_initial_help, (char **)0x0 },
-  { "init-file", Charp, (int *)0x0, &bashrc_file },
-  { "login", Int, &make_login_shell, (char **)0x0 },
-  { "noediting", Int, &no_line_editing, (char **)0x0 },
-  { "noprofile", Int, &no_profile, (char **)0x0 },
-  { "norc", Int, &no_rc, (char **)0x0 },
-  { "posix", Int, &posixly_correct, (char **)0x0 },
-  { "protected", Int, &protected_mode, (char **)0x0 },
-  { "rcfile", Charp, (int *)0x0, &bashrc_file },
-#if defined (RESTRICTED_SHELL)
-  { "restricted", Int, &restricted, (char **)0x0 },
-#endif
-  { "verbose", Int, &echo_input_at_read, (char **)0x0 },
-  { "version", Int, &do_version, (char **)0x0 },
-  { "wordexp", Int, &wordexp_only, (char **)0x0 },
-  { (char *)0x0, Int, (int *)0x0, (char **)0x0 }
-};
-
-/* These are extern so execute_simple_command can set them, and then
-   longjmp back to main to execute a shell script, instead of calling
-   main () again and resulting in indefinite, possibly fatal, stack
-   growth. */
-procenv_t subshell_top_level;
-int subshell_argc;
-char **subshell_argv;
-char **subshell_envp;
-
-#if defined (BUFFERED_INPUT)
-/* The file descriptor from which the shell is reading input. */
-int default_buffered_input = -1;
-#endif
-
-/* The following two variables are not static so they can show up in $-. */
-int read_from_stdin;           /* -s flag supplied */
-int want_pending_command;      /* -c flag supplied */
-
-/* This variable is not static so it can be bound to $BASH_EXECUTION_STRING */
-char *command_execution_string;        /* argument to -c option */
-
-int malloc_trace_at_exit = 0;
-
-static int shell_reinitialized = 0;
-
-static FILE *default_input;
-
-static STRING_INT_ALIST *shopt_alist;
-static int shopt_ind = 0, shopt_len = 0;
-
-static int parse_long_options __P((char **, int, int));
-static int parse_shell_options __P((char **, int, int));
-static int bind_args __P((char **, int, int, int));
-
-static void start_debugger __P((void));
-
-static void add_shopt_to_alist __P((char *, int));
-static void run_shopt_alist __P((void));
-
-static void execute_env_file __P((char *));
-static void run_startup_files __P((void));
-static int open_shell_script __P((char *));
-static void set_bash_input __P((void));
-static int run_one_command __P((char *));
-static int run_wordexp __P((char *));
-
-static int uidget __P((void));
-
-static void init_interactive __P((void));
-static void init_noninteractive __P((void));
-static void init_interactive_script __P((void));
-
-static void set_shell_name __P((char *));
-static void shell_initialize __P((void));
-static void shell_reinitialize __P((void));
-
-static void show_shell_usage __P((FILE *, int));
-
-#ifdef __CYGWIN__
-static void
-_cygwin32_check_tmp ()
-{
-  struct stat sb;
-
-  if (stat ("/tmp", &sb) < 0)
-    internal_warning (_("could not find /tmp, please create!"));
-  else
-    {
-      if (S_ISDIR (sb.st_mode) == 0)
-       internal_warning (_("/tmp must be a valid directory name"));
-    }
-}
-#endif /* __CYGWIN__ */
-
-#if defined (NO_MAIN_ENV_ARG)
-/* systems without third argument to main() */
-int
-main (argc, argv)
-     int argc;
-     char **argv;
-#else /* !NO_MAIN_ENV_ARG */
-int
-main (argc, argv, env)
-     int argc;
-     char **argv, **env;
-#endif /* !NO_MAIN_ENV_ARG */
-{
-  register int i;
-  int code, old_errexit_flag;
-#if defined (RESTRICTED_SHELL)
-  int saverst;
-#endif
-  volatile int locally_skip_execution;
-  volatile int arg_index, top_level_arg_index;
-#ifdef __OPENNT
-  char **env;
-
-  env = environ;
-#endif /* __OPENNT */
-
-  USE_VAR(argc);
-  USE_VAR(argv);
-  USE_VAR(env);
-  USE_VAR(code);
-  USE_VAR(old_errexit_flag);
-#if defined (RESTRICTED_SHELL)
-  USE_VAR(saverst);
-#endif
-
-  /* Catch early SIGINTs. */
-  code = setjmp (top_level);
-  if (code)
-    exit (2);
-
-#if defined (USING_BASH_MALLOC) && defined (DEBUG) && !defined (DISABLE_MALLOC_WRAPPERS)
-#  if 1
-  malloc_set_register (1);
-#  endif
-#endif
-
-  check_dev_tty ();
-
-#ifdef __CYGWIN__
-  _cygwin32_check_tmp ();
-#endif /* __CYGWIN__ */
-
-  /* Wait forever if we are debugging a login shell. */
-  while (debugging_login_shell) sleep (3);
-
-  set_default_locale ();
-
-  running_setuid = uidget ();
-
-  if (getenv ("POSIXLY_CORRECT") || getenv ("POSIX_PEDANTIC"))
-    posixly_correct = 1;
-
-#if defined (USE_GNU_MALLOC_LIBRARY)
-  mcheck (programming_error, (void (*) ())0);
-#endif /* USE_GNU_MALLOC_LIBRARY */
-
-  if (setjmp (subshell_top_level))
-    {
-      argc = subshell_argc;
-      argv = subshell_argv;
-      env = subshell_envp;
-      sourced_env = 0;
-    }
-
-  shell_reinitialized = 0;
-
-  /* Initialize `local' variables for all `invocations' of main (). */
-  arg_index = 1;
-  if (arg_index > argc)
-    arg_index = argc;
-  command_execution_string = (char *)NULL;
-  want_pending_command = locally_skip_execution = read_from_stdin = 0;
-  default_input = stdin;
-#if defined (BUFFERED_INPUT)
-  default_buffered_input = -1;
-#endif
-
-  /* Fix for the `infinite process creation' bug when running shell scripts
-     from startup files on System V. */
-  login_shell = make_login_shell = 0;
-
-  /* If this shell has already been run, then reinitialize it to a
-     vanilla state. */
-  if (shell_initialized || shell_name)
-    {
-      /* Make sure that we do not infinitely recurse as a login shell. */
-      if (*shell_name == '-')
-       shell_name++;
-
-      shell_reinitialize ();
-      if (setjmp (top_level))
-       exit (2);
-    }
-
-  shell_environment = env;
-  set_shell_name (argv[0]);
-  shell_start_time = NOW;      /* NOW now defined in general.h */
-
-  /* Parse argument flags from the input line. */
-
-  /* Find full word arguments first. */
-  arg_index = parse_long_options (argv, arg_index, argc);
-
-  if (want_initial_help)
-    {
-      show_shell_usage (stdout, 1);
-      exit (EXECUTION_SUCCESS);
-    }
-
-  if (do_version)
-    {
-      show_shell_version (1);
-      exit (EXECUTION_SUCCESS);
-    }
-
-  /* All done with full word options; do standard shell option parsing.*/
-  this_command_name = shell_name;      /* for error reporting */
-  arg_index = parse_shell_options (argv, arg_index, argc);
-
-  /* If user supplied the "--login" (or -l) flag, then set and invert
-     LOGIN_SHELL. */
-  if (make_login_shell)
-    {
-      login_shell++;
-      login_shell = -login_shell;
-    }
-
-  set_login_shell (login_shell != 0);
-
-  if (dump_po_strings)
-    dump_translatable_strings = 1;
-
-  if (dump_translatable_strings)
-    read_but_dont_execute = 1;
-
-  if (running_setuid && privileged_mode == 0)
-    disable_priv_mode ();
-
-  /* Need to get the argument to a -c option processed in the
-     above loop.  The next arg is a command to execute, and the
-     following args are $0...$n respectively. */
-  if (want_pending_command)
-    {
-      command_execution_string = argv[arg_index];
-      if (command_execution_string == 0)
-       {
-         report_error (_("%s: option requires an argument"), "-c");
-         exit (EX_BADUSAGE);
-       }
-      arg_index++;
-    }
-  this_command_name = (char *)NULL;
-
-  cmd_init();          /* initialize the command object caches */
-
-  /* First, let the outside world know about our interactive status.
-     A shell is interactive if the `-i' flag was given, or if all of
-     the following conditions are met:
-       no -c command
-       no arguments remaining or the -s flag given
-       standard input is a terminal
-       standard error is a terminal
-     Refer to Posix.2, the description of the `sh' utility. */
-
-  if (forced_interactive ||            /* -i flag */
-      (!command_execution_string &&    /* No -c command and ... */
-       wordexp_only == 0 &&            /* No --wordexp and ... */
-       ((arg_index == argc) ||         /*   no remaining args or... */
-       read_from_stdin) &&             /*   -s flag with args, and */
-       isatty (fileno (stdin)) &&      /* Input is a terminal and */
-       isatty (fileno (stderr))))      /* error output is a terminal. */
-    init_interactive ();
-  else
-    init_noninteractive ();
-
-#define CLOSE_FDS_AT_LOGIN
-#if defined (CLOSE_FDS_AT_LOGIN)
-  /*
-   * Some systems have the bad habit of starting login shells with lots of open
-   * file descriptors.  For instance, most systems that have picked up the
-   * pre-4.0 Sun YP code leave a file descriptor open each time you call one
-   * of the getpw* functions, and it's set to be open across execs.  That
-   * means one for login, one for xterm, one for shelltool, etc.
-   */
-  if (login_shell && interactive_shell)
-    {
-      for (i = 3; i < 20; i++)
-       close (i);
-    }
-#endif /* CLOSE_FDS_AT_LOGIN */
-
-  /* If we're in a strict Posix.2 mode, turn on interactive comments,
-     alias expansion in non-interactive shells, and other Posix.2 things. */
-  if (posixly_correct)
-    {
-      bind_variable ("POSIXLY_CORRECT", "y", 0);
-      sv_strict_posix ("POSIXLY_CORRECT");
-    }
-
-  /* Now we run the shopt_alist and process the options. */
-  if (shopt_alist)
-    run_shopt_alist ();
-
-  /* From here on in, the shell must be a normal functioning shell.
-     Variables from the environment are expected to be set, etc. */
-  shell_initialize ();
-
-  set_default_lang ();
-  set_default_locale_vars ();
-
-  /*
-   * M-x term -> TERM=eterm EMACS=22.1 (term:0.96)     (eterm)
-   * M-x shell -> TERM=dumb EMACS=t                    (no line editing)
-   * M-x terminal -> TERM=emacs-em7955 EMACS=          (line editing)
-   */
-  if (interactive_shell)
-    {
-      char *term, *emacs;
-
-      term = get_string_value ("TERM");
-      emacs = get_string_value ("EMACS");
-
-      /* Not sure any emacs terminal emulator sets TERM=emacs any more */
-      no_line_editing |= term && (STREQ (term, "emacs"));
-      no_line_editing |= emacs && emacs[0] == 't' && emacs[1] == '\0' && STREQ (term, "dumb");
-
-      /* running_under_emacs == 2 for `eterm' */
-      running_under_emacs = (emacs != 0) || (term && STREQN (term, "emacs", 5));
-      running_under_emacs += term && STREQN (term, "eterm", 5) && strstr (emacs, "term");
-
-      if (running_under_emacs)
-       gnu_error_format = 1;
-    }
-
-  top_level_arg_index = arg_index;
-  old_errexit_flag = exit_immediately_on_error;
-
-  /* Give this shell a place to longjmp to before executing the
-     startup files.  This allows users to press C-c to abort the
-     lengthy startup. */
-  code = setjmp (top_level);
-  if (code)
-    {
-      if (code == EXITPROG || code == ERREXIT)
-       exit_shell (last_command_exit_value);
-      else
-       {
-#if defined (JOB_CONTROL)
-         /* Reset job control, since run_startup_files turned it off. */
-         set_job_control (interactive_shell);
-#endif
-         /* Reset value of `set -e', since it's turned off before running
-            the startup files. */
-         exit_immediately_on_error += old_errexit_flag;
-         locally_skip_execution++;
-       }
-    }
-
-  arg_index = top_level_arg_index;
-
-  /* Execute the start-up scripts. */
-
-  if (interactive_shell == 0)
-    {
-      unbind_variable ("PS1");
-      unbind_variable ("PS2");
-      interactive = 0;
-#if 0
-      /* This has already been done by init_noninteractive */
-      expand_aliases = posixly_correct;
-#endif
-    }
-  else
-    {
-      change_flag ('i', FLAG_ON);
-      interactive = 1;
-    }
-
-#if defined (RESTRICTED_SHELL)
-  /* Set restricted_shell based on whether the basename of $0 indicates that
-     the shell should be restricted or if the `-r' option was supplied at
-     startup. */
-  restricted_shell = shell_is_restricted (shell_name);
-
-  /* If the `-r' option is supplied at invocation, make sure that the shell
-     is not in restricted mode when running the startup files. */
-  saverst = restricted;
-  restricted = 0;
-#endif
-
-  /* The startup files are run with `set -e' temporarily disabled. */
-  if (locally_skip_execution == 0 && running_setuid == 0)
-    {
-      old_errexit_flag = exit_immediately_on_error;
-      exit_immediately_on_error = 0;
-
-      run_startup_files ();
-      exit_immediately_on_error += old_errexit_flag;
-    }
-
-  /* If we are invoked as `sh', turn on Posix mode. */
-  if (act_like_sh)
-    {
-      bind_variable ("POSIXLY_CORRECT", "y", 0);
-      sv_strict_posix ("POSIXLY_CORRECT");
-    }
-
-#if defined (RESTRICTED_SHELL)
-  /* Turn on the restrictions after executing the startup files.  This
-     means that `bash -r' or `set -r' invoked from a startup file will
-     turn on the restrictions after the startup files are executed. */
-  restricted = saverst || restricted;
-  if (shell_reinitialized == 0)
-    maybe_make_restricted (shell_name);
-#endif /* RESTRICTED_SHELL */
-
-  if (wordexp_only)
-    {
-      startup_state = 3;
-      last_command_exit_value = run_wordexp (argv[arg_index]);
-      exit_shell (last_command_exit_value);
-    }
-
-  if (command_execution_string)
-    {
-      arg_index = bind_args (argv, arg_index, argc, 0);
-      startup_state = 2;
-
-      if (debugging_mode)
-       start_debugger ();
-
-#if defined (ONESHOT)
-      executing = 1;
-      run_one_command (command_execution_string);
-      exit_shell (last_command_exit_value);
-#else /* ONESHOT */
-      with_input_from_string (command_execution_string, "-c");
-      goto read_and_execute;
-#endif /* !ONESHOT */
-    }
-
-  /* Get possible input filename and set up default_buffered_input or
-     default_input as appropriate. */
-  if (arg_index != argc && read_from_stdin == 0)
-    {
-      open_shell_script (argv[arg_index]);
-      arg_index++;
-    }
-  else if (interactive == 0)
-    /* In this mode, bash is reading a script from stdin, which is a
-       pipe or redirected file. */
-#if defined (BUFFERED_INPUT)
-    default_buffered_input = fileno (stdin);   /* == 0 */
-#else
-    setbuf (default_input, (char *)NULL);
-#endif /* !BUFFERED_INPUT */
-
-  set_bash_input ();
-
-  /* Bind remaining args to $1 ... $n */
-  arg_index = bind_args (argv, arg_index, argc, 1);
-
-  if (debugging_mode && locally_skip_execution == 0 && running_setuid == 0)
-    start_debugger ();
-
-  /* Do the things that should be done only for interactive shells. */
-  if (interactive_shell)
-    {
-      /* Set up for checking for presence of mail. */
-      reset_mail_timer ();
-      init_mail_dates ();
-
-#if defined (HISTORY)
-      /* Initialize the interactive history stuff. */
-      bash_initialize_history ();
-      /* Don't load the history from the history file if we've already
-        saved some lines in this session (e.g., by putting `history -s xx'
-        into one of the startup files). */
-      if (shell_initialized == 0 && history_lines_this_session == 0)
-       load_history ();
-#endif /* HISTORY */
-
-      /* Initialize terminal state for interactive shells after the
-        .bash_profile and .bashrc are interpreted. */
-      get_tty_state ();
-    }
-
-#if !defined (ONESHOT)
- read_and_execute:
-#endif /* !ONESHOT */
-
-  shell_initialized = 1;
-
-  /* Read commands until exit condition. */
-  reader_loop ();
-  exit_shell (last_command_exit_value);
-}
-
-static int
-parse_long_options (argv, arg_start, arg_end)
-     char **argv;
-     int arg_start, arg_end;
-{
-  int arg_index, longarg, i;
-  char *arg_string;
-
-  arg_index = arg_start;
-  while ((arg_index != arg_end) && (arg_string = argv[arg_index]) &&
-        (*arg_string == '-'))
-    {
-      longarg = 0;
-
-      /* Make --login equivalent to -login. */
-      if (arg_string[1] == '-' && arg_string[2])
-       {
-         longarg = 1;
-         arg_string++;
-       }
-
-      for (i = 0; long_args[i].name; i++)
-       {
-         if (STREQ (arg_string + 1, long_args[i].name))
-           {
-             if (long_args[i].type == Int)
-               *long_args[i].int_value = 1;
-             else if (argv[++arg_index] == 0)
-               {
-                 report_error (_("%s: option requires an argument"), long_args[i].name);
-                 exit (EX_BADUSAGE);
-               }
-             else
-               *long_args[i].char_value = argv[arg_index];
-
-             break;
-           }
-       }
-      if (long_args[i].name == 0)
-       {
-         if (longarg)
-           {
-             report_error (_("%s: invalid option"), argv[arg_index]);
-             show_shell_usage (stderr, 0);
-             exit (EX_BADUSAGE);
-           }
-         break;                /* No such argument.  Maybe flag arg. */
-       }
-
-      arg_index++;
-    }
-
-  return (arg_index);
-}
-
-static int
-parse_shell_options (argv, arg_start, arg_end)
-     char **argv;
-     int arg_start, arg_end;
-{
-  int arg_index;
-  int arg_character, on_or_off, next_arg, i;
-  char *o_option, *arg_string;
-
-  arg_index = arg_start;
-  while (arg_index != arg_end && (arg_string = argv[arg_index]) &&
-        (*arg_string == '-' || *arg_string == '+'))
-    {
-      /* There are flag arguments, so parse them. */
-      next_arg = arg_index + 1;
-
-      /* A single `-' signals the end of options.  From the 4.3 BSD sh.
-        An option `--' means the same thing; this is the standard
-        getopt(3) meaning. */
-      if (arg_string[0] == '-' &&
-          (arg_string[1] == '\0' ||
-            (arg_string[1] == '-' && arg_string[2] == '\0')))
-       return (next_arg);
-
-      i = 1;
-      on_or_off = arg_string[0];
-      while (arg_character = arg_string[i++])
-       {
-         switch (arg_character)
-           {
-           case 'c':
-             want_pending_command = 1;
-             break;
-
-           case 'l':
-             make_login_shell = 1;
-             break;
-
-           case 's':
-             read_from_stdin = 1;
-             break;
-
-           case 'o':
-             o_option = argv[next_arg];
-             if (o_option == 0)
-               {
-                 list_minus_o_opts (-1, (on_or_off == '-') ? 0 : 1);
-                 break;
-               }
-             if (set_minus_o_option (on_or_off, o_option) != EXECUTION_SUCCESS)
-               exit (EX_BADUSAGE);
-             next_arg++;
-             break;
-
-           case 'O':
-             /* Since some of these can be overridden by the normal
-                interactive/non-interactive shell initialization or
-                initializing posix mode, we save the options and process
-                them after initialization. */
-             o_option = argv[next_arg];
-             if (o_option == 0)
-               {
-                 shopt_listopt (o_option, (on_or_off == '-') ? 0 : 1);
-                 break;
-               }
-             add_shopt_to_alist (o_option, on_or_off);
-             next_arg++;
-             break;
-
-           case 'D':
-             dump_translatable_strings = 1;
-             break;
-
-           default:
-             if (change_flag (arg_character, on_or_off) == FLAG_ERROR)
-               {
-                 report_error (_("%c%c: invalid option"), on_or_off, arg_character);
-                 show_shell_usage (stderr, 0);
-                 exit (EX_BADUSAGE);
-               }
-           }
-       }
-      /* Can't do just a simple increment anymore -- what about
-        "bash -abouo emacs ignoreeof -hP"? */
-      arg_index = next_arg;
-    }
-
-  return (arg_index);
-}
-
-/* Exit the shell with status S. */
-void
-exit_shell (s)
-     int s;
-{
-  fflush (stdout);             /* XXX */
-  fflush (stderr);
-
-  /* Do trap[0] if defined.  Allow it to override the exit status
-     passed to us. */
-  if (signal_is_trapped (0))
-    s = run_exit_trap ();
-
-#if defined (PROCESS_SUBSTITUTION)
-  unlink_fifo_list ();
-#endif /* PROCESS_SUBSTITUTION */
-
-#if defined (HISTORY)
-  if (interactive_shell)
-    maybe_save_shell_history ();
-#endif /* HISTORY */
-
-#if defined (COPROCESS_SUPPORT)
-  coproc_flush ();
-#endif
-
-#if defined (JOB_CONTROL)
-  /* If the user has run `shopt -s huponexit', hangup all jobs when we exit
-     an interactive login shell.  ksh does this unconditionally. */
-  if (interactive_shell && login_shell && hup_on_exit)
-    hangup_all_jobs ();
-
-  /* If this shell is interactive, terminate all stopped jobs and
-     restore the original terminal process group.  Don't do this if we're
-     in a subshell and calling exit_shell after, for example, a failed
-     word expansion. */
-  if (subshell_environment == 0)
-    end_job_control ();
-#endif /* JOB_CONTROL */
-
-  /* Always return the exit status of the last command to our parent. */
-  sh_exit (s);
-}
-
-/* A wrapper for exit that (optionally) can do other things, like malloc
-   statistics tracing. */
-void
-sh_exit (s)
-     int s;
-{
-#if defined (MALLOC_DEBUG) && defined (USING_BASH_MALLOC)
-  if (malloc_trace_at_exit)
-    trace_malloc_stats (get_name_for_error (), (char *)NULL);
-#endif
-
-  exit (s);
-}
-
-/* Source the bash startup files.  If POSIXLY_CORRECT is non-zero, we obey
-   the Posix.2 startup file rules:  $ENV is expanded, and if the file it
-   names exists, that file is sourced.  The Posix.2 rules are in effect
-   for interactive shells only. (section 4.56.5.3) */
-
-/* Execute ~/.bashrc for most shells.  Never execute it if
-   ACT_LIKE_SH is set, or if NO_RC is set.
-
-   If the executable file "/usr/gnu/src/bash/foo" contains:
-
-   #!/usr/gnu/bin/bash
-   echo hello
-
-   then:
-
-        COMMAND            EXECUTE BASHRC
-        --------------------------------
-        bash -c foo            NO
-        bash foo               NO
-        foo                    NO
-        rsh machine ls         YES (for rsh, which calls `bash -c')
-        rsh machine foo        YES (for shell started by rsh) NO (for foo!)
-        echo ls | bash         NO
-        login                  NO
-        bash                   YES
-*/
-
-static void
-execute_env_file (env_file)
-      char *env_file;
-{
-  char *fn;
-
-  if (env_file && *env_file)
-    {
-      fn = expand_string_unsplit_to_string (env_file, Q_DOUBLE_QUOTES);
-      if (fn && *fn)
-       maybe_execute_file (fn, 1);
-      FREE (fn);
-    }
-}
-
-static void
-run_startup_files ()
-{
-#if defined (JOB_CONTROL)
-  int old_job_control;
-#endif
-  int sourced_login, run_by_ssh;
-
-  /* get the rshd/sshd case out of the way first. */
-  if (interactive_shell == 0 && no_rc == 0 && login_shell == 0 &&
-      act_like_sh == 0 && command_execution_string)
-    {
-#ifdef SSH_SOURCE_BASHRC
-      run_by_ssh = (find_variable ("SSH_CLIENT") != (SHELL_VAR *)0) ||
-                  (find_variable ("SSH2_CLIENT") != (SHELL_VAR *)0);
-#else
-      run_by_ssh = 0;
-#endif
-
-      /* If we were run by sshd or we think we were run by rshd, execute
-        ~/.bashrc if we are a top-level shell. */
-      if ((run_by_ssh || isnetconn (fileno (stdin))) && shell_level < 2)
-       {
-#ifdef SYS_BASHRC
-#  if defined (__OPENNT)
-         maybe_execute_file (_prefixInstallPath(SYS_BASHRC, NULL, 0), 1);
-#  else
-         maybe_execute_file (SYS_BASHRC, 1);
-#  endif
-#endif
-         maybe_execute_file (bashrc_file, 1);
-         return;
-       }
-    }
-
-#if defined (JOB_CONTROL)
-  /* Startup files should be run without job control enabled. */
-  old_job_control = interactive_shell ? set_job_control (0) : 0;
-#endif
-
-  sourced_login = 0;
-
-  /* A shell begun with the --login (or -l) flag that is not in posix mode
-     runs the login shell startup files, no matter whether or not it is
-     interactive.  If NON_INTERACTIVE_LOGIN_SHELLS is defined, run the
-     startup files if argv[0][0] == '-' as well. */
-#if defined (NON_INTERACTIVE_LOGIN_SHELLS)
-  if (login_shell && posixly_correct == 0)
-#else
-  if (login_shell < 0 && posixly_correct == 0)
-#endif
-    {
-      /* We don't execute .bashrc for login shells. */
-      no_rc++;
-
-      /* Execute /etc/profile and one of the personal login shell
-        initialization files. */
-      if (no_profile == 0)
-       {
-         maybe_execute_file (SYS_PROFILE, 1);
-
-         if (act_like_sh)      /* sh */
-           maybe_execute_file ("~/.profile", 1);
-         else if ((maybe_execute_file ("~/.bash_profile", 1) == 0) &&
-                  (maybe_execute_file ("~/.bash_login", 1) == 0))      /* bash */
-           maybe_execute_file ("~/.profile", 1);
-       }
-
-      sourced_login = 1;
-    }
-
-  /* A non-interactive shell not named `sh' and not in posix mode reads and
-     executes commands from $BASH_ENV.  If `su' starts a shell with `-c cmd'
-     and `-su' as the name of the shell, we want to read the startup files.
-     No other non-interactive shells read any startup files. */
-  if (interactive_shell == 0 && !(su_shell && login_shell))
-    {
-      if (posixly_correct == 0 && act_like_sh == 0 && privileged_mode == 0 &&
-           sourced_env++ == 0)
-       execute_env_file (get_string_value ("BASH_ENV"));
-      return;
-    }
-
-  /* Interactive shell or `-su' shell. */
-  if (posixly_correct == 0)              /* bash, sh */
-    {
-      if (login_shell && sourced_login++ == 0)
-       {
-         /* We don't execute .bashrc for login shells. */
-         no_rc++;
-
-         /* Execute /etc/profile and one of the personal login shell
-            initialization files. */
-         if (no_profile == 0)
-           {
-             maybe_execute_file (SYS_PROFILE, 1);
-
-             if (act_like_sh)  /* sh */
-               maybe_execute_file ("~/.profile", 1);
-             else if ((maybe_execute_file ("~/.bash_profile", 1) == 0) &&
-                      (maybe_execute_file ("~/.bash_login", 1) == 0))  /* bash */
-               maybe_execute_file ("~/.profile", 1);
-           }
-       }
-
-      /* bash */
-      if (act_like_sh == 0 && no_rc == 0)
-       {
-#ifdef SYS_BASHRC
-#  if defined (__OPENNT)
-         maybe_execute_file (_prefixInstallPath(SYS_BASHRC, NULL, 0), 1);
-#  else
-         maybe_execute_file (SYS_BASHRC, 1);
-#  endif
-#endif
-         maybe_execute_file (bashrc_file, 1);
-       }
-      /* sh */
-      else if (act_like_sh && privileged_mode == 0 && sourced_env++ == 0)
-       execute_env_file (get_string_value ("ENV"));
-    }
-  else         /* bash --posix, sh --posix */
-    {
-      /* bash and sh */
-      if (interactive_shell && privileged_mode == 0 && sourced_env++ == 0)
-       execute_env_file (get_string_value ("ENV"));
-    }
-
-#if defined (JOB_CONTROL)
-  set_job_control (old_job_control);
-#endif
-}
-
-#if defined (RESTRICTED_SHELL)
-/* Return 1 if the shell should be a restricted one based on NAME or the
-   value of `restricted'.  Don't actually do anything, just return a
-   boolean value. */
-int
-shell_is_restricted (name)
-     char *name;
-{
-  char *temp;
-
-  if (restricted)
-    return 1;
-  temp = base_pathname (name);
-  if (*temp == '-')
-    temp++;
-  return (STREQ (temp, RESTRICTED_SHELL_NAME));
-}
-
-/* Perhaps make this shell a `restricted' one, based on NAME.  If the
-   basename of NAME is "rbash", then this shell is restricted.  The
-   name of the restricted shell is a configurable option, see config.h.
-   In a restricted shell, PATH, SHELL, ENV, and BASH_ENV are read-only
-   and non-unsettable.
-   Do this also if `restricted' is already set to 1; maybe the shell was
-   started with -r. */
-int
-maybe_make_restricted (name)
-     char *name;
-{
-  char *temp;
-
-  temp = base_pathname (name);
-  if (*temp == '-')
-    temp++;
-  if (restricted || (STREQ (temp, RESTRICTED_SHELL_NAME)))
-    {
-      set_var_read_only ("PATH");
-      set_var_read_only ("SHELL");
-      set_var_read_only ("ENV");
-      set_var_read_only ("BASH_ENV");
-      restricted = 1;
-    }
-  return (restricted);
-}
-#endif /* RESTRICTED_SHELL */
-
-/* Fetch the current set of uids and gids and return 1 if we're running
-   setuid or setgid. */
-static int
-uidget ()
-{
-  uid_t u;
-
-  u = getuid ();
-  if (current_user.uid != u)
-    {
-      FREE (current_user.user_name);
-      FREE (current_user.shell);
-      FREE (current_user.home_dir);
-      current_user.user_name = current_user.shell = current_user.home_dir = (char *)NULL;
-    }
-  current_user.uid = u;
-  current_user.gid = getgid ();
-  current_user.euid = geteuid ();
-  current_user.egid = getegid ();
-
-  /* See whether or not we are running setuid or setgid. */
-  return (current_user.uid != current_user.euid) ||
-          (current_user.gid != current_user.egid);
-}
-
-void
-disable_priv_mode ()
-{
-  setuid (current_user.uid);
-  setgid (current_user.gid);
-  current_user.euid = current_user.uid;
-  current_user.egid = current_user.gid;
-}
-
-static int
-run_wordexp (words)
-     char *words;
-{
-  int code, nw, nb;
-  WORD_LIST *wl, *tl, *result;
-
-  code = setjmp (top_level);
-
-  if (code != NOT_JUMPED)
-    {
-      switch (code)
-       {
-         /* Some kind of throw to top_level has occured. */
-       case FORCE_EOF:
-         return last_command_exit_value = 127;
-       case ERREXIT:
-       case EXITPROG:
-         return last_command_exit_value;
-       case DISCARD:
-         return last_command_exit_value = 1;
-       default:
-         command_error ("run_wordexp", CMDERR_BADJUMP, code, 0);
-       }
-    }
-
-  /* Run it through the parser to get a list of words and expand them */
-  if (words && *words)
-    {
-      with_input_from_string (words, "--wordexp");
-      if (parse_command () != 0)
-       return (126);
-      if (global_command == 0)
-       {
-         printf ("0\n0\n");
-         return (0);
-       }
-      if (global_command->type != cm_simple)
-       return (126);
-      wl = global_command->value.Simple->words;
-      if (protected_mode)
-       for (tl = wl; tl; tl = tl->next)
-         tl->word->flags |= W_NOCOMSUB|W_NOPROCSUB;
-      result = wl ? expand_words_no_vars (wl) : (WORD_LIST *)0;
-    }
-  else
-    result = (WORD_LIST *)0;
-
-  last_command_exit_value = 0;
-
-  if (result == 0)
-    {
-      printf ("0\n0\n");
-      return (0);
-    }
-
-  /* Count up the number of words and bytes, and print them.  Don't count
-     the trailing NUL byte. */
-  for (nw = nb = 0, wl = result; wl; wl = wl->next)
-    {
-      nw++;
-      nb += strlen (wl->word->word);
-    }
-  printf ("%u\n%u\n", nw, nb);
-  /* Print each word on a separate line.  This will have to be changed when
-     the interface to glibc is completed. */
-  for (wl = result; wl; wl = wl->next)
-    printf ("%s\n", wl->word->word);
-
-  return (0);
-}
-
-#if defined (ONESHOT)
-/* Run one command, given as the argument to the -c option.  Tell
-   parse_and_execute not to fork for a simple command. */
-static int
-run_one_command (command)
-     char *command;
-{
-  int code;
-
-  code = setjmp (top_level);
-
-  if (code != NOT_JUMPED)
-    {
-#if defined (PROCESS_SUBSTITUTION)
-      unlink_fifo_list ();
-#endif /* PROCESS_SUBSTITUTION */
-      switch (code)
-       {
-         /* Some kind of throw to top_level has occured. */
-       case FORCE_EOF:
-         return last_command_exit_value = 127;
-       case ERREXIT:
-       case EXITPROG:
-         return last_command_exit_value;
-       case DISCARD:
-         return last_command_exit_value = 1;
-       default:
-         command_error ("run_one_command", CMDERR_BADJUMP, code, 0);
-       }
-    }
-   return (parse_and_execute (savestring (command), "-c", SEVAL_NOHIST));
-}
-#endif /* ONESHOT */
-
-static int
-bind_args (argv, arg_start, arg_end, start_index)
-     char **argv;
-     int arg_start, arg_end, start_index;
-{
-  register int i;
-  WORD_LIST *args;
-
-  for (i = arg_start, args = (WORD_LIST *)NULL; i < arg_end; i++)
-    args = make_word_list (make_word (argv[i]), args);
-  if (args)
-    {
-      args = REVERSE_LIST (args, WORD_LIST *);
-      if (start_index == 0)    /* bind to $0...$n for sh -c command */
-       {
-         /* Posix.2 4.56.3 says that the first argument after sh -c command
-            becomes $0, and the rest of the arguments become $1...$n */
-         shell_name = savestring (args->word->word);
-         FREE (dollar_vars[0]);
-         dollar_vars[0] = savestring (args->word->word);
-         remember_args (args->next, 1);
-         push_args (args->next);       /* BASH_ARGV and BASH_ARGC */
-       }
-      else                     /* bind to $1...$n for shell script */
-        {
-         remember_args (args, 1);
-         push_args (args);             /* BASH_ARGV and BASH_ARGC */
-        }
-
-      dispose_words (args);
-    }
-
-  return (i);
-}
-
-void
-unbind_args ()
-{
-  remember_args ((WORD_LIST *)NULL, 1);
-  pop_args ();                         /* Reset BASH_ARGV and BASH_ARGC */
-}
-
-static void
-start_debugger ()
-{
-#if defined (DEBUGGER) && defined (DEBUGGER_START_FILE)
-  int old_errexit;
-
-  old_errexit = exit_immediately_on_error;
-  exit_immediately_on_error = 0;
-
-  maybe_execute_file (DEBUGGER_START_FILE, 1);
-  function_trace_mode = 1;
-
-  exit_immediately_on_error += old_errexit;
-#endif
-}
-
-static int
-open_shell_script (script_name)
-     char *script_name;
-{
-  int fd, e, fd_is_tty;
-  char *filename, *path_filename, *t;
-  char sample[80];
-  int sample_len;
-  struct stat sb;
-#if defined (ARRAY_VARS)
-  SHELL_VAR *funcname_v, *bash_source_v, *bash_lineno_v;
-  ARRAY *funcname_a, *bash_source_a, *bash_lineno_a;
-#endif
-
-  filename = savestring (script_name);
-
-  fd = open (filename, O_RDONLY);
-  if ((fd < 0) && (errno == ENOENT) && (absolute_program (filename) == 0))
-    {
-      e = errno;
-      /* If it's not in the current directory, try looking through PATH
-        for it. */
-      path_filename = find_path_file (script_name);
-      if (path_filename)
-       {
-         free (filename);
-         filename = path_filename;
-         fd = open (filename, O_RDONLY);
-       }
-      else
-       errno = e;
-    }
-
-  if (fd < 0)
-    {
-      e = errno;
-      file_error (filename);
-      exit ((e == ENOENT) ? EX_NOTFOUND : EX_NOINPUT);
-    }
-
-  free (dollar_vars[0]);
-  dollar_vars[0] = savestring (script_name);
-
-#if defined (ARRAY_VARS)
-  GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a);
-  GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
-  GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a);
-
-  array_push (bash_source_a, filename);
-  if (bash_lineno_a)
-    {
-      t = itos (executing_line_number ());
-      array_push (bash_lineno_a, t);
-      free (t);
-    }
-  array_push (funcname_a, "main");
-#endif
-
-#ifdef HAVE_DEV_FD
-  fd_is_tty = isatty (fd);
-#else
-  fd_is_tty = 0;
-#endif
-
-  /* Only do this with non-tty file descriptors we can seek on. */
-  if (fd_is_tty == 0 && (lseek (fd, 0L, 1) != -1))
-    {
-      /* Check to see if the `file' in `bash file' is a binary file
-        according to the same tests done by execute_simple_command (),
-        and report an error and exit if it is. */
-      sample_len = read (fd, sample, sizeof (sample));
-      if (sample_len < 0)
-       {
-         e = errno;
-         if ((fstat (fd, &sb) == 0) && S_ISDIR (sb.st_mode))
-           internal_error (_("%s: is a directory"), filename);
-         else
-           {
-             errno = e;
-             file_error (filename);
-           }
-         exit (EX_NOEXEC);
-       }
-      else if (sample_len > 0 && (check_binary_file (sample, sample_len)))
-       {
-         internal_error (_("%s: cannot execute binary file"), filename);
-         exit (EX_BINARY_FILE);
-       }
-      /* Now rewind the file back to the beginning. */
-      lseek (fd, 0L, 0);
-    }
-
-  /* Open the script.  But try to move the file descriptor to a randomly
-     large one, in the hopes that any descriptors used by the script will
-     not match with ours. */
-  fd = move_to_high_fd (fd, 1, -1);
-
-#if defined (__CYGWIN__) && defined (O_TEXT)
-  setmode (fd, O_TEXT);
-#endif
-
-#if defined (BUFFERED_INPUT)
-  default_buffered_input = fd;
-  SET_CLOSE_ON_EXEC (default_buffered_input);
-#else /* !BUFFERED_INPUT */
-  default_input = fdopen (fd, "r");
-
-  if (default_input == 0)
-    {
-      file_error (filename);
-      exit (EX_NOTFOUND);
-    }
-
-  SET_CLOSE_ON_EXEC (fd);
-  if (fileno (default_input) != fd)
-    SET_CLOSE_ON_EXEC (fileno (default_input));
-#endif /* !BUFFERED_INPUT */
-
-  /* Just about the only way for this code to be executed is if something
-     like `bash -i /dev/stdin' is executed. */
-  if (interactive_shell && fd_is_tty)
-    {
-      dup2 (fd, 0);
-      close (fd);
-      fd = 0;
-#if defined (BUFFERED_INPUT)
-      default_buffered_input = 0;
-#else
-      fclose (default_input);
-      default_input = stdin;
-#endif
-    }
-  else if (forced_interactive && fd_is_tty == 0)
-    /* But if a script is called with something like `bash -i scriptname',
-       we need to do a non-interactive setup here, since we didn't do it
-       before. */
-    init_interactive_script ();
-
-  free (filename);
-  return (fd);
-}
-
-/* Initialize the input routines for the parser. */
-static void
-set_bash_input ()
-{
-  /* Make sure the fd from which we are reading input is not in
-     no-delay mode. */
-#if defined (BUFFERED_INPUT)
-  if (interactive == 0)
-    sh_unset_nodelay_mode (default_buffered_input);
-  else
-#endif /* !BUFFERED_INPUT */
-    sh_unset_nodelay_mode (fileno (stdin));
-
-  /* with_input_from_stdin really means `with_input_from_readline' */
-  if (interactive && no_line_editing == 0)
-    with_input_from_stdin ();
-#if defined (BUFFERED_INPUT)
-  else if (interactive == 0)
-    with_input_from_buffered_stream (default_buffered_input, dollar_vars[0]);
-#endif /* BUFFERED_INPUT */
-  else
-    with_input_from_stream (default_input, dollar_vars[0]);
-}
-
-/* Close the current shell script input source and forget about it.  This is
-   extern so execute_cmd.c:initialize_subshell() can call it.  If CHECK_ZERO
-   is non-zero, we close default_buffered_input even if it's the standard
-   input (fd 0). */
-void
-unset_bash_input (check_zero)
-     int check_zero;
-{
-#if defined (BUFFERED_INPUT)
-  if ((check_zero && default_buffered_input >= 0) ||
-      (check_zero == 0 && default_buffered_input > 0))
-    {
-      close_buffered_fd (default_buffered_input);
-      default_buffered_input = bash_input.location.buffered_fd = -1;
-      bash_input.type = st_none;               /* XXX */
-    }
-#else /* !BUFFERED_INPUT */
-  if (default_input)
-    {
-      fclose (default_input);
-      default_input = (FILE *)NULL;
-    }
-#endif /* !BUFFERED_INPUT */
-}
-      
-
-#if !defined (PROGRAM)
-#  define PROGRAM "bash"
-#endif
-
-static void
-set_shell_name (argv0)
-     char *argv0;
-{
-  /* Here's a hack.  If the name of this shell is "sh", then don't do
-     any startup files; just try to be more like /bin/sh. */
-  shell_name = argv0 ? base_pathname (argv0) : PROGRAM;
-
-  if (argv0 && *argv0 == '-')
-    {
-      if (*shell_name == '-')
-       shell_name++;
-      login_shell++;
-    }
-
-  if (shell_name[0] == 's' && shell_name[1] == 'h' && shell_name[2] == '\0')
-    act_like_sh++;
-  if (shell_name[0] == 's' && shell_name[1] == 'u' && shell_name[2] == '\0')
-    su_shell++;
-
-  shell_name = argv0 ? argv0 : PROGRAM;
-  FREE (dollar_vars[0]);
-  dollar_vars[0] = savestring (shell_name);
-
-  /* A program may start an interactive shell with
-         "execl ("/bin/bash", "-", NULL)".
-     If so, default the name of this shell to our name. */
-  if (!shell_name || !*shell_name || (shell_name[0] == '-' && !shell_name[1]))
-    shell_name = PROGRAM;
-}
-
-static void
-init_interactive ()
-{
-  expand_aliases = interactive_shell = startup_state = 1;
-  interactive = 1;
-}
-
-static void
-init_noninteractive ()
-{
-#if defined (HISTORY)
-  bash_history_reinit (0);
-#endif /* HISTORY */
-  interactive_shell = startup_state = interactive = 0;
-  expand_aliases = posixly_correct;    /* XXX - was 0 not posixly_correct */
-  no_line_editing = 1;
-#if defined (JOB_CONTROL)
-  set_job_control (0);
-#endif /* JOB_CONTROL */
-}
-
-static void
-init_interactive_script ()
-{
-  init_noninteractive ();
-  expand_aliases = interactive_shell = startup_state = 1;
-}
-
-void
-get_current_user_info ()
-{
-  struct passwd *entry;
-
-  /* Don't fetch this more than once. */
-  if (current_user.user_name == 0)
-    {
-      entry = getpwuid (current_user.uid);
-      if (entry)
-       {
-         current_user.user_name = savestring (entry->pw_name);
-         current_user.shell = (entry->pw_shell && entry->pw_shell[0])
-                               ? savestring (entry->pw_shell)
-                               : savestring ("/bin/sh");
-         current_user.home_dir = savestring (entry->pw_dir);
-       }
-      else
-       {
-         current_user.user_name = _("I have no name!");
-         current_user.user_name = savestring (current_user.user_name);
-         current_user.shell = savestring ("/bin/sh");
-         current_user.home_dir = savestring ("/");
-       }
-      endpwent ();
-    }
-}
-
-/* Do whatever is necessary to initialize the shell.
-   Put new initializations in here. */
-static void
-shell_initialize ()
-{
-  char hostname[256];
-
-  /* Line buffer output for stderr and stdout. */
-  if (shell_initialized == 0)
-    {
-      sh_setlinebuf (stderr);
-      sh_setlinebuf (stdout);
-    }
-
-  /* Sort the array of shell builtins so that the binary search in
-     find_shell_builtin () works correctly. */
-  initialize_shell_builtins ();
-
-  /* Initialize the trap signal handlers before installing our own
-     signal handlers.  traps.c:restore_original_signals () is responsible
-     for restoring the original default signal handlers.  That function
-     is called when we make a new child. */
-  initialize_traps ();
-  initialize_signals (0);
-
-  /* It's highly unlikely that this will change. */
-  if (current_host_name == 0)
-    {
-      /* Initialize current_host_name. */
-      if (gethostname (hostname, 255) < 0)
-       current_host_name = "??host??";
-      else
-       current_host_name = savestring (hostname);
-    }
-
-  /* Initialize the stuff in current_user that comes from the password
-     file.  We don't need to do this right away if the shell is not
-     interactive. */
-  if (interactive_shell)
-    get_current_user_info ();
-
-  /* Initialize our interface to the tilde expander. */
-  tilde_initialize ();
-
-  /* Initialize internal and environment variables.  Don't import shell
-     functions from the environment if we are running in privileged or
-     restricted mode or if the shell is running setuid. */
-#if defined (RESTRICTED_SHELL)
-  initialize_shell_variables (shell_environment, privileged_mode||restricted||running_setuid);
-#else
-  initialize_shell_variables (shell_environment, privileged_mode||running_setuid);
-#endif
-
-  /* Initialize the data structures for storing and running jobs. */
-  initialize_job_control (0);
-
-  /* Initialize input streams to null. */
-  initialize_bash_input ();
-
-  initialize_flags ();
-
-  /* Initialize the shell options.  Don't import the shell options
-     from the environment variable $SHELLOPTS if we are running in
-     privileged or restricted mode or if the shell is running setuid. */
-#if defined (RESTRICTED_SHELL)
-  initialize_shell_options (privileged_mode||restricted||running_setuid);
-  initialize_bashopts (privileged_mode||restricted||running_setuid);
-#else
-  initialize_shell_options (privileged_mode||running_setuid);
-  initialize_bashopts (privileged_mode||running_setuid);
-#endif
-}
-
-/* Function called by main () when it appears that the shell has already
-   had some initialization performed.  This is supposed to reset the world
-   back to a pristine state, as if we had been exec'ed. */
-static void
-shell_reinitialize ()
-{
-  /* The default shell prompts. */
-  primary_prompt = PPROMPT;
-  secondary_prompt = SPROMPT;
-
-  /* Things that get 1. */
-  current_command_number = 1;
-
-  /* We have decided that the ~/.bashrc file should not be executed
-     for the invocation of each shell script.  If the variable $ENV
-     (or $BASH_ENV) is set, its value is used as the name of a file
-     to source. */
-  no_rc = no_profile = 1;
-
-  /* Things that get 0. */
-  login_shell = make_login_shell = interactive = executing = 0;
-  debugging = do_version = line_number = last_command_exit_value = 0;
-  forced_interactive = interactive_shell = subshell_environment = 0;
-  expand_aliases = 0;
-
-#if defined (HISTORY)
-  bash_history_reinit (0);
-#endif /* HISTORY */
-
-#if defined (RESTRICTED_SHELL)
-  restricted = 0;
-#endif /* RESTRICTED_SHELL */
-
-  /* Ensure that the default startup file is used.  (Except that we don't
-     execute this file for reinitialized shells). */
-  bashrc_file = "~/.bashrc";
-
-  /* Delete all variables and functions.  They will be reinitialized when
-     the environment is parsed. */
-  delete_all_contexts (shell_variables);
-  delete_all_variables (shell_functions);
-
-  reinit_special_variables ();
-
-#if defined (READLINE)
-  bashline_reinitialize ();
-#endif
-
-  shell_reinitialized = 1;
-}
-
-static void
-show_shell_usage (fp, extra)
-     FILE *fp;
-     int extra;
-{
-  int i;
-  char *set_opts, *s, *t;
-
-  if (extra)
-    fprintf (fp, _("GNU bash, version %s-(%s)\n"), shell_version_string (), MACHTYPE);
-  fprintf (fp, _("Usage:\t%s [GNU long option] [option] ...\n\t%s [GNU long option] [option] script-file ...\n"),
-            shell_name, shell_name);
-  fputs (_("GNU long options:\n"), fp);
-  for (i = 0; long_args[i].name; i++)
-    fprintf (fp, "\t--%s\n", long_args[i].name);
-
-  fputs (_("Shell options:\n"), fp);
-  fputs (_("\t-irsD or -c command or -O shopt_option\t\t(invocation only)\n"), fp);
-
-  for (i = 0, set_opts = 0; shell_builtins[i].name; i++)
-    if (STREQ (shell_builtins[i].name, "set"))
-      set_opts = savestring (shell_builtins[i].short_doc);
-  if (set_opts)
-    {
-      s = strchr (set_opts, '[');
-      if (s == 0)
-       s = set_opts;
-      while (*++s == '-')
-       ;
-      t = strchr (s, ']');
-      if (t)
-       *t = '\0';
-      fprintf (fp, _("\t-%s or -o option\n"), s);
-      free (set_opts);
-    }
-
-  if (extra)
-    {
-      fprintf (fp, _("Type `%s -c \"help set\"' for more information about shell options.\n"), shell_name);
-      fprintf (fp, _("Type `%s -c help' for more information about shell builtin commands.\n"), shell_name);
-      fprintf (fp, _("Use the `bashbug' command to report bugs.\n"));
-    }
-}
-
-static void
-add_shopt_to_alist (opt, on_or_off)
-     char *opt;
-     int on_or_off;
-{
-  if (shopt_ind >= shopt_len)
-    {
-      shopt_len += 8;
-      shopt_alist = (STRING_INT_ALIST *)xrealloc (shopt_alist, shopt_len * sizeof (shopt_alist[0]));
-    }
-  shopt_alist[shopt_ind].word = opt;
-  shopt_alist[shopt_ind].token = on_or_off;
-  shopt_ind++;
-}
-
-static void
-run_shopt_alist ()
-{
-  register int i;
-
-  for (i = 0; i < shopt_ind; i++)
-    if (shopt_setopt (shopt_alist[i].word, (shopt_alist[i].token == '-')) != EXECUTION_SUCCESS)
-      exit (EX_BADUSAGE);
-  free (shopt_alist);
-  shopt_alist = 0;
-  shopt_ind = shopt_len = 0;
-}
diff --git a/shell.h~ b/shell.h~
deleted file mode 100644 (file)
index 57f5288..0000000
--- a/shell.h~
+++ /dev/null
@@ -1,166 +0,0 @@
-/* shell.h -- The data structures used by the shell */
-
-/* Copyright (C) 1993-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/>.
-*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "bashjmp.h"
-
-#include "command.h"
-#include "syntax.h"
-#include "general.h"
-#include "error.h"
-#include "variables.h"
-#include "arrayfunc.h"
-#include "quit.h"
-#include "maxpath.h"
-#include "unwind_prot.h"
-#include "dispose_cmd.h"
-#include "make_cmd.h"
-#include "ocache.h"
-#include "subst.h"
-#include "sig.h"
-#include "pathnames.h"
-#include "externs.h"
-
-extern int EOF_Reached;
-
-#define NO_PIPE -1
-#define REDIRECT_BOTH -2
-
-#define NO_VARIABLE -1
-
-/* Values that can be returned by execute_command (). */
-#define EXECUTION_FAILURE 1
-#define EXECUTION_SUCCESS 0
-
-/* Usage messages by builtins result in a return status of 2. */
-#define EX_BADUSAGE    2
-
-/* Special exit statuses used by the shell, internally and externally. */
-#define EX_RETRYFAIL   124
-#define EX_WEXPCOMSUB  125
-#define EX_BINARY_FILE 126
-#define EX_NOEXEC      126
-#define EX_NOINPUT     126
-#define EX_NOTFOUND    127
-
-#define EX_SHERRBASE   256     /* all special error values are > this. */
-
-#define EX_BADSYNTAX   257     /* shell syntax error */
-#define EX_USAGE       258     /* syntax error in usage */
-#define EX_REDIRFAIL   259     /* redirection failed */
-#define EX_BADASSIGN   260     /* variable assignment error */
-#define EX_EXPFAIL     261     /* word expansion failed */
-
-/* Flag values that control parameter pattern substitution. */
-#define MATCH_ANY      0x000
-#define MATCH_BEG      0x001
-#define MATCH_END      0x002
-
-#define MATCH_TYPEMASK 0x003
-
-#define MATCH_GLOBREP  0x010
-#define MATCH_QUOTED   0x020
-#define MATCH_STARSUB  0x040
-
-/* Some needed external declarations. */
-extern char **shell_environment;
-extern WORD_LIST *rest_of_args;
-
-/* Generalized global variables. */
-extern int debugging_mode;
-extern int executing, login_shell;
-extern int interactive, interactive_shell;
-extern int startup_state;
-extern int shell_compatibility_level;
-
-/* Structure to pass around that holds a bitmap of file descriptors
-   to close, and the size of that structure.  Used in execute_cmd.c. */
-struct fd_bitmap {
-  int size;
-  char *bitmap;
-};
-
-#define FD_BITMAP_SIZE 32
-
-#define CTLESC '\001'
-#define CTLNUL '\177'
-
-/* Information about the current user. */
-struct user_info {
-  uid_t uid, euid;
-  gid_t gid, egid;
-  char *user_name;
-  char *shell;         /* shell from the password file */
-  char *home_dir;
-};
-
-extern struct user_info current_user;
-
-/* Force gcc to not clobber X on a longjmp().  Old versions of gcc mangle
-   this badly. */
-#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ > 8)
-#  define USE_VAR(x)   ((void) &(x))
-#else
-#  define USE_VAR(x)
-#endif
-
-/* Structure in which to save partial parsing state when doing things like
-   PROMPT_COMMAND and bash_execute_unix_command execution. */
-
-typedef struct _sh_parser_state_t {
-
-  /* parsing state */
-  int parser_state;
-  int *token_state;
-
-  /* input line state -- line number saved elsewhere */
-  int input_line_terminator;
-  int eof_encountered;
-
-#if defined (HANDLE_MULTIBYTE)
-  /* Nothing right now for multibyte state, but might want something later. */
-#endif
-
-  /* history state affecting or modified by the parser */
-  int current_command_line_count;
-#if defined (HISTORY)
-  int remember_on_history;
-  int history_expansion_inhibited;
-#endif
-
-  /* execution state possibly modified by the parser */
-  int last_command_exit_value;
-#if defined (ARRAY_VARS)
-  ARRAY *pipestatus;
-#endif
-  sh_builtin_func_t *last_shell_builtin, *this_shell_builtin;
-
-  /* flags state affecting the parser */
-  int expand_aliases;
-  int echo_input_at_read;
-  
-} sh_parser_state_t;
-
-/* Let's try declaring these here. */
-extern sh_parser_state_t *save_parser_state __P((sh_parser_state_t *));
-extern void restore_parser_state __P((sh_parser_state_t *));
diff --git a/sig.c~ b/sig.c~
deleted file mode 100644 (file)
index 625ce0d..0000000
--- a/sig.c~
+++ /dev/null
@@ -1,664 +0,0 @@
-/* sig.c - interface for shell signal handlers and signal initialization. */
-
-/* Copyright (C) 1994-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/>.
-*/
-
-#include "config.h"
-
-#include "bashtypes.h"
-
-#if defined (HAVE_UNISTD_H)
-#  ifdef _MINIX
-#    include <sys/types.h>
-#  endif
-#  include <unistd.h>
-#endif
-
-#include <stdio.h>
-#include <signal.h>
-
-#include "bashintl.h"
-
-#include "shell.h"
-#if defined (JOB_CONTROL)
-#include "jobs.h"
-#endif /* JOB_CONTROL */
-#include "siglist.h"
-#include "sig.h"
-#include "trap.h"
-
-#include "builtins/common.h"
-
-#if defined (READLINE)
-#  include "bashline.h"
-#endif
-
-#if defined (HISTORY)
-#  include "bashhist.h"
-#endif
-
-extern int last_command_exit_value;
-extern int last_command_exit_signal;
-extern int return_catch_flag;
-extern int loop_level, continuing, breaking;
-extern int executing_list;
-extern int comsub_ignore_return;
-extern int parse_and_execute_level, shell_initialized;
-
-/* Non-zero after SIGINT. */
-volatile int interrupt_state = 0;
-
-/* Non-zero after SIGWINCH */
-volatile int sigwinch_received = 0;
-
-/* Set to the value of any terminating signal received. */
-volatile int terminating_signal = 0;
-
-/* The environment at the top-level R-E loop.  We use this in
-   the case of error return. */
-procenv_t top_level;
-
-#if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS)
-/* The signal masks that this shell runs with. */
-sigset_t top_level_mask;
-#endif /* JOB_CONTROL */
-
-/* When non-zero, we throw_to_top_level (). */
-int interrupt_immediately = 0;
-
-/* When non-zero, we call the terminating signal handler immediately. */
-int terminate_immediately = 0;
-
-#if defined (SIGWINCH)
-static SigHandler *old_winch = (SigHandler *)SIG_DFL;
-#endif
-
-static void initialize_shell_signals __P((void));
-
-void
-initialize_signals (reinit)
-     int reinit;
-{
-  initialize_shell_signals ();
-  initialize_job_signals ();
-#if !defined (HAVE_SYS_SIGLIST) && !defined (HAVE_UNDER_SYS_SIGLIST) && !defined (HAVE_STRSIGNAL)
-  if (reinit == 0)
-    initialize_siglist ();
-#endif /* !HAVE_SYS_SIGLIST && !HAVE_UNDER_SYS_SIGLIST && !HAVE_STRSIGNAL */
-}
-
-/* A structure describing a signal that terminates the shell if not
-   caught.  The orig_handler member is present so children can reset
-   these signals back to their original handlers. */
-struct termsig {
-     int signum;
-     SigHandler *orig_handler;
-     int orig_flags;
-};
-
-#define NULL_HANDLER (SigHandler *)SIG_DFL
-
-/* The list of signals that would terminate the shell if not caught.
-   We catch them, but just so that we can write the history file,
-   and so forth. */
-static struct termsig terminating_signals[] = {
-#ifdef SIGHUP
-{  SIGHUP, NULL_HANDLER, 0 },
-#endif
-
-#ifdef SIGINT
-{  SIGINT, NULL_HANDLER, 0 },
-#endif
-
-#ifdef SIGILL
-{  SIGILL, NULL_HANDLER, 0 },
-#endif
-
-#ifdef SIGTRAP
-{  SIGTRAP, NULL_HANDLER, 0 },
-#endif
-
-#ifdef SIGIOT
-{  SIGIOT, NULL_HANDLER, 0 },
-#endif
-
-#ifdef SIGDANGER
-{  SIGDANGER, NULL_HANDLER, 0 },
-#endif
-
-#ifdef SIGEMT
-{  SIGEMT, NULL_HANDLER, 0 },
-#endif
-
-#ifdef SIGFPE
-{  SIGFPE, NULL_HANDLER, 0 },
-#endif
-
-#ifdef SIGBUS
-{  SIGBUS, NULL_HANDLER, 0 },
-#endif
-
-#ifdef SIGSEGV
-{  SIGSEGV, NULL_HANDLER, 0 },
-#endif
-
-#ifdef SIGSYS
-{  SIGSYS, NULL_HANDLER, 0 },
-#endif
-
-#ifdef SIGPIPE
-{  SIGPIPE, NULL_HANDLER, 0 },
-#endif
-
-#ifdef SIGALRM
-{  SIGALRM, NULL_HANDLER, 0 },
-#endif
-
-#ifdef SIGTERM
-{  SIGTERM, NULL_HANDLER, 0 },
-#endif
-
-#ifdef SIGXCPU
-{  SIGXCPU, NULL_HANDLER, 0 },
-#endif
-
-#ifdef SIGXFSZ
-{  SIGXFSZ, NULL_HANDLER, 0 },
-#endif
-
-#ifdef SIGVTALRM
-{  SIGVTALRM, NULL_HANDLER, 0 },
-#endif
-
-#if 0
-#ifdef SIGPROF
-{  SIGPROF, NULL_HANDLER, 0 },
-#endif
-#endif
-
-#ifdef SIGLOST
-{  SIGLOST, NULL_HANDLER, 0 },
-#endif
-
-#ifdef SIGUSR1
-{  SIGUSR1, NULL_HANDLER, 0 },
-#endif
-
-#ifdef SIGUSR2
-{  SIGUSR2, NULL_HANDLER, 0 },
-#endif
-};
-
-#define TERMSIGS_LENGTH (sizeof (terminating_signals) / sizeof (struct termsig))
-
-#define XSIG(x) (terminating_signals[x].signum)
-#define XHANDLER(x) (terminating_signals[x].orig_handler)
-#define XSAFLAGS(x) (terminating_signals[x].orig_flags)
-
-static int termsigs_initialized = 0;
-
-/* Initialize signals that will terminate the shell to do some
-   unwind protection.  For non-interactive shells, we only call
-   this when a trap is defined for EXIT (0). */
-void
-initialize_terminating_signals ()
-{
-  register int i;
-#if defined (HAVE_POSIX_SIGNALS)
-  struct sigaction act, oact;
-#endif
-
-  if (termsigs_initialized)
-    return;
-
-  /* The following code is to avoid an expensive call to
-     set_signal_handler () for each terminating_signals.  Fortunately,
-     this is possible in Posix.  Unfortunately, we have to call signal ()
-     on non-Posix systems for each signal in terminating_signals. */
-#if defined (HAVE_POSIX_SIGNALS)
-  act.sa_handler = termsig_sighandler;
-  act.sa_flags = 0;
-  sigemptyset (&act.sa_mask);
-  sigemptyset (&oact.sa_mask);
-  for (i = 0; i < TERMSIGS_LENGTH; i++)
-    sigaddset (&act.sa_mask, XSIG (i));
-  for (i = 0; i < TERMSIGS_LENGTH; i++)
-    {
-      /* If we've already trapped it, don't do anything. */
-      if (signal_is_trapped (XSIG (i)))
-       continue;
-
-      sigaction (XSIG (i), &act, &oact);
-      XHANDLER(i) = oact.sa_handler;
-      XSAFLAGS(i) = oact.sa_flags;
-      /* Don't do anything with signals that are ignored at shell entry
-        if the shell is not interactive. */
-      if (!interactive_shell && XHANDLER (i) == SIG_IGN)
-       {
-         sigaction (XSIG (i), &oact, &act);
-         set_signal_ignored (XSIG (i));
-       }
-#if defined (SIGPROF) && !defined (_MINIX)
-      if (XSIG (i) == SIGPROF && XHANDLER (i) != SIG_DFL && XHANDLER (i) != SIG_IGN)
-       sigaction (XSIG (i), &oact, (struct sigaction *)NULL);
-#endif /* SIGPROF && !_MINIX */
-    }
-
-#else /* !HAVE_POSIX_SIGNALS */
-
-  for (i = 0; i < TERMSIGS_LENGTH; i++)
-    {
-      /* If we've already trapped it, don't do anything. */
-      if (signal_is_trapped (XSIG (i)))
-       continue;
-
-      XHANDLER(i) = signal (XSIG (i), termsig_sighandler);
-      XSAFLAGS(i) = 0;
-      /* Don't do anything with signals that are ignored at shell entry
-        if the shell is not interactive. */
-      if (!interactive_shell && XHANDLER (i) == SIG_IGN)
-       {
-         signal (XSIG (i), SIG_IGN);
-         set_signal_ignored (XSIG (i));
-       }
-#ifdef SIGPROF
-      if (XSIG (i) == SIGPROF && XHANDLER (i) != SIG_DFL && XHANDLER (i) != SIG_IGN)
-       signal (XSIG (i), XHANDLER (i));
-#endif
-    }
-
-#endif /* !HAVE_POSIX_SIGNALS */
-
-  termsigs_initialized = 1;
-}
-
-static void
-initialize_shell_signals ()
-{
-  if (interactive)
-    initialize_terminating_signals ();
-
-#if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS)
-  /* All shells use the signal mask they inherit, and pass it along
-     to child processes.  Children will never block SIGCHLD, though. */
-  sigemptyset (&top_level_mask);
-  sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &top_level_mask);
-#  if defined (SIGCHLD)
-  sigdelset (&top_level_mask, SIGCHLD);
-#  endif
-#endif /* JOB_CONTROL || HAVE_POSIX_SIGNALS */
-
-  /* And, some signals that are specifically ignored by the shell. */
-  set_signal_handler (SIGQUIT, SIG_IGN);
-
-  if (interactive)
-    {
-      set_signal_handler (SIGINT, sigint_sighandler);
-      set_signal_handler (SIGTERM, SIG_IGN);
-      set_sigwinch_handler ();
-    }
-}
-
-void
-reset_terminating_signals ()
-{
-  register int i;
-#if defined (HAVE_POSIX_SIGNALS)
-  struct sigaction act;
-#endif
-
-  if (termsigs_initialized == 0)
-    return;
-
-#if defined (HAVE_POSIX_SIGNALS)
-  act.sa_flags = 0;
-  sigemptyset (&act.sa_mask);
-  for (i = 0; i < TERMSIGS_LENGTH; i++)
-    {
-      /* Skip a signal if it's trapped or handled specially, because the
-        trap code will restore the correct value. */
-      if (signal_is_trapped (XSIG (i)) || signal_is_special (XSIG (i)))
-       continue;
-
-      act.sa_handler = XHANDLER (i);
-      act.sa_flags = XSAFLAGS (i);
-      sigaction (XSIG (i), &act, (struct sigaction *) NULL);
-    }
-#else /* !HAVE_POSIX_SIGNALS */
-  for (i = 0; i < TERMSIGS_LENGTH; i++)
-    {
-      if (signal_is_trapped (XSIG (i)) || signal_is_special (XSIG (i)))
-       continue;
-
-      signal (XSIG (i), XHANDLER (i));
-    }
-#endif /* !HAVE_POSIX_SIGNALS */
-}
-#undef XSIG
-#undef XHANDLER
-
-/* Run some of the cleanups that should be performed when we run
-   jump_to_top_level from a builtin command context.  XXX - might want to
-   also call reset_parser here. */
-void
-top_level_cleanup ()
-{
-  /* Clean up string parser environment. */
-  while (parse_and_execute_level)
-    parse_and_execute_cleanup ();
-
-#if defined (PROCESS_SUBSTITUTION)
-  unlink_fifo_list ();
-#endif /* PROCESS_SUBSTITUTION */
-
-  run_unwind_protects ();
-  loop_level = continuing = breaking = 0;
-  executing_list = comsub_ignore_return = return_catch_flag = 0;
-}
-
-/* What to do when we've been interrupted, and it is safe to handle it. */
-void
-throw_to_top_level ()
-{
-  int print_newline = 0;
-
-  if (interrupt_state)
-    {
-      print_newline = 1;
-      DELINTERRUPT;
-    }
-
-  if (interrupt_state)
-    return;
-
-  last_command_exit_signal = (last_command_exit_value > 128) ?
-                               (last_command_exit_value - 128) : 0;
-  last_command_exit_value |= 128;
-
-  /* Run any traps set on SIGINT. */
-  run_interrupt_trap ();
-
-  /* Clean up string parser environment. */
-  while (parse_and_execute_level)
-    parse_and_execute_cleanup ();
-
-#if defined (JOB_CONTROL)
-  give_terminal_to (shell_pgrp, 0);
-#endif /* JOB_CONTROL */
-
-#if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS)
-  /* This should not be necessary on systems using sigsetjmp/siglongjmp. */
-  sigprocmask (SIG_SETMASK, &top_level_mask, (sigset_t *)NULL);
-#endif
-
-  reset_parser ();
-
-#if defined (READLINE)
-  if (interactive)
-    bashline_reset ();
-#endif /* READLINE */
-
-#if defined (PROCESS_SUBSTITUTION)
-  unlink_fifo_list ();
-#endif /* PROCESS_SUBSTITUTION */
-
-  run_unwind_protects ();
-  loop_level = continuing = breaking = 0;
-  executing_list = comsub_ignore_return = return_catch_flag = 0;
-
-  if (interactive && print_newline)
-    {
-      fflush (stdout);
-      fprintf (stderr, "\n");
-      fflush (stderr);
-    }
-
-  /* An interrupted `wait' command in a script does not exit the script. */
-  if (interactive || (interactive_shell && !shell_initialized) ||
-      (print_newline && signal_is_trapped (SIGINT)))
-    jump_to_top_level (DISCARD);
-  else
-    jump_to_top_level (EXITPROG);
-}
-
-/* This is just here to isolate the longjmp calls. */
-void
-jump_to_top_level (value)
-     int value;
-{
-  longjmp (top_level, value);
-}
-
-sighandler
-termsig_sighandler (sig)
-     int sig;
-{
-  /* If we get called twice with the same signal before handling it,
-     terminate right away. */
-  if (
-#ifdef SIGHUP
-    sig != SIGHUP &&
-#endif
-#ifdef SIGINT
-    sig != SIGINT &&
-#endif
-#ifdef SIGDANGER
-    sig != SIGDANGER &&
-#endif
-#ifdef SIGPIPE
-    sig != SIGPIPE &&
-#endif
-#ifdef SIGALRM
-    sig != SIGALRM &&
-#endif
-#ifdef SIGTERM
-    sig != SIGTERM &&
-#endif
-#ifdef SIGXCPU
-    sig != SIGXCPU &&
-#endif
-#ifdef SIGXFSZ
-    sig != SIGXFSZ &&
-#endif
-#ifdef SIGVTALRM
-    sig != SIGVTALRM &&
-#endif
-#ifdef SIGLOST
-    sig != SIGLOST &&
-#endif
-#ifdef SIGUSR1
-    sig != SIGUSR1 &&
-#endif
-#ifdef SIGUSR2
-   sig != SIGUSR2 &&
-#endif
-   sig == terminating_signal)
-    terminate_immediately = 1;
-
-  terminating_signal = sig;
-
-  /* XXX - should this also trigger when interrupt_immediately is set? */
-  if (terminate_immediately)
-    {
-      terminate_immediately = 0;
-      termsig_handler (sig);
-    }
-
-  SIGRETURN (0);
-}
-
-void
-termsig_handler (sig)
-     int sig;
-{
-  static int handling_termsig = 0;
-
-  /* Simple semaphore to keep this function from being executed multiple
-     times.  Since we no longer are running as a signal handler, we don't
-     block multiple occurrences of the terminating signals while running. */
-  if (handling_termsig)
-    return;
-  handling_termsig = 1;
-  terminating_signal = 0;      /* keep macro from re-testing true. */
-
-  /* I don't believe this condition ever tests true. */
-  if (sig == SIGINT && signal_is_trapped (SIGINT))
-    run_interrupt_trap ();
-
-#if defined (HISTORY)
-  if (interactive_shell && sig != SIGABRT)
-    maybe_save_shell_history ();
-#endif /* HISTORY */
-
-#if defined (JOB_CONTROL)
-  if (interactive && sig == SIGHUP)
-    hangup_all_jobs ();
-  end_job_control ();
-#endif /* JOB_CONTROL */
-
-#if defined (PROCESS_SUBSTITUTION)
-  unlink_fifo_list ();
-#endif /* PROCESS_SUBSTITUTION */
-
-  /* Reset execution context */
-  loop_level = continuing = breaking = 0;
-  executing_list = comsub_ignore_return = return_catch_flag = 0;
-
-  run_exit_trap ();
-  set_signal_handler (sig, SIG_DFL);
-  kill (getpid (), sig);
-}
-
-/* What we really do when SIGINT occurs. */
-sighandler
-sigint_sighandler (sig)
-     int sig;
-{
-#if defined (MUST_REINSTALL_SIGHANDLERS)
-  signal (sig, sigint_sighandler);
-#endif
-
-  /* interrupt_state needs to be set for the stack of interrupts to work
-     right.  Should it be set unconditionally? */
-  if (interrupt_state == 0)
-    ADDINTERRUPT;
-
-  if (interrupt_immediately)
-    {
-      interrupt_immediately = 0;
-      last_command_exit_value = 128 + sig;
-      throw_to_top_level ();
-    }
-
-  SIGRETURN (0);
-}
-
-#if defined (SIGWINCH)
-sighandler
-sigwinch_sighandler (sig)
-     int sig;
-{
-#if defined (MUST_REINSTALL_SIGHANDLERS)
-  set_signal_handler (SIGWINCH, sigwinch_sighandler);
-#endif /* MUST_REINSTALL_SIGHANDLERS */
-  sigwinch_received = 1;
-  SIGRETURN (0);
-}
-#endif /* SIGWINCH */
-
-void
-set_sigwinch_handler ()
-{
-#if defined (SIGWINCH)
- old_winch = set_signal_handler (SIGWINCH, sigwinch_sighandler);
-#endif
-}
-
-void
-unset_sigwinch_handler ()
-{
-#if defined (SIGWINCH)
-  set_signal_handler (SIGWINCH, old_winch);
-#endif
-}
-
-/* Signal functions used by the rest of the code. */
-#if !defined (HAVE_POSIX_SIGNALS)
-
-#if defined (JOB_CONTROL)
-/* Perform OPERATION on NEWSET, perhaps leaving information in OLDSET. */
-sigprocmask (operation, newset, oldset)
-     int operation, *newset, *oldset;
-{
-  int old, new;
-
-  if (newset)
-    new = *newset;
-  else
-    new = 0;
-
-  switch (operation)
-    {
-    case SIG_BLOCK:
-      old = sigblock (new);
-      break;
-
-    case SIG_SETMASK:
-      sigsetmask (new);
-      break;
-
-    default:
-      internal_error (_("sigprocmask: %d: invalid operation"), operation);
-    }
-
-  if (oldset)
-    *oldset = old;
-}
-#endif /* JOB_CONTROL */
-
-#else
-
-#if !defined (SA_INTERRUPT)
-#  define SA_INTERRUPT 0
-#endif
-
-#if !defined (SA_RESTART)
-#  define SA_RESTART 0
-#endif
-
-SigHandler *
-set_signal_handler (sig, handler)
-     int sig;
-     SigHandler *handler;
-{
-  struct sigaction act, oact;
-
-  act.sa_handler = handler;
-  act.sa_flags = 0;
-#if 0
-  if (sig == SIGALRM)
-    act.sa_flags |= SA_INTERRUPT;      /* XXX */
-  else
-    act.sa_flags |= SA_RESTART;                /* XXX */
-#endif
-  sigemptyset (&act.sa_mask);
-  sigemptyset (&oact.sa_mask);
-  sigaction (sig, &act, &oact);
-  return (oact.sa_handler);
-}
-#endif /* HAVE_POSIX_SIGNALS */
diff --git a/siglist.c~ b/siglist.c~
deleted file mode 100644 (file)
index 27eb26a..0000000
+++ /dev/null
@@ -1,228 +0,0 @@
-/* siglist.c -- signal list for those machines that don't have one. */
-
-/* Copyright (C) 1989-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/>.
-*/
-
-#include "config.h"
-
-#if !defined (HAVE_SYS_SIGLIST) && !defined (HAVE_UNDER_SYS_SIGLIST) && !defined (HAVE_STRSIGNAL)
-
-#include <stdio.h>
-#include "bashtypes.h"
-#include <signal.h>
-
-#include "siglist.h"
-
-#if !defined (NSIG)
-#  include "trap.h"
-#endif
-
-#include "xmalloc.h"
-
-char *sys_siglist[NSIG];
-
-void
-initialize_siglist ()
-{
-  register int i;
-
-  for (i = 0; i < NSIG; i++)
-    sys_siglist[i] = (char *)0x0;
-
-  sys_siglist[0] = _("Bogus signal");
-
-#if defined (SIGHUP)
-  sys_siglist[SIGHUP] = _("Hangup");
-#endif
-
-#if defined (SIGINT)
-  sys_siglist[SIGINT] = _("Interrupt");
-#endif
-
-#if defined (SIGQUIT)
-  sys_siglist[SIGQUIT] = _("Quit");
-#endif
-
-#if defined (SIGILL)
-  sys_siglist[SIGILL] = _("Illegal instruction");
-#endif
-
-#if defined (SIGTRAP)
-  sys_siglist[SIGTRAP] = _("BPT trace/trap");
-#endif
-
-#if defined (SIGIOT) && !defined (SIGABRT)
-#define SIGABRT SIGIOT
-#endif
-
-#if defined (SIGABRT)
-  sys_siglist[SIGABRT] = _("ABORT instruction");
-#endif
-
-#if defined (SIGEMT)
-  sys_siglist[SIGEMT] = _("EMT instruction");
-#endif
-
-#if defined (SIGFPE)
-  sys_siglist[SIGFPE] = _("Floating point exception");
-#endif
-
-#if defined (SIGKILL)
-  sys_siglist[SIGKILL] = _("Killed");
-#endif
-
-#if defined (SIGBUS)
-  sys_siglist[SIGBUS] = _("Bus error");
-#endif
-
-#if defined (SIGSEGV)
-  sys_siglist[SIGSEGV] = _("Segmentation fault");
-#endif
-
-#if defined (SIGSYS)
-  sys_siglist[SIGSYS] = _("Bad system call");
-#endif
-
-#if defined (SIGPIPE)
-  sys_siglist[SIGPIPE] = _("Broken pipe");
-#endif
-
-#if defined (SIGALRM)
-  sys_siglist[SIGALRM] = _("Alarm clock");
-#endif
-
-#if defined (SIGTERM)
-  sys_siglist[SIGTERM] = _("Terminated");
-#endif
-
-#if defined (SIGURG)
-  sys_siglist[SIGURG] = _("Urgent IO condition");
-#endif
-
-#if defined (SIGSTOP)
-  sys_siglist[SIGSTOP] = _("Stopped (signal)");
-#endif
-
-#if defined (SIGTSTP)
-  sys_siglist[SIGTSTP] = _("Stopped");
-#endif
-
-#if defined (SIGCONT)
-  sys_siglist[SIGCONT] = _("Continue");
-#endif
-
-#if !defined (SIGCHLD) && defined (SIGCLD)
-#define SIGCHLD SIGCLD
-#endif
-
-#if defined (SIGCHLD)
-  sys_siglist[SIGCHLD] = _("Child death or stop");
-#endif
-
-#if defined (SIGTTIN)
-  sys_siglist[SIGTTIN] = _("Stopped (tty input)");
-#endif
-
-#if defined (SIGTTOU)
-  sys_siglist[SIGTTOU] = _("Stopped (tty output)");
-#endif
-
-#if defined (SIGIO)
-  sys_siglist[SIGIO] = _("I/O ready");
-#endif
-
-#if defined (SIGXCPU)
-  sys_siglist[SIGXCPU] = _("CPU limit");
-#endif
-
-#if defined (SIGXFSZ)
-  sys_siglist[SIGXFSZ] = _("File limit");
-#endif
-
-#if defined (SIGVTALRM)
-  sys_siglist[SIGVTALRM] = _("Alarm (virtual)");
-#endif
-
-#if defined (SIGPROF)
-  sys_siglist[SIGPROF] = _("Alarm (profile)");
-#endif
-
-#if defined (SIGWINCH)
-  sys_siglist[SIGWINCH] = _("Window changed");
-#endif
-
-#if defined (SIGLOST)
-  sys_siglist[SIGLOST] = _("Record lock");
-#endif
-
-#if defined (SIGUSR1)
-  sys_siglist[SIGUSR1] = _("User signal 1");
-#endif
-
-#if defined (SIGUSR2)
-  sys_siglist[SIGUSR2] = _("User signal 2");
-#endif
-
-#if defined (SIGMSG)
-  sys_siglist[SIGMSG] = _("HFT input data pending");
-#endif
-
-#if defined (SIGPWR)
-  sys_siglist[SIGPWR] = _("power failure imminent");
-#endif
-
-#if defined (SIGDANGER)
-  sys_siglist[SIGDANGER] = _("system crash imminent");
-#endif
-
-#if defined (SIGMIGRATE)
-  sys_siglist[SIGMIGRATE] = _("migrate process to another CPU");
-#endif
-
-#if defined (SIGPRE)
-  sys_siglist[SIGPRE] = _("programming error");
-#endif
-
-#if defined (SIGGRANT)
-  sys_siglist[SIGGRANT] = _("HFT monitor mode granted");
-#endif
-
-#if defined (SIGRETRACT)
-  sys_siglist[SIGRETRACT] = _("HFT monitor mode retracted");
-#endif
-
-#if defined (SIGSOUND)
-  sys_siglist[SIGSOUND] = _("HFT sound sequence has completed");
-#endif
-
-#if defined (SIGINFO)
-  sys_siglist[SIGINFO] = _("Information request");
-#endif
-
-  for (i = 0; i < NSIG; i++)
-    {
-      if (!sys_siglist[i])
-       {
-         sys_siglist[i] =
-           (char *)xmalloc (10 + strlen (_("Unknown Signal #")));
-
-         sprintf (sys_siglist[i], _("Unknown Signal #%d"), i);
-       }
-    }
-}
-#endif /* !HAVE_SYS_SIGLIST && !HAVE_UNDER_SYS_SIGLIST && !HAVE_STRSIGNAL */
diff --git a/subst.c.orig b/subst.c.orig
deleted file mode 100644 (file)
index a407597..0000000
+++ /dev/null
@@ -1,9041 +0,0 @@
-/* subst.c -- The part of the shell that does parameter, command, arithmetic,
-   and globbing substitutions. */
-
-/* ``Have a little faith, there's magic in the night.  You ain't a
-     beauty, but, hey, you're alright.'' */
-
-/* Copyright (C) 1987-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/>.
-*/
-
-#include "config.h"
-
-#include "bashtypes.h"
-#include <stdio.h>
-#include "chartypes.h"
-#if defined (HAVE_PWD_H)
-#  include <pwd.h>
-#endif
-#include <signal.h>
-#include <errno.h>
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include "bashansi.h"
-#include "posixstat.h"
-#include "bashintl.h"
-
-#include "shell.h"
-#include "flags.h"
-#include "jobs.h"
-#include "execute_cmd.h"
-#include "filecntl.h"
-#include "trap.h"
-#include "pathexp.h"
-#include "mailcheck.h"
-
-#include "shmbutil.h"
-
-#include "builtins/getopt.h"
-#include "builtins/common.h"
-
-#include "builtins/builtext.h"
-
-#include <tilde/tilde.h>
-#include <glob/strmatch.h>
-
-#if !defined (errno)
-extern int errno;
-#endif /* !errno */
-
-/* The size that strings change by. */
-#define DEFAULT_INITIAL_ARRAY_SIZE 112
-#define DEFAULT_ARRAY_SIZE 128
-
-/* Variable types. */
-#define VT_VARIABLE    0
-#define VT_POSPARMS    1
-#define VT_ARRAYVAR    2
-#define VT_ARRAYMEMBER 3
-#define VT_ASSOCVAR    4
-
-#define VT_STARSUB     128     /* $* or ${array[*]} -- used to split */
-
-/* Flags for quoted_strchr */
-#define ST_BACKSL      0x01
-#define ST_CTLESC      0x02
-#define ST_SQUOTE      0x04    /* unused yet */
-#define ST_DQUOTE      0x08    /* unused yet */
-
-/* Flags for the `pflags' argument to param_expand() */
-#define PF_NOCOMSUB    0x01    /* Do not perform command substitution */
-#define PF_IGNUNBOUND  0x02    /* ignore unbound vars even if -u set */
-
-/* These defs make it easier to use the editor. */
-#define LBRACE         '{'
-#define RBRACE         '}'
-#define LPAREN         '('
-#define RPAREN         ')'
-
-#if defined (HANDLE_MULTIBYTE)
-#define WLPAREN                L'('
-#define WRPAREN                L')'
-#endif
-
-/* Evaluates to 1 if C is one of the shell's special parameters whose length
-   can be taken, but is also one of the special expansion characters. */
-#define VALID_SPECIAL_LENGTH_PARAM(c) \
-  ((c) == '-' || (c) == '?' || (c) == '#')
-
-/* Evaluates to 1 if C is one of the shell's special parameters for which an
-   indirect variable reference may be made. */
-#define VALID_INDIR_PARAM(c) \
-  ((c) == '#' || (c) == '?' || (c) == '@' || (c) == '*')
-
-/* Evaluates to 1 if C is one of the OP characters that follows the parameter
-   in ${parameter[:]OPword}. */
-#define VALID_PARAM_EXPAND_CHAR(c) (sh_syntaxtab[(unsigned char)c] & CSUBSTOP)
-
-/* Evaluates to 1 if this is one of the shell's special variables. */
-#define SPECIAL_VAR(name, wi) \
- ((DIGIT (*name) && all_digits (name)) || \
-      (name[1] == '\0' && (sh_syntaxtab[(unsigned char)*name] & CSPECVAR)) || \
-      (wi && name[2] == '\0' && VALID_INDIR_PARAM (name[1])))
-
-/* An expansion function that takes a string and a quoted flag and returns
-   a WORD_LIST *.  Used as the type of the third argument to
-   expand_string_if_necessary(). */
-typedef WORD_LIST *EXPFUNC __P((char *, int));
-
-/* Process ID of the last command executed within command substitution. */
-pid_t last_command_subst_pid = NO_PID;
-pid_t current_command_subst_pid = NO_PID;
-
-/* Variables used to keep track of the characters in IFS. */
-SHELL_VAR *ifs_var;
-char *ifs_value;
-unsigned char ifs_cmap[UCHAR_MAX + 1];
-
-#if defined (HANDLE_MULTIBYTE)
-unsigned char ifs_firstc[MB_LEN_MAX];
-size_t ifs_firstc_len;
-#else
-unsigned char ifs_firstc;
-#endif
-
-/* Sentinel to tell when we are performing variable assignments preceding a
-   command name and putting them into the environment.  Used to make sure
-   we use the temporary environment when looking up variable values. */
-int assigning_in_environment;
-
-/* Used to hold a list of variable assignments preceding a command.  Global
-   so the SIGCHLD handler in jobs.c can unwind-protect it when it runs a
-   SIGCHLD trap and so it can be saved and restored by the trap handlers. */
-WORD_LIST *subst_assign_varlist = (WORD_LIST *)NULL;
-
-/* Extern functions and variables from different files. */
-extern int last_command_exit_value, last_command_exit_signal;
-extern int subshell_environment;
-extern int subshell_level, parse_and_execute_level;
-extern int eof_encountered;
-extern int return_catch_flag, return_catch_value;
-extern pid_t dollar_dollar_pid;
-extern int posixly_correct;
-extern char *this_command_name;
-extern struct fd_bitmap *current_fds_to_close;
-extern int wordexp_only;
-extern int expanding_redir;
-extern int tempenv_assign_error;
-
-#if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE)
-extern wchar_t *wcsdup __P((const wchar_t *));
-#endif
-
-/* Non-zero means to allow unmatched globbed filenames to expand to
-   a null file. */
-int allow_null_glob_expansion;
-
-/* Non-zero means to throw an error when globbing fails to match anything. */
-int fail_glob_expansion;
-
-#if 0
-/* Variables to keep track of which words in an expanded word list (the
-   output of expand_word_list_internal) are the result of globbing
-   expansions.  GLOB_ARGV_FLAGS is used by execute_cmd.c.
-   (CURRENTLY UNUSED). */
-char *glob_argv_flags;
-static int glob_argv_flags_size;
-#endif
-
-static WORD_LIST expand_word_error, expand_word_fatal;
-static WORD_DESC expand_wdesc_error, expand_wdesc_fatal;
-static char expand_param_error, expand_param_fatal;
-static char extract_string_error, extract_string_fatal;
-
-/* Tell the expansion functions to not longjmp back to top_level on fatal
-   errors.  Enabled when doing completion and prompt string expansion. */
-static int no_longjmp_on_fatal_error = 0;
-
-/* Set by expand_word_unsplit; used to inhibit splitting and re-joining
-   $* on $IFS, primarily when doing assignment statements. */
-static int expand_no_split_dollar_star = 0;
-
-/* A WORD_LIST of words to be expanded by expand_word_list_internal,
-   without any leading variable assignments. */
-static WORD_LIST *garglist = (WORD_LIST *)NULL;
-
-static char *quoted_substring __P((char *, int, int));
-static int quoted_strlen __P((char *));
-static char *quoted_strchr __P((char *, int, int));
-
-static char *expand_string_if_necessary __P((char *, int, EXPFUNC *));
-static inline char *expand_string_to_string_internal __P((char *, int, EXPFUNC *));
-static WORD_LIST *call_expand_word_internal __P((WORD_DESC *, int, int, int *, int *));
-static WORD_LIST *expand_string_internal __P((char *, int));
-static WORD_LIST *expand_string_leave_quoted __P((char *, int));
-static WORD_LIST *expand_string_for_rhs __P((char *, int, int *, int *));
-
-static WORD_LIST *list_quote_escapes __P((WORD_LIST *));
-static char *make_quoted_char __P((int));
-static WORD_LIST *quote_list __P((WORD_LIST *));
-
-static int unquoted_substring __P((char *, char *));
-static int unquoted_member __P((int, char *));
-
-#if defined (ARRAY_VARS)
-static SHELL_VAR *do_compound_assignment __P((char *, char *, int));
-#endif
-static int do_assignment_internal __P((const WORD_DESC *, int));
-
-static char *string_extract_verbatim __P((char *, size_t, int *, char *, int));
-static char *string_extract __P((char *, int *, char *, int));
-static char *string_extract_double_quoted __P((char *, int *, int));
-static inline char *string_extract_single_quoted __P((char *, int *));
-static inline int skip_single_quoted __P((const char *, size_t, int));
-static int skip_double_quoted __P((char *, size_t, int));
-static char *extract_delimited_string __P((char *, int *, char *, char *, char *, int));
-static char *extract_dollar_brace_string __P((char *, int *, int, int));
-static int skip_matched_pair __P((const char *, int, int, int, int));
-
-static char *pos_params __P((char *, int, int, int));
-
-static unsigned char *mb_getcharlens __P((char *, int));
-
-static char *remove_upattern __P((char *, char *, int));
-#if defined (HANDLE_MULTIBYTE) 
-static wchar_t *remove_wpattern __P((wchar_t *, size_t, wchar_t *, int));
-#endif
-static char *remove_pattern __P((char *, char *, int));
-
-static int match_pattern_char __P((char *, char *));
-static int match_upattern __P((char *, char *, int, char **, char **));
-#if defined (HANDLE_MULTIBYTE)
-static int match_pattern_wchar __P((wchar_t *, wchar_t *));
-static int match_wpattern __P((wchar_t *, char **, size_t, wchar_t *, int, char **, char **));
-#endif
-static int match_pattern __P((char *, char *, int, char **, char **));
-static int getpatspec __P((int, char *));
-static char *getpattern __P((char *, int, int));
-static char *variable_remove_pattern __P((char *, char *, int, int));
-static char *list_remove_pattern __P((WORD_LIST *, char *, int, int, int));
-static char *parameter_list_remove_pattern __P((int, char *, int, int));
-#ifdef ARRAY_VARS
-static char *array_remove_pattern __P((SHELL_VAR *, char *, int, char *, int));
-#endif
-static char *parameter_brace_remove_pattern __P((char *, char *, char *, int, int));
-
-static char *process_substitute __P((char *, int));
-
-static char *read_comsub __P((int, int, int *));
-
-#ifdef ARRAY_VARS
-static arrayind_t array_length_reference __P((char *));
-#endif
-
-static int valid_brace_expansion_word __P((char *, int));
-static int chk_atstar __P((char *, int, int *, int *));
-static int chk_arithsub __P((const char *, int));
-
-static WORD_DESC *parameter_brace_expand_word __P((char *, int, int, int));
-static WORD_DESC *parameter_brace_expand_indir __P((char *, int, int, int *, int *));
-static WORD_DESC *parameter_brace_expand_rhs __P((char *, char *, int, int, int *, int *));
-static void parameter_brace_expand_error __P((char *, char *));
-
-static int valid_length_expression __P((char *));
-static intmax_t parameter_brace_expand_length __P((char *));
-
-static char *skiparith __P((char *, int));
-static int verify_substring_values __P((SHELL_VAR *, char *, char *, int, intmax_t *, intmax_t *));
-static int get_var_and_type __P((char *, char *, int, SHELL_VAR **, char **));
-static char *mb_substring __P((char *, int, int));
-static char *parameter_brace_substring __P((char *, char *, char *, int));
-
-static char *pos_params_pat_subst __P((char *, char *, char *, int));
-
-static char *parameter_brace_patsub __P((char *, char *, char *, int));
-
-static char *pos_params_casemod __P((char *, char *, int, int));
-static char *parameter_brace_casemod __P((char *, char *, int, char *, int));
-
-static WORD_DESC *parameter_brace_expand __P((char *, int *, int, int *, int *));
-static WORD_DESC *param_expand __P((char *, int *, int, int *, int *, int *, int *, int));
-
-static WORD_LIST *expand_word_internal __P((WORD_DESC *, int, int, int *, int *));
-
-static WORD_LIST *word_list_split __P((WORD_LIST *));
-
-static void exp_jump_to_top_level __P((int));
-
-static WORD_LIST *separate_out_assignments __P((WORD_LIST *));
-static WORD_LIST *glob_expand_word_list __P((WORD_LIST *, int));
-#ifdef BRACE_EXPANSION
-static WORD_LIST *brace_expand_word_list __P((WORD_LIST *, int));
-#endif
-#if defined (ARRAY_VARS)
-static int make_internal_declare __P((char *, char *));
-#endif
-static WORD_LIST *shell_expand_word_list __P((WORD_LIST *, int));
-static WORD_LIST *expand_word_list_internal __P((WORD_LIST *, int));
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Utility Functions                           */
-/*                                                                 */
-/* **************************************************************** */
-
-#if defined (DEBUG)
-void
-dump_word_flags (flags)
-     int flags;
-{
-  int f;
-
-  f = flags;
-  fprintf (stderr, "%d -> ", f);
-  if (f & W_ASSIGNASSOC)
-    {
-      f &= ~W_ASSIGNASSOC;
-      fprintf (stderr, "W_ASSIGNASSOC%s", f ? "|" : "");
-    }
-  if (f & W_HASCTLESC)
-    {
-      f &= ~W_HASCTLESC;
-      fprintf (stderr, "W_HASCTLESC%s", f ? "|" : "");
-    }
-  if (f & W_NOPROCSUB)
-    {
-      f &= ~W_NOPROCSUB;
-      fprintf (stderr, "W_NOPROCSUB%s", f ? "|" : "");
-    }
-  if (f & W_DQUOTE)
-    {
-      f &= ~W_DQUOTE;
-      fprintf (stderr, "W_DQUOTE%s", f ? "|" : "");
-    }
-  if (f & W_HASQUOTEDNULL)
-    {
-      f &= ~W_HASQUOTEDNULL;
-      fprintf (stderr, "W_HASQUOTEDNULL%s", f ? "|" : "");
-    }
-  if (f & W_ASSIGNARG)
-    {
-      f &= ~W_ASSIGNARG;
-      fprintf (stderr, "W_ASSIGNARG%s", f ? "|" : "");
-    }
-  if (f & W_ASSNBLTIN)
-    {
-      f &= ~W_ASSNBLTIN;
-      fprintf (stderr, "W_ASSNBLTIN%s", f ? "|" : "");
-    }
-  if (f & W_COMPASSIGN)
-    {
-      f &= ~W_COMPASSIGN;
-      fprintf (stderr, "W_COMPASSIGN%s", f ? "|" : "");
-    }
-  if (f & W_NOEXPAND)
-    {
-      f &= ~W_NOEXPAND;
-      fprintf (stderr, "W_NOEXPAND%s", f ? "|" : "");
-    }
-  if (f & W_ITILDE)
-    {
-      f &= ~W_ITILDE;
-      fprintf (stderr, "W_ITILDE%s", f ? "|" : "");
-    }
-  if (f & W_NOTILDE)
-    {
-      f &= ~W_NOTILDE;
-      fprintf (stderr, "W_NOTILDE%s", f ? "|" : "");
-    }
-  if (f & W_ASSIGNRHS)
-    {
-      f &= ~W_ASSIGNRHS;
-      fprintf (stderr, "W_ASSIGNRHS%s", f ? "|" : "");
-    }
-  if (f & W_NOCOMSUB)
-    {
-      f &= ~W_NOCOMSUB;
-      fprintf (stderr, "W_NOCOMSUB%s", f ? "|" : "");
-    }
-  if (f & W_DOLLARSTAR)
-    {
-      f &= ~W_DOLLARSTAR;
-      fprintf (stderr, "W_DOLLARSTAR%s", f ? "|" : "");
-    }
-  if (f & W_DOLLARAT)
-    {
-      f &= ~W_DOLLARAT;
-      fprintf (stderr, "W_DOLLARAT%s", f ? "|" : "");
-    }
-  if (f & W_TILDEEXP)
-    {
-      f &= ~W_TILDEEXP;
-      fprintf (stderr, "W_TILDEEXP%s", f ? "|" : "");
-    }
-  if (f & W_NOSPLIT2)
-    {
-      f &= ~W_NOSPLIT2;
-      fprintf (stderr, "W_NOSPLIT2%s", f ? "|" : "");
-    }
-  if (f & W_NOGLOB)
-    {
-      f &= ~W_NOGLOB;
-      fprintf (stderr, "W_NOGLOB%s", f ? "|" : "");
-    }
-  if (f & W_NOSPLIT)
-    {
-      f &= ~W_NOSPLIT;
-      fprintf (stderr, "W_NOSPLIT%s", f ? "|" : "");
-    }
-  if (f & W_GLOBEXP)
-    {
-      f &= ~W_GLOBEXP;
-      fprintf (stderr, "W_GLOBEXP%s", f ? "|" : "");
-    }
-  if (f & W_ASSIGNMENT)
-    {
-      f &= ~W_ASSIGNMENT;
-      fprintf (stderr, "W_ASSIGNMENT%s", f ? "|" : "");
-    }
-  if (f & W_QUOTED)
-    {
-      f &= ~W_QUOTED;
-      fprintf (stderr, "W_QUOTED%s", f ? "|" : "");
-    }
-  if (f & W_HASDOLLAR)
-    {
-      f &= ~W_HASDOLLAR;
-      fprintf (stderr, "W_HASDOLLAR%s", f ? "|" : "");
-    }
-  fprintf (stderr, "\n");
-  fflush (stderr);
-}
-#endif
-
-#ifdef INCLUDE_UNUSED
-static char *
-quoted_substring (string, start, end)
-     char *string;
-     int start, end;
-{
-  register int len, l;
-  register char *result, *s, *r;
-
-  len = end - start;
-
-  /* Move to string[start], skipping quoted characters. */
-  for (s = string, l = 0; *s && l < start; )
-    {
-      if (*s == CTLESC)
-       {
-         s++;
-         continue;
-       }
-      l++;
-      if (*s == 0)
-       break;
-    }
-
-  r = result = (char *)xmalloc (2*len + 1);      /* save room for quotes */
-
-  /* Copy LEN characters, including quote characters. */
-  s = string + l;
-  for (l = 0; l < len; s++)
-    {
-      if (*s == CTLESC)
-       *r++ = *s++;
-      *r++ = *s;
-      l++;
-      if (*s == 0)
-       break;
-    }
-  *r = '\0';
-  return result;
-}
-#endif
-
-#ifdef INCLUDE_UNUSED
-/* Return the length of S, skipping over quoted characters */
-static int
-quoted_strlen (s)
-     char *s;
-{
-  register char *p;
-  int i;
-
-  i = 0;
-  for (p = s; *p; p++)
-    {
-      if (*p == CTLESC)
-       {
-         p++;
-         if (*p == 0)
-           return (i + 1);
-       }
-      i++;
-    }
-
-  return i;
-}
-#endif
-
-/* Find the first occurrence of character C in string S, obeying shell
-   quoting rules.  If (FLAGS & ST_BACKSL) is non-zero, backslash-escaped
-   characters are skipped.  If (FLAGS & ST_CTLESC) is non-zero, characters
-   escaped with CTLESC are skipped. */
-static char *
-quoted_strchr (s, c, flags)
-     char *s;
-     int c, flags;
-{
-  register char *p;
-
-  for (p = s; *p; p++)
-    {
-      if (((flags & ST_BACKSL) && *p == '\\')
-           || ((flags & ST_CTLESC) && *p == CTLESC))
-       {
-         p++;
-         if (*p == '\0')
-           return ((char *)NULL);
-         continue;
-       }
-      else if (*p == c)
-       return p;
-    }
-  return ((char *)NULL);
-}
-
-/* Return 1 if CHARACTER appears in an unquoted portion of
-   STRING.  Return 0 otherwise.  CHARACTER must be a single-byte character. */
-static int
-unquoted_member (character, string)
-     int character;
-     char *string;
-{
-  size_t slen;
-  int sindex, c;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string);
-  sindex = 0;
-  while (c = string[sindex])
-    {
-      if (c == character)
-       return (1);
-
-      switch (c)
-       {
-       default:
-         ADVANCE_CHAR (string, slen, sindex);
-         break;
-
-       case '\\':
-         sindex++;
-         if (string[sindex])
-           ADVANCE_CHAR (string, slen, sindex);
-         break;
-
-       case '\'':
-         sindex = skip_single_quoted (string, slen, ++sindex);
-         break;
-
-       case '"':
-         sindex = skip_double_quoted (string, slen, ++sindex);
-         break;
-       }
-    }
-  return (0);
-}
-
-/* Return 1 if SUBSTR appears in an unquoted portion of STRING. */
-static int
-unquoted_substring (substr, string)
-     char *substr, *string;
-{
-  size_t slen;
-  int sindex, c, sublen;
-  DECLARE_MBSTATE;
-
-  if (substr == 0 || *substr == '\0')
-    return (0);
-
-  slen = strlen (string);
-  sublen = strlen (substr);
-  for (sindex = 0; c = string[sindex]; )
-    {
-      if (STREQN (string + sindex, substr, sublen))
-       return (1);
-
-      switch (c)
-       {
-       case '\\':
-         sindex++;
-
-         if (string[sindex])
-           ADVANCE_CHAR (string, slen, sindex);
-         break;
-
-       case '\'':
-         sindex = skip_single_quoted (string, slen, ++sindex);
-         break;
-
-       case '"':
-         sindex = skip_double_quoted (string, slen, ++sindex);
-         break;
-
-       default:
-         ADVANCE_CHAR (string, slen, sindex);
-         break;
-       }
-    }
-  return (0);
-}
-
-/* Most of the substitutions must be done in parallel.  In order
-   to avoid using tons of unclear goto's, I have some functions
-   for manipulating malloc'ed strings.  They all take INDX, a
-   pointer to an integer which is the offset into the string
-   where manipulation is taking place.  They also take SIZE, a
-   pointer to an integer which is the current length of the
-   character array for this string. */
-
-/* Append SOURCE to TARGET at INDEX.  SIZE is the current amount
-   of space allocated to TARGET.  SOURCE can be NULL, in which
-   case nothing happens.  Gets rid of SOURCE by freeing it.
-   Returns TARGET in case the location has changed. */
-INLINE char *
-sub_append_string (source, target, indx, size)
-     char *source, *target;
-     int *indx, *size;
-{
-  if (source)
-    {
-      int srclen, n;
-
-      srclen = STRLEN (source);
-      if (srclen >= (int)(*size - *indx))
-       {
-         n = srclen + *indx;
-         n = (n + DEFAULT_ARRAY_SIZE) - (n % DEFAULT_ARRAY_SIZE);
-         target = (char *)xrealloc (target, (*size = n));
-       }
-
-      FASTCOPY (source, target + *indx, srclen);
-      *indx += srclen;
-      target[*indx] = '\0';
-
-      free (source);
-    }
-  return (target);
-}
-
-#if 0
-/* UNUSED */
-/* Append the textual representation of NUMBER to TARGET.
-   INDX and SIZE are as in SUB_APPEND_STRING. */
-char *
-sub_append_number (number, target, indx, size)
-     intmax_t number;
-     int *indx, *size;
-     char *target;
-{
-  char *temp;
-
-  temp = itos (number);
-  return (sub_append_string (temp, target, indx, size));
-}
-#endif
-
-/* Extract a substring from STRING, starting at SINDEX and ending with
-   one of the characters in CHARLIST.  Don't make the ending character
-   part of the string.  Leave SINDEX pointing at the ending character.
-   Understand about backslashes in the string.  If (flags & SX_VARNAME)
-   is non-zero, and array variables have been compiled into the shell,
-   everything between a `[' and a corresponding `]' is skipped over.
-   If (flags & SX_NOALLOC) is non-zero, don't return the substring, just
-   update SINDEX.  If (flags & SX_REQMATCH) is non-zero, the string must
-   contain a closing character from CHARLIST. */
-static char *
-string_extract (string, sindex, charlist, flags)
-     char *string;
-     int *sindex;
-     char *charlist;
-     int flags;
-{
-  register int c, i;
-  int found;
-  size_t slen;
-  char *temp;
-  DECLARE_MBSTATE;
-
-  slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0;
-  i = *sindex;
-  found = 0;
-  while (c = string[i])
-    {
-      if (c == '\\')
-       {
-         if (string[i + 1])
-           i++;
-         else
-           break;
-       }
-#if defined (ARRAY_VARS)
-      else if ((flags & SX_VARNAME) && c == '[')
-       {
-         int ni;
-         /* If this is an array subscript, skip over it and continue. */
-         ni = skipsubscript (string, i, 0);
-         if (string[ni] == ']')
-           i = ni;
-       }
-#endif
-      else if (MEMBER (c, charlist))
-       {
-         found = 1;
-         break;
-       }
-
-      ADVANCE_CHAR (string, slen, i);
-    }
-
-  /* If we had to have a matching delimiter and didn't find one, return an
-     error and let the caller deal with it. */
-  if ((flags & SX_REQMATCH) && found == 0)
-    {
-      *sindex = i;
-      return (&extract_string_error);
-    }
-  
-  temp = (flags & SX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i);
-  *sindex = i;
-  
-  return (temp);
-}
-
-/* Extract the contents of STRING as if it is enclosed in double quotes.
-   SINDEX, when passed in, is the offset of the character immediately
-   following the opening double quote; on exit, SINDEX is left pointing after
-   the closing double quote.  If STRIPDQ is non-zero, unquoted double
-   quotes are stripped and the string is terminated by a null byte.
-   Backslashes between the embedded double quotes are processed.  If STRIPDQ
-   is zero, an unquoted `"' terminates the string. */
-static char *
-string_extract_double_quoted (string, sindex, stripdq)
-     char *string;
-     int *sindex, stripdq;
-{
-  size_t slen;
-  char *send;
-  int j, i, t;
-  unsigned char c;
-  char *temp, *ret;            /* The new string we return. */
-  int pass_next, backquote, si;        /* State variables for the machine. */
-  int dquote;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string + *sindex) + *sindex;
-  send = string + slen;
-
-  pass_next = backquote = dquote = 0;
-  temp = (char *)xmalloc (1 + slen - *sindex);
-
-  j = 0;
-  i = *sindex;
-  while (c = string[i])
-    {
-      /* Process a character that was quoted by a backslash. */
-      if (pass_next)
-       {
-         /* Posix.2 sez:
-
-            ``The backslash shall retain its special meaning as an escape
-            character only when followed by one of the characters:
-               $       `       "       \       <newline>''.
-
-            If STRIPDQ is zero, we handle the double quotes here and let
-            expand_word_internal handle the rest.  If STRIPDQ is non-zero,
-            we have already been through one round of backslash stripping,
-            and want to strip these backslashes only if DQUOTE is non-zero,
-            indicating that we are inside an embedded double-quoted string. */
-
-            /* If we are in an embedded quoted string, then don't strip
-               backslashes before characters for which the backslash
-               retains its special meaning, but remove backslashes in
-               front of other characters.  If we are not in an
-               embedded quoted string, don't strip backslashes at all.
-               This mess is necessary because the string was already
-               surrounded by double quotes (and sh has some really weird
-               quoting rules).
-               The returned string will be run through expansion as if
-               it were double-quoted. */
-         if ((stripdq == 0 && c != '"') ||
-             (stripdq && ((dquote && (sh_syntaxtab[c] & CBSDQUOTE)) || dquote == 0)))
-           temp[j++] = '\\';
-         pass_next = 0;
-
-add_one_character:
-         COPY_CHAR_I (temp, j, string, send, i);
-         continue;
-       }
-
-      /* A backslash protects the next character.  The code just above
-        handles preserving the backslash in front of any character but
-        a double quote. */
-      if (c == '\\')
-       {
-         pass_next++;
-         i++;
-         continue;
-       }
-
-      /* Inside backquotes, ``the portion of the quoted string from the
-        initial backquote and the characters up to the next backquote
-        that is not preceded by a backslash, having escape characters
-        removed, defines that command''. */
-      if (backquote)
-       {
-         if (c == '`')
-           backquote = 0;
-         temp[j++] = c;
-         i++;
-         continue;
-       }
-
-      if (c == '`')
-       {
-         temp[j++] = c;
-         backquote++;
-         i++;
-         continue;
-       }
-
-      /* Pass everything between `$(' and the matching `)' or a quoted
-        ${ ... } pair through according to the Posix.2 specification. */
-      if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
-       {
-         int free_ret = 1;
-
-         si = i + 2;
-         if (string[i + 1] == LPAREN)
-           ret = extract_command_subst (string, &si, 0);
-         else
-           ret = extract_dollar_brace_string (string, &si, 1, 0);
-
-         temp[j++] = '$';
-         temp[j++] = string[i + 1];
-
-         /* Just paranoia; ret will not be 0 unless no_longjmp_on_fatal_error
-            is set. */
-         if (ret == 0 && no_longjmp_on_fatal_error)
-           {
-             free_ret = 0;
-             ret = string + i + 2;
-           }
-
-         for (t = 0; ret[t]; t++, j++)
-           temp[j] = ret[t];
-         temp[j] = string[si];
-
-         if (string[si])
-           {
-             j++;
-             i = si + 1;
-           }
-         else
-           i = si;
-
-         if (free_ret)
-           free (ret);
-         continue;
-       }
-
-      /* Add any character but a double quote to the quoted string we're
-        accumulating. */
-      if (c != '"')
-       goto add_one_character;
-
-      /* c == '"' */
-      if (stripdq)
-       {
-         dquote ^= 1;
-         i++;
-         continue;
-       }
-
-      break;
-    }
-  temp[j] = '\0';
-
-  /* Point to after the closing quote. */
-  if (c)
-    i++;
-  *sindex = i;
-
-  return (temp);
-}
-
-/* This should really be another option to string_extract_double_quoted. */
-static int
-skip_double_quoted (string, slen, sind)
-     char *string;
-     size_t slen;
-     int sind;
-{
-  int c, i;
-  char *ret;
-  int pass_next, backquote, si;
-  DECLARE_MBSTATE;
-
-  pass_next = backquote = 0;
-  i = sind;
-  while (c = string[i])
-    {
-      if (pass_next)
-       {
-         pass_next = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (c == '\\')
-       {
-         pass_next++;
-         i++;
-         continue;
-       }
-      else if (backquote)
-       {
-         if (c == '`')
-           backquote = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (c == '`')
-       {
-         backquote++;
-         i++;
-         continue;
-       }
-      else if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
-       {
-         si = i + 2;
-         if (string[i + 1] == LPAREN)
-           ret = extract_command_subst (string, &si, SX_NOALLOC);
-         else
-           ret = extract_dollar_brace_string (string, &si, 1, SX_NOALLOC);
-
-         i = si + 1;
-         continue;
-       }
-      else if (c != '"')
-       {
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else
-       break;
-    }
-
-  if (c)
-    i++;
-
-  return (i);
-}
-
-/* Extract the contents of STRING as if it is enclosed in single quotes.
-   SINDEX, when passed in, is the offset of the character immediately
-   following the opening single quote; on exit, SINDEX is left pointing after
-   the closing single quote. */
-static inline char *
-string_extract_single_quoted (string, sindex)
-     char *string;
-     int *sindex;
-{
-  register int i;
-  size_t slen;
-  char *t;
-  DECLARE_MBSTATE;
-
-  /* Don't need slen for ADVANCE_CHAR unless multibyte chars possible. */
-  slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0;
-  i = *sindex;
-  while (string[i] && string[i] != '\'')
-    ADVANCE_CHAR (string, slen, i);
-
-  t = substring (string, *sindex, i);
-
-  if (string[i])
-    i++;
-  *sindex = i;
-
-  return (t);
-}
-
-static inline int
-skip_single_quoted (string, slen, sind)
-     const char *string;
-     size_t slen;
-     int sind;
-{
-  register int c;
-  DECLARE_MBSTATE;
-
-  c = sind;
-  while (string[c] && string[c] != '\'')
-    ADVANCE_CHAR (string, slen, c);
-
-  if (string[c])
-    c++;
-  return c;
-}
-
-/* Just like string_extract, but doesn't hack backslashes or any of
-   that other stuff.  Obeys CTLESC quoting.  Used to do splitting on $IFS. */
-static char *
-string_extract_verbatim (string, slen, sindex, charlist, flags)
-     char *string;
-     size_t slen;
-     int *sindex;
-     char *charlist;
-     int flags;
-{
-  register int i;
-#if defined (HANDLE_MULTIBYTE)
-  size_t clen;
-  wchar_t *wcharlist;
-#endif
-  int c;
-  char *temp;
-  DECLARE_MBSTATE;
-
-  if (charlist[0] == '\'' && charlist[1] == '\0')
-    {
-      temp = string_extract_single_quoted (string, sindex);
-      --*sindex;       /* leave *sindex at separator character */
-      return temp;
-    }
-
-  i = *sindex;
-#if 0
-  /* See how the MBLEN and ADVANCE_CHAR macros work to understand why we need
-     this only if MB_CUR_MAX > 1. */
-  slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 1;
-#endif
-#if defined (HANDLE_MULTIBYTE)
-  clen = strlen (charlist);
-  wcharlist = 0;
-#endif
-  while (c = string[i])
-    {
-#if defined (HANDLE_MULTIBYTE)
-      size_t mblength;
-#endif
-      if ((flags & SX_NOCTLESC) == 0 && c == CTLESC)
-       {
-         i += 2;
-         continue;
-       }
-      /* Even if flags contains SX_NOCTLESC, we let CTLESC quoting CTLNUL
-        through, to protect the CTLNULs from later calls to
-        remove_quoted_nulls. */
-      else if ((flags & SX_NOESCCTLNUL) == 0 && c == CTLESC && string[i+1] == CTLNUL)
-       {
-         i += 2;
-         continue;
-       }
-
-#if defined (HANDLE_MULTIBYTE)
-      mblength = MBLEN (string + i, slen - i);
-      if (mblength > 1)
-       {
-         wchar_t wc;
-         mblength = mbtowc (&wc, string + i, slen - i);
-         if (MB_INVALIDCH (mblength))
-           {
-             if (MEMBER (c, charlist))
-               break;
-           }
-         else
-           {
-             if (wcharlist == 0)
-               {
-                 size_t len;
-                 len = mbstowcs (wcharlist, charlist, 0);
-                 if (len == -1)
-                   len = 0;
-                 wcharlist = (wchar_t *)xmalloc (sizeof (wchar_t) * (len + 1));
-                 mbstowcs (wcharlist, charlist, len + 1);
-               }
-
-             if (wcschr (wcharlist, wc))
-               break;
-           }
-       }
-      else             
-#endif
-      if (MEMBER (c, charlist))
-       break;
-
-      ADVANCE_CHAR (string, slen, i);
-    }
-
-#if defined (HANDLE_MULTIBYTE)
-  FREE (wcharlist);
-#endif
-
-  temp = substring (string, *sindex, i);
-  *sindex = i;
-
-  return (temp);
-}
-
-/* Extract the $( construct in STRING, and return a new string.
-   Start extracting at (SINDEX) as if we had just seen "$(".
-   Make (SINDEX) get the position of the matching ")". )
-   XFLAGS is additional flags to pass to other extraction functions, */
-char *
-extract_command_subst (string, sindex, xflags)
-     char *string;
-     int *sindex;
-     int xflags;
-{
-  if (string[*sindex] == LPAREN)
-    return (extract_delimited_string (string, sindex, "$(", "(", ")", xflags|SX_COMMAND)); /*)*/
-  else
-    {
-      xflags |= (no_longjmp_on_fatal_error ? SX_NOLONGJMP : 0);
-      return (xparse_dolparen (string, string+*sindex, sindex, xflags));
-    }
-}
-
-/* Extract the $[ construct in STRING, and return a new string. (])
-   Start extracting at (SINDEX) as if we had just seen "$[".
-   Make (SINDEX) get the position of the matching "]". */
-char *
-extract_arithmetic_subst (string, sindex)
-     char *string;
-     int *sindex;
-{
-  return (extract_delimited_string (string, sindex, "$[", "[", "]", 0)); /*]*/
-}
-
-#if defined (PROCESS_SUBSTITUTION)
-/* Extract the <( or >( construct in STRING, and return a new string.
-   Start extracting at (SINDEX) as if we had just seen "<(".
-   Make (SINDEX) get the position of the matching ")". */ /*))*/
-char *
-extract_process_subst (string, starter, sindex)
-     char *string;
-     char *starter;
-     int *sindex;
-{
-  return (extract_delimited_string (string, sindex, starter, "(", ")", 0));
-}
-#endif /* PROCESS_SUBSTITUTION */
-
-#if defined (ARRAY_VARS)
-/* This can be fooled by unquoted right parens in the passed string. If
-   each caller verifies that the last character in STRING is a right paren,
-   we don't even need to call extract_delimited_string. */
-char *
-extract_array_assignment_list (string, sindex)
-     char *string;
-     int *sindex;
-{
-  int slen;
-  char *ret;
-
-  slen = strlen (string);      /* ( */
-  if (string[slen - 1] == ')')
-   {
-      ret = substring (string, *sindex, slen - 1);
-      *sindex = slen - 1;
-      return ret;
-    }
-  return 0;  
-}
-#endif
-
-/* Extract and create a new string from the contents of STRING, a
-   character string delimited with OPENER and CLOSER.  SINDEX is
-   the address of an int describing the current offset in STRING;
-   it should point to just after the first OPENER found.  On exit,
-   SINDEX gets the position of the last character of the matching CLOSER.
-   If OPENER is more than a single character, ALT_OPENER, if non-null,
-   contains a character string that can also match CLOSER and thus
-   needs to be skipped. */
-static char *
-extract_delimited_string (string, sindex, opener, alt_opener, closer, flags)
-     char *string;
-     int *sindex;
-     char *opener, *alt_opener, *closer;
-     int flags;
-{
-  int i, c, si;
-  size_t slen;
-  char *t, *result;
-  int pass_character, nesting_level, in_comment;
-  int len_closer, len_opener, len_alt_opener;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string + *sindex) + *sindex;
-  len_opener = STRLEN (opener);
-  len_alt_opener = STRLEN (alt_opener);
-  len_closer = STRLEN (closer);
-
-  pass_character = in_comment = 0;
-
-  nesting_level = 1;
-  i = *sindex;
-
-  while (nesting_level)
-    {
-      c = string[i];
-
-      if (c == 0)
-       break;
-
-      if (in_comment)
-       {
-         if (c == '\n')
-           in_comment = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-
-      if (pass_character)      /* previous char was backslash */
-       {
-         pass_character = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-
-      /* Not exactly right yet; should handle shell metacharacters and
-        multibyte characters, too.  See COMMENT_BEGIN define in parse.y */
-      if ((flags & SX_COMMAND) && c == '#' && (i == 0 || string[i - 1] == '\n' || shellblank (string[i - 1])))
-       {
-          in_comment = 1;
-          ADVANCE_CHAR (string, slen, i);
-          continue;
-       }
-        
-      if (c == CTLESC || c == '\\')
-       {
-         pass_character++;
-         i++;
-         continue;
-       }
-
-      /* Process a nested OPENER. */
-      if (STREQN (string + i, opener, len_opener))
-       {
-         si = i + len_opener;
-         t = extract_delimited_string (string, &si, opener, alt_opener, closer, flags|SX_NOALLOC);
-         i = si + 1;
-         continue;
-       }
-
-      /* Process a nested ALT_OPENER */
-      if (len_alt_opener && STREQN (string + i, alt_opener, len_alt_opener))
-       {
-         si = i + len_alt_opener;
-         t = extract_delimited_string (string, &si, alt_opener, alt_opener, closer, flags|SX_NOALLOC);
-         i = si + 1;
-         continue;
-       }
-
-      /* If the current substring terminates the delimited string, decrement
-        the nesting level. */
-      if (STREQN (string + i, closer, len_closer))
-       {
-         i += len_closer - 1;  /* move to last byte of the closer */
-         nesting_level--;
-         if (nesting_level == 0)
-           break;
-       }
-
-      /* Pass old-style command substitution through verbatim. */
-      if (c == '`')
-       {
-         si = i + 1;
-         t = string_extract (string, &si, "`", flags|SX_NOALLOC);
-         i = si + 1;
-         continue;
-       }
-
-      /* Pass single-quoted and double-quoted strings through verbatim. */
-      if (c == '\'' || c == '"')
-       {
-         si = i + 1;
-         i = (c == '\'') ? skip_single_quoted (string, slen, si)
-                         : skip_double_quoted (string, slen, si);
-         continue;
-       }
-
-      /* move past this character, which was not special. */
-      ADVANCE_CHAR (string, slen, i);
-    }
-
-  if (c == 0 && nesting_level)
-    {
-      if (no_longjmp_on_fatal_error == 0)
-       {
-         report_error (_("bad substitution: no closing `%s' in %s"), closer, string);
-         last_command_exit_value = EXECUTION_FAILURE;
-         exp_jump_to_top_level (DISCARD);
-       }
-      else
-       {
-         *sindex = i;
-         return (char *)NULL;
-       }
-    }
-
-  si = i - *sindex - len_closer + 1;
-  if (flags & SX_NOALLOC)
-    result = (char *)NULL;
-  else    
-    {
-      result = (char *)xmalloc (1 + si);
-      strncpy (result, string + *sindex, si);
-      result[si] = '\0';
-    }
-  *sindex = i;
-
-  return (result);
-}
-
-/* Extract a parameter expansion expression within ${ and } from STRING.
-   Obey the Posix.2 rules for finding the ending `}': count braces while
-   skipping over enclosed quoted strings and command substitutions.
-   SINDEX is the address of an int describing the current offset in STRING;
-   it should point to just after the first `{' found.  On exit, SINDEX
-   gets the position of the matching `}'.  QUOTED is non-zero if this
-   occurs inside double quotes. */
-/* XXX -- this is very similar to extract_delimited_string -- XXX */
-static char *
-extract_dollar_brace_string (string, sindex, quoted, flags)
-     char *string;
-     int *sindex, quoted, flags;
-{
-  register int i, c;
-  size_t slen;
-  int pass_character, nesting_level, si;
-  char *result, *t;
-  DECLARE_MBSTATE;
-
-  pass_character = 0;
-  nesting_level = 1;
-  slen = strlen (string + *sindex) + *sindex;
-
-  i = *sindex;
-  while (c = string[i])
-    {
-      if (pass_character)
-       {
-         pass_character = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-
-      /* CTLESCs and backslashes quote the next character. */
-      if (c == CTLESC || c == '\\')
-       {
-         pass_character++;
-         i++;
-         continue;
-       }
-
-      if (string[i] == '$' && string[i+1] == LBRACE)
-       {
-         nesting_level++;
-         i += 2;
-         continue;
-       }
-
-      if (c == RBRACE)
-       {
-         nesting_level--;
-         if (nesting_level == 0)
-           break;
-         i++;
-         continue;
-       }
-
-      /* Pass the contents of old-style command substitutions through
-        verbatim. */
-      if (c == '`')
-       {
-         si = i + 1;
-         t = string_extract (string, &si, "`", flags|SX_NOALLOC);
-         i = si + 1;
-         continue;
-       }
-
-      /* Pass the contents of new-style command substitutions and
-        arithmetic substitutions through verbatim. */
-      if (string[i] == '$' && string[i+1] == LPAREN)
-       {
-         si = i + 2;
-         t = extract_command_subst (string, &si, flags|SX_NOALLOC);
-         i = si + 1;
-         continue;
-       }
-
-      /* Pass the contents of single-quoted and double-quoted strings
-        through verbatim. */
-      if (c == '\'' || c == '"')
-       {
-         si = i + 1;
-         i = (c == '\'') ? skip_single_quoted (string, slen, si)
-                         : skip_double_quoted (string, slen, si);
-         /* skip_XXX_quoted leaves index one past close quote */
-         continue;
-       }
-
-      /* move past this character, which was not special. */
-      ADVANCE_CHAR (string, slen, i);
-    }
-
-  if (c == 0 && nesting_level)
-    {
-      if (no_longjmp_on_fatal_error == 0)
-       {                       /* { */
-         report_error (_("bad substitution: no closing `%s' in %s"), "}", string);
-         last_command_exit_value = EXECUTION_FAILURE;
-         exp_jump_to_top_level (DISCARD);
-       }
-      else
-       {
-         *sindex = i;
-         return ((char *)NULL);
-       }
-    }
-
-  result = (flags & SX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i);
-  *sindex = i;
-
-  return (result);
-}
-
-/* Remove backslashes which are quoting backquotes from STRING.  Modifies
-   STRING, and returns a pointer to it. */
-char *
-de_backslash (string)
-     char *string;
-{
-  register size_t slen;
-  register int i, j, prev_i;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string);
-  i = j = 0;
-
-  /* Loop copying string[i] to string[j], i >= j. */
-  while (i < slen)
-    {
-      if (string[i] == '\\' && (string[i + 1] == '`' || string[i + 1] == '\\' ||
-                             string[i + 1] == '$'))
-       i++;
-      prev_i = i;
-      ADVANCE_CHAR (string, slen, i);
-      if (j < prev_i)
-       do string[j++] = string[prev_i++]; while (prev_i < i);
-      else
-       j = i;
-    }
-  string[j] = '\0';
-
-  return (string);
-}
-
-#if 0
-/*UNUSED*/
-/* Replace instances of \! in a string with !. */
-void
-unquote_bang (string)
-     char *string;
-{
-  register int i, j;
-  register char *temp;
-
-  temp = (char *)xmalloc (1 + strlen (string));
-
-  for (i = 0, j = 0; (temp[j] = string[i]); i++, j++)
-    {
-      if (string[i] == '\\' && string[i + 1] == '!')
-       {
-         temp[j] = '!';
-         i++;
-       }
-    }
-  strcpy (string, temp);
-  free (temp);
-}
-#endif
-
-#define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
-
-/* This function assumes s[i] == open; returns with s[ret] == close; used to
-   parse array subscripts.  FLAGS & 1 means to not attempt to skip over
-   matched pairs of quotes or backquotes, or skip word expansions; it is
-   intended to be used after expansion has been performed and during final
-   assignment parsing (see arrayfunc.c:assign_compound_array_list()). */
-static int
-skip_matched_pair (string, start, open, close, flags)
-     const char *string;
-     int start, open, close, flags;
-{
-  int i, pass_next, backq, si, c, count;
-  size_t slen;
-  char *temp, *ss;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string + start) + start;
-  no_longjmp_on_fatal_error = 1;
-
-  i = start + 1;               /* skip over leading bracket */
-  count = 1;
-  pass_next = backq = 0;
-  ss = (char *)string;
-  while (c = string[i])
-    {
-      if (pass_next)
-       {
-         pass_next = 0;
-         if (c == 0)
-           CQ_RETURN(i);
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (c == '\\')
-       {
-         pass_next = 1;
-         i++;
-         continue;
-       }
-      else if (backq)
-       {
-         if (c == '`')
-           backq = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if ((flags & 1) == 0 && c == '`')
-       {
-         backq = 1;
-         i++;
-         continue;
-       }
-      else if ((flags & 1) == 0 && c == open)
-       {
-         count++;
-         i++;
-         continue;
-       }
-      else if (c == close)
-       {
-         count--;
-         if (count == 0)
-           break;
-         i++;
-         continue;
-       }
-      else if ((flags & 1) == 0 && (c == '\'' || c == '"'))
-       {
-         i = (c == '\'') ? skip_single_quoted (ss, slen, ++i)
-                         : skip_double_quoted (ss, slen, ++i);
-         /* no increment, the skip functions increment past the closing quote. */
-       }
-      else if ((flags&1) == 0 && c == '$' && (string[i+1] == LPAREN || string[i+1] == LBRACE))
-       {
-         si = i + 2;
-         if (string[si] == '\0')
-           CQ_RETURN(si);
-
-         if (string[i+1] == LPAREN)
-           temp = extract_delimited_string (ss, &si, "$(", "(", ")", SX_NOALLOC|SX_COMMAND); /* ) */
-         else
-           temp = extract_dollar_brace_string (ss, &si, 0, SX_NOALLOC);
-         i = si;
-         if (string[i] == '\0')        /* don't increment i past EOS in loop */
-           break;
-         i++;
-         continue;
-       }
-      else
-       ADVANCE_CHAR (string, slen, i);
-    }
-
-  CQ_RETURN(i);
-}
-
-#if defined (ARRAY_VARS)
-int
-skipsubscript (string, start, flags)
-     const char *string;
-     int start, flags;
-{
-  return (skip_matched_pair (string, start, '[', ']', flags));
-}
-#endif
-
-/* Skip characters in STRING until we find a character in DELIMS, and return
-   the index of that character.  START is the index into string at which we
-   begin.  This is similar in spirit to strpbrk, but it returns an index into
-   STRING and takes a starting index.  This little piece of code knows quite
-   a lot of shell syntax.  It's very similar to skip_double_quoted and other
-   functions of that ilk. */
-int
-skip_to_delim (string, start, delims, flags)
-     char *string;
-     int start;
-     char *delims;
-     int flags;
-{
-  int i, pass_next, backq, si, c, invert, skipquote, skipcmd;
-  size_t slen;
-  char *temp;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string + start) + start;
-  if (flags & SD_NOJMP)
-    no_longjmp_on_fatal_error = 1;
-  invert = (flags & SD_INVERT);
-  skipcmd = (flags & SD_NOSKIPCMD) == 0;
-
-  i = start;
-  pass_next = backq = 0;
-  while (c = string[i])
-    {
-      /* If this is non-zero, we should not let quote characters be delimiters
-        and the current character is a single or double quote.  We should not
-        test whether or not it's a delimiter until after we skip single- or
-        double-quoted strings. */
-      skipquote = ((flags & SD_NOQUOTEDELIM) && (c == '\'' || c =='"'));
-      if (pass_next)
-       {
-         pass_next = 0;
-         if (c == 0)
-           CQ_RETURN(i);
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (c == '\\')
-       {
-         pass_next = 1;
-         i++;
-         continue;
-       }
-      else if (backq)
-       {
-         if (c == '`')
-           backq = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (c == '`')
-       {
-         backq = 1;
-         i++;
-         continue;
-       }
-      else if (skipquote == 0 && invert == 0 && member (c, delims))
-       break;
-      else if (c == '\'' || c == '"')
-       {
-         i = (c == '\'') ? skip_single_quoted (string, slen, ++i)
-                         : skip_double_quoted (string, slen, ++i);
-         /* no increment, the skip functions increment past the closing quote. */
-       }
-      else if (c == '$' && ((skipcmd && string[i+1] == LPAREN) || string[i+1] == LBRACE))
-       {
-         si = i + 2;
-         if (string[si] == '\0')
-           CQ_RETURN(si);
-
-         if (string[i+1] == LPAREN)
-           temp = extract_delimited_string (string, &si, "$(", "(", ")", SX_NOALLOC|SX_COMMAND); /* ) */
-         else
-           temp = extract_dollar_brace_string (string, &si, 0, SX_NOALLOC);
-         i = si;
-         if (string[i] == '\0')        /* don't increment i past EOS in loop */
-           break;
-         i++;
-         continue;
-       }
-#if defined (PROCESS_SUBSTITUTION)
-      else if (skipcmd && (c == '<' || c == '>') && string[i+1] == LPAREN)
-       {
-         si = i + 2;
-         if (string[si] == '\0')
-           CQ_RETURN(si);
-         temp = extract_process_subst (string, (c == '<') ? "<(" : ">(", &si);
-         i = si;
-         if (string[i] == '\0')
-           break;
-         i++;
-         continue;
-       }
-#endif /* PROCESS_SUBSTITUTION */
-      else if ((skipquote || invert) && (member (c, delims) == 0))
-       break;
-      else
-       ADVANCE_CHAR (string, slen, i);
-    }
-
-  CQ_RETURN(i);
-}
-
-#if defined (READLINE)
-/* Return 1 if the portion of STRING ending at EINDEX is quoted (there is
-   an unclosed quoted string), or if the character at EINDEX is quoted
-   by a backslash. NO_LONGJMP_ON_FATAL_ERROR is used to flag that the various
-   single and double-quoted string parsing functions should not return an
-   error if there are unclosed quotes or braces.  The characters that this
-   recognizes need to be the same as the contents of
-   rl_completer_quote_characters. */
-
-int
-char_is_quoted (string, eindex)
-     char *string;
-     int eindex;
-{
-  int i, pass_next, c;
-  size_t slen;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string);
-  no_longjmp_on_fatal_error = 1;
-  i = pass_next = 0;
-  while (i <= eindex)
-    {
-      c = string[i];
-
-      if (pass_next)
-       {
-         pass_next = 0;
-         if (i >= eindex)      /* XXX was if (i >= eindex - 1) */
-           CQ_RETURN(1);
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (c == '\\')
-       {
-         pass_next = 1;
-         i++;
-         continue;
-       }
-      else if (c == '\'' || c == '"')
-       {
-         i = (c == '\'') ? skip_single_quoted (string, slen, ++i)
-                         : skip_double_quoted (string, slen, ++i);
-         if (i > eindex)
-           CQ_RETURN(1);
-         /* no increment, the skip_xxx functions go one past end */
-       }
-      else
-       ADVANCE_CHAR (string, slen, i);
-    }
-
-  CQ_RETURN(0);
-}
-
-int
-unclosed_pair (string, eindex, openstr)
-     char *string;
-     int eindex;
-     char *openstr;
-{
-  int i, pass_next, openc, olen;
-  size_t slen;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string);
-  olen = strlen (openstr);
-  i = pass_next = openc = 0;
-  while (i <= eindex)
-    {
-      if (pass_next)
-       {
-         pass_next = 0;
-         if (i >= eindex)      /* XXX was if (i >= eindex - 1) */
-           return 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (string[i] == '\\')
-       {
-         pass_next = 1;
-         i++;
-         continue;
-       }
-      else if (STREQN (string + i, openstr, olen))
-       {
-         openc = 1 - openc;
-         i += olen;
-       }
-      else if (string[i] == '\'' || string[i] == '"')
-       {
-         i = (string[i] == '\'') ? skip_single_quoted (string, slen, i)
-                                 : skip_double_quoted (string, slen, i);
-         if (i > eindex)
-           return 0;
-       }
-      else
-       ADVANCE_CHAR (string, slen, i);
-    }
-  return (openc);
-}
-
-/* Split STRING (length SLEN) at DELIMS, and return a WORD_LIST with the
-   individual words.  If DELIMS is NULL, the current value of $IFS is used
-   to split the string, and the function follows the shell field splitting
-   rules.  SENTINEL is an index to look for.  NWP, if non-NULL,
-   gets the number of words in the returned list.  CWP, if non-NULL, gets
-   the index of the word containing SENTINEL.  Non-whitespace chars in
-   DELIMS delimit separate fields. */
-WORD_LIST *
-split_at_delims (string, slen, delims, sentinel, flags, nwp, cwp)
-     char *string;
-     int slen;
-     char *delims;
-     int sentinel, flags;
-     int *nwp, *cwp;
-{
-  int ts, te, i, nw, cw, ifs_split, dflags;
-  char *token, *d, *d2;
-  WORD_LIST *ret, *tl;
-
-  if (string == 0 || *string == '\0')
-    {
-      if (nwp)
-       *nwp = 0;
-      if (cwp)
-       *cwp = 0;       
-      return ((WORD_LIST *)NULL);
-    }
-
-  d = (delims == 0) ? ifs_value : delims;
-  ifs_split = delims == 0;
-
-  /* Make d2 the non-whitespace characters in delims */
-  d2 = 0;
-  if (delims)
-    {
-      size_t slength;
-#if defined (HANDLE_MULTIBYTE)
-      size_t mblength = 1;
-#endif
-      DECLARE_MBSTATE;
-
-      slength = strlen (delims);
-      d2 = (char *)xmalloc (slength + 1);
-      i = ts = 0;
-      while (delims[i])
-       {
-#if defined (HANDLE_MULTIBYTE)
-         mbstate_t state_bak;
-         state_bak = state;
-         mblength = MBRLEN (delims + i, slength, &state);
-         if (MB_INVALIDCH (mblength))
-           state = state_bak;
-         else if (mblength > 1)
-           {
-             memcpy (d2 + ts, delims + i, mblength);
-             ts += mblength;
-             i += mblength;
-             slength -= mblength;
-             continue;
-           }
-#endif
-         if (whitespace (delims[i]) == 0)
-           d2[ts++] = delims[i];
-
-         i++;
-         slength--;
-       }
-      d2[ts] = '\0';
-    }
-
-  ret = (WORD_LIST *)NULL;
-
-  /* Remove sequences of whitespace characters at the start of the string, as
-     long as those characters are delimiters. */
-  for (i = 0; member (string[i], d) && spctabnl (string[i]); i++)
-    ;
-  if (string[i] == '\0')
-    return (ret);
-
-  ts = i;
-  nw = 0;
-  cw = -1;
-  dflags = flags|SD_NOJMP;
-  while (1)
-    {
-      te = skip_to_delim (string, ts, d, dflags);
-
-      /* If we have a non-whitespace delimiter character, use it to make a
-        separate field.  This is just about what $IFS splitting does and
-        is closer to the behavior of the shell parser. */
-      if (ts == te && d2 && member (string[ts], d2))
-       {
-         te = ts + 1;
-         /* If we're using IFS splitting, the non-whitespace delimiter char
-            and any additional IFS whitespace delimits a field. */
-         if (ifs_split)
-           while (member (string[te], d) && spctabnl (string[te]))
-             te++;
-         else
-           while (member (string[te], d2))
-             te++;
-       }
-
-      token = substring (string, ts, te);
-
-      ret = add_string_to_list (token, ret);
-      free (token);
-      nw++;
-
-      if (sentinel >= ts && sentinel <= te)
-       cw = nw;
-
-      /* If the cursor is at whitespace just before word start, set the
-        sentinel word to the current word. */
-      if (cwp && cw == -1 && sentinel == ts-1)
-       cw = nw;
-
-      /* If the cursor is at whitespace between two words, make a new, empty
-        word, add it before (well, after, since the list is in reverse order)
-        the word we just added, and set the current word to that one. */
-      if (cwp && cw == -1 && sentinel < ts)
-       {
-         tl = make_word_list (make_word (""), ret->next);
-         ret->next = tl;
-         cw = nw;
-         nw++;
-       }
-
-      if (string[te] == 0)
-       break;
-
-      i = te;
-      while (member (string[i], d) && (ifs_split || spctabnl(string[i])))
-       i++;
-
-      if (string[i])
-       ts = i;
-      else
-       break;
-    }
-
-  /* Special case for SENTINEL at the end of STRING.  If we haven't found
-     the word containing SENTINEL yet, and the index we're looking for is at
-     the end of STRING (or past the end of the previously-found token,
-     possible if the end of the line is composed solely of IFS whitespace)
-     add an additional null argument and set the current word pointer to that. */
-  if (cwp && cw == -1 && (sentinel >= slen || sentinel >= te))
-    {
-      if (whitespace (string[sentinel - 1]))
-       {
-         token = "";
-         ret = add_string_to_list (token, ret);
-         nw++;
-       }
-      cw = nw;
-    }
-
-  if (nwp)
-    *nwp = nw;
-  if (cwp)
-    *cwp = cw;
-
-  return (REVERSE_LIST (ret, WORD_LIST *));
-}
-#endif /* READLINE */
-
-#if 0
-/* UNUSED */
-/* Extract the name of the variable to bind to from the assignment string. */
-char *
-assignment_name (string)
-     char *string;
-{
-  int offset;
-  char *temp;
-
-  offset = assignment (string, 0);
-  if (offset == 0)
-    return (char *)NULL;
-  temp = substring (string, 0, offset);
-  return (temp);
-}
-#endif
-
-/* **************************************************************** */
-/*                                                                 */
-/*     Functions to convert strings to WORD_LISTs and vice versa    */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Return a single string of all the words in LIST.  SEP is the separator
-   to put between individual elements of LIST in the output string. */
-char *
-string_list_internal (list, sep)
-     WORD_LIST *list;
-     char *sep;
-{
-  register WORD_LIST *t;
-  char *result, *r;
-  int word_len, sep_len, result_size;
-
-  if (list == 0)
-    return ((char *)NULL);
-
-  /* Short-circuit quickly if we don't need to separate anything. */
-  if (list->next == 0)
-    return (savestring (list->word->word));
-
-  /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */
-  sep_len = STRLEN (sep);
-  result_size = 0;
-
-  for (t = list; t; t = t->next)
-    {
-      if (t != list)
-       result_size += sep_len;
-      result_size += strlen (t->word->word);
-    }
-
-  r = result = (char *)xmalloc (result_size + 1);
-
-  for (t = list; t; t = t->next)
-    {
-      if (t != list && sep_len)
-       {
-         if (sep_len > 1)
-           {
-             FASTCOPY (sep, r, sep_len);
-             r += sep_len;
-           }
-         else
-           *r++ = sep[0];
-       }
-
-      word_len = strlen (t->word->word);
-      FASTCOPY (t->word->word, r, word_len);
-      r += word_len;
-    }
-
-  *r = '\0';
-  return (result);
-}
-
-/* Return a single string of all the words present in LIST, separating
-   each word with a space. */
-char *
-string_list (list)
-     WORD_LIST *list;
-{
-  return (string_list_internal (list, " "));
-}
-
-/* An external interface that can be used by the rest of the shell to
-   obtain a string containing the first character in $IFS.  Handles all
-   the multibyte complications.  If LENP is non-null, it is set to the
-   length of the returned string. */
-char *
-ifs_firstchar (lenp)
-     int *lenp;
-{
-  char *ret;
-  int len;
-
-  ret = xmalloc (MB_LEN_MAX + 1);
-#if defined (HANDLE_MULTIBYTE)
-  if (ifs_firstc_len == 1)
-    {
-      ret[0] = ifs_firstc[0];
-      ret[1] = '\0';
-      len = ret[0] ? 1 : 0;
-    }
-  else
-    {
-      memcpy (ret, ifs_firstc, ifs_firstc_len);
-      ret[len = ifs_firstc_len] = '\0';
-    }
-#else
-  ret[0] = ifs_firstc;
-  ret[1] = '\0';
-  len = ret[0] ? 0 : 1;
-#endif
-
-  if (lenp)
-    *lenp = len;
-
-  return ret;
-}
-
-/* Return a single string of all the words present in LIST, obeying the
-   quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the
-   expansion [of $*] appears within a double quoted string, it expands
-   to a single field with the value of each parameter separated by the
-   first character of the IFS variable, or by a <space> if IFS is unset." */
-char *
-string_list_dollar_star (list)
-     WORD_LIST *list;
-{
-  char *ret;
-#if defined (HANDLE_MULTIBYTE)
-#  if defined (__GNUC__)
-  char sep[MB_CUR_MAX + 1];
-#  else
-  char *sep = 0;
-#  endif
-#else
-  char sep[2];
-#endif
-
-#if defined (HANDLE_MULTIBYTE)
-#  if !defined (__GNUC__)
-  sep = (char *)xmalloc (MB_CUR_MAX + 1);
-#  endif /* !__GNUC__ */
-  if (ifs_firstc_len == 1)
-    {
-      sep[0] = ifs_firstc[0];
-      sep[1] = '\0';
-    }
-  else
-    {
-      memcpy (sep, ifs_firstc, ifs_firstc_len);
-      sep[ifs_firstc_len] = '\0';
-    }
-#else
-  sep[0] = ifs_firstc;
-  sep[1] = '\0';
-#endif
-
-  ret = string_list_internal (list, sep);
-#if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
-  free (sep);
-#endif
-  return ret;
-}
-
-/* Turn $@ into a string.  If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-   is non-zero, the $@ appears within double quotes, and we should quote
-   the list before converting it into a string.  If IFS is unset, and the
-   word is not quoted, we just need to quote CTLESC and CTLNUL characters
-   in the words in the list, because the default value of $IFS is
-   <space><tab><newline>, IFS characters in the words in the list should
-   also be split.  If IFS is null, and the word is not quoted, we need
-   to quote the words in the list to preserve the positional parameters
-   exactly. */
-char *
-string_list_dollar_at (list, quoted)
-     WORD_LIST *list;
-     int quoted;
-{
-  char *ifs, *ret;
-#if defined (HANDLE_MULTIBYTE)
-#  if defined (__GNUC__)
-  char sep[MB_CUR_MAX + 1];
-#  else
-  char *sep = 0;
-#  endif /* !__GNUC__ */
-#else
-  char sep[2];
-#endif
-  WORD_LIST *tlist;
-
-  /* XXX this could just be ifs = ifs_value; */
-  ifs = ifs_var ? value_cell (ifs_var) : (char *)0;
-
-#if defined (HANDLE_MULTIBYTE)
-#  if !defined (__GNUC__)
-  sep = (char *)xmalloc (MB_CUR_MAX + 1);
-#  endif /* !__GNUC__ */
-  if (ifs && *ifs)
-    {
-      if (ifs_firstc_len == 1)
-       {
-         sep[0] = ifs_firstc[0];
-         sep[1] = '\0';
-       }
-      else
-       {
-         memcpy (sep, ifs_firstc, ifs_firstc_len);
-         sep[ifs_firstc_len] = '\0';
-       }
-    }
-  else
-    {
-      sep[0] = ' ';
-      sep[1] = '\0';
-    }
-#else
-  sep[0] = (ifs == 0 || *ifs == 0) ? ' ' : *ifs;
-  sep[1] = '\0';
-#endif
-
-  /* XXX -- why call quote_list if ifs == 0?  we can get away without doing
-     it now that quote_escapes quotes spaces */
-#if 0
-  tlist = ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (ifs && *ifs == 0))
-#else
-  tlist = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES|Q_PATQUOTE))
-#endif
-               ? quote_list (list)
-               : list_quote_escapes (list);
-
-  ret = string_list_internal (tlist, sep);
-#if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
-  free (sep);
-#endif
-  return ret;
-}
-
-/* Turn the positional paramters into a string, understanding quoting and
-   the various subtleties of using the first character of $IFS as the
-   separator.  Calls string_list_dollar_at, string_list_dollar_star, and
-   string_list as appropriate. */
-char *
-string_list_pos_params (pchar, list, quoted)
-     int pchar;
-     WORD_LIST *list;
-     int quoted;
-{
-  char *ret;
-  WORD_LIST *tlist;
-
-  if (pchar == '*' && (quoted & Q_DOUBLE_QUOTES))
-    {
-      tlist = quote_list (list);
-      word_list_remove_quoted_nulls (tlist);
-      ret = string_list_dollar_star (tlist);
-    }
-  else if (pchar == '*' && (quoted & Q_HERE_DOCUMENT))
-    {
-      tlist = quote_list (list);
-      word_list_remove_quoted_nulls (tlist);
-      ret = string_list (tlist);
-    }
-  else if (pchar == '*')
-    {
-      /* Even when unquoted, string_list_dollar_star does the right thing
-        making sure that the first character of $IFS is used as the
-        separator. */
-      ret = string_list_dollar_star (list);
-    }
-  else if (pchar == '@' && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-    /* We use string_list_dollar_at, but only if the string is quoted, since
-       that quotes the escapes if it's not, which we don't want.  We could
-       use string_list (the old code did), but that doesn't do the right
-       thing if the first character of $IFS is not a space.  We use
-       string_list_dollar_star if the string is unquoted so we make sure that
-       the elements of $@ are separated by the first character of $IFS for
-       later splitting. */
-    ret = string_list_dollar_at (list, quoted);
-  else if (pchar == '@')
-    ret = string_list_dollar_star (list);
-  else
-    ret = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (list) : list);
-
-  return ret;
-}
-
-/* Return the list of words present in STRING.  Separate the string into
-   words at any of the characters found in SEPARATORS.  If QUOTED is
-   non-zero then word in the list will have its quoted flag set, otherwise
-   the quoted flag is left as make_word () deemed fit.
-
-   This obeys the P1003.2 word splitting semantics.  If `separators' is
-   exactly <space><tab><newline>, then the splitting algorithm is that of
-   the Bourne shell, which treats any sequence of characters from `separators'
-   as a delimiter.  If IFS is unset, which results in `separators' being set
-   to "", no splitting occurs.  If separators has some other value, the
-   following rules are applied (`IFS white space' means zero or more
-   occurrences of <space>, <tab>, or <newline>, as long as those characters
-   are in `separators'):
-
-       1) IFS white space is ignored at the start and the end of the
-          string.
-       2) Each occurrence of a character in `separators' that is not
-          IFS white space, along with any adjacent occurrences of
-          IFS white space delimits a field.
-       3) Any nonzero-length sequence of IFS white space delimits a field.
-   */
-
-/* BEWARE!  list_string strips null arguments.  Don't call it twice and
-   expect to have "" preserved! */
-
-/* This performs word splitting and quoted null character removal on
-   STRING. */
-#define issep(c) \
-       (((separators)[0]) ? ((separators)[1] ? isifs(c) \
-                                             : (c) == (separators)[0]) \
-                          : 0)
-
-WORD_LIST *
-list_string (string, separators, quoted)
-     register char *string, *separators;
-     int quoted;
-{
-  WORD_LIST *result;
-  WORD_DESC *t;
-  char *current_word, *s;
-  int sindex, sh_style_split, whitesep, xflags;
-  size_t slen;
-
-  if (!string || !*string)
-    return ((WORD_LIST *)NULL);
-
-  sh_style_split = separators && separators[0] == ' ' &&
-                                separators[1] == '\t' &&
-                                separators[2] == '\n' &&
-                                separators[3] == '\0';
-  for (xflags = 0, s = ifs_value; s && *s; s++)
-    {
-      if (*s == CTLESC) xflags |= SX_NOCTLESC;
-      else if (*s == CTLNUL) xflags |= SX_NOESCCTLNUL;
-    }
-
-  slen = 0;
-  /* Remove sequences of whitespace at the beginning of STRING, as
-     long as those characters appear in IFS.  Do not do this if
-     STRING is quoted or if there are no separator characters. */
-  if (!quoted || !separators || !*separators)
-    {
-      for (s = string; *s && spctabnl (*s) && issep (*s); s++);
-
-      if (!*s)
-       return ((WORD_LIST *)NULL);
-
-      string = s;
-    }
-
-  /* OK, now STRING points to a word that does not begin with white space.
-     The splitting algorithm is:
-       extract a word, stopping at a separator
-       skip sequences of spc, tab, or nl as long as they are separators
-     This obeys the field splitting rules in Posix.2. */
-  slen = (MB_CUR_MAX > 1) ? strlen (string) : 1;
-  for (result = (WORD_LIST *)NULL, sindex = 0; string[sindex]; )
-    {
-      /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
-        unless multibyte chars are possible. */
-      current_word = string_extract_verbatim (string, slen, &sindex, separators, xflags);
-      if (current_word == 0)
-       break;
-
-      /* If we have a quoted empty string, add a quoted null argument.  We
-        want to preserve the quoted null character iff this is a quoted
-        empty string; otherwise the quoted null characters are removed
-        below. */
-      if (QUOTED_NULL (current_word))
-       {
-         t = alloc_word_desc ();
-         t->word = make_quoted_char ('\0');
-         t->flags |= W_QUOTED|W_HASQUOTEDNULL;
-         result = make_word_list (t, result);
-       }
-      else if (current_word[0] != '\0')
-       {
-         /* If we have something, then add it regardless.  However,
-            perform quoted null character removal on the current word. */
-         remove_quoted_nulls (current_word);
-         result = add_string_to_list (current_word, result);
-         result->word->flags &= ~W_HASQUOTEDNULL;      /* just to be sure */
-         if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
-           result->word->flags |= W_QUOTED;
-       }
-
-      /* If we're not doing sequences of separators in the traditional
-        Bourne shell style, then add a quoted null argument. */
-      else if (!sh_style_split && !spctabnl (string[sindex]))
-       {
-         t = alloc_word_desc ();
-         t->word = make_quoted_char ('\0');
-         t->flags |= W_QUOTED|W_HASQUOTEDNULL;
-         result = make_word_list (t, result);
-       }
-
-      free (current_word);
-
-      /* Note whether or not the separator is IFS whitespace, used later. */
-      whitesep = string[sindex] && spctabnl (string[sindex]);
-
-      /* Move past the current separator character. */
-      if (string[sindex])
-       {
-         DECLARE_MBSTATE;
-         ADVANCE_CHAR (string, slen, sindex);
-       }
-
-      /* Now skip sequences of space, tab, or newline characters if they are
-        in the list of separators. */
-      while (string[sindex] && spctabnl (string[sindex]) && issep (string[sindex]))
-       sindex++;
-
-      /* If the first separator was IFS whitespace and the current character
-        is a non-whitespace IFS character, it should be part of the current
-        field delimiter, not a separate delimiter that would result in an
-        empty field.  Look at POSIX.2, 3.6.5, (3)(b). */
-      if (string[sindex] && whitesep && issep (string[sindex]) && !spctabnl (string[sindex]))
-       {
-         sindex++;
-         /* An IFS character that is not IFS white space, along with any
-            adjacent IFS white space, shall delimit a field. (SUSv3) */
-         while (string[sindex] && spctabnl (string[sindex]) && isifs (string[sindex]))
-           sindex++;
-       }
-    }
-  return (REVERSE_LIST (result, WORD_LIST *));
-}
-
-/* Parse a single word from STRING, using SEPARATORS to separate fields.
-   ENDPTR is set to the first character after the word.  This is used by
-   the `read' builtin.  This is never called with SEPARATORS != $IFS;
-   it should be simplified.
-
-   XXX - this function is very similar to list_string; they should be
-        combined - XXX */
-char *
-get_word_from_string (stringp, separators, endptr)
-     char **stringp, *separators, **endptr;
-{
-  register char *s;
-  char *current_word;
-  int sindex, sh_style_split, whitesep, xflags;
-  size_t slen;
-
-  if (!stringp || !*stringp || !**stringp)
-    return ((char *)NULL);
-
-  sh_style_split = separators && separators[0] == ' ' &&
-                                separators[1] == '\t' &&
-                                separators[2] == '\n' &&
-                                separators[3] == '\0';
-  for (xflags = 0, s = ifs_value; s && *s; s++)
-    {
-      if (*s == CTLESC) xflags |= SX_NOCTLESC;
-      if (*s == CTLNUL) xflags |= SX_NOESCCTLNUL;
-    }
-
-  s = *stringp;
-  slen = 0;
-
-  /* Remove sequences of whitespace at the beginning of STRING, as
-     long as those characters appear in IFS. */
-  if (sh_style_split || !separators || !*separators)
-    {
-      for (; *s && spctabnl (*s) && isifs (*s); s++);
-
-      /* If the string is nothing but whitespace, update it and return. */
-      if (!*s)
-       {
-         *stringp = s;
-         if (endptr)
-           *endptr = s;
-         return ((char *)NULL);
-       }
-    }
-
-  /* OK, S points to a word that does not begin with white space.
-     Now extract a word, stopping at a separator, save a pointer to
-     the first character after the word, then skip sequences of spc,
-     tab, or nl as long as they are separators.
-
-     This obeys the field splitting rules in Posix.2. */
-  sindex = 0;
-  /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
-     unless multibyte chars are possible. */
-  slen = (MB_CUR_MAX > 1) ? strlen (s) : 1;
-  current_word = string_extract_verbatim (s, slen, &sindex, separators, xflags);
-
-  /* Set ENDPTR to the first character after the end of the word. */
-  if (endptr)
-    *endptr = s + sindex;
-
-  /* Note whether or not the separator is IFS whitespace, used later. */
-  whitesep = s[sindex] && spctabnl (s[sindex]);
-
-  /* Move past the current separator character. */
-  if (s[sindex])
-    {
-      DECLARE_MBSTATE;
-      ADVANCE_CHAR (s, slen, sindex);
-    }
-
-  /* Now skip sequences of space, tab, or newline characters if they are
-     in the list of separators. */
-  while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
-    sindex++;
-
-  /* If the first separator was IFS whitespace and the current character is
-     a non-whitespace IFS character, it should be part of the current field
-     delimiter, not a separate delimiter that would result in an empty field.
-     Look at POSIX.2, 3.6.5, (3)(b). */
-  if (s[sindex] && whitesep && isifs (s[sindex]) && !spctabnl (s[sindex]))
-    {
-      sindex++;
-      /* An IFS character that is not IFS white space, along with any adjacent
-        IFS white space, shall delimit a field. */
-      while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
-       sindex++;
-    }
-
-  /* Update STRING to point to the next field. */
-  *stringp = s + sindex;
-  return (current_word);
-}
-
-/* Remove IFS white space at the end of STRING.  Start at the end
-   of the string and walk backwards until the beginning of the string
-   or we find a character that's not IFS white space and not CTLESC.
-   Only let CTLESC escape a white space character if SAW_ESCAPE is
-   non-zero.  */
-char *
-strip_trailing_ifs_whitespace (string, separators, saw_escape)
-     char *string, *separators;
-     int saw_escape;
-{
-  char *s;
-
-  s = string + STRLEN (string) - 1;
-  while (s > string && ((spctabnl (*s) && isifs (*s)) ||
-                       (saw_escape && *s == CTLESC && spctabnl (s[1]))))
-    s--;
-  *++s = '\0';
-  return string;
-}
-
-#if 0
-/* UNUSED */
-/* Split STRING into words at whitespace.  Obeys shell-style quoting with
-   backslashes, single and double quotes. */
-WORD_LIST *
-list_string_with_quotes (string)
-     char *string;
-{
-  WORD_LIST *list;
-  char *token, *s;
-  size_t s_len;
-  int c, i, tokstart, len;
-
-  for (s = string; s && *s && spctabnl (*s); s++)
-    ;
-  if (s == 0 || *s == 0)
-    return ((WORD_LIST *)NULL);
-
-  s_len = strlen (s);
-  tokstart = i = 0;
-  list = (WORD_LIST *)NULL;
-  while (1)
-    {
-      c = s[i];
-      if (c == '\\')
-       {
-         i++;
-         if (s[i])
-           i++;
-       }
-      else if (c == '\'')
-       i = skip_single_quoted (s, s_len, ++i);
-      else if (c == '"')
-       i = skip_double_quoted (s, s_len, ++i);
-      else if (c == 0 || spctabnl (c))
-       {
-         /* We have found the end of a token.  Make a word out of it and
-            add it to the word list. */
-         token = substring (s, tokstart, i);
-         list = add_string_to_list (token, list);
-         free (token);
-         while (spctabnl (s[i]))
-           i++;
-         if (s[i])
-           tokstart = i;
-         else
-           break;
-       }
-      else
-       i++;    /* normal character */
-    }
-  return (REVERSE_LIST (list, WORD_LIST *));
-}
-#endif
-
-/********************************************************/
-/*                                                     */
-/*     Functions to perform assignment statements      */
-/*                                                     */
-/********************************************************/
-
-#if defined (ARRAY_VARS)
-static SHELL_VAR *
-do_compound_assignment (name, value, flags)
-     char *name, *value;
-     int flags;
-{
-  SHELL_VAR *v;
-  int mklocal, mkassoc;
-  WORD_LIST *list;
-
-  mklocal = flags & ASS_MKLOCAL;
-  mkassoc = flags & ASS_MKASSOC;
-
-  if (mklocal && variable_context)
-    {
-      v = find_variable (name);
-      list = expand_compound_array_assignment (v, value, flags);
-      if (mkassoc)
-       v = make_local_assoc_variable (name);
-      else if (v == 0 || (array_p (v) == 0 && assoc_p (v) == 0) || v->context != variable_context)
-        v = make_local_array_variable (name);
-      assign_compound_array_list (v, list, flags);
-    }
-  else
-    v = assign_array_from_string (name, value, flags);
-
-  return (v);
-}
-#endif
-
-/* Given STRING, an assignment string, get the value of the right side
-   of the `=', and bind it to the left side.  If EXPAND is true, then
-   perform parameter expansion, command substitution, and arithmetic
-   expansion on the right-hand side.  Perform tilde expansion in any
-   case.  Do not perform word splitting on the result of expansion. */
-static int
-do_assignment_internal (word, expand)
-     const WORD_DESC *word;
-     int expand;
-{
-  int offset, tlen, appendop, assign_list, aflags, retval;
-  char *name, *value;
-  SHELL_VAR *entry;
-#if defined (ARRAY_VARS)
-  char *t;
-  int ni;
-#endif
-  const char *string;
-
-  if (word == 0 || word->word == 0)
-    return 0;
-
-  appendop = assign_list = aflags = 0;
-  string = word->word;
-  offset = assignment (string, 0);
-  name = savestring (string);
-  value = (char *)NULL;
-
-  if (name[offset] == '=')
-    {
-      char *temp;
-
-      if (name[offset - 1] == '+')
-       {
-         appendop = 1;
-         name[offset - 1] = '\0';
-       }
-
-      name[offset] = 0;                /* might need this set later */
-      temp = name + offset + 1;
-      tlen = STRLEN (temp);
-
-#if defined (ARRAY_VARS)
-      if (expand && (word->flags & W_COMPASSIGN))
-       {
-         assign_list = ni = 1;
-         value = extract_array_assignment_list (temp, &ni);
-       }
-      else
-#endif
-      if (expand && temp[0])
-       value = expand_string_if_necessary (temp, 0, expand_string_assignment);
-      else
-       value = savestring (temp);
-    }
-
-  if (value == 0)
-    {
-      value = (char *)xmalloc (1);
-      value[0] = '\0';
-    }
-
-  if (echo_command_at_execute)
-    {
-      if (appendop)
-       name[offset - 1] = '+';
-      xtrace_print_assignment (name, value, assign_list, 1);
-      if (appendop)
-       name[offset - 1] = '\0';
-    }
-
-#define ASSIGN_RETURN(r)       do { FREE (value); free (name); return (r); } while (0)
-
-  if (appendop)
-    aflags |= ASS_APPEND;
-
-#if defined (ARRAY_VARS)
-  if (t = mbschr (name, '['))  /*]*/
-    {
-      if (assign_list)
-       {
-         report_error (_("%s: cannot assign list to array member"), name);
-         ASSIGN_RETURN (0);
-       }
-      entry = assign_array_element (name, value, aflags);
-      if (entry == 0)
-       ASSIGN_RETURN (0);
-    }
-  else if (assign_list)
-    {
-      if (word->flags & W_ASSIGNARG)
-       aflags |= ASS_MKLOCAL;
-      if (word->flags & W_ASSIGNASSOC)
-       aflags |= ASS_MKASSOC;
-      entry = do_compound_assignment (name, value, aflags);
-    }
-  else
-#endif /* ARRAY_VARS */
-  entry = bind_variable (name, value, aflags);
-
-  stupidly_hack_special_variables (name);
-
-#if 1
-  /* Return 1 if the assignment seems to have been performed correctly. */
-  if (entry == 0 || readonly_p (entry))
-    retval = 0;                /* assignment failure */
-  else if (noassign_p (entry))
-    {
-      last_command_exit_value = EXECUTION_FAILURE;
-      retval = 1;      /* error status, but not assignment failure */
-    }
-  else
-    retval = 1;
-
-  if (entry && retval != 0 && noassign_p (entry) == 0)
-    VUNSETATTR (entry, att_invisible);
-
-  ASSIGN_RETURN (retval);
-#else
-  if (entry)
-    VUNSETATTR (entry, att_invisible);
-
-  ASSIGN_RETURN (entry ? ((readonly_p (entry) == 0) && noassign_p (entry) == 0) : 0);
-#endif
-}
-
-/* Perform the assignment statement in STRING, and expand the
-   right side by doing tilde, command and parameter expansion. */
-int
-do_assignment (string)
-     char *string;
-{
-  WORD_DESC td;
-
-  td.flags = W_ASSIGNMENT;
-  td.word = string;
-
-  return do_assignment_internal (&td, 1);
-}
-
-int
-do_word_assignment (word)
-     WORD_DESC *word;
-{
-  return do_assignment_internal (word, 1);
-}
-
-/* Given STRING, an assignment string, get the value of the right side
-   of the `=', and bind it to the left side.  Do not perform any word
-   expansions on the right hand side. */
-int
-do_assignment_no_expand (string)
-     char *string;
-{
-  WORD_DESC td;
-
-  td.flags = W_ASSIGNMENT;
-  td.word = string;
-
-  return (do_assignment_internal (&td, 0));
-}
-
-/***************************************************
- *                                                *
- *  Functions to manage the positional parameters  *
- *                                                *
- ***************************************************/
-
-/* Return the word list that corresponds to `$*'. */
-WORD_LIST *
-list_rest_of_args ()
-{
-  register WORD_LIST *list, *args;
-  int i;
-
-  /* Break out of the loop as soon as one of the dollar variables is null. */
-  for (i = 1, list = (WORD_LIST *)NULL; i < 10 && dollar_vars[i]; i++)
-    list = make_word_list (make_bare_word (dollar_vars[i]), list);
-
-  for (args = rest_of_args; args; args = args->next)
-    list = make_word_list (make_bare_word (args->word->word), list);
-
-  return (REVERSE_LIST (list, WORD_LIST *));
-}
-
-int
-number_of_args ()
-{
-  register WORD_LIST *list;
-  int n;
-
-  for (n = 0; n < 9 && dollar_vars[n+1]; n++)
-    ;
-  for (list = rest_of_args; list; list = list->next)
-    n++;
-  return n;
-}
-
-/* Return the value of a positional parameter.  This handles values > 10. */
-char *
-get_dollar_var_value (ind)
-     intmax_t ind;
-{
-  char *temp;
-  WORD_LIST *p;
-
-  if (ind < 10)
-    temp = dollar_vars[ind] ? savestring (dollar_vars[ind]) : (char *)NULL;
-  else /* We want something like ${11} */
-    {
-      ind -= 10;
-      for (p = rest_of_args; p && ind--; p = p->next)
-       ;
-      temp = p ? savestring (p->word->word) : (char *)NULL;
-    }
-  return (temp);
-}
-
-/* Make a single large string out of the dollar digit variables,
-   and the rest_of_args.  If DOLLAR_STAR is 1, then obey the special
-   case of "$*" with respect to IFS. */
-char *
-string_rest_of_args (dollar_star)
-     int dollar_star;
-{
-  register WORD_LIST *list;
-  char *string;
-
-  list = list_rest_of_args ();
-  string = dollar_star ? string_list_dollar_star (list) : string_list (list);
-  dispose_words (list);
-  return (string);
-}
-
-/* Return a string containing the positional parameters from START to
-   END, inclusive.  If STRING[0] == '*', we obey the rules for $*,
-   which only makes a difference if QUOTED is non-zero.  If QUOTED includes
-   Q_HERE_DOCUMENT or Q_DOUBLE_QUOTES, this returns a quoted list, otherwise
-   no quoting chars are added. */
-static char *
-pos_params (string, start, end, quoted)
-     char *string;
-     int start, end, quoted;
-{
-  WORD_LIST *save, *params, *h, *t;
-  char *ret;
-  int i;
-
-  /* see if we can short-circuit.  if start == end, we want 0 parameters. */
-  if (start == end)
-    return ((char *)NULL);
-
-  save = params = list_rest_of_args ();
-  if (save == 0)
-    return ((char *)NULL);
-
-  if (start == 0)              /* handle ${@:0[:x]} specially */
-    {
-      t = make_word_list (make_word (dollar_vars[0]), params);
-      save = params = t;
-    }
-
-  for (i = start ? 1 : 0; params && i < start; i++)
-    params = params->next;
-  if (params == 0)
-    return ((char *)NULL);
-  for (h = t = params; params && i < end; i++)
-    {
-      t = params;
-      params = params->next;
-    }
-
-  t->next = (WORD_LIST *)NULL;
-
-  ret = string_list_pos_params (string[0], h, quoted);
-
-  if (t != params)
-    t->next = params;
-
-  dispose_words (save);
-  return (ret);
-}
-
-/******************************************************************/
-/*                                                               */
-/*     Functions to expand strings to strings or WORD_LISTs      */
-/*                                                               */
-/******************************************************************/
-
-#if defined (PROCESS_SUBSTITUTION)
-#define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC || s == '~')
-#else
-#define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
-#endif
-
-/* If there are any characters in STRING that require full expansion,
-   then call FUNC to expand STRING; otherwise just perform quote
-   removal if necessary.  This returns a new string. */
-static char *
-expand_string_if_necessary (string, quoted, func)
-     char *string;
-     int quoted;
-     EXPFUNC *func;
-{
-  WORD_LIST *list;
-  size_t slen;
-  int i, saw_quote;
-  char *ret;
-  DECLARE_MBSTATE;
-
-  /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */
-  slen = (MB_CUR_MAX > 1) ? strlen (string) : 0;
-  i = saw_quote = 0;
-  while (string[i])
-    {
-      if (EXP_CHAR (string[i]))
-       break;
-      else if (string[i] == '\'' || string[i] == '\\' || string[i] == '"')
-       saw_quote = 1;
-      ADVANCE_CHAR (string, slen, i);
-    }
-
-  if (string[i])
-    {
-      list = (*func) (string, quoted);
-      if (list)
-       {
-         ret = string_list (list);
-         dispose_words (list);
-       }
-      else
-       ret = (char *)NULL;
-    }
-  else if (saw_quote && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
-    ret = string_quote_removal (string, quoted);
-  else
-    ret = savestring (string);
-
-  return ret;
-}
-
-static inline char *
-expand_string_to_string_internal (string, quoted, func)
-     char *string;
-     int quoted;
-     EXPFUNC *func;
-{
-  WORD_LIST *list;
-  char *ret;
-
-  if (string == 0 || *string == '\0')
-    return ((char *)NULL);
-
-  list = (*func) (string, quoted);
-  if (list)
-    {
-      ret = string_list (list);
-      dispose_words (list);
-    }
-  else
-    ret = (char *)NULL;
-
-  return (ret);
-}
-
-char *
-expand_string_to_string (string, quoted)
-     char *string;
-     int quoted;
-{
-  return (expand_string_to_string_internal (string, quoted, expand_string));
-}
-
-char *
-expand_string_unsplit_to_string (string, quoted)
-     char *string;
-     int quoted;
-{
-  return (expand_string_to_string_internal (string, quoted, expand_string_unsplit));
-}
-
-char *
-expand_assignment_string_to_string (string, quoted)
-     char *string;
-     int quoted;
-{
-  return (expand_string_to_string_internal (string, quoted, expand_string_assignment));
-}
-
-char *
-expand_arith_string (string, quoted)
-     char *string;
-     int quoted;
-{
-  return (expand_string_if_necessary (string, quoted, expand_string));
-}
-
-#if defined (COND_COMMAND)
-/* Just remove backslashes in STRING.  Returns a new string. */
-char *
-remove_backslashes (string)
-     char *string;
-{
-  char *r, *ret, *s;
-
-  r = ret = (char *)xmalloc (strlen (string) + 1);
-  for (s = string; s && *s; )
-    {
-      if (*s == '\\')
-       s++;
-      if (*s == 0)
-       break;
-      *r++ = *s++;
-    }
-  *r = '\0';
-  return ret;
-}
-
-/* This needs better error handling. */
-/* Expand W for use as an argument to a unary or binary operator in a
-   [[...]] expression.  If SPECIAL is 1, this is the rhs argument
-   to the != or == operator, and should be treated as a pattern.  In
-   this case, we quote the string specially for the globbing code.  If
-   SPECIAL is 2, this is an rhs argument for the =~ operator, and should
-   be quoted appropriately for regcomp/regexec.  The caller is responsible
-   for removing the backslashes if the unquoted word is needed later. */   
-char *
-cond_expand_word (w, special)
-     WORD_DESC *w;
-     int special;
-{
-  char *r, *p;
-  WORD_LIST *l;
-  int qflags;
-
-  if (w->word == 0 || w->word[0] == '\0')
-    return ((char *)NULL);
-
-  l = call_expand_word_internal (w, 0, 0, (int *)0, (int *)0);
-  if (l)
-    {
-      if (special == 0)
-       {
-         dequote_list (l);
-         r = string_list (l);
-       }
-      else
-       {
-         qflags = QGLOB_CVTNULL;
-         if (special == 2)
-           qflags |= QGLOB_REGEXP;
-         p = string_list (l);
-         r = quote_string_for_globbing (p, qflags);
-         free (p);
-       }
-      dispose_words (l);
-    }
-  else
-    r = (char *)NULL;
-
-  return r;
-}
-#endif
-
-/* Call expand_word_internal to expand W and handle error returns.
-   A convenience function for functions that don't want to handle
-   any errors or free any memory before aborting. */
-static WORD_LIST *
-call_expand_word_internal (w, q, i, c, e)
-     WORD_DESC *w;
-     int q, i, *c, *e;
-{
-  WORD_LIST *result;
-
-  result = expand_word_internal (w, q, i, c, e);
-  if (result == &expand_word_error || result == &expand_word_fatal)
-    {
-      /* By convention, each time this error is returned, w->word has
-        already been freed (it sometimes may not be in the fatal case,
-        but that doesn't result in a memory leak because we're going
-        to exit in most cases). */
-      w->word = (char *)NULL;
-      last_command_exit_value = EXECUTION_FAILURE;
-      exp_jump_to_top_level ((result == &expand_word_error) ? DISCARD : FORCE_EOF);
-      /* NOTREACHED */
-    }
-  else
-    return (result);
-}
-
-/* Perform parameter expansion, command substitution, and arithmetic
-   expansion on STRING, as if it were a word.  Leave the result quoted. */
-static WORD_LIST *
-expand_string_internal (string, quoted)
-     char *string;
-     int quoted;
-{
-  WORD_DESC td;
-  WORD_LIST *tresult;
-
-  if (string == 0 || *string == 0)
-    return ((WORD_LIST *)NULL);
-
-  td.flags = 0;
-  td.word = savestring (string);
-
-  tresult = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
-
-  FREE (td.word);
-  return (tresult);
-}
-
-/* Expand STRING by performing parameter expansion, command substitution,
-   and arithmetic expansion.  Dequote the resulting WORD_LIST before
-   returning it, but do not perform word splitting.  The call to
-   remove_quoted_nulls () is in here because word splitting normally
-   takes care of quote removal. */
-WORD_LIST *
-expand_string_unsplit (string, quoted)
-     char *string;
-     int quoted;
-{
-  WORD_LIST *value;
-
-  if (string == 0 || *string == '\0')
-    return ((WORD_LIST *)NULL);
-
-  expand_no_split_dollar_star = 1;
-  value = expand_string_internal (string, quoted);
-  expand_no_split_dollar_star = 0;
-
-  if (value)
-    {
-      if (value->word)
-       {
-         remove_quoted_nulls (value->word->word);
-         value->word->flags &= ~W_HASQUOTEDNULL;
-       }
-      dequote_list (value);
-    }
-  return (value);
-}
-
-/* Expand the rhs of an assignment statement */
-WORD_LIST *
-expand_string_assignment (string, quoted)
-     char *string;
-     int quoted;
-{
-  WORD_DESC td;
-  WORD_LIST *value;
-
-  if (string == 0 || *string == '\0')
-    return ((WORD_LIST *)NULL);
-
-  expand_no_split_dollar_star = 1;
-
-  td.flags = W_ASSIGNRHS;
-  td.word = savestring (string);
-  value = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
-  FREE (td.word);
-
-  expand_no_split_dollar_star = 0;
-
-  if (value)
-    {
-      if (value->word)
-       {
-         remove_quoted_nulls (value->word->word);
-         value->word->flags &= ~W_HASQUOTEDNULL;
-       }
-      dequote_list (value);
-    }
-  return (value);
-}
-
-
-/* Expand one of the PS? prompt strings. This is a sort of combination of
-   expand_string_unsplit and expand_string_internal, but returns the
-   passed string when an error occurs.  Might want to trap other calls
-   to jump_to_top_level here so we don't endlessly loop. */
-WORD_LIST *
-expand_prompt_string (string, quoted, wflags)
-     char *string;
-     int quoted;
-     int wflags;
-{
-  WORD_LIST *value;
-  WORD_DESC td;
-
-  if (string == 0 || *string == 0)
-    return ((WORD_LIST *)NULL);
-
-  td.flags = wflags;
-  td.word = savestring (string);
-
-  no_longjmp_on_fatal_error = 1;
-  value = expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
-  no_longjmp_on_fatal_error = 0;
-
-  if (value == &expand_word_error || value == &expand_word_fatal)
-    {
-      value = make_word_list (make_bare_word (string), (WORD_LIST *)NULL);
-      return value;
-    }
-  FREE (td.word);
-  if (value)
-    {
-      if (value->word)
-       {
-         remove_quoted_nulls (value->word->word);
-         value->word->flags &= ~W_HASQUOTEDNULL;
-       }
-      dequote_list (value);
-    }
-  return (value);
-}
-
-/* Expand STRING just as if you were expanding a word, but do not dequote
-   the resultant WORD_LIST.  This is called only from within this file,
-   and is used to correctly preserve quoted characters when expanding
-   things like ${1+"$@"}.  This does parameter expansion, command
-   substitution, arithmetic expansion, and word splitting. */
-static WORD_LIST *
-expand_string_leave_quoted (string, quoted)
-     char *string;
-     int quoted;
-{
-  WORD_LIST *tlist;
-  WORD_LIST *tresult;
-
-  if (string == 0 || *string == '\0')
-    return ((WORD_LIST *)NULL);
-
-  tlist = expand_string_internal (string, quoted);
-
-  if (tlist)
-    {
-      tresult = word_list_split (tlist);
-      dispose_words (tlist);
-      return (tresult);
-    }
-  return ((WORD_LIST *)NULL);
-}
-
-/* This does not perform word splitting or dequote the WORD_LIST
-   it returns. */
-static WORD_LIST *
-expand_string_for_rhs (string, quoted, dollar_at_p, has_dollar_at)
-     char *string;
-     int quoted, *dollar_at_p, *has_dollar_at;
-{
-  WORD_DESC td;
-  WORD_LIST *tresult;
-
-  if (string == 0 || *string == '\0')
-    return (WORD_LIST *)NULL;
-
-  td.flags = 0;
-  td.word = string;
-  tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, has_dollar_at);
-  return (tresult);
-}
-
-/* Expand STRING just as if you were expanding a word.  This also returns
-   a list of words.  Note that filename globbing is *NOT* done for word
-   or string expansion, just when the shell is expanding a command.  This
-   does parameter expansion, command substitution, arithmetic expansion,
-   and word splitting.  Dequote the resultant WORD_LIST before returning. */
-WORD_LIST *
-expand_string (string, quoted)
-     char *string;
-     int quoted;
-{
-  WORD_LIST *result;
-
-  if (string == 0 || *string == '\0')
-    return ((WORD_LIST *)NULL);
-
-  result = expand_string_leave_quoted (string, quoted);
-  return (result ? dequote_list (result) : result);
-}
-
-/***************************************************
- *                                                *
- *     Functions to handle quoting chars          *
- *                                                *
- ***************************************************/
-
-/* Conventions:
-
-     A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string.
-     The parser passes CTLNUL as CTLESC CTLNUL. */
-
-/* Quote escape characters in string s, but no other characters.  This is
-   used to protect CTLESC and CTLNUL in variable values from the rest of
-   the word expansion process after the variable is expanded (word splitting
-   and filename generation).  If IFS is null, we quote spaces as well, just
-   in case we split on spaces later (in the case of unquoted $@, we will
-   eventually attempt to split the entire word on spaces).  Corresponding
-   code exists in dequote_escapes.  Even if we don't end up splitting on
-   spaces, quoting spaces is not a problem.  This should never be called on
-   a string that is quoted with single or double quotes or part of a here
-   document (effectively double-quoted). */
-char *
-quote_escapes (string)
-     char *string;
-{
-  register char *s, *t;
-  size_t slen;
-  char *result, *send;
-  int quote_spaces, skip_ctlesc, skip_ctlnul;
-  DECLARE_MBSTATE; 
-
-  slen = strlen (string);
-  send = string + slen;
-
-  quote_spaces = (ifs_value && *ifs_value == 0);
-
-  for (skip_ctlesc = skip_ctlnul = 0, s = ifs_value; s && *s; s++)
-    skip_ctlesc |= *s == CTLESC, skip_ctlnul |= *s == CTLNUL;
-
-  t = result = (char *)xmalloc ((slen * 2) + 1);
-  s = string;
-
-  while (*s)
-    {
-      if ((skip_ctlesc == 0 && *s == CTLESC) || (skip_ctlnul == 0 && *s == CTLNUL) || (quote_spaces && *s == ' '))
-       *t++ = CTLESC;
-      COPY_CHAR_P (t, s, send);
-    }
-  *t = '\0';
-  return (result);
-}
-
-static WORD_LIST *
-list_quote_escapes (list)
-     WORD_LIST *list;
-{
-  register WORD_LIST *w;
-  char *t;
-
-  for (w = list; w; w = w->next)
-    {
-      t = w->word->word;
-      w->word->word = quote_escapes (t);
-      free (t);
-    }
-  return list;
-}
-
-/* Inverse of quote_escapes; remove CTLESC protecting CTLESC or CTLNUL.
-
-   The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL.
-   This is necessary to make unquoted CTLESC and CTLNUL characters in the
-   data stream pass through properly.
-
-   We need to remove doubled CTLESC characters inside quoted strings before
-   quoting the entire string, so we do not double the number of CTLESC
-   characters.
-
-   Also used by parts of the pattern substitution code. */
-char *
-dequote_escapes (string)
-     char *string;
-{
-  register char *s, *t, *s1;
-  size_t slen;
-  char *result, *send;
-  int quote_spaces;
-  DECLARE_MBSTATE;
-
-  if (string == 0)
-    return string;
-
-  slen = strlen (string);
-  send = string + slen;
-
-  t = result = (char *)xmalloc (slen + 1);
-
-  if (strchr (string, CTLESC) == 0)
-    return (strcpy (result, string));
-
-  quote_spaces = (ifs_value && *ifs_value == 0);
-
-  s = string;
-  while (*s)
-    {
-      if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL || (quote_spaces && s[1] == ' ')))
-       {
-         s++;
-         if (*s == '\0')
-           break;
-       }
-      COPY_CHAR_P (t, s, send);
-    }
-  *t = '\0';
-  return result;
-}
-
-/* Return a new string with the quoted representation of character C.
-   This turns "" into QUOTED_NULL, so the W_HASQUOTEDNULL flag needs to be
-   set in any resultant WORD_DESC where this value is the word. */
-static char *
-make_quoted_char (c)
-     int c;
-{
-  char *temp;
-
-  temp = (char *)xmalloc (3);
-  if (c == 0)
-    {
-      temp[0] = CTLNUL;
-      temp[1] = '\0';
-    }
-  else
-    {
-      temp[0] = CTLESC;
-      temp[1] = c;
-      temp[2] = '\0';
-    }
-  return (temp);
-}
-
-/* Quote STRING, returning a new string.  This turns "" into QUOTED_NULL, so
-   the W_HASQUOTEDNULL flag needs to be set in any resultant WORD_DESC where
-   this value is the word. */
-char *
-quote_string (string)
-     char *string;
-{
-  register char *t;
-  size_t slen;
-  char *result, *send;
-
-  if (*string == 0)
-    {
-      result = (char *)xmalloc (2);
-      result[0] = CTLNUL;
-      result[1] = '\0';
-    }
-  else
-    {
-      DECLARE_MBSTATE;
-
-      slen = strlen (string);
-      send = string + slen;
-
-      result = (char *)xmalloc ((slen * 2) + 1);
-
-      for (t = result; string < send; )
-       {
-         *t++ = CTLESC;
-         COPY_CHAR_P (t, string, send);
-       }
-      *t = '\0';
-    }
-  return (result);
-}
-
-/* De-quote quoted characters in STRING. */
-char *
-dequote_string (string)
-     char *string;
-{
-  register char *s, *t;
-  size_t slen;
-  char *result, *send;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string);
-
-  t = result = (char *)xmalloc (slen + 1);
-
-  if (QUOTED_NULL (string))
-    {
-      result[0] = '\0';
-      return (result);
-    }
-
-  /* If no character in the string can be quoted, don't bother examining
-     each character.  Just return a copy of the string passed to us. */
-  if (strchr (string, CTLESC) == NULL)
-    return (strcpy (result, string));
-
-  send = string + slen;
-  s = string;
-  while (*s)
-    {
-      if (*s == CTLESC)
-       {
-         s++;
-         if (*s == '\0')
-           break;
-       }
-      COPY_CHAR_P (t, s, send);
-    }
-
-  *t = '\0';
-  return (result);
-}
-
-/* Quote the entire WORD_LIST list. */
-static WORD_LIST *
-quote_list (list)
-     WORD_LIST *list;
-{
-  register WORD_LIST *w;
-  char *t;
-
-  for (w = list; w; w = w->next)
-    {
-      t = w->word->word;
-      w->word->word = quote_string (t);
-      if (*t == 0)
-       w->word->flags |= W_HASQUOTEDNULL;      /* XXX - turn on W_HASQUOTEDNULL here? */
-      w->word->flags |= W_QUOTED;
-      free (t);
-    }
-  return list;
-}
-
-/* De-quote quoted characters in each word in LIST. */
-WORD_LIST *
-dequote_list (list)
-     WORD_LIST *list;
-{
-  register char *s;
-  register WORD_LIST *tlist;
-
-  for (tlist = list; tlist; tlist = tlist->next)
-    {
-      s = dequote_string (tlist->word->word);
-      if (QUOTED_NULL (tlist->word->word))
-       tlist->word->flags &= ~W_HASQUOTEDNULL;
-      free (tlist->word->word);
-      tlist->word->word = s;
-    }
-  return list;
-}
-
-/* Remove CTLESC protecting a CTLESC or CTLNUL in place.  Return the passed
-   string. */
-char *
-remove_quoted_escapes (string)
-     char *string;
-{
-  char *t;
-
-  if (string)
-    {
-      t = dequote_escapes (string);
-      strcpy (string, t);
-      free (t);
-    }
-
-  return (string);
-}
-
-/* Perform quoted null character removal on STRING.  We don't allow any
-   quoted null characters in the middle or at the ends of strings because
-   of how expand_word_internal works.  remove_quoted_nulls () turns
-   STRING into an empty string iff it only consists of a quoted null,
-   and removes all unquoted CTLNUL characters. */
-char *
-remove_quoted_nulls (string)
-     char *string;
-{
-  register size_t slen;
-  register int i, j, prev_i;
-  DECLARE_MBSTATE;
-
-  if (strchr (string, CTLNUL) == 0)            /* XXX */
-    return string;                             /* XXX */
-
-  slen = strlen (string);
-  i = j = 0;
-
-  while (i < slen)
-    {
-      if (string[i] == CTLESC)
-       {
-         /* Old code had j++, but we cannot assume that i == j at this
-            point -- what if a CTLNUL has already been removed from the
-            string?  We don't want to drop the CTLESC or recopy characters
-            that we've already copied down. */
-         i++; string[j++] = CTLESC;
-         if (i == slen)
-           break;
-       }
-      else if (string[i] == CTLNUL)
-       i++;
-
-      prev_i = i;
-      ADVANCE_CHAR (string, slen, i);
-      if (j < prev_i)
-       {
-         do string[j++] = string[prev_i++]; while (prev_i < i);
-       }
-      else
-       j = i;
-    }
-  string[j] = '\0';
-
-  return (string);
-}
-
-/* Perform quoted null character removal on each element of LIST.
-   This modifies LIST. */
-void
-word_list_remove_quoted_nulls (list)
-     WORD_LIST *list;
-{
-  register WORD_LIST *t;
-
-  for (t = list; t; t = t->next)
-    {
-      remove_quoted_nulls (t->word->word);
-      t->word->flags &= ~W_HASQUOTEDNULL;
-    }
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*        Functions for Matching and Removing Patterns             */
-/*                                                                 */
-/* **************************************************************** */
-
-#if defined (HANDLE_MULTIBYTE)
-#if 0 /* Currently unused */
-static unsigned char *
-mb_getcharlens (string, len)
-     char *string;
-     int len;
-{
-  int i, offset, last;
-  unsigned char *ret;
-  char *p;
-  DECLARE_MBSTATE;
-
-  i = offset = 0;
-  last = 0;
-  ret = (unsigned char *)xmalloc (len);
-  memset (ret, 0, len);
-  while (string[last])
-    {
-      ADVANCE_CHAR (string, len, offset);
-      ret[last] = offset - last;
-      last = offset;
-    }
-  return ret;
-}
-#endif
-#endif
-
-/* Remove the portion of PARAM matched by PATTERN according to OP, where OP
-   can have one of 4 values:
-       RP_LONG_LEFT    remove longest matching portion at start of PARAM
-       RP_SHORT_LEFT   remove shortest matching portion at start of PARAM
-       RP_LONG_RIGHT   remove longest matching portion at end of PARAM
-       RP_SHORT_RIGHT  remove shortest matching portion at end of PARAM
-*/
-
-#define RP_LONG_LEFT   1
-#define RP_SHORT_LEFT  2
-#define RP_LONG_RIGHT  3
-#define RP_SHORT_RIGHT 4
-
-static char *
-remove_upattern (param, pattern, op)
-     char *param, *pattern;
-     int op;
-{
-  register int len;
-  register char *end;
-  register char *p, *ret, c;
-
-  len = STRLEN (param);
-  end = param + len;
-
-  switch (op)
-    {
-      case RP_LONG_LEFT:       /* remove longest match at start */
-       for (p = end; p >= param; p--)
-         {
-           c = *p; *p = '\0';
-           if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               *p = c;
-               return (savestring (p));
-             }
-           *p = c;
-
-         }
-       break;
-
-      case RP_SHORT_LEFT:      /* remove shortest match at start */
-       for (p = param; p <= end; p++)
-         {
-           c = *p; *p = '\0';
-           if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               *p = c;
-               return (savestring (p));
-             }
-           *p = c;
-         }
-       break;
-
-      case RP_LONG_RIGHT:      /* remove longest match at end */
-       for (p = param; p <= end; p++)
-         {
-           if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               c = *p; *p = '\0';
-               ret = savestring (param);
-               *p = c;
-               return (ret);
-             }
-         }
-       break;
-
-      case RP_SHORT_RIGHT:     /* remove shortest match at end */
-       for (p = end; p >= param; p--)
-         {
-           if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               c = *p; *p = '\0';
-               ret = savestring (param);
-               *p = c;
-               return (ret);
-             }
-         }
-       break;
-    }
-
-  return (savestring (param)); /* no match, return original string */
-}
-
-#if defined (HANDLE_MULTIBYTE)
-static wchar_t *
-remove_wpattern (wparam, wstrlen, wpattern, op)
-     wchar_t *wparam;
-     size_t wstrlen;
-     wchar_t *wpattern;
-     int op;
-{
-  wchar_t wc, *ret;
-  int n;
-
-  switch (op)
-    {
-      case RP_LONG_LEFT:       /* remove longest match at start */
-        for (n = wstrlen; n >= 0; n--)
-         {
-           wc = wparam[n]; wparam[n] = L'\0';
-           if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               wparam[n] = wc;
-               return (wcsdup (wparam + n));
-             }
-           wparam[n] = wc;
-         }
-       break;
-
-      case RP_SHORT_LEFT:      /* remove shortest match at start */
-       for (n = 0; n <= wstrlen; n++)
-         {
-           wc = wparam[n]; wparam[n] = L'\0';
-           if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               wparam[n] = wc;
-               return (wcsdup (wparam + n));
-             }
-           wparam[n] = wc;
-         }
-       break;
-
-      case RP_LONG_RIGHT:      /* remove longest match at end */
-        for (n = 0; n <= wstrlen; n++)
-         {
-           if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               wc = wparam[n]; wparam[n] = L'\0';
-               ret = wcsdup (wparam);
-               wparam[n] = wc;
-               return (ret);
-             }
-         }
-       break;
-
-      case RP_SHORT_RIGHT:     /* remove shortest match at end */
-       for (n = wstrlen; n >= 0; n--)
-         {
-           if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               wc = wparam[n]; wparam[n] = L'\0';
-               ret = wcsdup (wparam);
-               wparam[n] = wc;
-               return (ret);
-             }
-         }
-       break;
-    }
-
-  return (wcsdup (wparam));    /* no match, return original string */
-}
-#endif /* HANDLE_MULTIBYTE */
-
-static char *
-remove_pattern (param, pattern, op)
-     char *param, *pattern;
-     int op;
-{
-  if (param == NULL)
-    return (param);
-  if (*param == '\0' || pattern == NULL || *pattern == '\0')   /* minor optimization */
-    return (savestring (param));
-
-#if defined (HANDLE_MULTIBYTE)
-  if (MB_CUR_MAX > 1)
-    {
-      wchar_t *ret, *oret;
-      size_t n;
-      wchar_t *wparam, *wpattern;
-      mbstate_t ps;
-      char *xret;
-
-      n = xdupmbstowcs (&wpattern, NULL, pattern);
-      if (n == (size_t)-1)
-       return (remove_upattern (param, pattern, op));
-      n = xdupmbstowcs (&wparam, NULL, param);
-      if (n == (size_t)-1)
-       {
-         free (wpattern);
-         return (remove_upattern (param, pattern, op));
-       }
-      oret = ret = remove_wpattern (wparam, n, wpattern, op);
-
-      free (wparam);
-      free (wpattern);
-
-      n = strlen (param);
-      xret = (char *)xmalloc (n + 1);
-      memset (&ps, '\0', sizeof (mbstate_t));
-      n = wcsrtombs (xret, (const wchar_t **)&ret, n, &ps);
-      xret[n] = '\0';          /* just to make sure */
-      free (oret);
-      return xret;      
-    }
-  else
-#endif
-    return (remove_upattern (param, pattern, op));
-}
-
-/* Return 1 of the first character of STRING could match the first
-   character of pattern PAT.  Used to avoid n2 calls to strmatch(). */
-static int
-match_pattern_char (pat, string)
-     char *pat, *string;
-{
-  char c;
-
-  if (*string == 0)
-    return (0);
-
-  switch (c = *pat++)
-    {
-    default:
-      return (*string == c);
-    case '\\':
-      return (*string == *pat);
-    case '?':
-      return (*pat == LPAREN ? 1 : (*string != '\0'));
-    case '*':
-      return (1);
-    case '+':
-    case '!':
-    case '@':
-      return (*pat == LPAREN ? 1 : (*string == c));
-    case '[':
-      return (*string != '\0');
-    }
-}
-
-/* Match PAT anywhere in STRING and return the match boundaries.
-   This returns 1 in case of a successful match, 0 otherwise.  SP
-   and EP are pointers into the string where the match begins and
-   ends, respectively.  MTYPE controls what kind of match is attempted.
-   MATCH_BEG and MATCH_END anchor the match at the beginning and end
-   of the string, respectively.  The longest match is returned. */
-static int
-match_upattern (string, pat, mtype, sp, ep)
-     char *string, *pat;
-     int mtype;
-     char **sp, **ep;
-{
-  int c, len;
-  register char *p, *p1, *npat;
-  char *end;
-
-  /* If the pattern doesn't match anywhere in the string, go ahead and
-     short-circuit right away.  A minor optimization, saves a bunch of
-     unnecessary calls to strmatch (up to N calls for a string of N
-     characters) if the match is unsuccessful.  To preserve the semantics
-     of the substring matches below, we make sure that the pattern has
-     `*' as first and last character, making a new pattern if necessary. */
-  /* XXX - check this later if I ever implement `**' with special meaning,
-     since this will potentially result in `**' at the beginning or end */
-  len = STRLEN (pat);
-  if (pat[0] != '*' || (pat[0] == '*' && pat[1] == LPAREN && extended_glob) || pat[len - 1] != '*')
-    {
-      p = npat = (char *)xmalloc (len + 3);
-      p1 = pat;
-      if (*p1 != '*' || (*p1 == '*' && p1[1] == LPAREN && extended_glob))
-       *p++ = '*';
-      while (*p1)
-       *p++ = *p1++;
-      if (p1[-1] != '*' || p[-2] == '\\')
-       *p++ = '*';
-      *p = '\0';
-    }
-  else
-    npat = pat;
-  c = strmatch (npat, string, FNMATCH_EXTFLAG);
-  if (npat != pat)
-    free (npat);
-  if (c == FNM_NOMATCH)
-    return (0);
-
-  len = STRLEN (string);
-  end = string + len;
-
-  switch (mtype)
-    {
-    case MATCH_ANY:
-      for (p = string; p <= end; p++)
-       {
-         if (match_pattern_char (pat, p))
-           {
-             for (p1 = end; p1 >= p; p1--)
-               {
-                 c = *p1; *p1 = '\0';
-                 if (strmatch (pat, p, FNMATCH_EXTFLAG) == 0)
-                   {
-                     *p1 = c;
-                     *sp = p;
-                     *ep = p1;
-                     return 1;
-                   }
-                 *p1 = c;
-               }
-           }
-       }
-
-      return (0);
-
-    case MATCH_BEG:
-      if (match_pattern_char (pat, string) == 0)
-       return (0);
-
-      for (p = end; p >= string; p--)
-       {
-         c = *p; *p = '\0';
-         if (strmatch (pat, string, FNMATCH_EXTFLAG) == 0)
-           {
-             *p = c;
-             *sp = string;
-             *ep = p;
-             return 1;
-           }
-         *p = c;
-       }
-
-      return (0);
-
-    case MATCH_END:
-      for (p = string; p <= end; p++)
-       {
-         if (strmatch (pat, p, FNMATCH_EXTFLAG) == 0)
-           {
-             *sp = p;
-             *ep = end;
-             return 1;
-           }
-
-       }
-
-      return (0);
-    }
-
-  return (0);
-}
-
-#if defined (HANDLE_MULTIBYTE)
-/* Return 1 of the first character of WSTRING could match the first
-   character of pattern WPAT.  Wide character version. */
-static int
-match_pattern_wchar (wpat, wstring)
-     wchar_t *wpat, *wstring;
-{
-  wchar_t wc;
-
-  if (*wstring == 0)
-    return (0);
-
-  switch (wc = *wpat++)
-    {
-    default:
-      return (*wstring == wc);
-    case L'\\':
-      return (*wstring == *wpat);
-    case L'?':
-      return (*wpat == LPAREN ? 1 : (*wstring != L'\0'));
-    case L'*':
-      return (1);
-    case L'+':
-    case L'!':
-    case L'@':
-      return (*wpat == LPAREN ? 1 : (*wstring == wc));
-    case L'[':
-      return (*wstring != L'\0');
-    }
-}
-
-/* Match WPAT anywhere in WSTRING and return the match boundaries.
-   This returns 1 in case of a successful match, 0 otherwise.  Wide
-   character version. */
-static int
-match_wpattern (wstring, indices, wstrlen, wpat, mtype, sp, ep)
-     wchar_t *wstring;
-     char **indices;
-     size_t wstrlen;
-     wchar_t *wpat;
-     int mtype;
-     char **sp, **ep;
-{
-  wchar_t wc, *wp, *nwpat, *wp1;
-  int len;
-#if 0
-  size_t n, n1;        /* Apple's gcc seems to miscompile this badly */
-#else
-  int n, n1;
-#endif
-
-  /* If the pattern doesn't match anywhere in the string, go ahead and
-     short-circuit right away.  A minor optimization, saves a bunch of
-     unnecessary calls to strmatch (up to N calls for a string of N
-     characters) if the match is unsuccessful.  To preserve the semantics
-     of the substring matches below, we make sure that the pattern has
-     `*' as first and last character, making a new pattern if necessary. */
-  /* XXX - check this later if I ever implement `**' with special meaning,
-     since this will potentially result in `**' at the beginning or end */
-  len = wcslen (wpat);
-  if (wpat[0] != L'*' || (wpat[0] == L'*' && wpat[1] == WLPAREN && extended_glob) || wpat[len - 1] != L'*')
-    {
-      wp = nwpat = (wchar_t *)xmalloc ((len + 3) * sizeof (wchar_t));
-      wp1 = wpat;
-      if (*wp1 != L'*' || (*wp1 == '*' && wp1[1] == WLPAREN && extended_glob))
-       *wp++ = L'*';
-      while (*wp1 != L'\0')
-       *wp++ = *wp1++;
-      if (wp1[-1] != L'*' || wp1[-2] == L'\\')
-        *wp++ = L'*';
-      *wp = '\0';
-    }
-  else
-    nwpat = wpat;
-  len = wcsmatch (nwpat, wstring, FNMATCH_EXTFLAG);
-  if (nwpat != wpat)
-    free (nwpat);
-  if (len == FNM_NOMATCH)
-    return (0);
-
-  switch (mtype)
-    {
-    case MATCH_ANY:
-      for (n = 0; n <= wstrlen; n++)
-       {
-         if (match_pattern_wchar (wpat, wstring + n))
-           {
-             for (n1 = wstrlen; n1 >= n; n1--)
-               {
-                 wc = wstring[n1]; wstring[n1] = L'\0';
-                 if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG) == 0)
-                   {
-                     wstring[n1] = wc;
-                     *sp = indices[n];
-                     *ep = indices[n1];
-                     return 1;
-                   }
-                 wstring[n1] = wc;
-               }
-           }
-       }
-
-      return (0);
-
-    case MATCH_BEG:
-      if (match_pattern_wchar (wpat, wstring) == 0)
-       return (0);
-
-      for (n = wstrlen; n >= 0; n--)
-       {
-         wc = wstring[n]; wstring[n] = L'\0';
-         if (wcsmatch (wpat, wstring, FNMATCH_EXTFLAG) == 0)
-           {
-             wstring[n] = wc;
-             *sp = indices[0];
-             *ep = indices[n];
-             return 1;
-           }
-         wstring[n] = wc;
-       }
-
-      return (0);
-
-    case MATCH_END:
-      for (n = 0; n <= wstrlen; n++)
-       {
-         if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG) == 0)
-           {
-             *sp = indices[n];
-             *ep = indices[wstrlen];
-             return 1;
-           }
-       }
-
-      return (0);
-    }
-
-  return (0);
-}
-#endif /* HANDLE_MULTIBYTE */
-
-static int
-match_pattern (string, pat, mtype, sp, ep)
-     char *string, *pat;
-     int mtype;
-     char **sp, **ep;
-{
-#if defined (HANDLE_MULTIBYTE)
-  int ret;
-  size_t n;
-  wchar_t *wstring, *wpat;
-  char **indices;
-#endif
-
-  if (string == 0 || *string == 0 || pat == 0 || *pat == 0)
-    return (0);
-
-#if defined (HANDLE_MULTIBYTE)
-  if (MB_CUR_MAX > 1)
-    {
-      n = xdupmbstowcs (&wpat, NULL, pat);
-      if (n == (size_t)-1)
-       return (match_upattern (string, pat, mtype, sp, ep));
-      n = xdupmbstowcs (&wstring, &indices, string);
-      if (n == (size_t)-1)
-       {
-         free (wpat);
-         return (match_upattern (string, pat, mtype, sp, ep));
-       }
-      ret = match_wpattern (wstring, indices, n, wpat, mtype, sp, ep);
-
-      free (wpat);
-      free (wstring);
-      free (indices);
-
-      return (ret);
-    }
-  else
-#endif
-    return (match_upattern (string, pat, mtype, sp, ep));
-}
-
-static int
-getpatspec (c, value)
-     int c;
-     char *value;
-{
-  if (c == '#')
-    return ((*value == '#') ? RP_LONG_LEFT : RP_SHORT_LEFT);
-  else /* c == '%' */
-    return ((*value == '%') ? RP_LONG_RIGHT : RP_SHORT_RIGHT);
-}
-
-/* Posix.2 says that the WORD should be run through tilde expansion,
-   parameter expansion, command substitution and arithmetic expansion.
-   This leaves the result quoted, so quote_string_for_globbing () has
-   to be called to fix it up for strmatch ().  If QUOTED is non-zero,
-   it means that the entire expression was enclosed in double quotes.
-   This means that quoting characters in the pattern do not make any
-   special pattern characters quoted.  For example, the `*' in the
-   following retains its special meaning: "${foo#'*'}". */
-static char *
-getpattern (value, quoted, expandpat)
-     char *value;
-     int quoted, expandpat;
-{
-  char *pat, *tword;
-  WORD_LIST *l;
-#if 0
-  int i;
-#endif
-  /* There is a problem here:  how to handle single or double quotes in the
-     pattern string when the whole expression is between double quotes?
-     POSIX.2 says that enclosing double quotes do not cause the pattern to
-     be quoted, but does that leave us a problem with @ and array[@] and their
-     expansions inside a pattern? */
-#if 0
-  if (expandpat && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *tword)
-    {
-      i = 0;
-      pat = string_extract_double_quoted (tword, &i, 1);
-      free (tword);
-      tword = pat;
-    }
-#endif
-
-  /* expand_string_for_rhs () leaves WORD quoted and does not perform
-     word splitting. */
-  l = *value ? expand_string_for_rhs (value,
-                                     (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? Q_PATQUOTE : quoted,
-                                     (int *)NULL, (int *)NULL)
-            : (WORD_LIST *)0;
-  pat = string_list (l);
-  dispose_words (l);
-  if (pat)
-    {
-      tword = quote_string_for_globbing (pat, QGLOB_CVTNULL);
-      free (pat);
-      pat = tword;
-    }
-  return (pat);
-}
-
-#if 0
-/* Handle removing a pattern from a string as a result of ${name%[%]value}
-   or ${name#[#]value}. */
-static char *
-variable_remove_pattern (value, pattern, patspec, quoted)
-     char *value, *pattern;
-     int patspec, quoted;
-{
-  char *tword;
-
-  tword = remove_pattern (value, pattern, patspec);
-
-  return (tword);
-}
-#endif
-
-static char *
-list_remove_pattern (list, pattern, patspec, itype, quoted)
-     WORD_LIST *list;
-     char *pattern;
-     int patspec, itype, quoted;
-{
-  WORD_LIST *new, *l;
-  WORD_DESC *w;
-  char *tword;
-
-  for (new = (WORD_LIST *)NULL, l = list; l; l = l->next)
-    {
-      tword = remove_pattern (l->word->word, pattern, patspec);
-      w = alloc_word_desc ();
-      w->word = tword ? tword : savestring ("");
-      new = make_word_list (w, new);
-    }
-
-  l = REVERSE_LIST (new, WORD_LIST *);
-  tword = string_list_pos_params (itype, l, quoted);
-  dispose_words (l);
-
-  return (tword);
-}
-
-static char *
-parameter_list_remove_pattern (itype, pattern, patspec, quoted)
-     int itype;
-     char *pattern;
-     int patspec, quoted;
-{
-  char *ret;
-  WORD_LIST *list;
-
-  list = list_rest_of_args ();
-  if (list == 0)
-    return ((char *)NULL);
-  ret = list_remove_pattern (list, pattern, patspec, itype, quoted);
-  dispose_words (list);
-  return (ret);
-}
-
-#if defined (ARRAY_VARS)
-static char *
-array_remove_pattern (var, pattern, patspec, varname, quoted)
-     SHELL_VAR *var;
-     char *pattern;
-     int patspec;
-     char *varname;    /* so we can figure out how it's indexed */
-     int quoted;
-{
-  ARRAY *a;
-  HASH_TABLE *h;
-  int itype;
-  char *ret;
-  WORD_LIST *list;
-  SHELL_VAR *v;
-
-  /* compute itype from varname here */
-  v = array_variable_part (varname, &ret, 0);
-  itype = ret[0];
-
-  a = (v && array_p (v)) ? array_cell (v) : 0;
-  h = (v && assoc_p (v)) ? assoc_cell (v) : 0;
-  
-  list = a ? array_to_word_list (a) : (h ? assoc_to_word_list (h) : 0);
-  if (list == 0)
-   return ((char *)NULL);
-  ret = list_remove_pattern (list, pattern, patspec, itype, quoted);
-  dispose_words (list);
-
-  return ret;
-}
-#endif /* ARRAY_VARS */
-
-static char *
-parameter_brace_remove_pattern (varname, value, patstr, rtype, quoted)
-     char *varname, *value, *patstr;
-     int rtype, quoted;
-{
-  int vtype, patspec, starsub;
-  char *temp1, *val, *pattern;
-  SHELL_VAR *v;
-
-  if (value == 0)
-    return ((char *)NULL);
-
-  this_command_name = varname;
-
-  vtype = get_var_and_type (varname, value, quoted, &v, &val);
-  if (vtype == -1)
-    return ((char *)NULL);
-
-  starsub = vtype & VT_STARSUB;
-  vtype &= ~VT_STARSUB;
-
-  patspec = getpatspec (rtype, patstr);
-  if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT)
-    patstr++;
-
-  /* Need to pass getpattern newly-allocated memory in case of expansion --
-     the expansion code will free the passed string on an error. */
-  temp1 = savestring (patstr);
-  pattern = getpattern (temp1, quoted, 1);
-  free (temp1);
-
-  temp1 = (char *)NULL;                /* shut up gcc */
-  switch (vtype)
-    {
-    case VT_VARIABLE:
-    case VT_ARRAYMEMBER:
-      temp1 = remove_pattern (val, pattern, patspec);
-      if (vtype == VT_VARIABLE)
-       FREE (val);
-      if (temp1)
-       {
-         val = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-                       ? quote_string (temp1)
-                       : quote_escapes (temp1);
-         free (temp1);
-         temp1 = val;
-       }
-      break;
-#if defined (ARRAY_VARS)
-    case VT_ARRAYVAR:
-      temp1 = array_remove_pattern (v, pattern, patspec, varname, quoted);
-      if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
-       {
-         val = quote_escapes (temp1);
-         free (temp1);
-         temp1 = val;
-       }
-      break;
-#endif
-    case VT_POSPARMS:
-      temp1 = parameter_list_remove_pattern (varname[0], pattern, patspec, quoted);
-      if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
-       {
-         val = quote_escapes (temp1);
-         free (temp1);
-         temp1 = val;
-       }
-      break;
-    }
-
-  FREE (pattern);
-  return temp1;
-}    
-
-/*******************************************
- *                                        *
- *     Functions to expand WORD_DESCs     *
- *                                        *
- *******************************************/
-
-/* Expand WORD, performing word splitting on the result.  This does
-   parameter expansion, command substitution, arithmetic expansion,
-   word splitting, and quote removal. */
-
-WORD_LIST *
-expand_word (word, quoted)
-     WORD_DESC *word;
-     int quoted;
-{
-  WORD_LIST *result, *tresult;
-
-  tresult = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
-  result = word_list_split (tresult);
-  dispose_words (tresult);
-  return (result ? dequote_list (result) : result);
-}
-
-/* Expand WORD, but do not perform word splitting on the result.  This
-   does parameter expansion, command substitution, arithmetic expansion,
-   and quote removal. */
-WORD_LIST *
-expand_word_unsplit (word, quoted)
-     WORD_DESC *word;
-     int quoted;
-{
-  WORD_LIST *result;
-
-  expand_no_split_dollar_star = 1;
-#if defined (HANDLE_MULTIBYTE)
-  if (ifs_firstc[0] == 0)
-#else
-  if (ifs_firstc == 0)
-#endif
-    word->flags |= W_NOSPLIT;
-  result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
-  expand_no_split_dollar_star = 0;
-
-  return (result ? dequote_list (result) : result);
-}
-
-/* Perform shell expansions on WORD, but do not perform word splitting or
-   quote removal on the result.  Virtually identical to expand_word_unsplit;
-   could be combined if implementations don't diverge. */
-WORD_LIST *
-expand_word_leave_quoted (word, quoted)
-     WORD_DESC *word;
-     int quoted;
-{
-  WORD_LIST *result;
-
-  expand_no_split_dollar_star = 1;
-#if defined (HANDLE_MULTIBYTE)
-  if (ifs_firstc[0] == 0)
-#else
-  if (ifs_firstc == 0)
-#endif
-    word->flags |= W_NOSPLIT;
-  result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
-  expand_no_split_dollar_star = 0;
-
-  return result;
-}
-
-#if defined (PROCESS_SUBSTITUTION)
-
-/*****************************************************************/
-/*                                                              */
-/*                 Hacking Process Substitution                 */
-/*                                                              */
-/*****************************************************************/
-
-#if !defined (HAVE_DEV_FD)
-/* Named pipes must be removed explicitly with `unlink'.  This keeps a list
-   of FIFOs the shell has open.  unlink_fifo_list will walk the list and
-   unlink all of them. add_fifo_list adds the name of an open FIFO to the
-   list.  NFIFO is a count of the number of FIFOs in the list. */
-#define FIFO_INCR 20
-
-struct temp_fifo {
-  char *file;
-  pid_t proc;
-};
-
-static struct temp_fifo *fifo_list = (struct temp_fifo *)NULL;
-static int nfifo;
-static int fifo_list_size;
-
-static void
-add_fifo_list (pathname)
-     char *pathname;
-{
-  if (nfifo >= fifo_list_size - 1)
-    {
-      fifo_list_size += FIFO_INCR;
-      fifo_list = (struct temp_fifo *)xrealloc (fifo_list,
-                               fifo_list_size * sizeof (struct temp_fifo));
-    }
-
-  fifo_list[nfifo].file = savestring (pathname);
-  nfifo++;
-}
-
-void
-unlink_fifo_list ()
-{
-  int saved, i, j;
-
-  if (nfifo == 0)
-    return;
-
-  for (i = saved = 0; i < nfifo; i++)
-    {
-      if ((fifo_list[i].proc == -1) || (kill(fifo_list[i].proc, 0) == -1))
-       {
-         unlink (fifo_list[i].file);
-         free (fifo_list[i].file);
-         fifo_list[i].file = (char *)NULL;
-         fifo_list[i].proc = -1;
-       }
-      else
-       saved++;
-    }
-
-  /* If we didn't remove some of the FIFOs, compact the list. */
-  if (saved)
-    {
-      for (i = j = 0; i < nfifo; i++)
-       if (fifo_list[i].file)
-         {
-           fifo_list[j].file = fifo_list[i].file;
-           fifo_list[j].proc = fifo_list[i].proc;
-           j++;
-         }
-      nfifo = j;
-    }
-  else
-    nfifo = 0;
-}
-
-int
-fifos_pending ()
-{
-  return nfifo;
-}
-
-static char *
-make_named_pipe ()
-{
-  char *tname;
-
-  tname = sh_mktmpname ("sh-np", MT_USERANDOM|MT_USETMPDIR);
-  if (mkfifo (tname, 0600) < 0)
-    {
-      free (tname);
-      return ((char *)NULL);
-    }
-
-  add_fifo_list (tname);
-  return (tname);
-}
-
-#else /* HAVE_DEV_FD */
-
-/* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
-   has open to children.  NFDS is a count of the number of bits currently
-   set in DEV_FD_LIST.  TOTFDS is a count of the highest possible number
-   of open files. */
-static char *dev_fd_list = (char *)NULL;
-static int nfds;
-static int totfds;     /* The highest possible number of open files. */
-
-static void
-add_fifo_list (fd)
-     int fd;
-{
-  if (!dev_fd_list || fd >= totfds)
-    {
-      int ofds;
-
-      ofds = totfds;
-      totfds = getdtablesize ();
-      if (totfds < 0 || totfds > 256)
-       totfds = 256;
-      if (fd >= totfds)
-       totfds = fd + 2;
-
-      dev_fd_list = (char *)xrealloc (dev_fd_list, totfds);
-      memset (dev_fd_list + ofds, '\0', totfds - ofds);
-    }
-
-  dev_fd_list[fd] = 1;
-  nfds++;
-}
-
-int
-fifos_pending ()
-{
-  return 0;    /* used for cleanup; not needed with /dev/fd */
-}
-
-void
-unlink_fifo_list ()
-{
-  register int i;
-
-  if (nfds == 0)
-    return;
-
-  for (i = 0; nfds && i < totfds; i++)
-    if (dev_fd_list[i])
-      {
-       close (i);
-       dev_fd_list[i] = 0;
-       nfds--;
-      }
-
-  nfds = 0;
-}
-
-#if defined (NOTDEF)
-print_dev_fd_list ()
-{
-  register int i;
-
-  fprintf (stderr, "pid %ld: dev_fd_list:", (long)getpid ());
-  fflush (stderr);
-
-  for (i = 0; i < totfds; i++)
-    {
-      if (dev_fd_list[i])
-       fprintf (stderr, " %d", i);
-    }
-  fprintf (stderr, "\n");
-}
-#endif /* NOTDEF */
-
-static char *
-make_dev_fd_filename (fd)
-     int fd;
-{
-  char *ret, intbuf[INT_STRLEN_BOUND (int) + 1], *p;
-
-  ret = (char *)xmalloc (sizeof (DEV_FD_PREFIX) + 8);
-
-  strcpy (ret, DEV_FD_PREFIX);
-  p = inttostr (fd, intbuf, sizeof (intbuf));
-  strcpy (ret + sizeof (DEV_FD_PREFIX) - 1, p);
-
-  add_fifo_list (fd);
-  return (ret);
-}
-
-#endif /* HAVE_DEV_FD */
-
-/* Return a filename that will open a connection to the process defined by
-   executing STRING.  HAVE_DEV_FD, if defined, means open a pipe and return
-   a filename in /dev/fd corresponding to a descriptor that is one of the
-   ends of the pipe.  If not defined, we use named pipes on systems that have
-   them.  Systems without /dev/fd and named pipes are out of luck.
-
-   OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
-   use the read end of the pipe and dup that file descriptor to fd 0 in
-   the child.  If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
-   writing or use the write end of the pipe in the child, and dup that
-   file descriptor to fd 1 in the child.  The parent does the opposite. */
-
-static char *
-process_substitute (string, open_for_read_in_child)
-     char *string;
-     int open_for_read_in_child;
-{
-  char *pathname;
-  int fd, result;
-  pid_t old_pid, pid;
-#if defined (HAVE_DEV_FD)
-  int parent_pipe_fd, child_pipe_fd;
-  int fildes[2];
-#endif /* HAVE_DEV_FD */
-#if defined (JOB_CONTROL)
-  pid_t old_pipeline_pgrp;
-#endif
-
-  if (!string || !*string || wordexp_only)
-    return ((char *)NULL);
-
-#if !defined (HAVE_DEV_FD)
-  pathname = make_named_pipe ();
-#else /* HAVE_DEV_FD */
-  if (pipe (fildes) < 0)
-    {
-      sys_error (_("cannot make pipe for process substitution"));
-      return ((char *)NULL);
-    }
-  /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
-     the pipe in the parent, otherwise the read end. */
-  parent_pipe_fd = fildes[open_for_read_in_child];
-  child_pipe_fd = fildes[1 - open_for_read_in_child];
-  /* Move the parent end of the pipe to some high file descriptor, to
-     avoid clashes with FDs used by the script. */
-  parent_pipe_fd = move_to_high_fd (parent_pipe_fd, 1, 64);
-
-  pathname = make_dev_fd_filename (parent_pipe_fd);
-#endif /* HAVE_DEV_FD */
-
-  if (pathname == 0)
-    {
-      sys_error (_("cannot make pipe for process substitution"));
-      return ((char *)NULL);
-    }
-
-  old_pid = last_made_pid;
-
-#if defined (JOB_CONTROL)
-  old_pipeline_pgrp = pipeline_pgrp;
-  pipeline_pgrp = shell_pgrp;
-  save_pipeline (1);
-#endif /* JOB_CONTROL */
-
-  pid = make_child ((char *)NULL, 1);
-  if (pid == 0)
-    {
-      reset_terminating_signals ();    /* XXX */
-      free_pushed_string_input ();
-      /* Cancel traps, in trap.c. */
-      restore_original_signals ();
-      setup_async_signals ();
-      subshell_environment |= SUBSHELL_COMSUB|SUBSHELL_PROCSUB;
-    }
-
-#if defined (JOB_CONTROL)
-  set_sigchld_handler ();
-  stop_making_children ();
-  /* XXX - should we only do this in the parent? (as in command subst) */
-  pipeline_pgrp = old_pipeline_pgrp;
-#endif /* JOB_CONTROL */
-
-  if (pid < 0)
-    {
-      sys_error (_("cannot make child for process substitution"));
-      free (pathname);
-#if defined (HAVE_DEV_FD)
-      close (parent_pipe_fd);
-      close (child_pipe_fd);
-#endif /* HAVE_DEV_FD */
-      return ((char *)NULL);
-    }
-
-  if (pid > 0)
-    {
-#if defined (JOB_CONTROL)
-      restore_pipeline (1);
-#endif
-
-#if !defined (HAVE_DEV_FD)
-      fifo_list[nfifo-1].proc = pid;
-#endif
-
-      last_made_pid = old_pid;
-
-#if defined (JOB_CONTROL) && defined (PGRP_PIPE)
-      close_pgrp_pipe ();
-#endif /* JOB_CONTROL && PGRP_PIPE */
-
-#if defined (HAVE_DEV_FD)
-      close (child_pipe_fd);
-#endif /* HAVE_DEV_FD */
-
-      return (pathname);
-    }
-
-  set_sigint_handler ();
-
-#if defined (JOB_CONTROL)
-  set_job_control (0);
-#endif /* JOB_CONTROL */
-
-#if !defined (HAVE_DEV_FD)
-  /* Open the named pipe in the child. */
-  fd = open (pathname, open_for_read_in_child ? O_RDONLY|O_NONBLOCK : O_WRONLY);
-  if (fd < 0)
-    {
-      /* Two separate strings for ease of translation. */
-      if (open_for_read_in_child)
-       sys_error (_("cannot open named pipe %s for reading"), pathname);
-      else
-       sys_error (_("cannot open named pipe %s for writing"), pathname);
-
-      exit (127);
-    }
-  if (open_for_read_in_child)
-    {
-      if (sh_unset_nodelay_mode (fd) < 0)
-       {
-         sys_error (_("cannot reset nodelay mode for fd %d"), fd);
-         exit (127);
-       }
-    }
-#else /* HAVE_DEV_FD */
-  fd = child_pipe_fd;
-#endif /* HAVE_DEV_FD */
-
-  if (dup2 (fd, open_for_read_in_child ? 0 : 1) < 0)
-    {
-      sys_error (_("cannot duplicate named pipe %s as fd %d"), pathname,
-       open_for_read_in_child ? 0 : 1);
-      exit (127);
-    }
-
-  if (fd != (open_for_read_in_child ? 0 : 1))
-    close (fd);
-
-  /* Need to close any files that this process has open to pipes inherited
-     from its parent. */
-  if (current_fds_to_close)
-    {
-      close_fd_bitmap (current_fds_to_close);
-      current_fds_to_close = (struct fd_bitmap *)NULL;
-    }
-
-#if defined (HAVE_DEV_FD)
-  /* Make sure we close the parent's end of the pipe and clear the slot
-     in the fd list so it is not closed later, if reallocated by, for
-     instance, pipe(2). */
-  close (parent_pipe_fd);
-  dev_fd_list[parent_pipe_fd] = 0;
-#endif /* HAVE_DEV_FD */
-
-  result = parse_and_execute (string, "process substitution", (SEVAL_NONINT|SEVAL_NOHIST));
-
-#if !defined (HAVE_DEV_FD)
-  /* Make sure we close the named pipe in the child before we exit. */
-  close (open_for_read_in_child ? 0 : 1);
-#endif /* !HAVE_DEV_FD */
-
-  exit (result);
-  /*NOTREACHED*/
-}
-#endif /* PROCESS_SUBSTITUTION */
-
-/***********************************/
-/*                                */
-/*     Command Substitution       */
-/*                                */
-/***********************************/
-
-static char *
-read_comsub (fd, quoted, rflag)
-     int fd, quoted;
-     int *rflag;
-{
-  char *istring, buf[128], *bufp, *s;
-  int istring_index, istring_size, c, tflag, skip_ctlesc, skip_ctlnul;
-  ssize_t bufn;
-
-  istring = (char *)NULL;
-  istring_index = istring_size = bufn = tflag = 0;
-
-  for (skip_ctlesc = skip_ctlnul = 0, s = ifs_value; s && *s; s++)
-    skip_ctlesc |= *s == CTLESC, skip_ctlnul |= *s == CTLNUL;
-
-#ifdef __CYGWIN__
-  setmode (fd, O_TEXT);                /* we don't want CR/LF, we want Unix-style */
-#endif
-
-  /* Read the output of the command through the pipe.  This may need to be
-     changed to understand multibyte characters in the future. */
-  while (1)
-    {
-      if (fd < 0)
-       break;
-      if (--bufn <= 0)
-       {
-         bufn = zread (fd, buf, sizeof (buf));
-         if (bufn <= 0) 
-           break;
-         bufp = buf;
-       }
-      c = *bufp++;
-
-      if (c == 0)
-       {
-#if 0
-         internal_warning ("read_comsub: ignored null byte in input");
-#endif
-         continue;
-       }
-
-      /* Add the character to ISTRING, possibly after resizing it. */
-      RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE);
-
-      /* This is essentially quote_string inline */
-      if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) /* || c == CTLESC || c == CTLNUL */)
-       istring[istring_index++] = CTLESC;
-      /* Escape CTLESC and CTLNUL in the output to protect those characters
-        from the rest of the word expansions (word splitting and globbing.)
-        This is essentially quote_escapes inline. */
-      else if (skip_ctlesc == 0 && c == CTLESC)
-       {
-         tflag |= W_HASCTLESC;
-         istring[istring_index++] = CTLESC;
-       }
-      else if ((skip_ctlnul == 0 && c == CTLNUL) || (c == ' ' && (ifs_value && *ifs_value == 0)))
-       istring[istring_index++] = CTLESC;
-
-      istring[istring_index++] = c;
-
-#if 0
-#if defined (__CYGWIN__)
-      if (c == '\n' && istring_index > 1 && istring[istring_index - 2] == '\r')
-       {
-         istring_index--;
-         istring[istring_index - 1] = '\n';
-       }
-#endif
-#endif
-    }
-
-  if (istring)
-    istring[istring_index] = '\0';
-
-  /* If we read no output, just return now and save ourselves some
-     trouble. */
-  if (istring_index == 0)
-    {
-      FREE (istring);
-      if (rflag)
-       *rflag = tflag;
-      return (char *)NULL;
-    }
-
-  /* Strip trailing newlines from the output of the command. */
-  if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-    {
-      while (istring_index > 0)
-       {
-         if (istring[istring_index - 1] == '\n')
-           {
-             --istring_index;
-
-             /* If the newline was quoted, remove the quoting char. */
-             if (istring[istring_index - 1] == CTLESC)
-               --istring_index;
-           }
-         else
-           break;
-       }
-      istring[istring_index] = '\0';
-    }
-  else
-    strip_trailing (istring, istring_index - 1, 1);
-
-  if (rflag)
-    *rflag = tflag;
-  return istring;
-}
-
-/* Perform command substitution on STRING.  This returns a WORD_DESC * with the
-   contained string possibly quoted. */
-WORD_DESC *
-command_substitute (string, quoted)
-     char *string;
-     int quoted;
-{
-  pid_t pid, old_pid, old_pipeline_pgrp, old_async_pid;
-  char *istring;
-  int result, fildes[2], function_value, pflags, rc, tflag;
-  WORD_DESC *ret;
-
-  istring = (char *)NULL;
-
-  /* Don't fork () if there is no need to.  In the case of no command to
-     run, just return NULL. */
-  if (!string || !*string || (string[0] == '\n' && !string[1]))
-    return ((WORD_DESC *)NULL);
-
-  if (wordexp_only && read_but_dont_execute)
-    {
-      last_command_exit_value = EX_WEXPCOMSUB;
-      jump_to_top_level (EXITPROG);
-    }
-
-  /* We're making the assumption here that the command substitution will
-     eventually run a command from the file system.  Since we'll run
-     maybe_make_export_env in this subshell before executing that command,
-     the parent shell and any other shells it starts will have to remake
-     the environment.  If we make it before we fork, other shells won't
-     have to.  Don't bother if we have any temporary variable assignments,
-     though, because the export environment will be remade after this
-     command completes anyway, but do it if all the words to be expanded
-     are variable assignments. */
-  if (subst_assign_varlist == 0 || garglist == 0)
-    maybe_make_export_env ();  /* XXX */
-
-  /* Flags to pass to parse_and_execute() */
-  pflags = interactive ? SEVAL_RESETLINE : 0;
-
-  /* Pipe the output of executing STRING into the current shell. */
-  if (pipe (fildes) < 0)
-    {
-      sys_error (_("cannot make pipe for command substitution"));
-      goto error_exit;
-    }
-
-  old_pid = last_made_pid;
-#if defined (JOB_CONTROL)
-  old_pipeline_pgrp = pipeline_pgrp;
-  /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
-  if ((subshell_environment & SUBSHELL_PIPE) == 0)
-    pipeline_pgrp = shell_pgrp;
-  cleanup_the_pipeline ();
-#endif /* JOB_CONTROL */
-
-  old_async_pid = last_asynchronous_pid;
-  pid = make_child ((char *)NULL, subshell_environment&SUBSHELL_ASYNC);
-  last_asynchronous_pid = old_async_pid;
-
-  if (pid == 0)
-    /* Reset the signal handlers in the child, but don't free the
-       trap strings. */
-    reset_signal_handlers ();
-
-#if defined (JOB_CONTROL)
-  /* XXX DO THIS ONLY IN PARENT ? XXX */
-  set_sigchld_handler ();
-  stop_making_children ();
-  if (pid != 0)
-    pipeline_pgrp = old_pipeline_pgrp;
-#else
-  stop_making_children ();
-#endif /* JOB_CONTROL */
-
-  if (pid < 0)
-    {
-      sys_error (_("cannot make child for command substitution"));
-    error_exit:
-
-      FREE (istring);
-      close (fildes[0]);
-      close (fildes[1]);
-      return ((WORD_DESC *)NULL);
-    }
-
-  if (pid == 0)
-    {
-      set_sigint_handler ();   /* XXX */
-
-      free_pushed_string_input ();
-
-      if (dup2 (fildes[1], 1) < 0)
-       {
-         sys_error (_("command_substitute: cannot duplicate pipe as fd 1"));
-         exit (EXECUTION_FAILURE);
-       }
-
-      /* If standard output is closed in the parent shell
-        (such as after `exec >&-'), file descriptor 1 will be
-        the lowest available file descriptor, and end up in
-        fildes[0].  This can happen for stdin and stderr as well,
-        but stdout is more important -- it will cause no output
-        to be generated from this command. */
-      if ((fildes[1] != fileno (stdin)) &&
-         (fildes[1] != fileno (stdout)) &&
-         (fildes[1] != fileno (stderr)))
-       close (fildes[1]);
-
-      if ((fildes[0] != fileno (stdin)) &&
-         (fildes[0] != fileno (stdout)) &&
-         (fildes[0] != fileno (stderr)))
-       close (fildes[0]);
-
-      /* The currently executing shell is not interactive. */
-      interactive = 0;
-
-      /* This is a subshell environment. */
-      subshell_environment |= SUBSHELL_COMSUB;
-
-      /* When not in POSIX mode, command substitution does not inherit
-        the -e flag. */
-      if (posixly_correct == 0)
-       exit_immediately_on_error = 0;
-
-      remove_quoted_escapes (string);
-
-      startup_state = 2;       /* see if we can avoid a fork */
-      /* Give command substitution a place to jump back to on failure,
-        so we don't go back up to main (). */
-      result = setjmp (top_level);
-
-      /* If we're running a command substitution inside a shell function,
-        trap `return' so we don't return from the function in the subshell
-        and go off to never-never land. */
-      if (result == 0 && return_catch_flag)
-       function_value = setjmp (return_catch);
-      else
-       function_value = 0;
-
-      if (result == ERREXIT)
-       rc = last_command_exit_value;
-      else if (result == EXITPROG)
-       rc = last_command_exit_value;
-      else if (result)
-       rc = EXECUTION_FAILURE;
-      else if (function_value)
-       rc = return_catch_value;
-      else
-       {
-         subshell_level++;
-         rc = parse_and_execute (string, "command substitution", pflags|SEVAL_NOHIST);
-         subshell_level--;
-       }
-
-      last_command_exit_value = rc;
-      rc = run_exit_trap ();
-#if defined (PROCESS_SUBSTITUTION)
-      unlink_fifo_list ();
-#endif
-      exit (rc);
-    }
-  else
-    {
-#if defined (JOB_CONTROL) && defined (PGRP_PIPE)
-      close_pgrp_pipe ();
-#endif /* JOB_CONTROL && PGRP_PIPE */
-
-      close (fildes[1]);
-
-      tflag = 0;
-      istring = read_comsub (fildes[0], quoted, &tflag);
-
-      close (fildes[0]);
-
-      current_command_subst_pid = pid;
-      last_command_exit_value = wait_for (pid);
-      last_command_subst_pid = pid;
-      last_made_pid = old_pid;
-
-#if defined (JOB_CONTROL)
-      /* If last_command_exit_value > 128, then the substituted command
-        was terminated by a signal.  If that signal was SIGINT, then send
-        SIGINT to ourselves.  This will break out of loops, for instance. */
-      if (last_command_exit_value == (128 + SIGINT) && last_command_exit_signal == SIGINT)
-       kill (getpid (), SIGINT);
-
-      /* wait_for gives the terminal back to shell_pgrp.  If some other
-        process group should have it, give it away to that group here.
-        pipeline_pgrp is non-zero only while we are constructing a
-        pipline, so what we are concerned about is whether or not that
-        pipeline was started in the background.  A pipeline started in
-        the background should never get the tty back here. */
-#if 0
-      if (interactive && pipeline_pgrp != (pid_t)0 && pipeline_pgrp != last_asynchronous_pid)
-#else
-      if (interactive && pipeline_pgrp != (pid_t)0 && (subshell_environment & SUBSHELL_ASYNC) == 0)
-#endif
-       give_terminal_to (pipeline_pgrp, 0);
-#endif /* JOB_CONTROL */
-
-      ret = alloc_word_desc ();
-      ret->word = istring;
-      ret->flags = tflag;
-
-      return ret;
-    }
-}
-
-/********************************************************
- *                                                     *
- *     Utility functions for parameter expansion       *
- *                                                     *
- ********************************************************/
-
-#if defined (ARRAY_VARS)
-
-static arrayind_t
-array_length_reference (s)
-     char *s;
-{
-  int len;
-  arrayind_t ind;
-  char *akey;
-  char *t, c;
-  ARRAY *array;
-  SHELL_VAR *var;
-
-  var = array_variable_part (s, &t, &len);
-
-  /* If unbound variables should generate an error, report one and return
-     failure. */
-  if ((var == 0 || (assoc_p (var) == 0 && array_p (var) == 0)) && unbound_vars_is_error)
-    {
-      c = *--t;
-      *t = '\0';
-      last_command_exit_value = EXECUTION_FAILURE;
-      err_unboundvar (s);
-      *t = c;
-      return (-1);
-    }
-  else if (var == 0)
-    return 0;
-
-  /* We support a couple of expansions for variables that are not arrays.
-     We'll return the length of the value for v[0], and 1 for v[@] or
-     v[*].  Return 0 for everything else. */
-
-  array = array_p (var) ? array_cell (var) : (ARRAY *)NULL;
-
-  if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']')
-    {
-      if (assoc_p (var))
-       return (assoc_num_elements (assoc_cell (var)));
-      else if (array_p (var))
-       return (array_num_elements (array));
-      else
-       return 1;
-    }
-
-  if (assoc_p (var))
-    {
-      t[len - 1] = '\0';
-      akey = expand_assignment_string_to_string (t, 0);        /* [ */
-      t[len - 1] = ']';
-      if (akey == 0 || *akey == 0)
-       {
-         err_badarraysub (t);
-         return (-1);
-       }
-      t = assoc_reference (assoc_cell (var), akey);
-    }
-  else
-    {
-      ind = array_expand_index (t, len);
-      if (ind < 0)
-       {
-         err_badarraysub (t);
-         return (-1);
-       }
-      if (array_p (var))
-       t = array_reference (array, ind);
-      else
-       t = (ind == 0) ? value_cell (var) : (char *)NULL;
-    }
-
-  len = MB_STRLEN (t);
-  return (len);
-}
-#endif /* ARRAY_VARS */
-
-static int
-valid_brace_expansion_word (name, var_is_special)
-     char *name;
-     int var_is_special;
-{
-  if (DIGIT (*name) && all_digits (name))
-    return 1;
-  else if (var_is_special)
-    return 1;
-#if defined (ARRAY_VARS)
-  else if (valid_array_reference (name))
-    return 1;
-#endif /* ARRAY_VARS */
-  else if (legal_identifier (name))
-    return 1;
-  else
-    return 0;
-}
-
-static int
-chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at)
-     char *name;
-     int quoted;
-     int *quoted_dollar_atp, *contains_dollar_at;
-{
-  char *temp1;
-
-  if (name == 0)
-    {
-      if (quoted_dollar_atp)
-       *quoted_dollar_atp = 0;
-      if (contains_dollar_at)
-       *contains_dollar_at = 0;
-      return 0;
-    }
-
-  /* check for $@ and $* */
-  if (name[0] == '@' && name[1] == 0)
-    {
-      if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-       *quoted_dollar_atp = 1;
-      if (contains_dollar_at)
-       *contains_dollar_at = 1;
-      return 1;
-    }
-  else if (name[0] == '*' && name[1] == '\0' && quoted == 0)
-    {
-      if (contains_dollar_at)
-       *contains_dollar_at = 1;
-      return 1;
-    }
-
-  /* Now check for ${array[@]} and ${array[*]} */
-#if defined (ARRAY_VARS)
-  else if (valid_array_reference (name))
-    {
-      temp1 = mbschr (name, '[');
-      if (temp1 && temp1[1] == '@' && temp1[2] == ']')
-       {
-         if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-           *quoted_dollar_atp = 1;
-         if (contains_dollar_at)
-           *contains_dollar_at = 1;
-         return 1;
-       }       /* [ */
-      /* ${array[*]}, when unquoted, should be treated like ${array[@]},
-        which should result in separate words even when IFS is unset. */
-      if (temp1 && temp1[1] == '*' && temp1[2] == ']' && quoted == 0)
-       {
-         if (contains_dollar_at)
-           *contains_dollar_at = 1;
-         return 1;
-       }
-    }
-#endif
-  return 0;
-}
-
-/* Parameter expand NAME, and return a new string which is the expansion,
-   or NULL if there was no expansion.
-   VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
-   the shell, e.g., "@", "$", "*", etc.  QUOTED, if non-zero, means that
-   NAME was found inside of a double-quoted expression. */
-static WORD_DESC *
-parameter_brace_expand_word (name, var_is_special, quoted, pflags)
-     char *name;
-     int var_is_special, quoted, pflags;
-{
-  WORD_DESC *ret;
-  char *temp, *tt;
-  intmax_t arg_index;
-  SHELL_VAR *var;
-  int atype, rflags;
-
-  ret = 0;
-  temp = 0;
-  rflags = 0;
-
-  /* Handle multiple digit arguments, as in ${11}. */  
-  if (legal_number (name, &arg_index))
-    {
-      tt = get_dollar_var_value (arg_index);
-      if (tt)
-       temp = (*tt && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-                 ? quote_string (tt)
-                 : quote_escapes (tt);
-      else
-        temp = (char *)NULL;
-      FREE (tt);
-    }
-  else if (var_is_special)      /* ${@} */
-    {
-      int sindex;
-      tt = (char *)xmalloc (2 + strlen (name));
-      tt[sindex = 0] = '$';
-      strcpy (tt + 1, name);
-
-      ret = param_expand (tt, &sindex, quoted, (int *)NULL, (int *)NULL,
-                         (int *)NULL, (int *)NULL, pflags);
-      free (tt);
-    }
-#if defined (ARRAY_VARS)
-  else if (valid_array_reference (name))
-    {
-      temp = array_value (name, quoted, &atype);
-      if (atype == 0 && temp)
-       temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-                 ? quote_string (temp)
-                 : quote_escapes (temp);
-      else if (atype == 1 && temp && QUOTED_NULL (temp) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-       rflags |= W_HASQUOTEDNULL;
-    }
-#endif
-  else if (var = find_variable (name))
-    {
-      if (var_isset (var) && invisible_p (var) == 0)
-       {
-#if defined (ARRAY_VARS)
-         if (assoc_p (var))
-           temp = assoc_reference (assoc_cell (var), "0");
-         else if (array_p (var))
-           temp = array_reference (array_cell (var), 0);
-         else
-           temp = value_cell (var);
-#else
-         temp = value_cell (var);
-#endif
-
-         if (temp)
-           temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-                     ? quote_string (temp)
-                     : quote_escapes (temp);
-       }
-      else
-       temp = (char *)NULL;
-    }
-  else
-    temp = (char *)NULL;
-
-  if (ret == 0)
-    {
-      ret = alloc_word_desc ();
-      ret->word = temp;
-      ret->flags |= rflags;
-    }
-  return ret;
-}
-
-/* Expand an indirect reference to a variable: ${!NAME} expands to the
-   value of the variable whose name is the value of NAME. */
-static WORD_DESC *
-parameter_brace_expand_indir (name, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at)
-     char *name;
-     int var_is_special, quoted;
-     int *quoted_dollar_atp, *contains_dollar_at;
-{
-  char *temp, *t;
-  WORD_DESC *w;
-
-  w = parameter_brace_expand_word (name, var_is_special, quoted, PF_IGNUNBOUND);
-  t = w->word;
-  /* Have to dequote here if necessary */
-  if (t)
-    {
-      temp = (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
-               ? dequote_string (t)
-               : dequote_escapes (t);
-      free (t);
-      t = temp;
-    }
-  dispose_word_desc (w);
-
-  chk_atstar (t, quoted, quoted_dollar_atp, contains_dollar_at);
-  if (t == 0)
-    return (WORD_DESC *)NULL;
-
-  w = parameter_brace_expand_word (t, SPECIAL_VAR(t, 0), quoted, 0);
-  free (t);
-
-  return w;
-}
-
-/* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
-   depending on the value of C, the separating character.  C can be one of
-   "-", "+", or "=".  QUOTED is true if the entire brace expression occurs
-   between double quotes. */
-static WORD_DESC *
-parameter_brace_expand_rhs (name, value, c, quoted, qdollaratp, hasdollarat)
-     char *name, *value;
-     int c, quoted, *qdollaratp, *hasdollarat;
-{
-  WORD_DESC *w;
-  WORD_LIST *l;
-  char *t, *t1, *temp;
-  int hasdol;
-
-  /* If the entire expression is between double quotes, we want to treat
-     the value as a double-quoted string, with the exception that we strip
-     embedded unescaped double quotes (for sh backwards compatibility). */
-  if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *value)
-    {
-      hasdol = 0;
-      temp = string_extract_double_quoted (value, &hasdol, 1);
-    }
-  else
-    temp = value;
-
-  w = alloc_word_desc ();
-  hasdol = 0;
-  /* XXX was 0 not quoted */
-  l = *temp ? expand_string_for_rhs (temp, quoted, &hasdol, (int *)NULL)
-           : (WORD_LIST *)0;
-  if (hasdollarat)
-    *hasdollarat = hasdol || (l && l->next);
-  if (temp != value)
-    free (temp);
-  if (l)
-    {
-      /* The expansion of TEMP returned something.  We need to treat things
-         slightly differently if HASDOL is non-zero.  If we have "$@", the
-         individual words have already been quoted.  We need to turn them
-         into a string with the words separated by the first character of
-         $IFS without any additional quoting, so string_list_dollar_at won't
-         do the right thing.  We use string_list_dollar_star instead. */
-      temp = (hasdol || l->next) ? string_list_dollar_star (l) : string_list (l);
-
-      /* If l->next is not null, we know that TEMP contained "$@", since that
-        is the only expansion that creates more than one word. */
-      if (qdollaratp && ((hasdol && quoted) || l->next))
-       *qdollaratp = 1;
-      dispose_words (l);
-    }
-  else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && hasdol)
-    {
-      /* The brace expansion occurred between double quotes and there was
-        a $@ in TEMP.  It does not matter if the $@ is quoted, as long as
-        it does not expand to anything.  In this case, we want to return
-        a quoted empty string. */
-      temp = make_quoted_char ('\0');
-      w->flags |= W_HASQUOTEDNULL;
-    }
-  else
-    temp = (char *)NULL;
-
-  if (c == '-' || c == '+')
-    {
-      w->word = temp;
-      return w;
-    }
-
-  /* c == '=' */
-  t = temp ? savestring (temp) : savestring ("");
-  t1 = dequote_string (t);
-  free (t);
-#if defined (ARRAY_VARS)
-  if (valid_array_reference (name))
-    assign_array_element (name, t1, 0);
-  else
-#endif /* ARRAY_VARS */
-  bind_variable (name, t1, 0);
-  free (t1);
-
-  w->word = temp;
-  return w;
-}
-
-/* Deal with the right hand side of a ${name:?value} expansion in the case
-   that NAME is null or not set.  If VALUE is non-null it is expanded and
-   used as the error message to print, otherwise a standard message is
-   printed. */
-static void
-parameter_brace_expand_error (name, value)
-     char *name, *value;
-{
-  WORD_LIST *l;
-  char *temp;
-
-  if (value && *value)
-    {
-      l = expand_string (value, 0);
-      temp =  string_list (l);
-      report_error ("%s: %s", name, temp ? temp : ""); /* XXX was value not "" */
-      FREE (temp);
-      dispose_words (l);
-    }
-  else
-    report_error (_("%s: parameter null or not set"), name);
-
-  /* Free the data we have allocated during this expansion, since we
-     are about to longjmp out. */
-  free (name);
-  FREE (value);
-}
-
-/* Return 1 if NAME is something for which parameter_brace_expand_length is
-   OK to do. */
-static int
-valid_length_expression (name)
-     char *name;
-{
-  return (name[1] == '\0' ||                                   /* ${#} */
-         ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0') ||  /* special param */
-         (DIGIT (name[1]) && all_digits (name + 1)) || /* ${#11} */
-#if defined (ARRAY_VARS)
-         valid_array_reference (name + 1) ||                   /* ${#a[7]} */
-#endif
-         legal_identifier (name + 1));                         /* ${#PS1} */
-}
-
-#if defined (HANDLE_MULTIBYTE)
-size_t
-mbstrlen (s)
-     const char *s;
-{
-  size_t clen, nc;
-  mbstate_t mbs, mbsbak;
-
-  nc = 0;
-  memset (&mbs, 0, sizeof (mbs));
-  mbsbak = mbs;
-  while ((clen = mbrlen(s, MB_CUR_MAX, &mbs)) != 0)
-    {
-      if (MB_INVALIDCH(clen))
-        {
-         clen = 1;     /* assume single byte */
-         mbs = mbsbak;
-        }
-
-      s += clen;
-      nc++;
-      mbsbak = mbs;
-    }
-  return nc;
-}
-#endif
-      
-
-/* Handle the parameter brace expansion that requires us to return the
-   length of a parameter. */
-static intmax_t
-parameter_brace_expand_length (name)
-     char *name;
-{
-  char *t, *newname;
-  intmax_t number, arg_index;
-  WORD_LIST *list;
-#if defined (ARRAY_VARS)
-  SHELL_VAR *var;
-#endif
-
-  if (name[1] == '\0')                 /* ${#} */
-    number = number_of_args ();
-  else if ((name[1] == '@' || name[1] == '*') && name[2] == '\0')      /* ${#@}, ${#*} */
-    number = number_of_args ();
-  else if ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0')
-    {
-      /* Take the lengths of some of the shell's special parameters. */
-      switch (name[1])
-       {
-       case '-':
-         t = which_set_flags ();
-         break;
-       case '?':
-         t = itos (last_command_exit_value);
-         break;
-       case '$':
-         t = itos (dollar_dollar_pid);
-         break;
-       case '!':
-         if (last_asynchronous_pid == NO_PID)
-           t = (char *)NULL;
-         else
-           t = itos (last_asynchronous_pid);
-         break;
-       case '#':
-         t = itos (number_of_args ());
-         break;
-       }
-      number = STRLEN (t);
-      FREE (t);
-    }
-#if defined (ARRAY_VARS)
-  else if (valid_array_reference (name + 1))
-    number = array_length_reference (name + 1);
-#endif /* ARRAY_VARS */
-  else
-    {
-      number = 0;
-
-      if (legal_number (name + 1, &arg_index))         /* ${#1} */
-       {
-         t = get_dollar_var_value (arg_index);
-         number = MB_STRLEN (t);
-         FREE (t);
-       }
-#if defined (ARRAY_VARS)
-      else if ((var = find_variable (name + 1)) && (invisible_p (var) == 0) && (array_p (var) || assoc_p (var)))
-       {
-         if (assoc_p (var))
-           t = assoc_reference (assoc_cell (var), "0");
-         else
-           t = array_reference (array_cell (var), 0);
-         number = MB_STRLEN (t);
-       }
-#endif
-      else                             /* ${#PS1} */
-       {
-         newname = savestring (name);
-         newname[0] = '$';
-         list = expand_string (newname, Q_DOUBLE_QUOTES);
-         t = list ? string_list (list) : (char *)NULL;
-         free (newname);
-         if (list)
-           dispose_words (list);
-
-         number = MB_STRLEN (t);
-         FREE (t);
-       }
-    }
-
-  return (number);
-}
-
-/* Skip characters in SUBSTR until DELIM.  SUBSTR is an arithmetic expression,
-   so we do some ad-hoc parsing of an arithmetic expression to find
-   the first DELIM, instead of using strchr(3).  Two rules:
-       1.  If the substring contains a `(', read until closing `)'.
-       2.  If the substring contains a `?', read past one `:' for each `?'.
-*/
-
-static char *
-skiparith (substr, delim)
-     char *substr;
-     int delim;
-{
-  size_t sublen;
-  int skipcol, pcount, i;
-  DECLARE_MBSTATE;
-
-  sublen = strlen (substr);
-  i = skipcol = pcount = 0;
-  while (substr[i])
-    {
-      /* Balance parens */
-      if (substr[i] == LPAREN)
-       {
-         pcount++;
-         i++;
-         continue;
-       }
-      if (substr[i] == RPAREN && pcount)
-       {
-         pcount--;
-         i++;
-         continue;
-       }
-      if (pcount)
-       {
-         ADVANCE_CHAR (substr, sublen, i);
-         continue;
-       }
-
-      /* Skip one `:' for each `?' */
-      if (substr[i] == ':' && skipcol)
-       {
-         skipcol--;
-         i++;
-         continue;
-       }
-      if (substr[i] == delim)
-       break;
-      if (substr[i] == '?')
-       {
-         skipcol++;
-         i++;
-         continue;
-       }
-      ADVANCE_CHAR (substr, sublen, i);
-    }
-
-  return (substr + i);
-}
-
-/* Verify and limit the start and end of the desired substring.  If
-   VTYPE == 0, a regular shell variable is being used; if it is 1,
-   then the positional parameters are being used; if it is 2, then
-   VALUE is really a pointer to an array variable that should be used.
-   Return value is 1 if both values were OK, 0 if there was a problem
-   with an invalid expression, or -1 if the values were out of range. */
-static int
-verify_substring_values (v, value, substr, vtype, e1p, e2p)
-     SHELL_VAR *v;
-     char *value, *substr;
-     int vtype;
-     intmax_t *e1p, *e2p;
-{
-  char *t, *temp1, *temp2;
-  arrayind_t len;
-  int expok;
-#if defined (ARRAY_VARS)
- ARRAY *a;
- HASH_TABLE *h;
-#endif
-
-  /* duplicate behavior of strchr(3) */
-  t = skiparith (substr, ':');
-  if (*t && *t == ':')
-    *t = '\0';
-  else
-    t = (char *)0;
-
-  temp1 = expand_arith_string (substr, Q_DOUBLE_QUOTES);
-  *e1p = evalexp (temp1, &expok);
-  free (temp1);
-  if (expok == 0)
-    return (0);
-
-  len = -1;    /* paranoia */
-  switch (vtype)
-    {
-    case VT_VARIABLE:
-    case VT_ARRAYMEMBER:
-      len = MB_STRLEN (value);
-      break;
-    case VT_POSPARMS:
-      len = number_of_args () + 1;
-      if (*e1p == 0)
-       len++;          /* add one arg if counting from $0 */
-      break;
-#if defined (ARRAY_VARS)
-    case VT_ARRAYVAR:
-      /* For arrays, the first value deals with array indices.  Negative
-        offsets count from one past the array's maximum index.  Associative
-        arrays treat the number of elements as the maximum index. */
-      if (assoc_p (v))
-       {
-         h = assoc_cell (v);
-         len = assoc_num_elements (h) + (*e1p < 0);
-       }
-      else
-       {
-         a = (ARRAY *)value;
-         len = array_max_index (a) + (*e1p < 0);       /* arrays index from 0 to n - 1 */
-       }
-      break;
-#endif
-    }
-
-  if (len == -1)       /* paranoia */
-    return -1;
-
-  if (*e1p < 0)                /* negative offsets count from end */
-    *e1p += len;
-
-  if (*e1p > len || *e1p < 0)
-    return (-1);
-
-#if defined (ARRAY_VARS)
-  /* For arrays, the second offset deals with the number of elements. */
-  if (vtype == VT_ARRAYVAR)
-    len = assoc_p (v) ? assoc_num_elements (h) : array_num_elements (a);
-#endif
-
-  if (t)
-    {
-      t++;
-      temp2 = savestring (t);
-      temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES);
-      free (temp2);
-      t[-1] = ':';
-      *e2p = evalexp (temp1, &expok);
-      free (temp1);
-      if (expok == 0)
-       return (0);
-      if (*e2p < 0)
-       {
-         internal_error (_("%s: substring expression < 0"), t);
-         return (0);
-       }
-#if defined (ARRAY_VARS)
-      /* In order to deal with sparse arrays, push the intelligence about how
-        to deal with the number of elements desired down to the array-
-        specific functions.  */
-      if (vtype != VT_ARRAYVAR)
-#endif
-       {
-         *e2p += *e1p;         /* want E2 chars starting at E1 */
-         if (*e2p > len)
-           *e2p = len;
-       }
-    }
-  else
-    *e2p = len;
-
-  return (1);
-}
-
-/* Return the type of variable specified by VARNAME (simple variable,
-   positional param, or array variable).  Also return the value specified
-   by VARNAME (value of a variable or a reference to an array element).
-   If this returns VT_VARIABLE, the caller assumes that CTLESC and CTLNUL
-   characters in the value are quoted with CTLESC and takes appropriate
-   steps.  For convenience, *VALP is set to the dequoted VALUE. */
-static int
-get_var_and_type (varname, value, quoted, varp, valp)
-     char *varname, *value;
-     int quoted;
-     SHELL_VAR **varp;
-     char **valp;
-{
-  int vtype;
-  char *temp;
-#if defined (ARRAY_VARS)
-  SHELL_VAR *v;
-#endif
-
-  /* This sets vtype to VT_VARIABLE or VT_POSPARMS */
-  vtype = (varname[0] == '@' || varname[0] == '*') && varname[1] == '\0';
-  if (vtype == VT_POSPARMS && varname[0] == '*')
-    vtype |= VT_STARSUB;
-  *varp = (SHELL_VAR *)NULL;
-
-#if defined (ARRAY_VARS)
-  if (valid_array_reference (varname))
-    {
-      v = array_variable_part (varname, &temp, (int *)0);
-      if (v && (array_p (v) || assoc_p (v)))
-       { /* [ */
-         if (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']')
-           {
-             /* Callers have to differentiate betwen indexed and associative */
-             vtype = VT_ARRAYVAR;
-             if (temp[0] == '*')
-               vtype |= VT_STARSUB;
-             *valp = array_p (v) ? (char *)array_cell (v) : (char *)assoc_cell (v);
-           }
-         else
-           {
-             vtype = VT_ARRAYMEMBER;
-             *valp = array_value (varname, 1, (int *)NULL);
-           }
-         *varp = v;
-       }
-      else if (v && (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']'))
-       {
-         vtype = VT_VARIABLE;
-         *varp = v;
-         if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
-           *valp = dequote_string (value);
-         else
-           *valp = dequote_escapes (value);
-       }
-      else
-       {
-         vtype = VT_ARRAYMEMBER;
-         *varp = v;
-         *valp = array_value (varname, 1, (int *)NULL);
-       }
-    }
-  else if ((v = find_variable (varname)) && (invisible_p (v) == 0) && (assoc_p (v) || array_p (v)))
-    {
-      vtype = VT_ARRAYMEMBER;
-      *varp = v;
-      *valp = assoc_p (v) ? assoc_reference (assoc_cell (v), "0") : array_reference (array_cell (v), 0);
-    }
-  else
-#endif
-    {
-      if (value && vtype == VT_VARIABLE)
-       {
-         if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
-           *valp = dequote_string (value);
-         else
-           *valp = dequote_escapes (value);
-       }
-      else
-       *valp = value;
-    }
-
-  return vtype;
-}
-
-/******************************************************/
-/*                                                   */
-/* Functions to extract substrings of variable values */
-/*                                                   */
-/******************************************************/
-
-#if defined (HANDLE_MULTIBYTE)
-/* Character-oriented rather than strictly byte-oriented substrings.  S and
-   E, rather being strict indices into STRING, indicate character (possibly
-   multibyte character) positions that require calculation.
-   Used by the ${param:offset[:length]} expansion. */
-static char *
-mb_substring (string, s, e)
-     char *string;
-     int s, e;
-{
-  char *tt;
-  int start, stop, i, slen;
-  DECLARE_MBSTATE;
-
-  start = 0;
-  /* Don't need string length in ADVANCE_CHAR unless multibyte chars possible. */
-  slen = (MB_CUR_MAX > 1) ? STRLEN (string) : 0;
-
-  i = s;
-  while (string[start] && i--)
-    ADVANCE_CHAR (string, slen, start);
-  stop = start;
-  i = e - s;
-  while (string[stop] && i--)
-    ADVANCE_CHAR (string, slen, stop);
-  tt = substring (string, start, stop);
-  return tt;
-}
-#endif
-  
-/* Process a variable substring expansion: ${name:e1[:e2]}.  If VARNAME
-   is `@', use the positional parameters; otherwise, use the value of
-   VARNAME.  If VARNAME is an array variable, use the array elements. */
-
-static char *
-parameter_brace_substring (varname, value, substr, quoted)
-     char *varname, *value, *substr;
-     int quoted;
-{
-  intmax_t e1, e2;
-  int vtype, r, starsub;
-  char *temp, *val, *tt, *oname;
-  SHELL_VAR *v;
-
-  if (value == 0)
-    return ((char *)NULL);
-
-  oname = this_command_name;
-  this_command_name = varname;
-
-  vtype = get_var_and_type (varname, value, quoted, &v, &val);
-  if (vtype == -1)
-    {
-      this_command_name = oname;
-      return ((char *)NULL);
-    }
-
-  starsub = vtype & VT_STARSUB;
-  vtype &= ~VT_STARSUB;
-
-  r = verify_substring_values (v, val, substr, vtype, &e1, &e2);
-  this_command_name = oname;
-  if (r <= 0)
-    return ((r == 0) ? &expand_param_error : (char *)NULL);
-
-  switch (vtype)
-    {
-    case VT_VARIABLE:
-    case VT_ARRAYMEMBER:
-#if defined (HANDLE_MULTIBYTE)
-      if (MB_CUR_MAX > 1)
-       tt = mb_substring (val, e1, e2);
-      else
-#endif
-      tt = substring (val, e1, e2);
-
-      if (vtype == VT_VARIABLE)
-       FREE (val);
-      if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
-       temp = quote_string (tt);
-      else
-       temp = tt ? quote_escapes (tt) : (char *)NULL;
-      FREE (tt);
-      break;
-    case VT_POSPARMS:
-      tt = pos_params (varname, e1, e2, quoted);
-      if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
-       {
-         temp = tt ? quote_escapes (tt) : (char *)NULL;
-         FREE (tt);
-       }
-      else
-       temp = tt;
-      break;
-#if defined (ARRAY_VARS)
-    case VT_ARRAYVAR:
-      if (assoc_p (v))
-       /* we convert to list and take first e2 elements starting at e1th
-          element -- officially undefined for now */   
-       temp = assoc_subrange (assoc_cell (v), e1, e2, starsub, quoted);
-      else
-      /* We want E2 to be the number of elements desired (arrays can be sparse,
-        so verify_substring_values just returns the numbers specified and we
-        rely on array_subrange to understand how to deal with them). */
-       temp = array_subrange (array_cell (v), e1, e2, starsub, quoted);
-      /* array_subrange now calls array_quote_escapes as appropriate, so the
-        caller no longer needs to. */
-      break;
-#endif
-    default:
-      temp = (char *)NULL;
-    }
-
-  return temp;
-}
-
-/****************************************************************/
-/*                                                             */
-/* Functions to perform pattern substitution on variable values */
-/*                                                             */
-/****************************************************************/
-
-char *
-pat_subst (string, pat, rep, mflags)
-     char *string, *pat, *rep;
-     int mflags;
-{
-  char *ret, *s, *e, *str;
-  int rsize, rptr, l, replen, mtype;
-
-  mtype = mflags & MATCH_TYPEMASK;
-
-  /* Special cases:
-   *   1.  A null pattern with mtype == MATCH_BEG means to prefix STRING
-   *       with REP and return the result.
-   *   2.  A null pattern with mtype == MATCH_END means to append REP to
-   *       STRING and return the result.
-   */
-  if ((pat == 0 || *pat == 0) && (mtype == MATCH_BEG || mtype == MATCH_END))
-    {
-      replen = STRLEN (rep);
-      l = strlen (string);
-      ret = (char *)xmalloc (replen + l + 2);
-      if (replen == 0)
-       strcpy (ret, string);
-      else if (mtype == MATCH_BEG)
-       {
-         strcpy (ret, rep);
-         strcpy (ret + replen, string);
-       }
-      else
-       {
-         strcpy (ret, string);
-         strcpy (ret + l, rep);
-       }
-      return (ret);
-    }
-
-  ret = (char *)xmalloc (rsize = 64);
-  ret[0] = '\0';
-
-  for (replen = STRLEN (rep), rptr = 0, str = string;;)
-    {
-      if (match_pattern (str, pat, mtype, &s, &e) == 0)
-       break;
-      l = s - str;
-      RESIZE_MALLOCED_BUFFER (ret, rptr, (l + replen), rsize, 64);
-
-      /* OK, now copy the leading unmatched portion of the string (from
-        str to s) to ret starting at rptr (the current offset).  Then copy
-        the replacement string at ret + rptr + (s - str).  Increment
-        rptr (if necessary) and str and go on. */
-      if (l)
-       {
-         strncpy (ret + rptr, str, l);
-         rptr += l;
-       }
-      if (replen)
-       {
-         strncpy (ret + rptr, rep, replen);
-         rptr += replen;
-       }
-      str = e;         /* e == end of match */
-
-      if (((mflags & MATCH_GLOBREP) == 0) || mtype != MATCH_ANY)
-       break;
-
-      if (s == e)
-       {
-         /* On a zero-length match, make sure we copy one character, since
-            we increment one character to avoid infinite recursion. */
-         RESIZE_MALLOCED_BUFFER (ret, rptr, 1, rsize, 64);
-         ret[rptr++] = *str++;
-         e++;          /* avoid infinite recursion on zero-length match */
-       }
-    }
-
-  /* Now copy the unmatched portion of the input string */
-  if (*str)
-    {
-      RESIZE_MALLOCED_BUFFER (ret, rptr, STRLEN(str) + 1, rsize, 64);
-      strcpy (ret + rptr, str);
-    }
-  else
-    ret[rptr] = '\0';
-
-  return ret;
-}
-
-/* Do pattern match and replacement on the positional parameters. */
-static char *
-pos_params_pat_subst (string, pat, rep, mflags)
-     char *string, *pat, *rep;
-     int mflags;
-{
-  WORD_LIST *save, *params;
-  WORD_DESC *w;
-  char *ret;
-  int pchar, qflags;
-
-  save = params = list_rest_of_args ();
-  if (save == 0)
-    return ((char *)NULL);
-
-  for ( ; params; params = params->next)
-    {
-      ret = pat_subst (params->word->word, pat, rep, mflags);
-      w = alloc_word_desc ();
-      w->word = ret ? ret : savestring ("");
-      dispose_word (params->word);
-      params->word = w;
-    }
-
-  pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@';
-  qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0;
-
-#if 0
-  if ((mflags & (MATCH_QUOTED|MATCH_STARSUB)) == (MATCH_QUOTED|MATCH_STARSUB))
-    ret = string_list_dollar_star (quote_list (save));
-  else if ((mflags & MATCH_STARSUB) == MATCH_STARSUB)
-    ret = string_list_dollar_star (save);
-  else if ((mflags & MATCH_QUOTED) == MATCH_QUOTED)
-    ret = string_list_dollar_at (save, qflags);
-  else
-    ret = string_list_dollar_star (save);
-#else
-  ret = string_list_pos_params (pchar, save, qflags);
-#endif
-
-  dispose_words (save);
-
-  return (ret);
-}
-
-/* Perform pattern substitution on VALUE, which is the expansion of
-   VARNAME.  PATSUB is an expression supplying the pattern to match
-   and the string to substitute.  QUOTED is a flags word containing
-   the type of quoting currently in effect. */
-static char *
-parameter_brace_patsub (varname, value, patsub, quoted)
-     char *varname, *value, *patsub;
-     int quoted;
-{
-  int vtype, mflags, starsub, delim;
-  char *val, *temp, *pat, *rep, *p, *lpatsub, *tt;
-  SHELL_VAR *v;
-
-  if (value == 0)
-    return ((char *)NULL);
-
-  this_command_name = varname;
-
-  vtype = get_var_and_type (varname, value, quoted, &v, &val);
-  if (vtype == -1)
-    return ((char *)NULL);
-
-  starsub = vtype & VT_STARSUB;
-  vtype &= ~VT_STARSUB;
-
-  mflags = 0;
-  if (patsub && *patsub == '/')
-    {
-      mflags |= MATCH_GLOBREP;
-      patsub++;
-    }
-
-  /* Malloc this because expand_string_if_necessary or one of the expansion
-     functions in its call chain may free it on a substitution error. */
-  lpatsub = savestring (patsub);
-
-  if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-    mflags |= MATCH_QUOTED;
-
-  if (starsub)
-    mflags |= MATCH_STARSUB;
-
-  /* If the pattern starts with a `/', make sure we skip over it when looking
-     for the replacement delimiter. */
-#if 0
-  if (rep = quoted_strchr ((*patsub == '/') ? lpatsub+1 : lpatsub, '/', ST_BACKSL))
-    *rep++ = '\0';
-  else
-    rep = (char *)NULL;
-#else
-  delim = skip_to_delim (lpatsub, ((*patsub == '/') ? 1 : 0), "/", 0);
-  if (lpatsub[delim] == '/')
-    {
-      lpatsub[delim] = 0;
-      rep = lpatsub + delim + 1;
-    }
-  else
-    rep = (char *)NULL;
-#endif
-
-  if (rep && *rep == '\0')
-    rep = (char *)NULL;
-
-  /* Perform the same expansions on the pattern as performed by the
-     pattern removal expansions. */
-  pat = getpattern (lpatsub, quoted, 1);
-
-  if (rep)
-    {
-      if ((mflags & MATCH_QUOTED) == 0)
-       rep = expand_string_if_necessary (rep, quoted, expand_string_unsplit);
-      else
-       rep = expand_string_to_string_internal (rep, quoted, expand_string_unsplit);
-    }
-
-  /* ksh93 doesn't allow the match specifier to be a part of the expanded
-     pattern.  This is an extension.  Make sure we don't anchor the pattern
-     at the beginning or end of the string if we're doing global replacement,
-     though. */
-  p = pat;
-  if (mflags & MATCH_GLOBREP)
-    mflags |= MATCH_ANY;
-  else if (pat && pat[0] == '#')
-    {
-      mflags |= MATCH_BEG;
-      p++;
-    }
-  else if (pat && pat[0] == '%')
-    {
-      mflags |= MATCH_END;
-      p++;
-    }
-  else
-    mflags |= MATCH_ANY;
-
-  /* OK, we now want to substitute REP for PAT in VAL.  If
-     flags & MATCH_GLOBREP is non-zero, the substitution is done
-     everywhere, otherwise only the first occurrence of PAT is
-     replaced.  The pattern matching code doesn't understand
-     CTLESC quoting CTLESC and CTLNUL so we use the dequoted variable
-     values passed in (VT_VARIABLE) so the pattern substitution
-     code works right.  We need to requote special chars after
-     we're done for VT_VARIABLE and VT_ARRAYMEMBER, and for the
-     other cases if QUOTED == 0, since the posparams and arrays
-     indexed by * or @ do special things when QUOTED != 0. */
-
-  switch (vtype)
-    {
-    case VT_VARIABLE:
-    case VT_ARRAYMEMBER:
-      temp = pat_subst (val, p, rep, mflags);
-      if (vtype == VT_VARIABLE)
-       FREE (val);
-      if (temp)
-       {
-         tt = (mflags & MATCH_QUOTED) ? quote_string (temp) : quote_escapes (temp);
-         free (temp);
-         temp = tt;
-       }
-      break;
-    case VT_POSPARMS:
-      temp = pos_params_pat_subst (val, p, rep, mflags);
-      if (temp && (mflags & MATCH_QUOTED) == 0)
-       {
-         tt = quote_escapes (temp);
-         free (temp);
-         temp = tt;
-       }
-      break;
-#if defined (ARRAY_VARS)
-    case VT_ARRAYVAR:
-      temp = assoc_p (v) ? assoc_patsub (assoc_cell (v), p, rep, mflags)
-                        : array_patsub (array_cell (v), p, rep, mflags);
-      /* Don't call quote_escapes anymore; array_patsub calls
-        array_quote_escapes as appropriate before adding the
-        space separators; ditto for assoc_patsub. */
-      break;
-#endif
-    }
-
-  FREE (pat);
-  FREE (rep);
-  free (lpatsub);
-
-  return temp;
-}
-
-/****************************************************************/
-/*                                                             */
-/*   Functions to perform case modification on variable values  */
-/*                                                             */
-/****************************************************************/
-
-/* Do case modification on the positional parameters. */
-
-static char *
-pos_params_modcase (string, pat, modop, mflags)
-     char *string, *pat;
-     int modop;
-     int mflags;
-{
-  WORD_LIST *save, *params;
-  WORD_DESC *w;
-  char *ret;
-  int pchar, qflags;
-
-  save = params = list_rest_of_args ();
-  if (save == 0)
-    return ((char *)NULL);
-
-  for ( ; params; params = params->next)
-    {
-      ret = sh_modcase (params->word->word, pat, modop);
-      w = alloc_word_desc ();
-      w->word = ret ? ret : savestring ("");
-      dispose_word (params->word);
-      params->word = w;
-    }
-
-  pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@';
-  qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0;
-
-  ret = string_list_pos_params (pchar, save, qflags);
-  dispose_words (save);
-
-  return (ret);
-}
-
-/* Perform case modification on VALUE, which is the expansion of
-   VARNAME.  MODSPEC is an expression supplying the type of modification
-   to perform.  QUOTED is a flags word containing the type of quoting
-   currently in effect. */
-static char *
-parameter_brace_casemod (varname, value, modspec, patspec, quoted)
-     char *varname, *value;
-     int modspec;
-     char *patspec;
-     int quoted;
-{
-  int vtype, starsub, modop, mflags, x;
-  char *val, *temp, *pat, *p, *lpat, *tt;
-  SHELL_VAR *v;
-
-  if (value == 0)
-    return ((char *)NULL);
-
-  this_command_name = varname;
-
-  vtype = get_var_and_type (varname, value, quoted, &v, &val);
-  if (vtype == -1)
-    return ((char *)NULL);
-
-  starsub = vtype & VT_STARSUB;
-  vtype &= ~VT_STARSUB;
-
-  modop = 0;
-  mflags = 0;
-  if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-    mflags |= MATCH_QUOTED;
-  if (starsub)
-    mflags |= MATCH_STARSUB;
-  
-  p = patspec;
-  if (modspec == '^')
-    {
-      x = p && p[0] == modspec;
-      modop = x ? CASE_UPPER : CASE_UPFIRST;
-      p += x;
-    }
-  else if (modspec == ',')
-    {
-      x = p && p[0] == modspec;
-      modop = x ? CASE_LOWER : CASE_LOWFIRST;
-      p += x;
-    }
-  else if (modspec == '~')
-    {
-      x = p && p[0] == modspec;
-      modop = x ? CASE_TOGGLEALL : CASE_TOGGLE;
-      p += x;
-    }
-    
-  lpat = p ? savestring (p) : 0;
-  /* Perform the same expansions on the pattern as performed by the
-     pattern removal expansions.  FOR LATER */
-  pat = lpat ? getpattern (lpat, quoted, 1) : 0;
-
-  /* OK, now we do the case modification. */
-  switch (vtype)
-    {
-    case VT_VARIABLE:
-    case VT_ARRAYMEMBER:
-      temp = sh_modcase (val, pat, modop);
-      if (vtype == VT_VARIABLE)
-       FREE (val);
-      if (temp)
-       {
-         tt = (mflags & MATCH_QUOTED) ? quote_string (temp) : quote_escapes (temp);
-         free (temp);
-         temp = tt;
-       }
-      break;
-
-    case VT_POSPARMS:
-      temp = pos_params_modcase (val, pat, modop, mflags);
-      if (temp && (mflags & MATCH_QUOTED)  == 0)
-       {
-         tt = quote_escapes (temp);
-         free (temp);
-         temp = tt;
-       }
-      break;
-
-#if defined (ARRAY_VARS)
-    case VT_ARRAYVAR:
-      temp = assoc_p (v) ? assoc_modcase (assoc_cell (v), pat, modop, mflags)
-                        : array_modcase (array_cell (v), pat, modop, mflags);
-      /* Don't call quote_escapes; array_modcase calls array_quote_escapes
-        as appropriate before adding the space separators; ditto for
-        assoc_modcase. */
-      break;
-#endif
-    }
-
-  FREE (pat);
-  free (lpat);
-
-  return temp;
-}
-
-/* Check for unbalanced parens in S, which is the contents of $(( ... )).  If
-   any occur, this must be a nested command substitution, so return 0.
-   Otherwise, return 1.  A valid arithmetic expression must always have a
-   ( before a matching ), so any cases where there are more right parens
-   means that this must not be an arithmetic expression, though the parser
-   will not accept it without a balanced total number of parens. */
-static int
-chk_arithsub (s, len)
-     const char *s;
-     int len;
-{
-  int i, count;
-  DECLARE_MBSTATE;
-
-  i = count = 0;
-  while (i < len)
-    {
-      if (s[i] == LPAREN)
-       count++;
-      else if (s[i] == RPAREN)
-       {
-         count--;
-         if (count < 0)
-           return 0;
-       }
-
-      switch (s[i])
-       {
-       default:
-         ADVANCE_CHAR (s, len, i);
-         break;
-
-       case '\\':
-         i++;
-         if (s[i])
-           ADVANCE_CHAR (s, len, i);
-         break;
-
-       case '\'':
-         i = skip_single_quoted (s, len, ++i);
-         break;
-
-       case '"':
-         i = skip_double_quoted ((char *)s, len, ++i);
-         break;
-       }
-    }
-
-  return (count == 0);
-}
-
-/****************************************************************/
-/*                                                             */
-/*     Functions to perform parameter expansion on a string    */
-/*                                                             */
-/****************************************************************/
-
-/* ${[#][!]name[[:][^[^]][,[,]]#[#]%[%]-=?+[word][:e1[:e2]]]} */
-static WORD_DESC *
-parameter_brace_expand (string, indexp, quoted, quoted_dollar_atp, contains_dollar_at)
-     char *string;
-     int *indexp, quoted, *quoted_dollar_atp, *contains_dollar_at;
-{
-  int check_nullness, var_is_set, var_is_null, var_is_special;
-  int want_substring, want_indir, want_patsub, want_casemod;
-  char *name, *value, *temp, *temp1;
-  WORD_DESC *tdesc, *ret;
-  int t_index, sindex, c, tflag, modspec;
-  intmax_t number;
-
-  temp = temp1 = value = (char *)NULL;
-  var_is_set = var_is_null = var_is_special = check_nullness = 0;
-  want_substring = want_indir = want_patsub = want_casemod = 0;
-
-  sindex = *indexp;
-  t_index = ++sindex;
-  /* ${#var} doesn't have any of the other parameter expansions on it. */
-  if (string[t_index] == '#' && legal_variable_starter (string[t_index+1]))            /* {{ */
-    name = string_extract (string, &t_index, "}", SX_VARNAME);
-  else
-#if defined (CASEMOD_EXPANSIONS)
-    /* To enable case-toggling expansions using the `~' operator character
-       change the 1 to 0. */
-#  if defined (CASEMOD_CAPCASE)
-    name = string_extract (string, &t_index, "#%^,~:-=?+/}", SX_VARNAME);
-#  else
-    name = string_extract (string, &t_index, "#%^,:-=?+/}", SX_VARNAME);
-#  endif /* CASEMOD_CAPCASE */
-#else
-    name = string_extract (string, &t_index, "#%:-=?+/}", SX_VARNAME);
-#endif /* CASEMOD_EXPANSIONS */
-
-  ret = 0;
-  tflag = 0;
-
-  /* If the name really consists of a special variable, then make sure
-     that we have the entire name.  We don't allow indirect references
-     to special variables except `#', `?', `@' and `*'. */
-  if ((sindex == t_index &&
-       (string[t_index] == '-' ||
-        string[t_index] == '?' ||
-        string[t_index] == '#')) ||
-      (sindex == t_index - 1 && string[sindex] == '!' &&
-       (string[t_index] == '#' ||
-        string[t_index] == '?' ||
-        string[t_index] == '@' ||
-        string[t_index] == '*')))
-    {
-      t_index++;
-      free (name);
-      temp1 = string_extract (string, &t_index, "#%:-=?+/}", 0);
-      name = (char *)xmalloc (3 + (strlen (temp1)));
-      *name = string[sindex];
-      if (string[sindex] == '!')
-       {
-         /* indirect reference of $#, $?, $@, or $* */
-         name[1] = string[sindex + 1];
-         strcpy (name + 2, temp1);
-       }
-      else     
-       strcpy (name + 1, temp1);
-      free (temp1);
-    }
-  sindex = t_index;
-
-  /* Find out what character ended the variable name.  Then
-     do the appropriate thing. */
-  if (c = string[sindex])
-    sindex++;
-
-  /* If c is followed by one of the valid parameter expansion
-     characters, move past it as normal.  If not, assume that
-     a substring specification is being given, and do not move
-     past it. */
-  if (c == ':' && VALID_PARAM_EXPAND_CHAR (string[sindex]))
-    {
-      check_nullness++;
-      if (c = string[sindex])
-       sindex++;
-    }
-  else if (c == ':' && string[sindex] != RBRACE)
-    want_substring = 1;
-  else if (c == '/' && string[sindex] != RBRACE)
-    want_patsub = 1;
-#if defined (CASEMOD_EXPANSIONS)
-  else if (c == '^' || c == ',' || c == '~')
-    {
-      modspec = c;
-      want_casemod = 1;
-    }
-#endif
-
-  /* Catch the valid and invalid brace expressions that made it through the
-     tests above. */
-  /* ${#-} is a valid expansion and means to take the length of $-.
-     Similarly for ${#?} and ${##}... */
-  if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
-       VALID_SPECIAL_LENGTH_PARAM (c) && string[sindex] == RBRACE)
-    {
-      name = (char *)xrealloc (name, 3);
-      name[1] = c;
-      name[2] = '\0';
-      c = string[sindex++];
-    }
-
-  /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */
-  if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
-       member (c, "%:=+/") && string[sindex] == RBRACE)
-    {
-      temp = (char *)NULL;
-      goto bad_substitution;
-    }
-
-  /* Indirect expansion begins with a `!'.  A valid indirect expansion is
-     either a variable name, one of the positional parameters or a special
-     variable that expands to one of the positional parameters. */
-  want_indir = *name == '!' &&
-    (legal_variable_starter ((unsigned char)name[1]) || DIGIT (name[1])
-                                       || VALID_INDIR_PARAM (name[1]));
-
-  /* Determine the value of this variable. */
-
-  /* Check for special variables, directly referenced. */
-  if (SPECIAL_VAR (name, want_indir))
-    var_is_special++;
-
-  /* Check for special expansion things, like the length of a parameter */
-  if (*name == '#' && name[1])
-    {
-      /* If we are not pointing at the character just after the
-        closing brace, then we haven't gotten all of the name.
-        Since it begins with a special character, this is a bad
-        substitution.  Also check NAME for validity before trying
-        to go on. */
-      if (string[sindex - 1] != RBRACE || (valid_length_expression (name) == 0))
-       {
-         temp = (char *)NULL;
-         goto bad_substitution;
-       }
-
-      number = parameter_brace_expand_length (name);
-      free (name);
-
-      *indexp = sindex;
-      if (number < 0)
-        return (&expand_wdesc_error);
-      else
-       {
-         ret = alloc_word_desc ();
-         ret->word = itos (number);
-         return ret;
-       }
-    }
-
-  /* ${@} is identical to $@. */
-  if (name[0] == '@' && name[1] == '\0')
-    {
-      if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-       *quoted_dollar_atp = 1;
-
-      if (contains_dollar_at)
-       *contains_dollar_at = 1;
-    }
-
-  /* Process ${!PREFIX*} expansion. */
-  if (want_indir && string[sindex - 1] == RBRACE &&
-      (string[sindex - 2] == '*' || string[sindex - 2] == '@') &&
-      legal_variable_starter ((unsigned char) name[1]))
-    {
-      char **x;
-      WORD_LIST *xlist;
-
-      temp1 = savestring (name + 1);
-      number = strlen (temp1);
-      temp1[number - 1] = '\0';
-      x = all_variables_matching_prefix (temp1);
-      xlist = strvec_to_word_list (x, 0, 0);
-      if (string[sindex - 2] == '*')
-       temp = string_list_dollar_star (xlist);
-      else
-       {
-         temp = string_list_dollar_at (xlist, quoted);
-         if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-           *quoted_dollar_atp = 1;
-         if (contains_dollar_at)
-           *contains_dollar_at = 1;
-       }
-      free (x);
-      dispose_words (xlist);
-      free (temp1);
-      *indexp = sindex;
-
-      ret = alloc_word_desc ();
-      ret->word = temp;
-      return ret;
-    }
-
-#if defined (ARRAY_VARS)      
-  /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */ /* [ */
-  if (want_indir && string[sindex - 1] == RBRACE &&
-      string[sindex - 2] == ']' && valid_array_reference (name+1))
-    {
-      char *x, *x1;
-
-      temp1 = savestring (name + 1);
-      x = array_variable_name (temp1, &x1, (int *)0);  /* [ */
-      FREE (x);
-      if (ALL_ELEMENT_SUB (x1[0]) && x1[1] == ']')
-       {
-         temp = array_keys (temp1, quoted);    /* handles assoc vars too */
-         if (x1[0] == '@')
-           {
-             if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-               *quoted_dollar_atp = 1;
-             if (contains_dollar_at)
-               *contains_dollar_at = 1;
-           }       
-
-         free (temp1);
-         *indexp = sindex;
-
-         ret = alloc_word_desc ();
-         ret->word = temp;
-         return ret;
-       }
-
-      free (temp1);
-    }
-#endif /* ARRAY_VARS */
-      
-  /* Make sure that NAME is valid before trying to go on. */
-  if (valid_brace_expansion_word (want_indir ? name + 1 : name,
-                                       var_is_special) == 0)
-    {
-      temp = (char *)NULL;
-      goto bad_substitution;
-    }
-
-  if (want_indir)
-    tdesc = parameter_brace_expand_indir (name + 1, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at);
-  else
-    tdesc = parameter_brace_expand_word (name, var_is_special, quoted, PF_IGNUNBOUND);
-
-  if (tdesc)
-    {
-      temp = tdesc->word;
-      tflag = tdesc->flags;
-      dispose_word_desc (tdesc);
-    }
-  else
-    temp = (char  *)0;
-
-#if defined (ARRAY_VARS)
-  if (valid_array_reference (name))
-    chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at);
-#endif
-
-  var_is_set = temp != (char *)0;
-  var_is_null = check_nullness && (var_is_set == 0 || *temp == 0);
-
-  /* Get the rest of the stuff inside the braces. */
-  if (c && c != RBRACE)
-    {
-      /* Extract the contents of the ${ ... } expansion
-        according to the Posix.2 rules. */
-      value = extract_dollar_brace_string (string, &sindex, quoted, 0);
-      if (string[sindex] == RBRACE)
-       sindex++;
-      else
-       goto bad_substitution;
-    }
-  else
-    value = (char *)NULL;
-
-  *indexp = sindex;
-
-  /* If this is a substring spec, process it and add the result. */
-  if (want_substring)
-    {
-      temp1 = parameter_brace_substring (name, temp, value, quoted);
-      FREE (name);
-      FREE (value);
-      FREE (temp);
-
-      if (temp1 == &expand_param_error)
-       return (&expand_wdesc_error);
-      else if (temp1 == &expand_param_fatal)
-       return (&expand_wdesc_fatal);
-
-      ret = alloc_word_desc ();
-      ret->word = temp1;
-      if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-       ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
-      return ret;
-    }
-  else if (want_patsub)
-    {
-      temp1 = parameter_brace_patsub (name, temp, value, quoted);
-      FREE (name);
-      FREE (value);
-      FREE (temp);
-
-      if (temp1 == &expand_param_error)
-       return (&expand_wdesc_error);
-      else if (temp1 == &expand_param_fatal)
-       return (&expand_wdesc_fatal);
-
-      ret = alloc_word_desc ();
-      ret->word = temp1;
-      ret = alloc_word_desc ();
-      ret->word = temp1;
-      if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-       ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
-      return ret;
-    }
-#if defined (CASEMOD_EXPANSIONS)
-  else if (want_casemod)
-    {
-      temp1 = parameter_brace_casemod (name, temp, modspec, value, quoted);
-      FREE (name);
-      FREE (value);
-      FREE (temp);
-
-      if (temp1 == &expand_param_error)
-       return (&expand_wdesc_error);
-      else if (temp1 == &expand_param_fatal)
-       return (&expand_wdesc_fatal);
-
-      ret = alloc_word_desc ();
-      ret->word = temp1;
-      if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-       ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
-      return ret;
-    }
-#endif
-
-  /* Do the right thing based on which character ended the variable name. */
-  switch (c)
-    {
-    default:
-    case '\0':
-    bad_substitution:
-      report_error (_("%s: bad substitution"), string ? string : "??");
-      FREE (value);
-      FREE (temp);
-      free (name);
-      return &expand_wdesc_error;
-
-    case RBRACE:
-      if (var_is_set == 0 && unbound_vars_is_error && ((name[0] != '@' && name[0] != '*') || name[1]))
-       {
-         last_command_exit_value = EXECUTION_FAILURE;
-         err_unboundvar (name);
-         FREE (value);
-         FREE (temp);
-         free (name);
-         return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
-       }
-      break;
-
-    case '#':  /* ${param#[#]pattern} */
-    case '%':  /* ${param%[%]pattern} */
-      if (value == 0 || *value == '\0' || temp == 0 || *temp == '\0')
-       {
-         FREE (value);
-         break;
-       }
-      temp1 = parameter_brace_remove_pattern (name, temp, value, c, quoted);
-      free (temp);
-      free (value);
-
-      ret = alloc_word_desc ();
-      ret->word = temp1;
-      if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-       ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
-      return ret;
-
-    case '-':
-    case '=':
-    case '?':
-    case '+':
-      if (var_is_set && var_is_null == 0)
-       {
-         /* If the operator is `+', we don't want the value of the named
-            variable for anything, just the value of the right hand side. */
-
-         if (c == '+')
-           {
-             /* XXX -- if we're double-quoted and the named variable is "$@",
-                       we want to turn off any special handling of "$@" --
-                       we're not using it, so whatever is on the rhs applies. */
-             if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-               *quoted_dollar_atp = 0;
-             if (contains_dollar_at)
-               *contains_dollar_at = 0;
-
-             FREE (temp);
-             if (value)
-               {
-                 ret = parameter_brace_expand_rhs (name, value, c,
-                                                   quoted,
-                                                   quoted_dollar_atp,
-                                                   contains_dollar_at);
-                 /* XXX - fix up later, esp. noting presence of
-                          W_HASQUOTEDNULL in ret->flags */
-                 free (value);
-               }
-             else
-               temp = (char *)NULL;
-           }
-         else
-           {
-             FREE (value);
-           }
-         /* Otherwise do nothing; just use the value in TEMP. */
-       }
-      else     /* VAR not set or VAR is NULL. */
-       {
-         FREE (temp);
-         temp = (char *)NULL;
-         if (c == '=' && var_is_special)
-           {
-             report_error (_("$%s: cannot assign in this way"), name);
-             free (name);
-             free (value);
-             return &expand_wdesc_error;
-           }
-         else if (c == '?')
-           {
-             parameter_brace_expand_error (name, value);
-             return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
-           }
-         else if (c != '+')
-           {
-             /* XXX -- if we're double-quoted and the named variable is "$@",
-                       we want to turn off any special handling of "$@" --
-                       we're not using it, so whatever is on the rhs applies. */
-             if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-               *quoted_dollar_atp = 0;
-             if (contains_dollar_at)
-               *contains_dollar_at = 0;
-
-             ret = parameter_brace_expand_rhs (name, value, c, quoted,
-                                               quoted_dollar_atp,
-                                               contains_dollar_at);
-             /* XXX - fix up later, esp. noting presence of
-                      W_HASQUOTEDNULL in tdesc->flags */
-           }
-         free (value);
-       }
-
-      break;
-    }
-  free (name);
-
-  if (ret == 0)
-    {
-      ret = alloc_word_desc ();
-      ret->flags = tflag;
-      ret->word = temp;
-    }
-  return (ret);
-}
-
-/* Expand a single ${xxx} expansion.  The braces are optional.  When
-   the braces are used, parameter_brace_expand() does the work,
-   possibly calling param_expand recursively. */
-static WORD_DESC *
-param_expand (string, sindex, quoted, expanded_something,
-             contains_dollar_at, quoted_dollar_at_p, had_quoted_null_p,
-             pflags)
-     char *string;
-     int *sindex, quoted, *expanded_something, *contains_dollar_at;
-     int *quoted_dollar_at_p, *had_quoted_null_p, pflags;
-{
-  char *temp, *temp1, uerror[3];
-  int zindex, t_index, expok;
-  unsigned char c;
-  intmax_t number;
-  SHELL_VAR *var;
-  WORD_LIST *list;
-  WORD_DESC *tdesc, *ret;
-  int tflag;
-
-  zindex = *sindex;
-  c = string[++zindex];
-
-  temp = (char *)NULL;
-  ret = tdesc = (WORD_DESC *)NULL;
-  tflag = 0;
-
-  /* Do simple cases first. Switch on what follows '$'. */
-  switch (c)
-    {
-    /* $0 .. $9? */
-    case '0':
-    case '1':
-    case '2':
-    case '3':
-    case '4':
-    case '5':
-    case '6':
-    case '7':
-    case '8':
-    case '9':
-      temp1 = dollar_vars[TODIGIT (c)];
-      if (unbound_vars_is_error && temp1 == (char *)NULL)
-       {
-         uerror[0] = '$';
-         uerror[1] = c;
-         uerror[2] = '\0';
-         last_command_exit_value = EXECUTION_FAILURE;
-         err_unboundvar (uerror);
-         return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
-       }
-      if (temp1)
-       temp = (*temp1 && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-                 ? quote_string (temp1)
-                 : quote_escapes (temp1);
-      else
-       temp = (char *)NULL;
-
-      break;
-
-    /* $$ -- pid of the invoking shell. */
-    case '$':
-      temp = itos (dollar_dollar_pid);
-      break;
-
-    /* $# -- number of positional parameters. */
-    case '#':
-      temp = itos (number_of_args ());
-      break;
-
-    /* $? -- return value of the last synchronous command. */
-    case '?':
-      temp = itos (last_command_exit_value);
-      break;
-
-    /* $- -- flags supplied to the shell on invocation or by `set'. */
-    case '-':
-      temp = which_set_flags ();
-      break;
-
-      /* $! -- Pid of the last asynchronous command. */
-    case '!':
-      /* If no asynchronous pids have been created, expand to nothing.
-        If `set -u' has been executed, and no async processes have
-        been created, this is an expansion error. */
-      if (last_asynchronous_pid == NO_PID)
-       {
-         if (expanded_something)
-           *expanded_something = 0;
-         temp = (char *)NULL;
-         if (unbound_vars_is_error)
-           {
-             uerror[0] = '$';
-             uerror[1] = c;
-             uerror[2] = '\0';
-             last_command_exit_value = EXECUTION_FAILURE;
-             err_unboundvar (uerror);
-             return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
-           }
-       }
-      else
-       temp = itos (last_asynchronous_pid);
-      break;
-
-    /* The only difference between this and $@ is when the arg is quoted. */
-    case '*':          /* `$*' */
-      list = list_rest_of_args ();
-
-#if 0
-      /* According to austin-group posix proposal by Geoff Clare in
-        <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
-
-       "The shell shall write a message to standard error and
-        immediately exit when it tries to expand an unset parameter
-        other than the '@' and '*' special parameters."
-      */
-
-      if (list == 0 && unbound_vars_is_error && (pflags & PF_IGNUNBOUND) == 0)
-       {
-         uerror[0] = '$';
-         uerror[1] = '*';
-         uerror[2] = '\0';
-         last_command_exit_value = EXECUTION_FAILURE;
-         err_unboundvar (uerror);
-         return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
-       }
-#endif
-
-      /* If there are no command-line arguments, this should just
-        disappear if there are other characters in the expansion,
-        even if it's quoted. */
-      if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && list == 0)
-       temp = (char *)NULL;
-      else if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES|Q_PATQUOTE))
-       {
-         /* If we have "$*" we want to make a string of the positional
-            parameters, separated by the first character of $IFS, and
-            quote the whole string, including the separators.  If IFS
-            is unset, the parameters are separated by ' '; if $IFS is
-            null, the parameters are concatenated. */
-         temp = (quoted & (Q_DOUBLE_QUOTES|Q_PATQUOTE)) ? string_list_dollar_star (list) : string_list (list);
-         temp1 = quote_string (temp);
-         if (*temp == 0)
-           tflag |= W_HASQUOTEDNULL;
-         free (temp);
-         temp = temp1;
-       }
-      else
-       {
-         /* We check whether or not we're eventually going to split $* here,
-            for example when IFS is empty and we are processing the rhs of
-            an assignment statement.  In that case, we don't separate the
-            arguments at all.  Otherwise, if the $* is not quoted it is
-            identical to $@ */
-#if 1
-#  if defined (HANDLE_MULTIBYTE)
-         if (expand_no_split_dollar_star && ifs_firstc[0] == 0)
-#  else
-         if (expand_no_split_dollar_star && ifs_firstc == 0)
-#  endif
-           temp = string_list_dollar_star (list);
-         else
-           temp = string_list_dollar_at (list, quoted);
-#else
-         temp = string_list_dollar_at (list, quoted);
-#endif
-         if (expand_no_split_dollar_star == 0 && contains_dollar_at)
-           *contains_dollar_at = 1;
-       }
-
-      dispose_words (list);
-      break;
-
-    /* When we have "$@" what we want is "$1" "$2" "$3" ... This
-       means that we have to turn quoting off after we split into
-       the individually quoted arguments so that the final split
-       on the first character of $IFS is still done.  */
-    case '@':          /* `$@' */
-      list = list_rest_of_args ();
-
-#if 0
-      /* According to austin-group posix proposal by Geoff Clare in
-        <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
-
-       "The shell shall write a message to standard error and
-        immediately exit when it tries to expand an unset parameter
-        other than the '@' and '*' special parameters."
-      */
-
-      if (list == 0 && unbound_vars_is_error && (pflags & PF_IGNUNBOUND) == 0)
-       {
-         uerror[0] = '$';
-         uerror[1] = '@';
-         uerror[2] = '\0';
-         last_command_exit_value = EXECUTION_FAILURE;
-         err_unboundvar (uerror);
-         return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
-       }
-#endif
-
-      /* We want to flag the fact that we saw this.  We can't turn
-        off quoting entirely, because other characters in the
-        string might need it (consider "\"$@\""), but we need some
-        way to signal that the final split on the first character
-        of $IFS should be done, even though QUOTED is 1. */
-      /* XXX - should this test include Q_PATQUOTE? */
-      if (quoted_dollar_at_p && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-       *quoted_dollar_at_p = 1;
-      if (contains_dollar_at)
-       *contains_dollar_at = 1;
-
-      /* We want to separate the positional parameters with the first
-        character of $IFS in case $IFS is something other than a space.
-        We also want to make sure that splitting is done no matter what --
-        according to POSIX.2, this expands to a list of the positional
-        parameters no matter what IFS is set to. */
-      temp = string_list_dollar_at (list, quoted);
-
-      dispose_words (list);
-      break;
-
-    case LBRACE:
-      tdesc = parameter_brace_expand (string, &zindex, quoted,
-                                     quoted_dollar_at_p,
-                                     contains_dollar_at);
-
-      if (tdesc == &expand_wdesc_error || tdesc == &expand_wdesc_fatal)
-       return (tdesc);
-      temp = tdesc ? tdesc->word : (char *)0;
-
-      /* XXX */
-      /* Quoted nulls should be removed if there is anything else
-        in the string. */
-      /* Note that we saw the quoted null so we can add one back at
-        the end of this function if there are no other characters
-        in the string, discard TEMP, and go on.  The exception to
-        this is when we have "${@}" and $1 is '', since $@ needs
-        special handling. */
-      if (tdesc && tdesc->word && (tdesc->flags & W_HASQUOTEDNULL) && QUOTED_NULL (temp))
-       {
-         if (had_quoted_null_p)
-           *had_quoted_null_p = 1;
-         if (*quoted_dollar_at_p == 0)
-           {
-             free (temp);
-             tdesc->word = temp = (char *)NULL;
-           }
-           
-       }
-
-      ret = tdesc;
-      goto return0;
-
-    /* Do command or arithmetic substitution. */
-    case LPAREN:
-      /* We have to extract the contents of this paren substitution. */
-      t_index = zindex + 1;
-      temp = extract_command_subst (string, &t_index, 0);
-      zindex = t_index;
-
-      /* For Posix.2-style `$(( ))' arithmetic substitution,
-        extract the expression and pass it to the evaluator. */
-      if (temp && *temp == LPAREN)
-       {
-         char *temp2;
-         temp1 = temp + 1;
-         temp2 = savestring (temp1);
-         t_index = strlen (temp2) - 1;
-
-         if (temp2[t_index] != RPAREN)
-           {
-             free (temp2);
-             goto comsub;
-           }
-
-         /* Cut off ending `)' */
-         temp2[t_index] = '\0';
-
-         if (chk_arithsub (temp2, t_index) == 0)
-           {
-             free (temp2);
-             goto comsub;
-           }
-
-         /* Expand variables found inside the expression. */
-         temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES);
-         free (temp2);
-
-arithsub:
-         /* No error messages. */
-         this_command_name = (char *)NULL;
-         number = evalexp (temp1, &expok);
-         free (temp);
-         free (temp1);
-         if (expok == 0)
-           {
-             if (interactive_shell == 0 && posixly_correct)
-               {
-                 last_command_exit_value = EXECUTION_FAILURE;
-                 return (&expand_wdesc_fatal);
-               }
-             else
-               return (&expand_wdesc_error);
-           }
-         temp = itos (number);
-         break;
-       }
-
-comsub:
-      if (pflags & PF_NOCOMSUB)
-       /* we need zindex+1 because string[zindex] == RPAREN */
-       temp1 = substring (string, *sindex, zindex+1);
-      else
-       {
-         tdesc = command_substitute (temp, quoted);
-         temp1 = tdesc ? tdesc->word : (char *)NULL;
-         if (tdesc)
-           dispose_word_desc (tdesc);
-       }
-      FREE (temp);
-      temp = temp1;
-      break;
-
-    /* Do POSIX.2d9-style arithmetic substitution.  This will probably go
-       away in a future bash release. */
-    case '[':
-      /* Extract the contents of this arithmetic substitution. */
-      t_index = zindex + 1;
-      temp = extract_arithmetic_subst (string, &t_index);
-      zindex = t_index;
-      if (temp == 0)
-       {
-         temp = savestring (string);
-         if (expanded_something)
-           *expanded_something = 0;
-         goto return0;
-       }         
-
-       /* Do initial variable expansion. */
-      temp1 = expand_arith_string (temp, Q_DOUBLE_QUOTES);
-
-      goto arithsub;
-
-    default:
-      /* Find the variable in VARIABLE_LIST. */
-      temp = (char *)NULL;
-
-      for (t_index = zindex; (c = string[zindex]) && legal_variable_char (c); zindex++)
-       ;
-      temp1 = (zindex > t_index) ? substring (string, t_index, zindex) : (char *)NULL;
-
-      /* If this isn't a variable name, then just output the `$'. */
-      if (temp1 == 0 || *temp1 == '\0')
-       {
-         FREE (temp1);
-         temp = (char *)xmalloc (2);
-         temp[0] = '$';
-         temp[1] = '\0';
-         if (expanded_something)
-           *expanded_something = 0;
-         goto return0;
-       }
-
-      /* If the variable exists, return its value cell. */
-      var = find_variable (temp1);
-
-      if (var && invisible_p (var) == 0 && var_isset (var))
-       {
-#if defined (ARRAY_VARS)
-         if (assoc_p (var) || array_p (var))
-           {
-             temp = array_p (var) ? array_reference (array_cell (var), 0)
-                                  : assoc_reference (assoc_cell (var), "0");
-             if (temp)
-               temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-                         ? quote_string (temp)
-                         : quote_escapes (temp);
-             else if (unbound_vars_is_error)
-               goto unbound_variable;
-           }
-         else
-#endif
-           {
-             temp = value_cell (var);
-
-             temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-                       ? quote_string (temp)
-                       : quote_escapes (temp);
-           }
-
-         free (temp1);
-
-         goto return0;
-       }
-
-      temp = (char *)NULL;
-
-unbound_variable:
-      if (unbound_vars_is_error)
-       {
-         last_command_exit_value = EXECUTION_FAILURE;
-         err_unboundvar (temp1);
-       }
-      else
-       {
-         free (temp1);
-         goto return0;
-       }
-
-      free (temp1);
-      last_command_exit_value = EXECUTION_FAILURE;
-      return ((unbound_vars_is_error && interactive_shell == 0)
-               ? &expand_wdesc_fatal
-               : &expand_wdesc_error);
-    }
-
-  if (string[zindex])
-    zindex++;
-
-return0:
-  *sindex = zindex;
-
-  if (ret == 0)
-    {
-      ret = alloc_word_desc ();
-      ret->flags = tflag;      /* XXX */
-      ret->word = temp;
-    }
-  return ret;
-}
-
-/* Make a word list which is the result of parameter and variable
-   expansion, command substitution, arithmetic substitution, and
-   quote removal of WORD.  Return a pointer to a WORD_LIST which is
-   the result of the expansion.  If WORD contains a null word, the
-   word list returned is also null.
-
-   QUOTED contains flag values defined in shell.h.
-
-   ISEXP is used to tell expand_word_internal that the word should be
-   treated as the result of an expansion.  This has implications for
-   how IFS characters in the word are treated.
-
-   CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
-   they point to an integer value which receives information about expansion.
-   CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
-   EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
-   else zero.
-
-   This only does word splitting in the case of $@ expansion.  In that
-   case, we split on ' '. */
-
-/* Values for the local variable quoted_state. */
-#define UNQUOTED        0
-#define PARTIALLY_QUOTED 1
-#define WHOLLY_QUOTED    2
-
-static WORD_LIST *
-expand_word_internal (word, quoted, isexp, contains_dollar_at, expanded_something)
-     WORD_DESC *word;
-     int quoted, isexp;
-     int *contains_dollar_at;
-     int *expanded_something;
-{
-  WORD_LIST *list;
-  WORD_DESC *tword;
-
-  /* The intermediate string that we build while expanding. */
-  char *istring;
-
-  /* The current size of the above object. */
-  int istring_size;
-
-  /* Index into ISTRING. */
-  int istring_index;
-
-  /* Temporary string storage. */
-  char *temp, *temp1;
-
-  /* The text of WORD. */
-  register char *string;
-
-  /* The size of STRING. */
-  size_t string_size;
-
-  /* The index into STRING. */
-  int sindex;
-
-  /* This gets 1 if we see a $@ while quoted. */
-  int quoted_dollar_at;
-
-  /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
-     whether WORD contains no quoting characters, a partially quoted
-     string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
-  int quoted_state;
-
-  /* State flags */
-  int had_quoted_null;
-  int has_dollar_at;
-  int tflag;
-
-  int assignoff;               /* If assignment, offset of `=' */
-
-  register unsigned char c;    /* Current character. */
-  int t_index;                 /* For calls to string_extract_xxx. */
-
-  char twochars[2];
-
-  DECLARE_MBSTATE;
-
-  istring = (char *)xmalloc (istring_size = DEFAULT_INITIAL_ARRAY_SIZE);
-  istring[istring_index = 0] = '\0';
-  quoted_dollar_at = had_quoted_null = has_dollar_at = 0;
-  quoted_state = UNQUOTED;
-
-  string = word->word;
-  if (string == 0)
-    goto finished_with_string;
-  /* Don't need the string length for the SADD... and COPY_ macros unless
-     multibyte characters are possible. */
-  string_size = (MB_CUR_MAX > 1) ? strlen (string) : 1;
-
-  if (contains_dollar_at)
-    *contains_dollar_at = 0;
-
-  assignoff = -1;
-
-  /* Begin the expansion. */
-
-  for (sindex = 0; ;)
-    {
-      c = string[sindex];
-
-      /* Case on toplevel character. */
-      switch (c)
-       {
-       case '\0':
-         goto finished_with_string;
-
-       case CTLESC:
-         sindex++;
-#if HANDLE_MULTIBYTE
-         if (MB_CUR_MAX > 1 && string[sindex])
-           {
-             SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
-           }
-         else
-#endif
-           {
-             temp = (char *)xmalloc (3);
-             temp[0] = CTLESC;
-             temp[1] = c = string[sindex];
-             temp[2] = '\0';
-           }
-
-dollar_add_string:
-         if (string[sindex])
-           sindex++;
-
-add_string:
-         if (temp)
-           {
-             istring = sub_append_string (temp, istring, &istring_index, &istring_size);
-             temp = (char *)0;
-           }
-
-         break;
-
-#if defined (PROCESS_SUBSTITUTION)
-         /* Process substitution. */
-       case '<':
-       case '>':
-         {
-           if (string[++sindex] != LPAREN || (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (word->flags & (W_DQUOTE|W_NOPROCSUB)) || posixly_correct)
-             {
-               sindex--;       /* add_character: label increments sindex */
-               goto add_character;
-             }
-           else
-             t_index = sindex + 1; /* skip past both '<' and LPAREN */
-
-           temp1 = extract_process_subst (string, (c == '<') ? "<(" : ">(", &t_index); /*))*/
-           sindex = t_index;
-
-           /* If the process substitution specification is `<()', we want to
-              open the pipe for writing in the child and produce output; if
-              it is `>()', we want to open the pipe for reading in the child
-              and consume input. */
-           temp = temp1 ? process_substitute (temp1, (c == '>')) : (char *)0;
-
-           FREE (temp1);
-
-           goto dollar_add_string;
-         }
-#endif /* PROCESS_SUBSTITUTION */
-
-       case '=':
-         /* Posix.2 section 3.6.1 says that tildes following `=' in words
-            which are not assignment statements are not expanded.  If the
-            shell isn't in posix mode, though, we perform tilde expansion
-            on `likely candidate' unquoted assignment statements (flags
-            include W_ASSIGNMENT but not W_QUOTED).  A likely candidate
-            contains an unquoted :~ or =~.  Something to think about: we
-            now have a flag that says  to perform tilde expansion on arguments
-            to `assignment builtins' like declare and export that look like
-            assignment statements.  We now do tilde expansion on such words
-            even in POSIX mode. */     
-         if (word->flags & (W_ASSIGNRHS|W_NOTILDE))
-           {
-             if (isexp == 0 && isifs (c))
-               goto add_ifs_character;
-             else
-               goto add_character;
-           }
-         /* If we're not in posix mode or forcing assignment-statement tilde
-            expansion, note where the `=' appears in the word and prepare to
-            do tilde expansion following the first `='. */
-         if ((word->flags & W_ASSIGNMENT) &&
-             (posixly_correct == 0 || (word->flags & W_TILDEEXP)) &&
-             assignoff == -1 && sindex > 0)
-           assignoff = sindex;
-         if (sindex == assignoff && string[sindex+1] == '~')   /* XXX */
-           word->flags |= W_ITILDE;
-#if 0
-         else if ((word->flags & W_ASSIGNMENT) &&
-                  (posixly_correct == 0 || (word->flags & W_TILDEEXP)) &&
-                  string[sindex+1] == '~')
-           word->flags |= W_ITILDE;
-#endif
-         if (isexp == 0 && isifs (c))
-           goto add_ifs_character;
-         else
-           goto add_character;
-
-       case ':':
-         if (word->flags & W_NOTILDE)
-           {
-             if (isexp == 0 && isifs (c))
-               goto add_ifs_character;
-             else
-               goto add_character;
-           }
-
-         if ((word->flags & (W_ASSIGNMENT|W_ASSIGNRHS|W_TILDEEXP)) &&
-             string[sindex+1] == '~')
-           word->flags |= W_ITILDE;
-
-         if (isexp == 0 && isifs (c))
-           goto add_ifs_character;
-         else
-           goto add_character;
-
-       case '~':
-         /* If the word isn't supposed to be tilde expanded, or we're not
-            at the start of a word or after an unquoted : or = in an
-            assignment statement, we don't do tilde expansion. */
-         if ((word->flags & (W_NOTILDE|W_DQUOTE)) ||
-             (sindex > 0 && ((word->flags & W_ITILDE) == 0)) ||
-             (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-           {
-             word->flags &= ~W_ITILDE;
-             if (isexp == 0 && isifs (c) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
-               goto add_ifs_character;
-             else
-               goto add_character;
-           }
-
-         if (word->flags & W_ASSIGNRHS)
-           tflag = 2;
-         else if (word->flags & (W_ASSIGNMENT|W_TILDEEXP))
-           tflag = 1;
-         else
-           tflag = 0;
-
-         temp = bash_tilde_find_word (string + sindex, tflag, &t_index);
-           
-         word->flags &= ~W_ITILDE;
-
-         if (temp && *temp && t_index > 0)
-           {
-             temp1 = bash_tilde_expand (temp, tflag);
-             if  (temp1 && *temp1 == '~' && STREQ (temp, temp1))
-               {
-                 FREE (temp);
-                 FREE (temp1);
-                 goto add_character;           /* tilde expansion failed */
-               }
-             free (temp);
-             temp = temp1;
-             sindex += t_index;
-             goto add_quoted_string;           /* XXX was add_string */
-           }
-         else
-           {
-             FREE (temp);
-             goto add_character;
-           }
-       
-       case '$':
-         if (expanded_something)
-           *expanded_something = 1;
-
-         has_dollar_at = 0;
-         tword = param_expand (string, &sindex, quoted, expanded_something,
-                              &has_dollar_at, &quoted_dollar_at,
-                              &had_quoted_null,
-                              (word->flags & W_NOCOMSUB) ? PF_NOCOMSUB : 0);
-
-         if (tword == &expand_wdesc_error || tword == &expand_wdesc_fatal)
-           {
-             free (string);
-             free (istring);
-             return ((tword == &expand_wdesc_error) ? &expand_word_error
-                                                    : &expand_word_fatal);
-           }
-         if (contains_dollar_at && has_dollar_at)
-           *contains_dollar_at = 1;
-
-         if (tword && (tword->flags & W_HASQUOTEDNULL))
-           had_quoted_null = 1;
-
-         temp = tword->word;
-         dispose_word_desc (tword);
-
-         goto add_string;
-         break;
-
-       case '`':               /* Backquoted command substitution. */
-         {
-           t_index = sindex++;
-
-           temp = string_extract (string, &sindex, "`", SX_REQMATCH);
-           /* The test of sindex against t_index is to allow bare instances of
-              ` to pass through, for backwards compatibility. */
-           if (temp == &extract_string_error || temp == &extract_string_fatal)
-             {
-               if (sindex - 1 == t_index)
-                 {
-                   sindex = t_index;
-                   goto add_character;
-                 }
-               report_error (_("bad substitution: no closing \"`\" in %s") , string+t_index);
-               free (string);
-               free (istring);
-               return ((temp == &extract_string_error) ? &expand_word_error
-                                                       : &expand_word_fatal);
-             }
-               
-           if (expanded_something)
-             *expanded_something = 1;
-
-           if (word->flags & W_NOCOMSUB)
-             /* sindex + 1 because string[sindex] == '`' */
-             temp1 = substring (string, t_index, sindex + 1);
-           else
-             {
-               de_backslash (temp);
-               tword = command_substitute (temp, quoted);
-               temp1 = tword ? tword->word : (char *)NULL;
-               if (tword)
-                 dispose_word_desc (tword);
-             }
-           FREE (temp);
-           temp = temp1;
-           goto dollar_add_string;
-         }
-
-       case '\\':
-         if (string[sindex + 1] == '\n')
-           {
-             sindex += 2;
-             continue;
-           }
-
-         c = string[++sindex];
-
-         if (quoted & Q_HERE_DOCUMENT)
-           tflag = CBSHDOC;
-         else if (quoted & Q_DOUBLE_QUOTES)
-           tflag = CBSDQUOTE;
-         else
-           tflag = 0;
-
-         if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && ((sh_syntaxtab[c] & tflag) == 0))
-           {
-             SCOPY_CHAR_I (twochars, '\\', c, string, sindex, string_size);
-           }
-         else if (c == 0)
-           {
-             c = CTLNUL;
-             sindex--;         /* add_character: label increments sindex */
-             goto add_character;
-           }
-         else
-           {
-             SCOPY_CHAR_I (twochars, CTLESC, c, string, sindex, string_size);
-           }
-
-         sindex++;
-add_twochars:
-         /* BEFORE jumping here, we need to increment sindex if appropriate */
-         RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size,
-                                 DEFAULT_ARRAY_SIZE);
-         istring[istring_index++] = twochars[0];
-         istring[istring_index++] = twochars[1];
-         istring[istring_index] = '\0';
-
-         break;
-
-       case '"':
-#if 0
-         if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (word->flags & W_DQUOTE))
-#else
-         if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-#endif
-           goto add_character;
-
-         t_index = ++sindex;
-         temp = string_extract_double_quoted (string, &sindex, 0);
-
-         /* If the quotes surrounded the entire string, then the
-            whole word was quoted. */
-         quoted_state = (t_index == 1 && string[sindex] == '\0')
-                           ? WHOLLY_QUOTED
-                           : PARTIALLY_QUOTED;
-
-         if (temp && *temp)
-           {
-             tword = alloc_word_desc ();
-             tword->word = temp;
-
-             temp = (char *)NULL;
-
-             has_dollar_at = 0;
-             /* Need to get W_HASQUOTEDNULL flag through this function. */
-             list = expand_word_internal (tword, Q_DOUBLE_QUOTES, 0, &has_dollar_at, (int *)NULL);
-
-             if (list == &expand_word_error || list == &expand_word_fatal)
-               {
-                 free (istring);
-                 free (string);
-                 /* expand_word_internal has already freed temp_word->word
-                    for us because of the way it prints error messages. */
-                 tword->word = (char *)NULL;
-                 dispose_word (tword);
-                 return list;
-               }
-
-             dispose_word (tword);
-
-             /* "$@" (a double-quoted dollar-at) expands into nothing,
-                not even a NULL word, when there are no positional
-                parameters. */
-             if (list == 0 && has_dollar_at)
-               {
-                 quoted_dollar_at++;
-                 break;
-               }
-
-             /* If we get "$@", we know we have expanded something, so we
-                need to remember it for the final split on $IFS.  This is
-                a special case; it's the only case where a quoted string
-                can expand into more than one word.  It's going to come back
-                from the above call to expand_word_internal as a list with
-                a single word, in which all characters are quoted and
-                separated by blanks.  What we want to do is to turn it back
-                into a list for the next piece of code. */
-             if (list)
-               dequote_list (list);
-
-             if (list && list->word && (list->word->flags & W_HASQUOTEDNULL))
-               had_quoted_null = 1;
-
-             if (has_dollar_at)
-               {
-                 quoted_dollar_at++;
-                 if (contains_dollar_at)
-                   *contains_dollar_at = 1;
-                 if (expanded_something)
-                   *expanded_something = 1;
-               }
-           }
-         else
-           {
-             /* What we have is "".  This is a minor optimization. */
-             FREE (temp);
-             list = (WORD_LIST *)NULL;
-           }
-
-         /* The code above *might* return a list (consider the case of "$@",
-            where it returns "$1", "$2", etc.).  We can't throw away the
-            rest of the list, and we have to make sure each word gets added
-            as quoted.  We test on tresult->next:  if it is non-NULL, we
-            quote the whole list, save it to a string with string_list, and
-            add that string. We don't need to quote the results of this
-            (and it would be wrong, since that would quote the separators
-            as well), so we go directly to add_string. */
-         if (list)
-           {
-             if (list->next)
-               {
-                 /* Testing quoted_dollar_at makes sure that "$@" is
-                    split correctly when $IFS does not contain a space. */
-                 temp = quoted_dollar_at
-                               ? string_list_dollar_at (list, Q_DOUBLE_QUOTES)
-                               : string_list (quote_list (list));
-                 dispose_words (list);
-                 goto add_string;
-               }
-             else
-               {
-                 temp = savestring (list->word->word);
-                 tflag = list->word->flags;
-                 dispose_words (list);
-
-                 /* If the string is not a quoted null string, we want
-                    to remove any embedded unquoted CTLNUL characters.
-                    We do not want to turn quoted null strings back into
-                    the empty string, though.  We do this because we
-                    want to remove any quoted nulls from expansions that
-                    contain other characters.  For example, if we have
-                    x"$*"y or "x$*y" and there are no positional parameters,
-                    the $* should expand into nothing. */
-                 /* We use the W_HASQUOTEDNULL flag to differentiate the
-                    cases:  a quoted null character as above and when
-                    CTLNUL is contained in the (non-null) expansion
-                    of some variable.  We use the had_quoted_null flag to
-                    pass the value through this function to its caller. */
-                 if ((tflag & W_HASQUOTEDNULL) && QUOTED_NULL (temp) == 0)
-                   remove_quoted_nulls (temp); /* XXX */
-               }
-           }
-         else
-           temp = (char *)NULL;
-
-         /* We do not want to add quoted nulls to strings that are only
-            partially quoted; we can throw them away. */
-         if (temp == 0 && quoted_state == PARTIALLY_QUOTED)
-           continue;
-
-       add_quoted_string:
-
-         if (temp)
-           {
-             temp1 = temp;
-             temp = quote_string (temp);
-             free (temp1);
-             goto add_string;
-           }
-         else
-           {
-             /* Add NULL arg. */
-             c = CTLNUL;
-             sindex--;         /* add_character: label increments sindex */
-             goto add_character;
-           }
-
-         /* break; */
-
-       case '\'':
-#if 0
-         if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (word->flags & W_DQUOTE))
-#else
-         if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-#endif
-           goto add_character;
-
-         t_index = ++sindex;
-         temp = string_extract_single_quoted (string, &sindex);
-
-         /* If the entire STRING was surrounded by single quotes,
-            then the string is wholly quoted. */
-         quoted_state = (t_index == 1 && string[sindex] == '\0')
-                           ? WHOLLY_QUOTED
-                           : PARTIALLY_QUOTED;
-
-         /* If all we had was '', it is a null expansion. */
-         if (*temp == '\0')
-           {
-             free (temp);
-             temp = (char *)NULL;
-           }
-         else
-           remove_quoted_escapes (temp);       /* ??? */
-
-         /* We do not want to add quoted nulls to strings that are only
-            partially quoted; such nulls are discarded. */
-         if (temp == 0 && (quoted_state == PARTIALLY_QUOTED))
-           continue;
-
-         /* If we have a quoted null expansion, add a quoted NULL to istring. */
-         if (temp == 0)
-           {
-             c = CTLNUL;
-             sindex--;         /* add_character: label increments sindex */
-             goto add_character;
-           }
-         else
-           goto add_quoted_string;
-
-         /* break; */
-
-       default:
-         /* This is the fix for " $@ " */
-       add_ifs_character:
-         if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (isexp == 0 && isifs (c)))
-           {
-             if (string[sindex])       /* from old goto dollar_add_string */
-               sindex++;
-             if (c == 0)
-               {
-                 c = CTLNUL;
-                 goto add_character;
-               }
-             else
-               {
-#if HANDLE_MULTIBYTE
-                 if (MB_CUR_MAX > 1)
-                   sindex--;
-
-                 if (MB_CUR_MAX > 1)
-                   {
-                     SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
-                   }
-                 else
-#endif
-                   {
-                     twochars[0] = CTLESC;
-                     twochars[1] = c;
-if (c == ':')
-  itrace("add_ifs_character: adding quoted `%c'", c);
-                     goto add_twochars;
-                   }
-               }
-           }
-
-         SADD_MBCHAR (temp, string, sindex, string_size);
-
-       add_character:
-         RESIZE_MALLOCED_BUFFER (istring, istring_index, 1, istring_size,
-                                 DEFAULT_ARRAY_SIZE);
-         istring[istring_index++] = c;
-         istring[istring_index] = '\0';
-
-         /* Next character. */
-         sindex++;
-       }
-    }
-
-finished_with_string:
-  /* OK, we're ready to return.  If we have a quoted string, and
-     quoted_dollar_at is not set, we do no splitting at all; otherwise
-     we split on ' '.  The routines that call this will handle what to
-     do if nothing has been expanded. */
-
-  /* Partially and wholly quoted strings which expand to the empty
-     string are retained as an empty arguments.  Unquoted strings
-     which expand to the empty string are discarded.  The single
-     exception is the case of expanding "$@" when there are no
-     positional parameters.  In that case, we discard the expansion. */
-
-  /* Because of how the code that handles "" and '' in partially
-     quoted strings works, we need to make ISTRING into a QUOTED_NULL
-     if we saw quoting characters, but the expansion was empty.
-     "" and '' are tossed away before we get to this point when
-     processing partially quoted strings.  This makes "" and $xxx""
-     equivalent when xxx is unset.  We also look to see whether we
-     saw a quoted null from a ${} expansion and add one back if we
-     need to. */
-
-  /* If we expand to nothing and there were no single or double quotes
-     in the word, we throw it away.  Otherwise, we return a NULL word.
-     The single exception is for $@ surrounded by double quotes when
-     there are no positional parameters.  In that case, we also throw
-     the word away. */
-
-  if (*istring == '\0')
-    {
-      if (quoted_dollar_at == 0 && (had_quoted_null || quoted_state == PARTIALLY_QUOTED))
-       {
-         istring[0] = CTLNUL;
-         istring[1] = '\0';
-         tword = make_bare_word (istring);
-         tword->flags |= W_HASQUOTEDNULL;              /* XXX */
-         list = make_word_list (tword, (WORD_LIST *)NULL);
-         if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-           tword->flags |= W_QUOTED;
-       }
-      /* According to sh, ksh, and Posix.2, if a word expands into nothing
-        and a double-quoted "$@" appears anywhere in it, then the entire
-        word is removed. */
-      else  if (quoted_state == UNQUOTED || quoted_dollar_at)
-       list = (WORD_LIST *)NULL;
-#if 0
-      else
-       {
-         tword = make_bare_word (istring);
-         if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-           tword->flags |= W_QUOTED;
-         list = make_word_list (tword, (WORD_LIST *)NULL);
-       }
-#else
-      else
-       list = (WORD_LIST *)NULL;
-#endif
-    }
-  else if (word->flags & W_NOSPLIT)
-    {
-      tword = make_bare_word (istring);
-      if (word->flags & W_ASSIGNMENT)
-       tword->flags |= W_ASSIGNMENT;   /* XXX */
-      if (word->flags & W_COMPASSIGN)
-       tword->flags |= W_COMPASSIGN;   /* XXX */
-      if (word->flags & W_NOGLOB)
-       tword->flags |= W_NOGLOB;       /* XXX */
-      if (word->flags & W_NOEXPAND)
-       tword->flags |= W_NOEXPAND;     /* XXX */
-      if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-       tword->flags |= W_QUOTED;
-      if (had_quoted_null)
-       tword->flags |= W_HASQUOTEDNULL;
-      list = make_word_list (tword, (WORD_LIST *)NULL);
-    }
-  else
-    {
-      char *ifs_chars;
-
-      ifs_chars = (quoted_dollar_at || has_dollar_at) ? ifs_value : (char *)NULL;
-
-      /* If we have $@, we need to split the results no matter what.  If
-        IFS is unset or NULL, string_list_dollar_at has separated the
-        positional parameters with a space, so we split on space (we have
-        set ifs_chars to " \t\n" above if ifs is unset).  If IFS is set,
-        string_list_dollar_at has separated the positional parameters
-        with the first character of $IFS, so we split on $IFS. */
-      if (has_dollar_at && ifs_chars)
-       list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
-      else
-       {
-         tword = make_bare_word (istring);
-         if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED))
-           tword->flags |= W_QUOTED;
-         if (word->flags & W_ASSIGNMENT)
-           tword->flags |= W_ASSIGNMENT;
-         if (word->flags & W_COMPASSIGN)
-           tword->flags |= W_COMPASSIGN;
-         if (word->flags & W_NOGLOB)
-           tword->flags |= W_NOGLOB;
-         if (word->flags & W_NOEXPAND)
-           tword->flags |= W_NOEXPAND;
-         if (had_quoted_null)
-           tword->flags |= W_HASQUOTEDNULL;    /* XXX */
-         list = make_word_list (tword, (WORD_LIST *)NULL);
-       }
-    }
-
-  free (istring);
-  return (list);
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*                Functions for Quote Removal                      */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Perform quote removal on STRING.  If QUOTED > 0, assume we are obeying the
-   backslash quoting rules for within double quotes or a here document. */
-char *
-string_quote_removal (string, quoted)
-     char *string;
-     int quoted;
-{
-  size_t slen;
-  char *r, *result_string, *temp, *send;
-  int sindex, tindex, dquote;
-  unsigned char c;
-  DECLARE_MBSTATE;
-
-  /* The result can be no longer than the original string. */
-  slen = strlen (string);
-  send = string + slen;
-
-  r = result_string = (char *)xmalloc (slen + 1);
-
-  for (dquote = sindex = 0; c = string[sindex];)
-    {
-      switch (c)
-       {
-       case '\\':
-         c = string[++sindex];
-         if (c == 0)
-           {
-             *r++ = '\\';
-             break;
-           }
-         if (((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote) && (sh_syntaxtab[c] & CBSDQUOTE) == 0)
-           *r++ = '\\';
-         /* FALLTHROUGH */
-
-       default:
-         SCOPY_CHAR_M (r, string, send, sindex);
-         break;
-
-       case '\'':
-         if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote)
-           {
-             *r++ = c;
-             sindex++;
-             break;
-           }
-         tindex = sindex + 1;
-         temp = string_extract_single_quoted (string, &tindex);
-         if (temp)
-           {
-             strcpy (r, temp);
-             r += strlen (r);
-             free (temp);
-           }
-         sindex = tindex;
-         break;
-
-       case '"':
-         dquote = 1 - dquote;
-         sindex++;
-         break;
-       }
-    }
-    *r = '\0';
-    return (result_string);
-}
-
-#if 0
-/* UNUSED */
-/* Perform quote removal on word WORD.  This allocates and returns a new
-   WORD_DESC *. */
-WORD_DESC *
-word_quote_removal (word, quoted)
-     WORD_DESC *word;
-     int quoted;
-{
-  WORD_DESC *w;
-  char *t;
-
-  t = string_quote_removal (word->word, quoted);
-  w = alloc_word_desc ();
-  w->word = t ? t : savestring ("");
-  return (w);
-}
-
-/* Perform quote removal on all words in LIST.  If QUOTED is non-zero,
-   the members of the list are treated as if they are surrounded by
-   double quotes.  Return a new list, or NULL if LIST is NULL. */
-WORD_LIST *
-word_list_quote_removal (list, quoted)
-     WORD_LIST *list;
-     int quoted;
-{
-  WORD_LIST *result, *t, *tresult, *e;
-
-  for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
-    {
-      tresult = make_word_list (word_quote_removal (t->word, quoted), (WORD_LIST *)NULL);
-#if 0
-      result = (WORD_LIST *) list_append (result, tresult);
-#else
-      if (result == 0)
-       result = e = tresult;
-      else
-       {
-         e->next = tresult;
-         while (e->next)
-           e = e->next;
-       }
-#endif
-    }
-  return (result);
-}
-#endif
-
-/*******************************************
- *                                        *
- *    Functions to perform word splitting  *
- *                                        *
- *******************************************/
-
-void
-setifs (v)
-     SHELL_VAR *v;
-{
-  char *t;
-  unsigned char uc;
-
-  ifs_var = v;
-  ifs_value = (v && value_cell (v)) ? value_cell (v) : " \t\n";
-
-  /* Should really merge ifs_cmap with sh_syntaxtab.  XXX - doesn't yet
-     handle multibyte chars in IFS */
-  memset (ifs_cmap, '\0', sizeof (ifs_cmap));
-  for (t = ifs_value ; t && *t; t++)
-    {
-      uc = *t;
-      ifs_cmap[uc] = 1;
-    }
-
-#if defined (HANDLE_MULTIBYTE)
-  if (ifs_value == 0)
-    {
-      ifs_firstc[0] = '\0';
-      ifs_firstc_len = 1;
-    }
-  else
-    {
-      size_t ifs_len;
-      ifs_len = strnlen (ifs_value, MB_CUR_MAX);
-      ifs_firstc_len = MBLEN (ifs_value, ifs_len);
-      if (ifs_firstc_len == 1 || ifs_firstc_len == 0 || MB_INVALIDCH (ifs_firstc_len))
-       {
-         ifs_firstc[0] = ifs_value[0];
-         ifs_firstc[1] = '\0';
-         ifs_firstc_len = 1;
-       }
-      else
-       memcpy (ifs_firstc, ifs_value, ifs_firstc_len);
-    }
-#else
-  ifs_firstc = ifs_value ? *ifs_value : 0;
-#endif
-}
-
-char *
-getifs ()
-{
-  return ifs_value;
-}
-
-/* This splits a single word into a WORD LIST on $IFS, but only if the word
-   is not quoted.  list_string () performs quote removal for us, even if we
-   don't do any splitting. */
-WORD_LIST *
-word_split (w, ifs_chars)
-     WORD_DESC *w;
-     char *ifs_chars;
-{
-  WORD_LIST *result;
-
-  if (w)
-    {
-      char *xifs;
-
-      xifs = ((w->flags & W_QUOTED) || ifs_chars == 0) ? "" : ifs_chars;
-      result = list_string (w->word, xifs, w->flags & W_QUOTED);
-    }
-  else
-    result = (WORD_LIST *)NULL;
-
-  return (result);
-}
-
-/* Perform word splitting on LIST and return the RESULT.  It is possible
-   to return (WORD_LIST *)NULL. */
-static WORD_LIST *
-word_list_split (list)
-     WORD_LIST *list;
-{
-  WORD_LIST *result, *t, *tresult, *e;
-
-  for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
-    {
-      tresult = word_split (t->word, ifs_value);
-      if (result == 0)
-        result = e = tresult;
-      else
-       {
-         e->next = tresult;
-         while (e->next)
-           e = e->next;
-       }
-    }
-  return (result);
-}
-
-/**************************************************
- *                                               *
- *    Functions to expand an entire WORD_LIST    *
- *                                               *
- **************************************************/
-
-/* Do any word-expansion-specific cleanup and jump to top_level */
-static void
-exp_jump_to_top_level (v)
-     int v;
-{
-  set_pipestatus_from_exit (last_command_exit_value);
-
-  /* Cleanup code goes here. */
-  expand_no_split_dollar_star = 0;     /* XXX */
-  expanding_redir = 0;
-  assigning_in_environment = 0;
-
-  if (parse_and_execute_level == 0)
-    top_level_cleanup ();                      /* from sig.c */
-
-  jump_to_top_level (v);
-}
-
-/* Put NLIST (which is a WORD_LIST * of only one element) at the front of
-   ELIST, and set ELIST to the new list. */
-#define PREPEND_LIST(nlist, elist) \
-       do { nlist->next = elist; elist = nlist; } while (0)
-
-/* Separate out any initial variable assignments from TLIST.  If set -k has
-   been executed, remove all assignment statements from TLIST.  Initial
-   variable assignments and other environment assignments are placed
-   on SUBST_ASSIGN_VARLIST. */
-static WORD_LIST *
-separate_out_assignments (tlist)
-     WORD_LIST *tlist;
-{
-  register WORD_LIST *vp, *lp;
-
-  if (tlist == 0)
-    return ((WORD_LIST *)NULL);
-
-  if (subst_assign_varlist)
-    dispose_words (subst_assign_varlist);      /* Clean up after previous error */
-
-  subst_assign_varlist = (WORD_LIST *)NULL;
-  vp = lp = tlist;
-
-  /* Separate out variable assignments at the start of the command.
-     Loop invariant: vp->next == lp
-     Loop postcondition:
-       lp = list of words left after assignment statements skipped
-       tlist = original list of words
-  */
-  while (lp && (lp->word->flags & W_ASSIGNMENT))
-    {
-      vp = lp;
-      lp = lp->next;
-    }
-
-  /* If lp != tlist, we have some initial assignment statements.
-     We make SUBST_ASSIGN_VARLIST point to the list of assignment
-     words and TLIST point to the remaining words.  */
-  if (lp != tlist)
-    {
-      subst_assign_varlist = tlist;
-      /* ASSERT(vp->next == lp); */
-      vp->next = (WORD_LIST *)NULL;    /* terminate variable list */
-      tlist = lp;                      /* remainder of word list */
-    }
-
-  /* vp == end of variable list */
-  /* tlist == remainder of original word list without variable assignments */
-  if (!tlist)
-    /* All the words in tlist were assignment statements */
-    return ((WORD_LIST *)NULL);
-
-  /* ASSERT(tlist != NULL); */
-  /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
-
-  /* If the -k option is in effect, we need to go through the remaining
-     words, separate out the assignment words, and place them on
-     SUBST_ASSIGN_VARLIST. */
-  if (place_keywords_in_env)
-    {
-      WORD_LIST *tp;   /* tp == running pointer into tlist */
-
-      tp = tlist;
-      lp = tlist->next;
-
-      /* Loop Invariant: tp->next == lp */
-      /* Loop postcondition: tlist == word list without assignment statements */
-      while (lp)
-       {
-         if (lp->word->flags & W_ASSIGNMENT)
-           {
-             /* Found an assignment statement, add this word to end of
-                subst_assign_varlist (vp). */
-             if (!subst_assign_varlist)
-               subst_assign_varlist = vp = lp;
-             else
-               {
-                 vp->next = lp;
-                 vp = lp;
-               }
-
-             /* Remove the word pointed to by LP from TLIST. */
-             tp->next = lp->next;
-             /* ASSERT(vp == lp); */
-             lp->next = (WORD_LIST *)NULL;
-             lp = tp->next;
-           }
-         else
-           {
-             tp = lp;
-             lp = lp->next;
-           }
-       }
-    }
-  return (tlist);
-}
-
-#define WEXP_VARASSIGN 0x001
-#define WEXP_BRACEEXP  0x002
-#define WEXP_TILDEEXP  0x004
-#define WEXP_PARAMEXP  0x008
-#define WEXP_PATHEXP   0x010
-
-/* All of the expansions, including variable assignments at the start of
-   the list. */
-#define WEXP_ALL       (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
-
-/* All of the expansions except variable assignments at the start of
-   the list. */
-#define WEXP_NOVARS    (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
-
-/* All of the `shell expansions': brace expansion, tilde expansion, parameter
-   expansion, command substitution, arithmetic expansion, word splitting, and
-   quote removal. */
-#define WEXP_SHELLEXP  (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
-
-/* Take the list of words in LIST and do the various substitutions.  Return
-   a new list of words which is the expanded list, and without things like
-   variable assignments. */
-
-WORD_LIST *
-expand_words (list)
-     WORD_LIST *list;
-{
-  return (expand_word_list_internal (list, WEXP_ALL));
-}
-
-/* Same as expand_words (), but doesn't hack variable or environment
-   variables. */
-WORD_LIST *
-expand_words_no_vars (list)
-     WORD_LIST *list;
-{
-  return (expand_word_list_internal (list, WEXP_NOVARS));
-}
-
-WORD_LIST *
-expand_words_shellexp (list)
-     WORD_LIST *list;
-{
-  return (expand_word_list_internal (list, WEXP_SHELLEXP));
-}
-
-static WORD_LIST *
-glob_expand_word_list (tlist, eflags)
-     WORD_LIST *tlist;
-     int eflags;
-{
-  char **glob_array, *temp_string;
-  register int glob_index;
-  WORD_LIST *glob_list, *output_list, *disposables, *next;
-  WORD_DESC *tword;
-
-  output_list = disposables = (WORD_LIST *)NULL;
-  glob_array = (char **)NULL;
-  while (tlist)
-    {
-      /* For each word, either globbing is attempted or the word is
-        added to orig_list.  If globbing succeeds, the results are
-        added to orig_list and the word (tlist) is added to the list
-        of disposable words.  If globbing fails and failed glob
-        expansions are left unchanged (the shell default), the
-        original word is added to orig_list.  If globbing fails and
-        failed glob expansions are removed, the original word is
-        added to the list of disposable words.  orig_list ends up
-        in reverse order and requires a call to REVERSE_LIST to
-        be set right.  After all words are examined, the disposable
-        words are freed. */
-      next = tlist->next;
-
-      /* If the word isn't an assignment and contains an unquoted
-        pattern matching character, then glob it. */
-      if ((tlist->word->flags & W_NOGLOB) == 0 &&
-         unquoted_glob_pattern_p (tlist->word->word))
-       {
-         glob_array = shell_glob_filename (tlist->word->word);
-
-         /* Handle error cases.
-            I don't think we should report errors like "No such file
-            or directory".  However, I would like to report errors
-            like "Read failed". */
-
-         if (glob_array == 0 || GLOB_FAILED (glob_array))
-           {
-             glob_array = (char **)xmalloc (sizeof (char *));
-             glob_array[0] = (char *)NULL;
-           }
-
-         /* Dequote the current word in case we have to use it. */
-         if (glob_array[0] == NULL)
-           {
-             temp_string = dequote_string (tlist->word->word);
-             free (tlist->word->word);
-             tlist->word->word = temp_string;
-           }
-
-         /* Make the array into a word list. */
-         glob_list = (WORD_LIST *)NULL;
-         for (glob_index = 0; glob_array[glob_index]; glob_index++)
-           {
-             tword = make_bare_word (glob_array[glob_index]);
-             tword->flags |= W_GLOBEXP;        /* XXX */
-             glob_list = make_word_list (tword, glob_list);
-           }
-
-         if (glob_list)
-           {
-             output_list = (WORD_LIST *)list_append (glob_list, output_list);
-             PREPEND_LIST (tlist, disposables);
-           }
-         else if (fail_glob_expansion != 0)
-           {
-             report_error (_("no match: %s"), tlist->word->word);
-             exp_jump_to_top_level (DISCARD);
-           }
-         else if (allow_null_glob_expansion == 0)
-           {
-             /* Failed glob expressions are left unchanged. */
-             PREPEND_LIST (tlist, output_list);
-           }
-         else
-           {
-             /* Failed glob expressions are removed. */
-             PREPEND_LIST (tlist, disposables);
-           }
-       }
-      else
-       {
-         /* Dequote the string. */
-         temp_string = dequote_string (tlist->word->word);
-         free (tlist->word->word);
-         tlist->word->word = temp_string;
-         PREPEND_LIST (tlist, output_list);
-       }
-
-      strvec_dispose (glob_array);
-      glob_array = (char **)NULL;
-
-      tlist = next;
-    }
-
-  if (disposables)
-    dispose_words (disposables);
-
-  if (output_list)
-    output_list = REVERSE_LIST (output_list, WORD_LIST *);
-
-  return (output_list);
-}
-
-#if defined (BRACE_EXPANSION)
-static WORD_LIST *
-brace_expand_word_list (tlist, eflags)
-     WORD_LIST *tlist;
-     int eflags;
-{
-  register char **expansions;
-  char *temp_string;
-  WORD_LIST *disposables, *output_list, *next;
-  WORD_DESC *w;
-  int eindex;
-
-  for (disposables = output_list = (WORD_LIST *)NULL; tlist; tlist = next)
-    {
-      next = tlist->next;
-
-      if ((tlist->word->flags & (W_COMPASSIGN|W_ASSIGNARG)) == (W_COMPASSIGN|W_ASSIGNARG))
-        {
-/*itrace("brace_expand_word_list: %s: W_COMPASSIGN|W_ASSIGNARG", tlist->word->word);*/
-         PREPEND_LIST (tlist, output_list);
-         continue;
-        }
-          
-      /* Only do brace expansion if the word has a brace character.  If
-        not, just add the word list element to BRACES and continue.  In
-        the common case, at least when running shell scripts, this will
-        degenerate to a bunch of calls to `mbschr', and then what is
-        basically a reversal of TLIST into BRACES, which is corrected
-        by a call to REVERSE_LIST () on BRACES when the end of TLIST
-        is reached. */
-      if (mbschr (tlist->word->word, LBRACE))
-       {
-         expansions = brace_expand (tlist->word->word);
-
-         for (eindex = 0; temp_string = expansions[eindex]; eindex++)
-           {
-             w = make_word (temp_string);
-             /* If brace expansion didn't change the word, preserve
-                the flags.  We may want to preserve the flags
-                unconditionally someday -- XXX */
-             if (STREQ (temp_string, tlist->word->word))
-               w->flags = tlist->word->flags;
-             output_list = make_word_list (w, output_list);
-             free (expansions[eindex]);
-           }
-         free (expansions);
-
-         /* Add TLIST to the list of words to be freed after brace
-            expansion has been performed. */
-         PREPEND_LIST (tlist, disposables);
-       }
-      else
-       PREPEND_LIST (tlist, output_list);
-    }
-
-  if (disposables)
-    dispose_words (disposables);
-
-  if (output_list)
-    output_list = REVERSE_LIST (output_list, WORD_LIST *);
-
-  return (output_list);
-}
-#endif
-
-#if defined (ARRAY_VARS)
-/* Take WORD, a compound associative array assignment, and internally run
-   'declare -A w', where W is the variable name portion of WORD. */
-static int
-make_internal_declare (word, option)
-     char *word;
-     char *option;
-{
-  int t;
-  WORD_LIST *wl;
-  WORD_DESC *w;
-
-  w = make_word (word);
-
-  t = assignment (w->word, 0);
-  w->word[t] = '\0';
-
-  wl = make_word_list (w, (WORD_LIST *)NULL);
-  wl = make_word_list (make_word (option), wl);
-
-  return (declare_builtin (wl));  
-}  
-#endif
-
-static WORD_LIST *
-shell_expand_word_list (tlist, eflags)
-     WORD_LIST *tlist;
-     int eflags;
-{
-  WORD_LIST *expanded, *orig_list, *new_list, *next, *temp_list;
-  int expanded_something, has_dollar_at;
-  char *temp_string;
-
-  /* We do tilde expansion all the time.  This is what 1003.2 says. */
-  new_list = (WORD_LIST *)NULL;
-  for (orig_list = tlist; tlist; tlist = next)
-    {
-      temp_string = tlist->word->word;
-
-      next = tlist->next;
-
-#if defined (ARRAY_VARS)
-      /* If this is a compound array assignment to a builtin that accepts
-         such assignments (e.g., `declare'), take the assignment and perform
-         it separately, handling the semantics of declarations inside shell
-         functions.  This avoids the double-evaluation of such arguments,
-         because `declare' does some evaluation of compound assignments on
-         its own. */
-      if ((tlist->word->flags & (W_COMPASSIGN|W_ASSIGNARG)) == (W_COMPASSIGN|W_ASSIGNARG))
-       {
-         int t;
-
-         if (tlist->word->flags & W_ASSIGNASSOC)
-           make_internal_declare (tlist->word->word, "-A");
-
-         t = do_word_assignment (tlist->word);
-         if (t == 0)
-           {
-             last_command_exit_value = EXECUTION_FAILURE;
-             exp_jump_to_top_level (DISCARD);
-           }
-
-         /* Now transform the word as ksh93 appears to do and go on */
-         t = assignment (tlist->word->word, 0);
-         tlist->word->word[t] = '\0';
-         tlist->word->flags &= ~(W_ASSIGNMENT|W_NOSPLIT|W_COMPASSIGN|W_ASSIGNARG|W_ASSIGNASSOC);
-       }
-#endif
-
-      expanded_something = 0;
-      expanded = expand_word_internal
-       (tlist->word, 0, 0, &has_dollar_at, &expanded_something);
-
-      if (expanded == &expand_word_error || expanded == &expand_word_fatal)
-       {
-         /* By convention, each time this error is returned,
-            tlist->word->word has already been freed. */
-         tlist->word->word = (char *)NULL;
-
-         /* Dispose our copy of the original list. */
-         dispose_words (orig_list);
-         /* Dispose the new list we're building. */
-         dispose_words (new_list);
-
-         last_command_exit_value = EXECUTION_FAILURE;
-         if (expanded == &expand_word_error)
-           exp_jump_to_top_level (DISCARD);
-         else
-           exp_jump_to_top_level (FORCE_EOF);
-       }
-
-      /* Don't split words marked W_NOSPLIT. */
-      if (expanded_something && (tlist->word->flags & W_NOSPLIT) == 0)
-       {
-         temp_list = word_list_split (expanded);
-         dispose_words (expanded);
-       }
-      else
-       {
-         /* If no parameter expansion, command substitution, process
-            substitution, or arithmetic substitution took place, then
-            do not do word splitting.  We still have to remove quoted
-            null characters from the result. */
-         word_list_remove_quoted_nulls (expanded);
-         temp_list = expanded;
-       }
-
-      expanded = REVERSE_LIST (temp_list, WORD_LIST *);
-      new_list = (WORD_LIST *)list_append (expanded, new_list);
-    }
-
-  if (orig_list)  
-    dispose_words (orig_list);
-
-  if (new_list)
-    new_list = REVERSE_LIST (new_list, WORD_LIST *);
-
-  return (new_list);
-}
-
-/* The workhorse for expand_words () and expand_words_no_vars ().
-   First arg is LIST, a WORD_LIST of words.
-   Second arg EFLAGS is a flags word controlling which expansions are
-   performed.
-
-   This does all of the substitutions: brace expansion, tilde expansion,
-   parameter expansion, command substitution, arithmetic expansion,
-   process substitution, word splitting, and pathname expansion, according
-   to the bits set in EFLAGS.  Words with the W_QUOTED or W_NOSPLIT bits
-   set, or for which no expansion is done, do not undergo word splitting.
-   Words with the W_NOGLOB bit set do not undergo pathname expansion. */
-static WORD_LIST *
-expand_word_list_internal (list, eflags)
-     WORD_LIST *list;
-     int eflags;
-{
-  WORD_LIST *new_list, *temp_list;
-  int tint;
-
-  if (list == 0)
-    return ((WORD_LIST *)NULL);
-
-  garglist = new_list = copy_word_list (list);
-  if (eflags & WEXP_VARASSIGN)
-    {
-      garglist = new_list = separate_out_assignments (new_list);
-      if (new_list == 0)
-       {
-         if (subst_assign_varlist)
-           {
-             /* All the words were variable assignments, so they are placed
-                into the shell's environment. */
-             for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
-               {
-                 this_command_name = (char *)NULL;     /* no arithmetic errors */
-                 tint = do_word_assignment (temp_list->word);
-                 /* Variable assignment errors in non-interactive shells
-                    running in Posix.2 mode cause the shell to exit. */
-                 if (tint == 0)
-                   {
-                     last_command_exit_value = EXECUTION_FAILURE;
-                     if (interactive_shell == 0 && posixly_correct)
-                       exp_jump_to_top_level (FORCE_EOF);
-                     else
-                       exp_jump_to_top_level (DISCARD);
-                   }
-               }
-             dispose_words (subst_assign_varlist);
-             subst_assign_varlist = (WORD_LIST *)NULL;
-           }
-         return ((WORD_LIST *)NULL);
-       }
-    }
-
-  /* Begin expanding the words that remain.  The expansions take place on
-     things that aren't really variable assignments. */
-
-#if defined (BRACE_EXPANSION)
-  /* Do brace expansion on this word if there are any brace characters
-     in the string. */
-  if ((eflags & WEXP_BRACEEXP) && brace_expansion && new_list)
-    new_list = brace_expand_word_list (new_list, eflags);
-#endif /* BRACE_EXPANSION */
-
-  /* Perform the `normal' shell expansions: tilde expansion, parameter and
-     variable substitution, command substitution, arithmetic expansion,
-     and word splitting. */
-  new_list = shell_expand_word_list (new_list, eflags);
-
-  /* Okay, we're almost done.  Now let's just do some filename
-     globbing. */
-  if (new_list)
-    {
-      if ((eflags & WEXP_PATHEXP) && disallow_filename_globbing == 0)
-       /* Glob expand the word list unless globbing has been disabled. */
-       new_list = glob_expand_word_list (new_list, eflags);
-      else
-       /* Dequote the words, because we're not performing globbing. */
-       new_list = dequote_list (new_list);
-    }
-
-  if ((eflags & WEXP_VARASSIGN) && subst_assign_varlist)
-    {
-      sh_wassign_func_t *assign_func;
-
-      /* If the remainder of the words expand to nothing, Posix.2 requires
-        that the variable and environment assignments affect the shell's
-        environment. */
-      assign_func = new_list ? assign_in_env : do_word_assignment;
-      tempenv_assign_error = 0;
-
-      for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
-       {
-         this_command_name = (char *)NULL;
-         assigning_in_environment = (assign_func == assign_in_env);
-         tint = (*assign_func) (temp_list->word);
-         assigning_in_environment = 0;
-         /* Variable assignment errors in non-interactive shells running
-            in Posix.2 mode cause the shell to exit. */
-         if (tint == 0)
-           {
-             if (assign_func == do_word_assignment)
-               {
-                 last_command_exit_value = EXECUTION_FAILURE;
-                 if (interactive_shell == 0 && posixly_correct)
-                   exp_jump_to_top_level (FORCE_EOF);
-                 else
-                   exp_jump_to_top_level (DISCARD);
-               }
-             else
-               tempenv_assign_error++;
-           }
-       }
-
-      dispose_words (subst_assign_varlist);
-      subst_assign_varlist = (WORD_LIST *)NULL;
-    }
-
-#if 0
-  tint = list_length (new_list) + 1;
-  RESIZE_MALLOCED_BUFFER (glob_argv_flags, 0, tint, glob_argv_flags_size, 16);
-  for (tint = 0, temp_list = new_list; temp_list; temp_list = temp_list->next)
-    glob_argv_flags[tint++] = (temp_list->word->flags & W_GLOBEXP) ? '1' : '0';
-  glob_argv_flags[tint] = '\0';
-#endif
-
-  return (new_list);
-}
diff --git a/subst.c.save b/subst.c.save
deleted file mode 100644 (file)
index 74bd05a..0000000
+++ /dev/null
@@ -1,8848 +0,0 @@
-/* subst.c -- The part of the shell that does parameter, command, arithmetic,
-   and globbing substitutions. */
-
-/* ``Have a little faith, there's magic in the night.  You ain't a
-     beauty, but, hey, you're alright.'' */
-
-/* Copyright (C) 1987-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/>.
-*/
-
-#include "config.h"
-
-#include "bashtypes.h"
-#include <stdio.h>
-#include "chartypes.h"
-#if defined (HAVE_PWD_H)
-#  include <pwd.h>
-#endif
-#include <signal.h>
-#include <errno.h>
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include "bashansi.h"
-#include "posixstat.h"
-#include "bashintl.h"
-
-#include "shell.h"
-#include "flags.h"
-#include "jobs.h"
-#include "execute_cmd.h"
-#include "filecntl.h"
-#include "trap.h"
-#include "pathexp.h"
-#include "mailcheck.h"
-
-#include "shmbutil.h"
-
-#include "builtins/getopt.h"
-#include "builtins/common.h"
-
-#include "builtins/builtext.h"
-
-#include <tilde/tilde.h>
-#include <glob/strmatch.h>
-
-#if !defined (errno)
-extern int errno;
-#endif /* !errno */
-
-/* The size that strings change by. */
-#define DEFAULT_INITIAL_ARRAY_SIZE 112
-#define DEFAULT_ARRAY_SIZE 128
-
-/* Variable types. */
-#define VT_VARIABLE    0
-#define VT_POSPARMS    1
-#define VT_ARRAYVAR    2
-#define VT_ARRAYMEMBER 3
-#define VT_ASSOCVAR    4
-
-#define VT_STARSUB     128     /* $* or ${array[*]} -- used to split */
-
-/* Flags for quoted_strchr */
-#define ST_BACKSL      0x01
-#define ST_CTLESC      0x02
-#define ST_SQUOTE      0x04    /* unused yet */
-#define ST_DQUOTE      0x08    /* unused yet */
-
-/* Flags for the `pflags' argument to param_expand() */
-#define PF_NOCOMSUB    0x01    /* Do not perform command substitution */
-#define PF_IGNUNBOUND  0x02    /* ignore unbound vars even if -u set */
-
-/* These defs make it easier to use the editor. */
-#define LBRACE         '{'
-#define RBRACE         '}'
-#define LPAREN         '('
-#define RPAREN         ')'
-
-/* Evaluates to 1 if C is one of the shell's special parameters whose length
-   can be taken, but is also one of the special expansion characters. */
-#define VALID_SPECIAL_LENGTH_PARAM(c) \
-  ((c) == '-' || (c) == '?' || (c) == '#')
-
-/* Evaluates to 1 if C is one of the shell's special parameters for which an
-   indirect variable reference may be made. */
-#define VALID_INDIR_PARAM(c) \
-  ((c) == '#' || (c) == '?' || (c) == '@' || (c) == '*')
-
-/* Evaluates to 1 if C is one of the OP characters that follows the parameter
-   in ${parameter[:]OPword}. */
-#define VALID_PARAM_EXPAND_CHAR(c) (sh_syntaxtab[(unsigned char)c] & CSUBSTOP)
-
-/* Evaluates to 1 if this is one of the shell's special variables. */
-#define SPECIAL_VAR(name, wi) \
- ((DIGIT (*name) && all_digits (name)) || \
-      (name[1] == '\0' && (sh_syntaxtab[(unsigned char)*name] & CSPECVAR)) || \
-      (wi && name[2] == '\0' && VALID_INDIR_PARAM (name[1])))
-
-/* An expansion function that takes a string and a quoted flag and returns
-   a WORD_LIST *.  Used as the type of the third argument to
-   expand_string_if_necessary(). */
-typedef WORD_LIST *EXPFUNC __P((char *, int));
-
-/* Process ID of the last command executed within command substitution. */
-pid_t last_command_subst_pid = NO_PID;
-pid_t current_command_subst_pid = NO_PID;
-
-/* Variables used to keep track of the characters in IFS. */
-SHELL_VAR *ifs_var;
-char *ifs_value;
-unsigned char ifs_cmap[UCHAR_MAX + 1];
-
-#if defined (HANDLE_MULTIBYTE)
-unsigned char ifs_firstc[MB_LEN_MAX];
-size_t ifs_firstc_len;
-#else
-unsigned char ifs_firstc;
-#endif
-
-int assigning_in_environment;
-
-/* Extern functions and variables from different files. */
-extern int last_command_exit_value, last_command_exit_signal;
-extern int subshell_environment;
-extern int subshell_level, parse_and_execute_level;
-extern int eof_encountered;
-extern int return_catch_flag, return_catch_value;
-extern pid_t dollar_dollar_pid;
-extern int posixly_correct;
-extern char *this_command_name;
-extern struct fd_bitmap *current_fds_to_close;
-extern int wordexp_only;
-extern int expanding_redir;
-extern int tempenv_assign_error;
-
-#if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE)
-extern wchar_t *wcsdup __P((const wchar_t *));
-#endif
-
-/* Non-zero means to allow unmatched globbed filenames to expand to
-   a null file. */
-int allow_null_glob_expansion;
-
-/* Non-zero means to throw an error when globbing fails to match anything. */
-int fail_glob_expansion;
-
-#if 0
-/* Variables to keep track of which words in an expanded word list (the
-   output of expand_word_list_internal) are the result of globbing
-   expansions.  GLOB_ARGV_FLAGS is used by execute_cmd.c.
-   (CURRENTLY UNUSED). */
-char *glob_argv_flags;
-static int glob_argv_flags_size;
-#endif
-
-static WORD_LIST expand_word_error, expand_word_fatal;
-static WORD_DESC expand_wdesc_error, expand_wdesc_fatal;
-static char expand_param_error, expand_param_fatal;
-static char extract_string_error, extract_string_fatal;
-
-/* Tell the expansion functions to not longjmp back to top_level on fatal
-   errors.  Enabled when doing completion and prompt string expansion. */
-static int no_longjmp_on_fatal_error = 0;
-
-/* Set by expand_word_unsplit; used to inhibit splitting and re-joining
-   $* on $IFS, primarily when doing assignment statements. */
-static int expand_no_split_dollar_star = 0;
-
-/* Used to hold a list of variable assignments preceding a command.  Global
-   so the SIGCHLD handler in jobs.c can unwind-protect it when it runs a
-   SIGCHLD trap. */
-WORD_LIST *subst_assign_varlist = (WORD_LIST *)NULL;
-
-/* A WORD_LIST of words to be expanded by expand_word_list_internal,
-   without any leading variable assignments. */
-static WORD_LIST *garglist = (WORD_LIST *)NULL;
-
-static char *quoted_substring __P((char *, int, int));
-static int quoted_strlen __P((char *));
-static char *quoted_strchr __P((char *, int, int));
-
-static char *expand_string_if_necessary __P((char *, int, EXPFUNC *));
-static inline char *expand_string_to_string_internal __P((char *, int, EXPFUNC *));
-static WORD_LIST *call_expand_word_internal __P((WORD_DESC *, int, int, int *, int *));
-static WORD_LIST *expand_string_internal __P((char *, int));
-static WORD_LIST *expand_string_leave_quoted __P((char *, int));
-static WORD_LIST *expand_string_for_rhs __P((char *, int, int *, int *));
-
-static WORD_LIST *list_quote_escapes __P((WORD_LIST *));
-static char *make_quoted_char __P((int));
-static WORD_LIST *quote_list __P((WORD_LIST *));
-
-static int unquoted_substring __P((char *, char *));
-static int unquoted_member __P((int, char *));
-
-#if defined (ARRAY_VARS)
-static SHELL_VAR *do_compound_assignment __P((char *, char *, int));
-#endif
-static int do_assignment_internal __P((const WORD_DESC *, int));
-
-static char *string_extract_verbatim __P((char *, size_t, int *, char *, int));
-static char *string_extract __P((char *, int *, char *, int));
-static char *string_extract_double_quoted __P((char *, int *, int));
-static inline char *string_extract_single_quoted __P((char *, int *));
-static inline int skip_single_quoted __P((const char *, size_t, int));
-static int skip_double_quoted __P((char *, size_t, int));
-static char *extract_delimited_string __P((char *, int *, char *, char *, char *, int));
-static char *extract_dollar_brace_string __P((char *, int *, int, int));
-static int skip_matched_pair __P((const char *, int, int, int, int));
-
-static char *pos_params __P((char *, int, int, int));
-
-static unsigned char *mb_getcharlens __P((char *, int));
-
-static char *remove_upattern __P((char *, char *, int));
-#if defined (HANDLE_MULTIBYTE) 
-static wchar_t *remove_wpattern __P((wchar_t *, size_t, wchar_t *, int));
-#endif
-static char *remove_pattern __P((char *, char *, int));
-
-static int match_pattern_char __P((char *, char *));
-static int match_upattern __P((char *, char *, int, char **, char **));
-#if defined (HANDLE_MULTIBYTE)
-static int match_pattern_wchar __P((wchar_t *, wchar_t *));
-static int match_wpattern __P((wchar_t *, char **, size_t, wchar_t *, int, char **, char **));
-#endif
-static int match_pattern __P((char *, char *, int, char **, char **));
-static int getpatspec __P((int, char *));
-static char *getpattern __P((char *, int, int));
-static char *variable_remove_pattern __P((char *, char *, int, int));
-static char *list_remove_pattern __P((WORD_LIST *, char *, int, int, int));
-static char *parameter_list_remove_pattern __P((int, char *, int, int));
-#ifdef ARRAY_VARS
-static char *array_remove_pattern __P((SHELL_VAR *, char *, int, char *, int));
-#endif
-static char *parameter_brace_remove_pattern __P((char *, char *, char *, int, int));
-
-static char *process_substitute __P((char *, int));
-
-static char *read_comsub __P((int, int, int *));
-
-#ifdef ARRAY_VARS
-static arrayind_t array_length_reference __P((char *));
-#endif
-
-static int valid_brace_expansion_word __P((char *, int));
-static int chk_atstar __P((char *, int, int *, int *));
-static int chk_arithsub __P((const char *, int));
-
-static WORD_DESC *parameter_brace_expand_word __P((char *, int, int, int));
-static WORD_DESC *parameter_brace_expand_indir __P((char *, int, int, int *, int *));
-static WORD_DESC *parameter_brace_expand_rhs __P((char *, char *, int, int, int *, int *));
-static void parameter_brace_expand_error __P((char *, char *));
-
-static int valid_length_expression __P((char *));
-static intmax_t parameter_brace_expand_length __P((char *));
-
-static char *skiparith __P((char *, int));
-static int verify_substring_values __P((SHELL_VAR *, char *, char *, int, intmax_t *, intmax_t *));
-static int get_var_and_type __P((char *, char *, int, SHELL_VAR **, char **));
-static char *mb_substring __P((char *, int, int));
-static char *parameter_brace_substring __P((char *, char *, char *, int));
-
-static char *pos_params_pat_subst __P((char *, char *, char *, int));
-
-static char *parameter_brace_patsub __P((char *, char *, char *, int));
-
-static char *pos_params_casemod __P((char *, char *, int, int));
-static char *parameter_brace_casemod __P((char *, char *, int, char *, int));
-
-static WORD_DESC *parameter_brace_expand __P((char *, int *, int, int *, int *));
-static WORD_DESC *param_expand __P((char *, int *, int, int *, int *, int *, int *, int));
-
-static WORD_LIST *expand_word_internal __P((WORD_DESC *, int, int, int *, int *));
-
-static WORD_LIST *word_list_split __P((WORD_LIST *));
-
-static void exp_jump_to_top_level __P((int));
-
-static WORD_LIST *separate_out_assignments __P((WORD_LIST *));
-static WORD_LIST *glob_expand_word_list __P((WORD_LIST *, int));
-#ifdef BRACE_EXPANSION
-static WORD_LIST *brace_expand_word_list __P((WORD_LIST *, int));
-#endif
-#if defined (ARRAY_VARS)
-static int make_internal_declare __P((char *, char *));
-#endif
-static WORD_LIST *shell_expand_word_list __P((WORD_LIST *, int));
-static WORD_LIST *expand_word_list_internal __P((WORD_LIST *, int));
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Utility Functions                           */
-/*                                                                 */
-/* **************************************************************** */
-
-#ifdef INCLUDE_UNUSED
-static char *
-quoted_substring (string, start, end)
-     char *string;
-     int start, end;
-{
-  register int len, l;
-  register char *result, *s, *r;
-
-  len = end - start;
-
-  /* Move to string[start], skipping quoted characters. */
-  for (s = string, l = 0; *s && l < start; )
-    {
-      if (*s == CTLESC)
-       {
-         s++;
-         continue;
-       }
-      l++;
-      if (*s == 0)
-       break;
-    }
-
-  r = result = (char *)xmalloc (2*len + 1);      /* save room for quotes */
-
-  /* Copy LEN characters, including quote characters. */
-  s = string + l;
-  for (l = 0; l < len; s++)
-    {
-      if (*s == CTLESC)
-       *r++ = *s++;
-      *r++ = *s;
-      l++;
-      if (*s == 0)
-       break;
-    }
-  *r = '\0';
-  return result;
-}
-#endif
-
-#ifdef INCLUDE_UNUSED
-/* Return the length of S, skipping over quoted characters */
-static int
-quoted_strlen (s)
-     char *s;
-{
-  register char *p;
-  int i;
-
-  i = 0;
-  for (p = s; *p; p++)
-    {
-      if (*p == CTLESC)
-       {
-         p++;
-         if (*p == 0)
-           return (i + 1);
-       }
-      i++;
-    }
-
-  return i;
-}
-#endif
-
-/* Find the first occurrence of character C in string S, obeying shell
-   quoting rules.  If (FLAGS & ST_BACKSL) is non-zero, backslash-escaped
-   characters are skipped.  If (FLAGS & ST_CTLESC) is non-zero, characters
-   escaped with CTLESC are skipped. */
-static char *
-quoted_strchr (s, c, flags)
-     char *s;
-     int c, flags;
-{
-  register char *p;
-
-  for (p = s; *p; p++)
-    {
-      if (((flags & ST_BACKSL) && *p == '\\')
-           || ((flags & ST_CTLESC) && *p == CTLESC))
-       {
-         p++;
-         if (*p == '\0')
-           return ((char *)NULL);
-         continue;
-       }
-      else if (*p == c)
-       return p;
-    }
-  return ((char *)NULL);
-}
-
-/* Return 1 if CHARACTER appears in an unquoted portion of
-   STRING.  Return 0 otherwise.  CHARACTER must be a single-byte character. */
-static int
-unquoted_member (character, string)
-     int character;
-     char *string;
-{
-  size_t slen;
-  int sindex, c;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string);
-  sindex = 0;
-  while (c = string[sindex])
-    {
-      if (c == character)
-       return (1);
-
-      switch (c)
-       {
-       default:
-         ADVANCE_CHAR (string, slen, sindex);
-         break;
-
-       case '\\':
-         sindex++;
-         if (string[sindex])
-           ADVANCE_CHAR (string, slen, sindex);
-         break;
-
-       case '\'':
-         sindex = skip_single_quoted (string, slen, ++sindex);
-         break;
-
-       case '"':
-         sindex = skip_double_quoted (string, slen, ++sindex);
-         break;
-       }
-    }
-  return (0);
-}
-
-/* Return 1 if SUBSTR appears in an unquoted portion of STRING. */
-static int
-unquoted_substring (substr, string)
-     char *substr, *string;
-{
-  size_t slen;
-  int sindex, c, sublen;
-  DECLARE_MBSTATE;
-
-  if (substr == 0 || *substr == '\0')
-    return (0);
-
-  slen = strlen (string);
-  sublen = strlen (substr);
-  for (sindex = 0; c = string[sindex]; )
-    {
-      if (STREQN (string + sindex, substr, sublen))
-       return (1);
-
-      switch (c)
-       {
-       case '\\':
-         sindex++;
-
-         if (string[sindex])
-           ADVANCE_CHAR (string, slen, sindex);
-         break;
-
-       case '\'':
-         sindex = skip_single_quoted (string, slen, ++sindex);
-         break;
-
-       case '"':
-         sindex = skip_double_quoted (string, slen, ++sindex);
-         break;
-
-       default:
-         ADVANCE_CHAR (string, slen, sindex);
-         break;
-       }
-    }
-  return (0);
-}
-
-/* Most of the substitutions must be done in parallel.  In order
-   to avoid using tons of unclear goto's, I have some functions
-   for manipulating malloc'ed strings.  They all take INDX, a
-   pointer to an integer which is the offset into the string
-   where manipulation is taking place.  They also take SIZE, a
-   pointer to an integer which is the current length of the
-   character array for this string. */
-
-/* Append SOURCE to TARGET at INDEX.  SIZE is the current amount
-   of space allocated to TARGET.  SOURCE can be NULL, in which
-   case nothing happens.  Gets rid of SOURCE by freeing it.
-   Returns TARGET in case the location has changed. */
-INLINE char *
-sub_append_string (source, target, indx, size)
-     char *source, *target;
-     int *indx, *size;
-{
-  if (source)
-    {
-      int srclen, n;
-
-      srclen = STRLEN (source);
-      if (srclen >= (int)(*size - *indx))
-       {
-         n = srclen + *indx;
-         n = (n + DEFAULT_ARRAY_SIZE) - (n % DEFAULT_ARRAY_SIZE);
-         target = (char *)xrealloc (target, (*size = n));
-       }
-
-      FASTCOPY (source, target + *indx, srclen);
-      *indx += srclen;
-      target[*indx] = '\0';
-
-      free (source);
-    }
-  return (target);
-}
-
-#if 0
-/* UNUSED */
-/* Append the textual representation of NUMBER to TARGET.
-   INDX and SIZE are as in SUB_APPEND_STRING. */
-char *
-sub_append_number (number, target, indx, size)
-     intmax_t number;
-     int *indx, *size;
-     char *target;
-{
-  char *temp;
-
-  temp = itos (number);
-  return (sub_append_string (temp, target, indx, size));
-}
-#endif
-
-/* Extract a substring from STRING, starting at SINDEX and ending with
-   one of the characters in CHARLIST.  Don't make the ending character
-   part of the string.  Leave SINDEX pointing at the ending character.
-   Understand about backslashes in the string.  If (flags & SX_VARNAME)
-   is non-zero, and array variables have been compiled into the shell,
-   everything between a `[' and a corresponding `]' is skipped over.
-   If (flags & SX_NOALLOC) is non-zero, don't return the substring, just
-   update SINDEX.  If (flags & SX_REQMATCH) is non-zero, the string must
-   contain a closing character from CHARLIST. */
-static char *
-string_extract (string, sindex, charlist, flags)
-     char *string;
-     int *sindex;
-     char *charlist;
-     int flags;
-{
-  register int c, i;
-  int found;
-  size_t slen;
-  char *temp;
-  DECLARE_MBSTATE;
-
-  slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0;
-  i = *sindex;
-  found = 0;
-  while (c = string[i])
-    {
-      if (c == '\\')
-       {
-         if (string[i + 1])
-           i++;
-         else
-           break;
-       }
-#if defined (ARRAY_VARS)
-      else if ((flags & SX_VARNAME) && c == '[')
-       {
-         int ni;
-         /* If this is an array subscript, skip over it and continue. */
-         ni = skipsubscript (string, i);
-         if (string[ni] == ']')
-           i = ni;
-       }
-#endif
-      else if (MEMBER (c, charlist))
-       {
-         found = 1;
-         break;
-       }
-
-      ADVANCE_CHAR (string, slen, i);
-    }
-
-  /* If we had to have a matching delimiter and didn't find one, return an
-     error and let the caller deal with it. */
-  if ((flags & SX_REQMATCH) && found == 0)
-    {
-      *sindex = i;
-      return (&extract_string_error);
-    }
-  
-  temp = (flags & SX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i);
-  *sindex = i;
-  
-  return (temp);
-}
-
-/* Extract the contents of STRING as if it is enclosed in double quotes.
-   SINDEX, when passed in, is the offset of the character immediately
-   following the opening double quote; on exit, SINDEX is left pointing after
-   the closing double quote.  If STRIPDQ is non-zero, unquoted double
-   quotes are stripped and the string is terminated by a null byte.
-   Backslashes between the embedded double quotes are processed.  If STRIPDQ
-   is zero, an unquoted `"' terminates the string. */
-static char *
-string_extract_double_quoted (string, sindex, stripdq)
-     char *string;
-     int *sindex, stripdq;
-{
-  size_t slen;
-  char *send;
-  int j, i, t;
-  unsigned char c;
-  char *temp, *ret;            /* The new string we return. */
-  int pass_next, backquote, si;        /* State variables for the machine. */
-  int dquote;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string + *sindex) + *sindex;
-  send = string + slen;
-
-  pass_next = backquote = dquote = 0;
-  temp = (char *)xmalloc (1 + slen - *sindex);
-
-  j = 0;
-  i = *sindex;
-  while (c = string[i])
-    {
-      /* Process a character that was quoted by a backslash. */
-      if (pass_next)
-       {
-         /* Posix.2 sez:
-
-            ``The backslash shall retain its special meaning as an escape
-            character only when followed by one of the characters:
-               $       `       "       \       <newline>''.
-
-            If STRIPDQ is zero, we handle the double quotes here and let
-            expand_word_internal handle the rest.  If STRIPDQ is non-zero,
-            we have already been through one round of backslash stripping,
-            and want to strip these backslashes only if DQUOTE is non-zero,
-            indicating that we are inside an embedded double-quoted string. */
-
-            /* If we are in an embedded quoted string, then don't strip
-               backslashes before characters for which the backslash
-               retains its special meaning, but remove backslashes in
-               front of other characters.  If we are not in an
-               embedded quoted string, don't strip backslashes at all.
-               This mess is necessary because the string was already
-               surrounded by double quotes (and sh has some really weird
-               quoting rules).
-               The returned string will be run through expansion as if
-               it were double-quoted. */
-         if ((stripdq == 0 && c != '"') ||
-             (stripdq && ((dquote && (sh_syntaxtab[c] & CBSDQUOTE)) || dquote == 0)))
-           temp[j++] = '\\';
-         pass_next = 0;
-
-add_one_character:
-         COPY_CHAR_I (temp, j, string, send, i);
-         continue;
-       }
-
-      /* A backslash protects the next character.  The code just above
-        handles preserving the backslash in front of any character but
-        a double quote. */
-      if (c == '\\')
-       {
-         pass_next++;
-         i++;
-         continue;
-       }
-
-      /* Inside backquotes, ``the portion of the quoted string from the
-        initial backquote and the characters up to the next backquote
-        that is not preceded by a backslash, having escape characters
-        removed, defines that command''. */
-      if (backquote)
-       {
-         if (c == '`')
-           backquote = 0;
-         temp[j++] = c;
-         i++;
-         continue;
-       }
-
-      if (c == '`')
-       {
-         temp[j++] = c;
-         backquote++;
-         i++;
-         continue;
-       }
-
-      /* Pass everything between `$(' and the matching `)' or a quoted
-        ${ ... } pair through according to the Posix.2 specification. */
-      if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
-       {
-         int free_ret = 1;
-
-         si = i + 2;
-         if (string[i + 1] == LPAREN)
-           ret = extract_command_subst (string, &si, 0);
-         else
-           ret = extract_dollar_brace_string (string, &si, 1, 0);
-
-         temp[j++] = '$';
-         temp[j++] = string[i + 1];
-
-         /* Just paranoia; ret will not be 0 unless no_longjmp_on_fatal_error
-            is set. */
-         if (ret == 0 && no_longjmp_on_fatal_error)
-           {
-             free_ret = 0;
-             ret = string + i + 2;
-           }
-
-         for (t = 0; ret[t]; t++, j++)
-           temp[j] = ret[t];
-         temp[j] = string[si];
-
-         if (string[si])
-           {
-             j++;
-             i = si + 1;
-           }
-         else
-           i = si;
-
-         if (free_ret)
-           free (ret);
-         continue;
-       }
-
-      /* Add any character but a double quote to the quoted string we're
-        accumulating. */
-      if (c != '"')
-       goto add_one_character;
-
-      /* c == '"' */
-      if (stripdq)
-       {
-         dquote ^= 1;
-         i++;
-         continue;
-       }
-
-      break;
-    }
-  temp[j] = '\0';
-
-  /* Point to after the closing quote. */
-  if (c)
-    i++;
-  *sindex = i;
-
-  return (temp);
-}
-
-/* This should really be another option to string_extract_double_quoted. */
-static int
-skip_double_quoted (string, slen, sind)
-     char *string;
-     size_t slen;
-     int sind;
-{
-  int c, i;
-  char *ret;
-  int pass_next, backquote, si;
-  DECLARE_MBSTATE;
-
-  pass_next = backquote = 0;
-  i = sind;
-  while (c = string[i])
-    {
-      if (pass_next)
-       {
-         pass_next = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (c == '\\')
-       {
-         pass_next++;
-         i++;
-         continue;
-       }
-      else if (backquote)
-       {
-         if (c == '`')
-           backquote = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (c == '`')
-       {
-         backquote++;
-         i++;
-         continue;
-       }
-      else if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
-       {
-         si = i + 2;
-         if (string[i + 1] == LPAREN)
-           ret = extract_command_subst (string, &si, SX_NOALLOC);
-         else
-           ret = extract_dollar_brace_string (string, &si, 1, SX_NOALLOC);
-
-         i = si + 1;
-         continue;
-       }
-      else if (c != '"')
-       {
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else
-       break;
-    }
-
-  if (c)
-    i++;
-
-  return (i);
-}
-
-/* Extract the contents of STRING as if it is enclosed in single quotes.
-   SINDEX, when passed in, is the offset of the character immediately
-   following the opening single quote; on exit, SINDEX is left pointing after
-   the closing single quote. */
-static inline char *
-string_extract_single_quoted (string, sindex)
-     char *string;
-     int *sindex;
-{
-  register int i;
-  size_t slen;
-  char *t;
-  DECLARE_MBSTATE;
-
-  /* Don't need slen for ADVANCE_CHAR unless multibyte chars possible. */
-  slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0;
-  i = *sindex;
-  while (string[i] && string[i] != '\'')
-    ADVANCE_CHAR (string, slen, i);
-
-  t = substring (string, *sindex, i);
-
-  if (string[i])
-    i++;
-  *sindex = i;
-
-  return (t);
-}
-
-static inline int
-skip_single_quoted (string, slen, sind)
-     const char *string;
-     size_t slen;
-     int sind;
-{
-  register int c;
-  DECLARE_MBSTATE;
-
-  c = sind;
-  while (string[c] && string[c] != '\'')
-    ADVANCE_CHAR (string, slen, c);
-
-  if (string[c])
-    c++;
-  return c;
-}
-
-/* Just like string_extract, but doesn't hack backslashes or any of
-   that other stuff.  Obeys CTLESC quoting.  Used to do splitting on $IFS. */
-static char *
-string_extract_verbatim (string, slen, sindex, charlist, flags)
-     char *string;
-     size_t slen;
-     int *sindex;
-     char *charlist;
-     int flags;
-{
-  register int i = *sindex;
-#if defined (HANDLE_MULTIBYTE)
-  size_t clen;
-  wchar_t *wcharlist;
-#endif
-  int c;
-  char *temp;
-  DECLARE_MBSTATE;
-
-  if (charlist[0] == '\'' && charlist[1] == '\0')
-    {
-      temp = string_extract_single_quoted (string, sindex);
-      --*sindex;       /* leave *sindex at separator character */
-      return temp;
-    }
-
-  i = *sindex;
-#if 0
-  /* See how the MBLEN and ADVANCE_CHAR macros work to understand why we need
-     this only if MB_CUR_MAX > 1. */
-  slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 1;
-#endif
-#if defined (HANDLE_MULTIBYTE)
-  clen = strlen (charlist);
-  wcharlist = 0;
-#endif
-  while (c = string[i])
-    {
-#if defined (HANDLE_MULTIBYTE)
-      size_t mblength;
-#endif
-      if ((flags & SX_NOCTLESC) == 0 && c == CTLESC)
-       {
-         i += 2;
-         continue;
-       }
-      /* Even if flags contains SX_NOCTLESC, we let CTLESC quoting CTLNUL
-        through, to protect the CTLNULs from later calls to
-        remove_quoted_nulls. */
-      else if ((flags & SX_NOESCCTLNUL) == 0 && c == CTLESC && string[i+1] == CTLNUL)
-       {
-         i += 2;
-         continue;
-       }
-
-#if defined (HANDLE_MULTIBYTE)
-      mblength = MBLEN (string + i, slen - i);
-      if (mblength > 1)
-       {
-         wchar_t wc;
-         mblength = mbtowc (&wc, string + i, slen - i);
-         if (MB_INVALIDCH (mblength))
-           {
-             if (MEMBER (c, charlist))
-               break;
-           }
-         else
-           {
-             if (wcharlist == 0)
-               {
-                 size_t len;
-                 len = mbstowcs (wcharlist, charlist, 0);
-                 if (len == -1)
-                   len = 0;
-                 wcharlist = (wchar_t *)xmalloc (sizeof (wchar_t) * (len + 1));
-                 mbstowcs (wcharlist, charlist, len + 1);
-               }
-
-             if (wcschr (wcharlist, wc))
-               break;
-           }
-       }
-      else             
-#endif
-      if (MEMBER (c, charlist))
-       break;
-
-      ADVANCE_CHAR (string, slen, i);
-    }
-
-#if defined (HANDLE_MULTIBYTE)
-  FREE (wcharlist);
-#endif
-
-  temp = substring (string, *sindex, i);
-  *sindex = i;
-
-  return (temp);
-}
-
-/* Extract the $( construct in STRING, and return a new string.
-   Start extracting at (SINDEX) as if we had just seen "$(".
-   Make (SINDEX) get the position of the matching ")". )
-   XFLAGS is additional flags to pass to other extraction functions, */
-char *
-extract_command_subst (string, sindex, xflags)
-     char *string;
-     int *sindex;
-     int xflags;
-{
-  if (string[*sindex] == '(')  /*)*/
-    return (extract_delimited_string (string, sindex, "$(", "(", ")", xflags|SX_COMMAND)); /*)*/
-  else
-    {
-      xflags |= (no_longjmp_on_fatal_error ? SX_NOLONGJMP : 0);
-      return (xparse_dolparen (string, string+*sindex, sindex, xflags));
-    }
-}
-
-/* Extract the $[ construct in STRING, and return a new string. (])
-   Start extracting at (SINDEX) as if we had just seen "$[".
-   Make (SINDEX) get the position of the matching "]". */
-char *
-extract_arithmetic_subst (string, sindex)
-     char *string;
-     int *sindex;
-{
-  return (extract_delimited_string (string, sindex, "$[", "[", "]", 0)); /*]*/
-}
-
-#if defined (PROCESS_SUBSTITUTION)
-/* Extract the <( or >( construct in STRING, and return a new string.
-   Start extracting at (SINDEX) as if we had just seen "<(".
-   Make (SINDEX) get the position of the matching ")". */ /*))*/
-char *
-extract_process_subst (string, starter, sindex)
-     char *string;
-     char *starter;
-     int *sindex;
-{
-  return (extract_delimited_string (string, sindex, starter, "(", ")", 0));
-}
-#endif /* PROCESS_SUBSTITUTION */
-
-#if defined (ARRAY_VARS)
-/* This can be fooled by unquoted right parens in the passed string. If
-   each caller verifies that the last character in STRING is a right paren,
-   we don't even need to call extract_delimited_string. */
-char *
-extract_array_assignment_list (string, sindex)
-     char *string;
-     int *sindex;
-{
-  int slen;
-  char *ret;
-
-  slen = strlen (string);      /* ( */
-  if (string[slen - 1] == ')')
-   {
-      ret = substring (string, *sindex, slen - 1);
-      *sindex = slen - 1;
-      return ret;
-    }
-  return 0;  
-}
-#endif
-
-/* Extract and create a new string from the contents of STRING, a
-   character string delimited with OPENER and CLOSER.  SINDEX is
-   the address of an int describing the current offset in STRING;
-   it should point to just after the first OPENER found.  On exit,
-   SINDEX gets the position of the last character of the matching CLOSER.
-   If OPENER is more than a single character, ALT_OPENER, if non-null,
-   contains a character string that can also match CLOSER and thus
-   needs to be skipped. */
-static char *
-extract_delimited_string (string, sindex, opener, alt_opener, closer, flags)
-     char *string;
-     int *sindex;
-     char *opener, *alt_opener, *closer;
-     int flags;
-{
-  int i, c, si;
-  size_t slen;
-  char *t, *result;
-  int pass_character, nesting_level, in_comment;
-  int len_closer, len_opener, len_alt_opener;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string + *sindex) + *sindex;
-  len_opener = STRLEN (opener);
-  len_alt_opener = STRLEN (alt_opener);
-  len_closer = STRLEN (closer);
-
-  pass_character = in_comment = 0;
-
-  nesting_level = 1;
-  i = *sindex;
-
-  while (nesting_level)
-    {
-      c = string[i];
-
-      if (c == 0)
-       break;
-
-      if (in_comment)
-       {
-         if (c == '\n')
-           in_comment = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-
-      if (pass_character)      /* previous char was backslash */
-       {
-         pass_character = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-
-      /* Not exactly right yet; should handle shell metacharacters and
-        multibyte characters, too.  See COMMENT_BEGIN define in parse.y */
-      if ((flags & SX_COMMAND) && c == '#' && (i == 0 || string[i - 1] == '\n' || shellblank (string[i - 1])))
-       {
-          in_comment = 1;
-          ADVANCE_CHAR (string, slen, i);
-          continue;
-       }
-        
-      if (c == CTLESC || c == '\\')
-       {
-         pass_character++;
-         i++;
-         continue;
-       }
-
-      /* Process a nested OPENER. */
-      if (STREQN (string + i, opener, len_opener))
-       {
-         si = i + len_opener;
-         t = extract_delimited_string (string, &si, opener, alt_opener, closer, flags|SX_NOALLOC);
-         i = si + 1;
-         continue;
-       }
-
-      /* Process a nested ALT_OPENER */
-      if (len_alt_opener && STREQN (string + i, alt_opener, len_alt_opener))
-       {
-         si = i + len_alt_opener;
-         t = extract_delimited_string (string, &si, alt_opener, alt_opener, closer, flags|SX_NOALLOC);
-         i = si + 1;
-         continue;
-       }
-
-      /* If the current substring terminates the delimited string, decrement
-        the nesting level. */
-      if (STREQN (string + i, closer, len_closer))
-       {
-         i += len_closer - 1;  /* move to last byte of the closer */
-         nesting_level--;
-         if (nesting_level == 0)
-           break;
-       }
-
-      /* Pass old-style command substitution through verbatim. */
-      if (c == '`')
-       {
-         si = i + 1;
-         t = string_extract (string, &si, "`", flags|SX_NOALLOC);
-         i = si + 1;
-         continue;
-       }
-
-      /* Pass single-quoted and double-quoted strings through verbatim. */
-      if (c == '\'' || c == '"')
-       {
-         si = i + 1;
-         i = (c == '\'') ? skip_single_quoted (string, slen, si)
-                         : skip_double_quoted (string, slen, si);
-         continue;
-       }
-
-      /* move past this character, which was not special. */
-      ADVANCE_CHAR (string, slen, i);
-    }
-
-  if (c == 0 && nesting_level)
-    {
-      if (no_longjmp_on_fatal_error == 0)
-       {
-         report_error (_("bad substitution: no closing `%s' in %s"), closer, string);
-         last_command_exit_value = EXECUTION_FAILURE;
-         exp_jump_to_top_level (DISCARD);
-       }
-      else
-       {
-         *sindex = i;
-         return (char *)NULL;
-       }
-    }
-
-  si = i - *sindex - len_closer + 1;
-  if (flags & SX_NOALLOC)
-    result = (char *)NULL;
-  else    
-    {
-      result = (char *)xmalloc (1 + si);
-      strncpy (result, string + *sindex, si);
-      result[si] = '\0';
-    }
-  *sindex = i;
-
-  return (result);
-}
-
-/* Extract a parameter expansion expression within ${ and } from STRING.
-   Obey the Posix.2 rules for finding the ending `}': count braces while
-   skipping over enclosed quoted strings and command substitutions.
-   SINDEX is the address of an int describing the current offset in STRING;
-   it should point to just after the first `{' found.  On exit, SINDEX
-   gets the position of the matching `}'.  QUOTED is non-zero if this
-   occurs inside double quotes. */
-/* XXX -- this is very similar to extract_delimited_string -- XXX */
-static char *
-extract_dollar_brace_string (string, sindex, quoted, flags)
-     char *string;
-     int *sindex, quoted, flags;
-{
-  register int i, c;
-  size_t slen;
-  int pass_character, nesting_level, si;
-  char *result, *t;
-  DECLARE_MBSTATE;
-
-  pass_character = 0;
-  nesting_level = 1;
-  slen = strlen (string + *sindex) + *sindex;
-
-  i = *sindex;
-  while (c = string[i])
-    {
-      if (pass_character)
-       {
-         pass_character = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-
-      /* CTLESCs and backslashes quote the next character. */
-      if (c == CTLESC || c == '\\')
-       {
-         pass_character++;
-         i++;
-         continue;
-       }
-
-      if (string[i] == '$' && string[i+1] == LBRACE)
-       {
-         nesting_level++;
-         i += 2;
-         continue;
-       }
-
-      if (c == RBRACE)
-       {
-         nesting_level--;
-         if (nesting_level == 0)
-           break;
-         i++;
-         continue;
-       }
-
-      /* Pass the contents of old-style command substitutions through
-        verbatim. */
-      if (c == '`')
-       {
-         si = i + 1;
-         t = string_extract (string, &si, "`", flags|SX_NOALLOC);
-         i = si + 1;
-         continue;
-       }
-
-      /* Pass the contents of new-style command substitutions and
-        arithmetic substitutions through verbatim. */
-      if (string[i] == '$' && string[i+1] == LPAREN)
-       {
-         si = i + 2;
-         t = extract_command_subst (string, &si, flags|SX_NOALLOC);
-         i = si + 1;
-         continue;
-       }
-
-      /* Pass the contents of single-quoted and double-quoted strings
-        through verbatim. */
-      if (c == '\'' || c == '"')
-       {
-         si = i + 1;
-         i = (c == '\'') ? skip_single_quoted (string, slen, si)
-                         : skip_double_quoted (string, slen, si);
-         /* skip_XXX_quoted leaves index one past close quote */
-         continue;
-       }
-
-      /* move past this character, which was not special. */
-      ADVANCE_CHAR (string, slen, i);
-    }
-
-  if (c == 0 && nesting_level)
-    {
-      if (no_longjmp_on_fatal_error == 0)
-       {                       /* { */
-         report_error (_("bad substitution: no closing `%s' in %s"), "}", string);
-         last_command_exit_value = EXECUTION_FAILURE;
-         exp_jump_to_top_level (DISCARD);
-       }
-      else
-       {
-         *sindex = i;
-         return ((char *)NULL);
-       }
-    }
-
-  result = (flags & SX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i);
-  *sindex = i;
-
-  return (result);
-}
-
-/* Remove backslashes which are quoting backquotes from STRING.  Modifies
-   STRING, and returns a pointer to it. */
-char *
-de_backslash (string)
-     char *string;
-{
-  register size_t slen;
-  register int i, j, prev_i;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string);
-  i = j = 0;
-
-  /* Loop copying string[i] to string[j], i >= j. */
-  while (i < slen)
-    {
-      if (string[i] == '\\' && (string[i + 1] == '`' || string[i + 1] == '\\' ||
-                             string[i + 1] == '$'))
-       i++;
-      prev_i = i;
-      ADVANCE_CHAR (string, slen, i);
-      if (j < prev_i)
-       do string[j++] = string[prev_i++]; while (prev_i < i);
-      else
-       j = i;
-    }
-  string[j] = '\0';
-
-  return (string);
-}
-
-#if 0
-/*UNUSED*/
-/* Replace instances of \! in a string with !. */
-void
-unquote_bang (string)
-     char *string;
-{
-  register int i, j;
-  register char *temp;
-
-  temp = (char *)xmalloc (1 + strlen (string));
-
-  for (i = 0, j = 0; (temp[j] = string[i]); i++, j++)
-    {
-      if (string[i] == '\\' && string[i + 1] == '!')
-       {
-         temp[j] = '!';
-         i++;
-       }
-    }
-  strcpy (string, temp);
-  free (temp);
-}
-#endif
-
-#define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
-
-/* This function assumes s[i] == open; returns with s[ret] == close; used to
-   parse array subscripts.  FLAGS currently unused. */
-static int
-skip_matched_pair (string, start, open, close, flags)
-     const char *string;
-     int start, open, close, flags;
-{
-  int i, pass_next, backq, si, c, count;
-  size_t slen;
-  char *temp, *ss;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string + start) + start;
-  no_longjmp_on_fatal_error = 1;
-
-  i = start + 1;               /* skip over leading bracket */
-  count = 1;
-  pass_next = backq = 0;
-  ss = (char *)string;
-  while (c = string[i])
-    {
-      if (pass_next)
-       {
-         pass_next = 0;
-         if (c == 0)
-           CQ_RETURN(i);
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (c == '\\')
-       {
-         pass_next = 1;
-         i++;
-         continue;
-       }
-      else if (backq)
-       {
-         if (c == '`')
-           backq = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (c == '`')
-       {
-         backq = 1;
-         i++;
-         continue;
-       }
-      else if (c == open)
-       {
-         count++;
-         i++;
-         continue;
-       }
-      else if (c == close)
-       {
-         count--;
-         if (count == 0)
-           break;
-         i++;
-         continue;
-       }
-      else if (c == '\'' || c == '"')
-       {
-         i = (c == '\'') ? skip_single_quoted (ss, slen, ++i)
-                         : skip_double_quoted (ss, slen, ++i);
-         /* no increment, the skip functions increment past the closing quote. */
-       }
-      else if (c == '$' && (string[i+1] == LPAREN || string[i+1] == LBRACE))
-       {
-         si = i + 2;
-         if (string[si] == '\0')
-           CQ_RETURN(si);
-
-         if (string[i+1] == LPAREN)
-           temp = extract_delimited_string (ss, &si, "$(", "(", ")", SX_NOALLOC|SX_COMMAND); /* ) */
-         else
-           temp = extract_dollar_brace_string (ss, &si, 0, SX_NOALLOC);
-         i = si;
-         if (string[i] == '\0')        /* don't increment i past EOS in loop */
-           break;
-         i++;
-         continue;
-       }
-      else
-       ADVANCE_CHAR (string, slen, i);
-    }
-
-  CQ_RETURN(i);
-}
-
-#if defined (ARRAY_VARS)
-int
-skipsubscript (string, start)
-     const char *string;
-     int start;
-{
-  return (skip_matched_pair (string, start, '[', ']', 0));
-}
-#endif
-
-/* Skip characters in STRING until we find a character in DELIMS, and return
-   the index of that character.  START is the index into string at which we
-   begin.  This is similar in spirit to strpbrk, but it returns an index into
-   STRING and takes a starting index.  This little piece of code knows quite
-   a lot of shell syntax.  It's very similar to skip_double_quoted and other
-   functions of that ilk. */
-int
-skip_to_delim (string, start, delims, flags)
-     char *string;
-     int start;
-     char *delims;
-     int flags;
-{
-  int i, pass_next, backq, si, c, invert;
-  size_t slen;
-  char *temp;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string + start) + start;
-  if (flags & SD_NOJMP)
-    no_longjmp_on_fatal_error = 1;
-  invert = (flags & SD_INVERT);
-
-  i = start;
-  pass_next = backq = 0;
-  while (c = string[i])
-    {
-      if (pass_next)
-       {
-         pass_next = 0;
-         if (c == 0)
-           CQ_RETURN(i);
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (c == '\\')
-       {
-         pass_next = 1;
-         i++;
-         continue;
-       }
-      else if (backq)
-       {
-         if (c == '`')
-           backq = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (c == '`')
-       {
-         backq = 1;
-         i++;
-         continue;
-       }
-      else if (invert == 0 && member (c, delims))
-       break;
-      else if (c == '\'' || c == '"')
-       {
-         i = (c == '\'') ? skip_single_quoted (string, slen, ++i)
-                         : skip_double_quoted (string, slen, ++i);
-         /* no increment, the skip functions increment past the closing quote. */
-       }
-      else if (c == '$' && (string[i+1] == LPAREN || string[i+1] == LBRACE))
-       {
-         si = i + 2;
-         if (string[si] == '\0')
-           CQ_RETURN(si);
-
-         if (string[i+1] == LPAREN)
-           temp = extract_delimited_string (string, &si, "$(", "(", ")", SX_NOALLOC|SX_COMMAND); /* ) */
-         else
-           temp = extract_dollar_brace_string (string, &si, 0, SX_NOALLOC);
-         i = si;
-         if (string[i] == '\0')        /* don't increment i past EOS in loop */
-           break;
-         i++;
-         continue;
-       }
-      else if (invert && (member (c, delims) == 0))
-       break;
-      else
-       ADVANCE_CHAR (string, slen, i);
-    }
-
-  CQ_RETURN(i);
-}
-
-#if defined (READLINE)
-/* Return 1 if the portion of STRING ending at EINDEX is quoted (there is
-   an unclosed quoted string), or if the character at EINDEX is quoted
-   by a backslash. NO_LONGJMP_ON_FATAL_ERROR is used to flag that the various
-   single and double-quoted string parsing functions should not return an
-   error if there are unclosed quotes or braces.  The characters that this
-   recognizes need to be the same as the contents of
-   rl_completer_quote_characters. */
-
-int
-char_is_quoted (string, eindex)
-     char *string;
-     int eindex;
-{
-  int i, pass_next, c;
-  size_t slen;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string);
-  no_longjmp_on_fatal_error = 1;
-  i = pass_next = 0;
-  while (i <= eindex)
-    {
-      c = string[i];
-
-      if (pass_next)
-       {
-         pass_next = 0;
-         if (i >= eindex)      /* XXX was if (i >= eindex - 1) */
-           CQ_RETURN(1);
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (c == '\\')
-       {
-         pass_next = 1;
-         i++;
-         continue;
-       }
-      else if (c == '\'' || c == '"')
-       {
-         i = (c == '\'') ? skip_single_quoted (string, slen, ++i)
-                         : skip_double_quoted (string, slen, ++i);
-         if (i > eindex)
-           CQ_RETURN(1);
-         /* no increment, the skip_xxx functions go one past end */
-       }
-      else
-       ADVANCE_CHAR (string, slen, i);
-    }
-
-  CQ_RETURN(0);
-}
-
-int
-unclosed_pair (string, eindex, openstr)
-     char *string;
-     int eindex;
-     char *openstr;
-{
-  int i, pass_next, openc, olen;
-  size_t slen;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string);
-  olen = strlen (openstr);
-  i = pass_next = openc = 0;
-  while (i <= eindex)
-    {
-      if (pass_next)
-       {
-         pass_next = 0;
-         if (i >= eindex)      /* XXX was if (i >= eindex - 1) */
-           return 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (string[i] == '\\')
-       {
-         pass_next = 1;
-         i++;
-         continue;
-       }
-      else if (STREQN (string + i, openstr, olen))
-       {
-         openc = 1 - openc;
-         i += olen;
-       }
-      else if (string[i] == '\'' || string[i] == '"')
-       {
-         i = (string[i] == '\'') ? skip_single_quoted (string, slen, i)
-                                 : skip_double_quoted (string, slen, i);
-         if (i > eindex)
-           return 0;
-       }
-      else
-       ADVANCE_CHAR (string, slen, i);
-    }
-  return (openc);
-}
-
-/* Split STRING (length SLEN) at DELIMS, and return a WORD_LIST with the
-   individual words.  If DELIMS is NULL, the current value of $IFS is used
-   to split the string, and the function follows the shell field splitting
-   rules.  SENTINEL is an index to look for.  NWP, if non-NULL,
-   gets the number of words in the returned list.  CWP, if non-NULL, gets
-   the index of the word containing SENTINEL.  Non-whitespace chars in
-   DELIMS delimit separate fields. */
-WORD_LIST *
-split_at_delims (string, slen, delims, sentinel, nwp, cwp)
-     char *string;
-     int slen;
-     char *delims;
-     int sentinel;
-     int *nwp, *cwp;
-{
-  int ts, te, i, nw, cw, ifs_split;
-  char *token, *d, *d2;
-  WORD_LIST *ret, *tl;
-
-  if (string == 0 || *string == '\0')
-    {
-      if (nwp)
-       *nwp = 0;
-      if (cwp)
-       *cwp = 0;       
-      return ((WORD_LIST *)NULL);
-    }
-
-  d = (delims == 0) ? ifs_value : delims;
-  ifs_split = delims == 0;
-
-  /* Make d2 the non-whitespace characters in delims */
-  d2 = 0;
-  if (delims)
-    {
-      size_t slength;
-#if defined (HANDLE_MULTIBYTE)
-      size_t mblength = 1;
-#endif
-      DECLARE_MBSTATE;
-
-      slength = strlen (delims);
-      d2 = (char *)xmalloc (slength + 1);
-      i = ts = 0;
-      while (delims[i])
-       {
-#if defined (HANDLE_MULTIBYTE)
-         mbstate_t state_bak;
-         state_bak = state;
-         mblength = MBRLEN (delims + i, slength, &state);
-         if (MB_INVALIDCH (mblength))
-           state = state_bak;
-         else if (mblength > 1)
-           {
-             memcpy (d2 + ts, delims + i, mblength);
-             ts += mblength;
-             i += mblength;
-             slength -= mblength;
-             continue;
-           }
-#endif
-         if (whitespace (delims[i]) == 0)
-           d2[ts++] = delims[i];
-
-         i++;
-         slength--;
-       }
-      d2[ts] = '\0';
-    }
-
-  ret = (WORD_LIST *)NULL;
-
-  /* Remove sequences of whitspace characters at the start of the string, as
-     long as those characters are delimiters. */
-  for (i = 0; member (string[i], d) && spctabnl (string[i]); i++)
-    ;
-  if (string[i] == '\0')
-    return (ret);
-
-  ts = i;
-  nw = 0;
-  cw = -1;
-  while (1)
-    {
-      te = skip_to_delim (string, ts, d, SD_NOJMP);
-
-      /* If we have a non-whitespace delimiter character, use it to make a
-        separate field.  This is just about what $IFS splitting does and
-        is closer to the behavior of the shell parser. */
-      if (ts == te && d2 && member (string[ts], d2))
-       {
-         te = ts + 1;
-         /* If we're using IFS splitting, the non-whitespace delimiter char
-            and any additional IFS whitespace delimits a field. */
-         if (ifs_split)
-           while (member (string[te], d) && spctabnl (string[te]))
-             te++;
-         else
-           while (member (string[te], d2))
-             te++;
-       }
-
-      token = substring (string, ts, te);
-
-      ret = add_string_to_list (token, ret);
-      free (token);
-      nw++;
-
-      if (sentinel >= ts && sentinel <= te)
-       cw = nw;
-
-      /* If the cursor is at whitespace just before word start, set the
-        sentinel word to the current word. */
-      if (cwp && cw == -1 && sentinel == ts-1)
-       cw = nw;
-
-      /* If the cursor is at whitespace between two words, make a new, empty
-        word, add it before (well, after, since the list is in reverse order)
-        the word we just added, and set the current word to that one. */
-      if (cwp && cw == -1 && sentinel < ts)
-       {
-         tl = make_word_list (make_word (""), ret->next);
-         ret->next = tl;
-         cw = nw;
-         nw++;
-       }
-
-      if (string[te] == 0)
-       break;
-
-      i = te;
-      while (member (string[i], d) && (ifs_split || spctabnl(string[i])))
-       i++;
-
-      if (string[i])
-       ts = i;
-      else
-       break;
-    }
-
-  /* Special case for SENTINEL at the end of STRING.  If we haven't found
-     the word containing SENTINEL yet, and the index we're looking for is at
-     the end of STRING, add an additional null argument and set the current
-     word pointer to that. */
-  if (cwp && cw == -1 && sentinel >= slen)
-    {
-      if (whitespace (string[sentinel - 1]))
-       {
-         token = "";
-         ret = add_string_to_list (token, ret);
-         nw++;
-       }
-      cw = nw;
-    }
-
-  if (nwp)
-    *nwp = nw;
-  if (cwp)
-    *cwp = cw;
-
-  return (REVERSE_LIST (ret, WORD_LIST *));
-}
-#endif /* READLINE */
-
-#if 0
-/* UNUSED */
-/* Extract the name of the variable to bind to from the assignment string. */
-char *
-assignment_name (string)
-     char *string;
-{
-  int offset;
-  char *temp;
-
-  offset = assignment (string, 0);
-  if (offset == 0)
-    return (char *)NULL;
-  temp = substring (string, 0, offset);
-  return (temp);
-}
-#endif
-
-/* **************************************************************** */
-/*                                                                 */
-/*     Functions to convert strings to WORD_LISTs and vice versa    */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Return a single string of all the words in LIST.  SEP is the separator
-   to put between individual elements of LIST in the output string. */
-char *
-string_list_internal (list, sep)
-     WORD_LIST *list;
-     char *sep;
-{
-  register WORD_LIST *t;
-  char *result, *r;
-  int word_len, sep_len, result_size;
-
-  if (list == 0)
-    return ((char *)NULL);
-
-  /* Short-circuit quickly if we don't need to separate anything. */
-  if (list->next == 0)
-    return (savestring (list->word->word));
-
-  /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */
-  sep_len = STRLEN (sep);
-  result_size = 0;
-
-  for (t = list; t; t = t->next)
-    {
-      if (t != list)
-       result_size += sep_len;
-      result_size += strlen (t->word->word);
-    }
-
-  r = result = (char *)xmalloc (result_size + 1);
-
-  for (t = list; t; t = t->next)
-    {
-      if (t != list && sep_len)
-       {
-         if (sep_len > 1)
-           {
-             FASTCOPY (sep, r, sep_len);
-             r += sep_len;
-           }
-         else
-           *r++ = sep[0];
-       }
-
-      word_len = strlen (t->word->word);
-      FASTCOPY (t->word->word, r, word_len);
-      r += word_len;
-    }
-
-  *r = '\0';
-  return (result);
-}
-
-/* Return a single string of all the words present in LIST, separating
-   each word with a space. */
-char *
-string_list (list)
-     WORD_LIST *list;
-{
-  return (string_list_internal (list, " "));
-}
-
-/* An external interface that can be used by the rest of the shell to
-   obtain a string containing the first character in $IFS.  Handles all
-   the multibyte complications.  If LENP is non-null, it is set to the
-   length of the returned string. */
-char *
-ifs_firstchar (lenp)
-     int *lenp;
-{
-  char *ret;
-  int len;
-
-  ret = xmalloc (MB_LEN_MAX + 1);
-#if defined (HANDLE_MULTIBYTE)
-  if (ifs_firstc_len == 1)
-    {
-      ret[0] = ifs_firstc[0];
-      ret[1] = '\0';
-      len = ret[0] ? 1 : 0;
-    }
-  else
-    {
-      memcpy (ret, ifs_firstc, ifs_firstc_len);
-      ret[len = ifs_firstc_len] = '\0';
-    }
-#else
-  ret[0] = ifs_firstc;
-  ret[1] = '\0';
-  len = ret[0] ? 0 : 1;
-#endif
-
-  if (lenp)
-    *lenp = len;
-
-  return ret;
-}
-
-/* Return a single string of all the words present in LIST, obeying the
-   quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the
-   expansion [of $*] appears within a double quoted string, it expands
-   to a single field with the value of each parameter separated by the
-   first character of the IFS variable, or by a <space> if IFS is unset." */
-char *
-string_list_dollar_star (list)
-     WORD_LIST *list;
-{
-  char *ret;
-#if defined (HANDLE_MULTIBYTE)
-#  if defined (__GNUC__)
-  char sep[MB_CUR_MAX + 1];
-#  else
-  char *sep = 0;
-#  endif
-#else
-  char sep[2];
-#endif
-
-#if defined (HANDLE_MULTIBYTE)
-#  if !defined (__GNUC__)
-  sep = (char *)xmalloc (MB_CUR_MAX + 1);
-#  endif /* !__GNUC__ */
-  if (ifs_firstc_len == 1)
-    {
-      sep[0] = ifs_firstc[0];
-      sep[1] = '\0';
-    }
-  else
-    {
-      memcpy (sep, ifs_firstc, ifs_firstc_len);
-      sep[ifs_firstc_len] = '\0';
-    }
-#else
-  sep[0] = ifs_firstc;
-  sep[1] = '\0';
-#endif
-
-  ret = string_list_internal (list, sep);
-#if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
-  free (sep);
-#endif
-  return ret;
-}
-
-/* Turn $@ into a string.  If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-   is non-zero, the $@ appears within double quotes, and we should quote
-   the list before converting it into a string.  If IFS is unset, and the
-   word is not quoted, we just need to quote CTLESC and CTLNUL characters
-   in the words in the list, because the default value of $IFS is
-   <space><tab><newline>, IFS characters in the words in the list should
-   also be split.  If IFS is null, and the word is not quoted, we need
-   to quote the words in the list to preserve the positional parameters
-   exactly. */
-char *
-string_list_dollar_at (list, quoted)
-     WORD_LIST *list;
-     int quoted;
-{
-  char *ifs, *ret;
-#if defined (HANDLE_MULTIBYTE)
-#  if defined (__GNUC__)
-  char sep[MB_CUR_MAX + 1];
-#  else
-  char *sep = 0;
-#  endif /* !__GNUC__ */
-#else
-  char sep[2];
-#endif
-  WORD_LIST *tlist;
-
-  /* XXX this could just be ifs = ifs_value; */
-  ifs = ifs_var ? value_cell (ifs_var) : (char *)0;
-
-#if defined (HANDLE_MULTIBYTE)
-#  if !defined (__GNUC__)
-  sep = (char *)xmalloc (MB_CUR_MAX + 1);
-#  endif /* !__GNUC__ */
-  if (ifs && *ifs)
-    {
-      if (ifs_firstc_len == 1)
-       {
-         sep[0] = ifs_firstc[0];
-         sep[1] = '\0';
-       }
-      else
-       {
-         memcpy (sep, ifs_firstc, ifs_firstc_len);
-         sep[ifs_firstc_len] = '\0';
-       }
-    }
-  else
-    {
-      sep[0] = ' ';
-      sep[1] = '\0';
-    }
-#else
-  sep[0] = (ifs == 0 || *ifs == 0) ? ' ' : *ifs;
-  sep[1] = '\0';
-#endif
-
-  /* XXX -- why call quote_list if ifs == 0?  we can get away without doing
-     it now that quote_escapes quotes spaces */
-#if 0
-  tlist = ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (ifs && *ifs == 0))
-#else
-  tlist = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES|Q_PATQUOTE))
-#endif
-               ? quote_list (list)
-               : list_quote_escapes (list);
-
-  ret = string_list_internal (tlist, sep);
-#if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
-  free (sep);
-#endif
-  return ret;
-}
-
-/* Turn the positional paramters into a string, understanding quoting and
-   the various subtleties of using the first character of $IFS as the
-   separator.  Calls string_list_dollar_at, string_list_dollar_star, and
-   string_list as appropriate. */
-char *
-string_list_pos_params (pchar, list, quoted)
-     int pchar;
-     WORD_LIST *list;
-     int quoted;
-{
-  char *ret;
-  WORD_LIST *tlist;
-
-  if (pchar == '*' && (quoted & Q_DOUBLE_QUOTES))
-    {
-      tlist = quote_list (list);
-      word_list_remove_quoted_nulls (tlist);
-      ret = string_list_dollar_star (tlist);
-    }
-  else if (pchar == '*' && (quoted & Q_HERE_DOCUMENT))
-    {
-      tlist = quote_list (list);
-      word_list_remove_quoted_nulls (tlist);
-      ret = string_list (tlist);
-    }
-  else if (pchar == '*')
-    {
-      /* Even when unquoted, string_list_dollar_star does the right thing
-        making sure that the first character of $IFS is used as the
-        separator. */
-      ret = string_list_dollar_star (list);
-    }
-  else if (pchar == '@' && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-    /* We use string_list_dollar_at, but only if the string is quoted, since
-       that quotes the escapes if it's not, which we don't want.  We could
-       use string_list (the old code did), but that doesn't do the right
-       thing if the first character of $IFS is not a space.  We use
-       string_list_dollar_star if the string is unquoted so we make sure that
-       the elements of $@ are separated by the first character of $IFS for
-       later splitting. */
-    ret = string_list_dollar_at (list, quoted);
-  else if (pchar == '@')
-    ret = string_list_dollar_star (list);
-  else
-    ret = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (list) : list);
-
-  return ret;
-}
-
-/* Return the list of words present in STRING.  Separate the string into
-   words at any of the characters found in SEPARATORS.  If QUOTED is
-   non-zero then word in the list will have its quoted flag set, otherwise
-   the quoted flag is left as make_word () deemed fit.
-
-   This obeys the P1003.2 word splitting semantics.  If `separators' is
-   exactly <space><tab><newline>, then the splitting algorithm is that of
-   the Bourne shell, which treats any sequence of characters from `separators'
-   as a delimiter.  If IFS is unset, which results in `separators' being set
-   to "", no splitting occurs.  If separators has some other value, the
-   following rules are applied (`IFS white space' means zero or more
-   occurrences of <space>, <tab>, or <newline>, as long as those characters
-   are in `separators'):
-
-       1) IFS white space is ignored at the start and the end of the
-          string.
-       2) Each occurrence of a character in `separators' that is not
-          IFS white space, along with any adjacent occurrences of
-          IFS white space delimits a field.
-       3) Any nonzero-length sequence of IFS white space delimits a field.
-   */
-
-/* BEWARE!  list_string strips null arguments.  Don't call it twice and
-   expect to have "" preserved! */
-
-/* This performs word splitting and quoted null character removal on
-   STRING. */
-#define issep(c) \
-       (((separators)[0]) ? ((separators)[1] ? isifs(c) \
-                                             : (c) == (separators)[0]) \
-                          : 0)
-
-WORD_LIST *
-list_string (string, separators, quoted)
-     register char *string, *separators;
-     int quoted;
-{
-  WORD_LIST *result;
-  WORD_DESC *t;
-  char *current_word, *s;
-  int sindex, sh_style_split, whitesep, xflags;
-  size_t slen;
-
-  if (!string || !*string)
-    return ((WORD_LIST *)NULL);
-
-  sh_style_split = separators && separators[0] == ' ' &&
-                                separators[1] == '\t' &&
-                                separators[2] == '\n' &&
-                                separators[3] == '\0';
-  for (xflags = 0, s = ifs_value; s && *s; s++)
-    {
-      if (*s == CTLESC) xflags |= SX_NOCTLESC;
-      else if (*s == CTLNUL) xflags |= SX_NOESCCTLNUL;
-    }
-
-  slen = 0;
-  /* Remove sequences of whitespace at the beginning of STRING, as
-     long as those characters appear in IFS.  Do not do this if
-     STRING is quoted or if there are no separator characters. */
-  if (!quoted || !separators || !*separators)
-    {
-      for (s = string; *s && spctabnl (*s) && issep (*s); s++);
-
-      if (!*s)
-       return ((WORD_LIST *)NULL);
-
-      string = s;
-    }
-
-  /* OK, now STRING points to a word that does not begin with white space.
-     The splitting algorithm is:
-       extract a word, stopping at a separator
-       skip sequences of spc, tab, or nl as long as they are separators
-     This obeys the field splitting rules in Posix.2. */
-  slen = (MB_CUR_MAX > 1) ? strlen (string) : 1;
-  for (result = (WORD_LIST *)NULL, sindex = 0; string[sindex]; )
-    {
-      /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
-        unless multibyte chars are possible. */
-      current_word = string_extract_verbatim (string, slen, &sindex, separators, xflags);
-      if (current_word == 0)
-       break;
-
-      /* If we have a quoted empty string, add a quoted null argument.  We
-        want to preserve the quoted null character iff this is a quoted
-        empty string; otherwise the quoted null characters are removed
-        below. */
-      if (QUOTED_NULL (current_word))
-       {
-         t = alloc_word_desc ();
-         t->word = make_quoted_char ('\0');
-         t->flags |= W_QUOTED|W_HASQUOTEDNULL;
-         result = make_word_list (t, result);
-       }
-      else if (current_word[0] != '\0')
-       {
-         /* If we have something, then add it regardless.  However,
-            perform quoted null character removal on the current word. */
-         remove_quoted_nulls (current_word);
-         result = add_string_to_list (current_word, result);
-         result->word->flags &= ~W_HASQUOTEDNULL;      /* just to be sure */
-         if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
-           result->word->flags |= W_QUOTED;
-       }
-
-      /* If we're not doing sequences of separators in the traditional
-        Bourne shell style, then add a quoted null argument. */
-      else if (!sh_style_split && !spctabnl (string[sindex]))
-       {
-         t = alloc_word_desc ();
-         t->word = make_quoted_char ('\0');
-         t->flags |= W_QUOTED|W_HASQUOTEDNULL;
-         result = make_word_list (t, result);
-       }
-
-      free (current_word);
-
-      /* Note whether or not the separator is IFS whitespace, used later. */
-      whitesep = string[sindex] && spctabnl (string[sindex]);
-
-      /* Move past the current separator character. */
-      if (string[sindex])
-       {
-         DECLARE_MBSTATE;
-         ADVANCE_CHAR (string, slen, sindex);
-       }
-
-      /* Now skip sequences of space, tab, or newline characters if they are
-        in the list of separators. */
-      while (string[sindex] && spctabnl (string[sindex]) && issep (string[sindex]))
-       sindex++;
-
-      /* If the first separator was IFS whitespace and the current character
-        is a non-whitespace IFS character, it should be part of the current
-        field delimiter, not a separate delimiter that would result in an
-        empty field.  Look at POSIX.2, 3.6.5, (3)(b). */
-      if (string[sindex] && whitesep && issep (string[sindex]) && !spctabnl (string[sindex]))
-       {
-         sindex++;
-         /* An IFS character that is not IFS white space, along with any
-            adjacent IFS white space, shall delimit a field. (SUSv3) */
-         while (string[sindex] && spctabnl (string[sindex]) && isifs (string[sindex]))
-           sindex++;
-       }
-    }
-  return (REVERSE_LIST (result, WORD_LIST *));
-}
-
-/* Parse a single word from STRING, using SEPARATORS to separate fields.
-   ENDPTR is set to the first character after the word.  This is used by
-   the `read' builtin.  This is never called with SEPARATORS != $IFS;
-   it should be simplified.
-
-   XXX - this function is very similar to list_string; they should be
-        combined - XXX */
-char *
-get_word_from_string (stringp, separators, endptr)
-     char **stringp, *separators, **endptr;
-{
-  register char *s;
-  char *current_word;
-  int sindex, sh_style_split, whitesep, xflags;
-  size_t slen;
-
-  if (!stringp || !*stringp || !**stringp)
-    return ((char *)NULL);
-
-  sh_style_split = separators && separators[0] == ' ' &&
-                                separators[1] == '\t' &&
-                                separators[2] == '\n' &&
-                                separators[3] == '\0';
-  for (xflags = 0, s = ifs_value; s && *s; s++)
-    {
-      if (*s == CTLESC) xflags |= SX_NOCTLESC;
-      if (*s == CTLNUL) xflags |= SX_NOESCCTLNUL;
-    }
-
-  s = *stringp;
-  slen = 0;
-
-  /* Remove sequences of whitespace at the beginning of STRING, as
-     long as those characters appear in IFS. */
-  if (sh_style_split || !separators || !*separators)
-    {
-      for (; *s && spctabnl (*s) && isifs (*s); s++);
-
-      /* If the string is nothing but whitespace, update it and return. */
-      if (!*s)
-       {
-         *stringp = s;
-         if (endptr)
-           *endptr = s;
-         return ((char *)NULL);
-       }
-    }
-
-  /* OK, S points to a word that does not begin with white space.
-     Now extract a word, stopping at a separator, save a pointer to
-     the first character after the word, then skip sequences of spc,
-     tab, or nl as long as they are separators.
-
-     This obeys the field splitting rules in Posix.2. */
-  sindex = 0;
-  /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
-     unless multibyte chars are possible. */
-  slen = (MB_CUR_MAX > 1) ? strlen (s) : 1;
-  current_word = string_extract_verbatim (s, slen, &sindex, separators, xflags);
-
-  /* Set ENDPTR to the first character after the end of the word. */
-  if (endptr)
-    *endptr = s + sindex;
-
-  /* Note whether or not the separator is IFS whitespace, used later. */
-  whitesep = s[sindex] && spctabnl (s[sindex]);
-
-  /* Move past the current separator character. */
-  if (s[sindex])
-    {
-      DECLARE_MBSTATE;
-      ADVANCE_CHAR (s, slen, sindex);
-    }
-
-  /* Now skip sequences of space, tab, or newline characters if they are
-     in the list of separators. */
-  while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
-    sindex++;
-
-  /* If the first separator was IFS whitespace and the current character is
-     a non-whitespace IFS character, it should be part of the current field
-     delimiter, not a separate delimiter that would result in an empty field.
-     Look at POSIX.2, 3.6.5, (3)(b). */
-  if (s[sindex] && whitesep && isifs (s[sindex]) && !spctabnl (s[sindex]))
-    {
-      sindex++;
-      /* An IFS character that is not IFS white space, along with any adjacent
-        IFS white space, shall delimit a field. */
-      while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
-       sindex++;
-    }
-
-  /* Update STRING to point to the next field. */
-  *stringp = s + sindex;
-  return (current_word);
-}
-
-/* Remove IFS white space at the end of STRING.  Start at the end
-   of the string and walk backwards until the beginning of the string
-   or we find a character that's not IFS white space and not CTLESC.
-   Only let CTLESC escape a white space character if SAW_ESCAPE is
-   non-zero.  */
-char *
-strip_trailing_ifs_whitespace (string, separators, saw_escape)
-     char *string, *separators;
-     int saw_escape;
-{
-  char *s;
-
-  s = string + STRLEN (string) - 1;
-  while (s > string && ((spctabnl (*s) && isifs (*s)) ||
-                       (saw_escape && *s == CTLESC && spctabnl (s[1]))))
-    s--;
-  *++s = '\0';
-  return string;
-}
-
-#if 0
-/* UNUSED */
-/* Split STRING into words at whitespace.  Obeys shell-style quoting with
-   backslashes, single and double quotes. */
-WORD_LIST *
-list_string_with_quotes (string)
-     char *string;
-{
-  WORD_LIST *list;
-  char *token, *s;
-  size_t s_len;
-  int c, i, tokstart, len;
-
-  for (s = string; s && *s && spctabnl (*s); s++)
-    ;
-  if (s == 0 || *s == 0)
-    return ((WORD_LIST *)NULL);
-
-  s_len = strlen (s);
-  tokstart = i = 0;
-  list = (WORD_LIST *)NULL;
-  while (1)
-    {
-      c = s[i];
-      if (c == '\\')
-       {
-         i++;
-         if (s[i])
-           i++;
-       }
-      else if (c == '\'')
-       i = skip_single_quoted (s, s_len, ++i);
-      else if (c == '"')
-       i = skip_double_quoted (s, s_len, ++i);
-      else if (c == 0 || spctabnl (c))
-       {
-         /* We have found the end of a token.  Make a word out of it and
-            add it to the word list. */
-         token = substring (s, tokstart, i);
-         list = add_string_to_list (token, list);
-         free (token);
-         while (spctabnl (s[i]))
-           i++;
-         if (s[i])
-           tokstart = i;
-         else
-           break;
-       }
-      else
-       i++;    /* normal character */
-    }
-  return (REVERSE_LIST (list, WORD_LIST *));
-}
-#endif
-
-/********************************************************/
-/*                                                     */
-/*     Functions to perform assignment statements      */
-/*                                                     */
-/********************************************************/
-
-#if defined (ARRAY_VARS)
-static SHELL_VAR *
-do_compound_assignment (name, value, flags)
-     char *name, *value;
-     int flags;
-{
-  SHELL_VAR *v;
-  int mklocal, mkassoc;
-  WORD_LIST *list;
-
-  mklocal = flags & ASS_MKLOCAL;
-  mkassoc = flags & ASS_MKASSOC;
-
-  if (mklocal && variable_context)
-    {
-      v = find_variable (name);
-      list = expand_compound_array_assignment (v, value, flags);
-      if (mkassoc)
-       v = make_local_assoc_variable (name);
-      else if (v == 0 || (array_p (v) == 0 && assoc_p (v) == 0) || v->context != variable_context)
-        v = make_local_array_variable (name);
-      assign_compound_array_list (v, list, flags);
-    }
-  else
-    v = assign_array_from_string (name, value, flags);
-
-  return (v);
-}
-#endif
-
-/* Given STRING, an assignment string, get the value of the right side
-   of the `=', and bind it to the left side.  If EXPAND is true, then
-   perform parameter expansion, command substitution, and arithmetic
-   expansion on the right-hand side.  Perform tilde expansion in any
-   case.  Do not perform word splitting on the result of expansion. */
-static int
-do_assignment_internal (word, expand)
-     const WORD_DESC *word;
-     int expand;
-{
-  int offset, tlen, appendop, assign_list, aflags, retval;
-  char *name, *value;
-  SHELL_VAR *entry;
-#if defined (ARRAY_VARS)
-  char *t;
-  int ni;
-#endif
-  const char *string;
-
-  if (word == 0 || word->word == 0)
-    return 0;
-
-  appendop = assign_list = aflags = 0;
-  string = word->word;
-  offset = assignment (string, 0);
-  name = savestring (string);
-  value = (char *)NULL;
-
-  if (name[offset] == '=')
-    {
-      char *temp;
-
-      if (name[offset - 1] == '+')
-       {
-         appendop = 1;
-         name[offset - 1] = '\0';
-       }
-
-      name[offset] = 0;                /* might need this set later */
-      temp = name + offset + 1;
-      tlen = STRLEN (temp);
-
-#if defined (ARRAY_VARS)
-      if (expand && (word->flags & W_COMPASSIGN))
-       {
-         assign_list = ni = 1;
-         value = extract_array_assignment_list (temp, &ni);
-       }
-      else
-#endif
-
-      if (expand && temp[0])
-       value = expand_string_if_necessary (temp, 0, expand_string_assignment);
-      else
-       value = savestring (temp);
-    }
-
-  if (value == 0)
-    {
-      value = (char *)xmalloc (1);
-      value[0] = '\0';
-    }
-
-  if (echo_command_at_execute)
-    {
-      if (appendop)
-       name[offset - 1] = '+';
-      xtrace_print_assignment (name, value, assign_list, 1);
-      if (appendop)
-       name[offset - 1] = '\0';
-    }
-
-#define ASSIGN_RETURN(r)       do { FREE (value); free (name); return (r); } while (0)
-
-  if (appendop)
-    aflags |= ASS_APPEND;
-
-#if defined (ARRAY_VARS)
-  if (t = xstrchr (name, '[')) /*]*/
-    {
-      if (assign_list)
-       {
-         report_error (_("%s: cannot assign list to array member"), name);
-         ASSIGN_RETURN (0);
-       }
-      entry = assign_array_element (name, value, aflags);
-      if (entry == 0)
-       ASSIGN_RETURN (0);
-    }
-  else if (assign_list)
-    {
-      if (word->flags & W_ASSIGNARG)
-       aflags |= ASS_MKLOCAL;
-      if (word->flags & W_ASSIGNASSOC)
-       aflags |= ASS_MKASSOC;
-      entry = do_compound_assignment (name, value, aflags);
-    }
-  else
-#endif /* ARRAY_VARS */
-  entry = bind_variable (name, value, aflags);
-
-  stupidly_hack_special_variables (name);
-
-#if 1
-  /* Return 1 if the assignment seems to have been performed correctly. */
-  if (entry == 0 || readonly_p (entry))
-    retval = 0;                /* assignment failure */
-  else if (noassign_p (entry))
-    {
-      last_command_exit_value = EXECUTION_FAILURE;
-      retval = 1;      /* error status, but not assignment failure */
-    }
-  else
-    retval = 1;
-
-  if (entry && retval != 0 && noassign_p (entry) == 0)
-    VUNSETATTR (entry, att_invisible);
-
-  ASSIGN_RETURN (retval);
-#else
-  if (entry)
-    VUNSETATTR (entry, att_invisible);
-
-  ASSIGN_RETURN (entry ? ((readonly_p (entry) == 0) && noassign_p (entry) == 0) : 0);
-#endif
-}
-
-/* Perform the assignment statement in STRING, and expand the
-   right side by doing tilde, command and parameter expansion. */
-int
-do_assignment (string)
-     char *string;
-{
-  WORD_DESC td;
-
-  td.flags = W_ASSIGNMENT;
-  td.word = string;
-
-  return do_assignment_internal (&td, 1);
-}
-
-int
-do_word_assignment (word)
-     WORD_DESC *word;
-{
-  return do_assignment_internal (word, 1);
-}
-
-/* Given STRING, an assignment string, get the value of the right side
-   of the `=', and bind it to the left side.  Do not perform any word
-   expansions on the right hand side. */
-int
-do_assignment_no_expand (string)
-     char *string;
-{
-  WORD_DESC td;
-
-  td.flags = W_ASSIGNMENT;
-  td.word = string;
-
-  return (do_assignment_internal (&td, 0));
-}
-
-/***************************************************
- *                                                *
- *  Functions to manage the positional parameters  *
- *                                                *
- ***************************************************/
-
-/* Return the word list that corresponds to `$*'. */
-WORD_LIST *
-list_rest_of_args ()
-{
-  register WORD_LIST *list, *args;
-  int i;
-
-  /* Break out of the loop as soon as one of the dollar variables is null. */
-  for (i = 1, list = (WORD_LIST *)NULL; i < 10 && dollar_vars[i]; i++)
-    list = make_word_list (make_bare_word (dollar_vars[i]), list);
-
-  for (args = rest_of_args; args; args = args->next)
-    list = make_word_list (make_bare_word (args->word->word), list);
-
-  return (REVERSE_LIST (list, WORD_LIST *));
-}
-
-int
-number_of_args ()
-{
-  register WORD_LIST *list;
-  int n;
-
-  for (n = 0; n < 9 && dollar_vars[n+1]; n++)
-    ;
-  for (list = rest_of_args; list; list = list->next)
-    n++;
-  return n;
-}
-
-/* Return the value of a positional parameter.  This handles values > 10. */
-char *
-get_dollar_var_value (ind)
-     intmax_t ind;
-{
-  char *temp;
-  WORD_LIST *p;
-
-  if (ind < 10)
-    temp = dollar_vars[ind] ? savestring (dollar_vars[ind]) : (char *)NULL;
-  else /* We want something like ${11} */
-    {
-      ind -= 10;
-      for (p = rest_of_args; p && ind--; p = p->next)
-       ;
-      temp = p ? savestring (p->word->word) : (char *)NULL;
-    }
-  return (temp);
-}
-
-/* Make a single large string out of the dollar digit variables,
-   and the rest_of_args.  If DOLLAR_STAR is 1, then obey the special
-   case of "$*" with respect to IFS. */
-char *
-string_rest_of_args (dollar_star)
-     int dollar_star;
-{
-  register WORD_LIST *list;
-  char *string;
-
-  list = list_rest_of_args ();
-  string = dollar_star ? string_list_dollar_star (list) : string_list (list);
-  dispose_words (list);
-  return (string);
-}
-
-/* Return a string containing the positional parameters from START to
-   END, inclusive.  If STRING[0] == '*', we obey the rules for $*,
-   which only makes a difference if QUOTED is non-zero.  If QUOTED includes
-   Q_HERE_DOCUMENT or Q_DOUBLE_QUOTES, this returns a quoted list, otherwise
-   no quoting chars are added. */
-static char *
-pos_params (string, start, end, quoted)
-     char *string;
-     int start, end, quoted;
-{
-  WORD_LIST *save, *params, *h, *t;
-  char *ret;
-  int i;
-
-  /* see if we can short-circuit.  if start == end, we want 0 parameters. */
-  if (start == end)
-    return ((char *)NULL);
-
-  save = params = list_rest_of_args ();
-  if (save == 0)
-    return ((char *)NULL);
-
-  if (start == 0)              /* handle ${@:0[:x]} specially */
-    {
-      t = make_word_list (make_word (dollar_vars[0]), params);
-      save = params = t;
-    }
-
-  for (i = 1; params && i < start; i++)
-    params = params->next;
-  if (params == 0)
-    return ((char *)NULL);
-  for (h = t = params; params && i < end; i++)
-    {
-      t = params;
-      params = params->next;
-    }
-
-  t->next = (WORD_LIST *)NULL;
-
-  ret = string_list_pos_params (string[0], h, quoted);
-
-  if (t != params)
-    t->next = params;
-
-  dispose_words (save);
-  return (ret);
-}
-
-/******************************************************************/
-/*                                                               */
-/*     Functions to expand strings to strings or WORD_LISTs      */
-/*                                                               */
-/******************************************************************/
-
-#if defined (PROCESS_SUBSTITUTION)
-#define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC || s == '~')
-#else
-#define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
-#endif
-
-/* If there are any characters in STRING that require full expansion,
-   then call FUNC to expand STRING; otherwise just perform quote
-   removal if necessary.  This returns a new string. */
-static char *
-expand_string_if_necessary (string, quoted, func)
-     char *string;
-     int quoted;
-     EXPFUNC *func;
-{
-  WORD_LIST *list;
-  size_t slen;
-  int i, saw_quote;
-  char *ret;
-  DECLARE_MBSTATE;
-
-  /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */
-  slen = (MB_CUR_MAX > 1) ? strlen (string) : 0;
-  i = saw_quote = 0;
-  while (string[i])
-    {
-      if (EXP_CHAR (string[i]))
-       break;
-      else if (string[i] == '\'' || string[i] == '\\' || string[i] == '"')
-       saw_quote = 1;
-      ADVANCE_CHAR (string, slen, i);
-    }
-
-  if (string[i])
-    {
-      list = (*func) (string, quoted);
-      if (list)
-       {
-         ret = string_list (list);
-         dispose_words (list);
-       }
-      else
-       ret = (char *)NULL;
-    }
-  else if (saw_quote && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
-    ret = string_quote_removal (string, quoted);
-  else
-    ret = savestring (string);
-
-  return ret;
-}
-
-static inline char *
-expand_string_to_string_internal (string, quoted, func)
-     char *string;
-     int quoted;
-     EXPFUNC *func;
-{
-  WORD_LIST *list;
-  char *ret;
-
-  if (string == 0 || *string == '\0')
-    return ((char *)NULL);
-
-  list = (*func) (string, quoted);
-  if (list)
-    {
-      ret = string_list (list);
-      dispose_words (list);
-    }
-  else
-    ret = (char *)NULL;
-
-  return (ret);
-}
-
-char *
-expand_string_to_string (string, quoted)
-     char *string;
-     int quoted;
-{
-  return (expand_string_to_string_internal (string, quoted, expand_string));
-}
-
-char *
-expand_string_unsplit_to_string (string, quoted)
-     char *string;
-     int quoted;
-{
-  return (expand_string_to_string_internal (string, quoted, expand_string_unsplit));
-}
-
-char *
-expand_assignment_string_to_string (string, quoted)
-     char *string;
-     int quoted;
-{
-  return (expand_string_to_string_internal (string, quoted, expand_string_assignment));
-}
-
-char *
-expand_arith_string (string, quoted)
-     char *string;
-     int quoted;
-{
-  return (expand_string_if_necessary (string, quoted, expand_string));
-}
-
-#if defined (COND_COMMAND)
-/* Just remove backslashes in STRING.  Returns a new string. */
-char *
-remove_backslashes (string)
-     char *string;
-{
-  char *r, *ret, *s;
-
-  r = ret = (char *)xmalloc (strlen (string) + 1);
-  for (s = string; s && *s; )
-    {
-      if (*s == '\\')
-       s++;
-      if (*s == 0)
-       break;
-      *r++ = *s++;
-    }
-  *r = '\0';
-  return ret;
-}
-
-/* This needs better error handling. */
-/* Expand W for use as an argument to a unary or binary operator in a
-   [[...]] expression.  If SPECIAL is 1, this is the rhs argument
-   to the != or == operator, and should be treated as a pattern.  In
-   this case, we quote the string specially for the globbing code.  If
-   SPECIAL is 2, this is an rhs argument for the =~ operator, and should
-   be quoted appropriately for regcomp/regexec.  The caller is responsible
-   for removing the backslashes if the unquoted word is needed later. */   
-char *
-cond_expand_word (w, special)
-     WORD_DESC *w;
-     int special;
-{
-  char *r, *p;
-  WORD_LIST *l;
-  int qflags;
-
-  if (w->word == 0 || w->word[0] == '\0')
-    return ((char *)NULL);
-
-  l = call_expand_word_internal (w, 0, 0, (int *)0, (int *)0);
-  if (l)
-    {
-      if (special == 0)
-       {
-         dequote_list (l);
-         r = string_list (l);
-       }
-      else
-       {
-         qflags = QGLOB_CVTNULL;
-         if (special == 2)
-           qflags |= QGLOB_REGEXP;
-         p = string_list (l);
-         r = quote_string_for_globbing (p, qflags);
-         free (p);
-       }
-      dispose_words (l);
-    }
-  else
-    r = (char *)NULL;
-
-  return r;
-}
-#endif
-
-/* Call expand_word_internal to expand W and handle error returns.
-   A convenience function for functions that don't want to handle
-   any errors or free any memory before aborting. */
-static WORD_LIST *
-call_expand_word_internal (w, q, i, c, e)
-     WORD_DESC *w;
-     int q, i, *c, *e;
-{
-  WORD_LIST *result;
-
-  result = expand_word_internal (w, q, i, c, e);
-  if (result == &expand_word_error || result == &expand_word_fatal)
-    {
-      /* By convention, each time this error is returned, w->word has
-        already been freed (it sometimes may not be in the fatal case,
-        but that doesn't result in a memory leak because we're going
-        to exit in most cases). */
-      w->word = (char *)NULL;
-      last_command_exit_value = EXECUTION_FAILURE;
-      exp_jump_to_top_level ((result == &expand_word_error) ? DISCARD : FORCE_EOF);
-      /* NOTREACHED */
-    }
-  else
-    return (result);
-}
-
-/* Perform parameter expansion, command substitution, and arithmetic
-   expansion on STRING, as if it were a word.  Leave the result quoted. */
-static WORD_LIST *
-expand_string_internal (string, quoted)
-     char *string;
-     int quoted;
-{
-  WORD_DESC td;
-  WORD_LIST *tresult;
-
-  if (string == 0 || *string == 0)
-    return ((WORD_LIST *)NULL);
-
-  td.flags = 0;
-  td.word = savestring (string);
-
-  tresult = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
-
-  FREE (td.word);
-  return (tresult);
-}
-
-/* Expand STRING by performing parameter expansion, command substitution,
-   and arithmetic expansion.  Dequote the resulting WORD_LIST before
-   returning it, but do not perform word splitting.  The call to
-   remove_quoted_nulls () is in here because word splitting normally
-   takes care of quote removal. */
-WORD_LIST *
-expand_string_unsplit (string, quoted)
-     char *string;
-     int quoted;
-{
-  WORD_LIST *value;
-
-  if (string == 0 || *string == '\0')
-    return ((WORD_LIST *)NULL);
-
-  expand_no_split_dollar_star = 1;
-  value = expand_string_internal (string, quoted);
-  expand_no_split_dollar_star = 0;
-
-  if (value)
-    {
-      if (value->word)
-       {
-         remove_quoted_nulls (value->word->word);
-         value->word->flags &= ~W_HASQUOTEDNULL;
-       }
-      dequote_list (value);
-    }
-  return (value);
-}
-
-/* Expand the rhs of an assignment statement */
-WORD_LIST *
-expand_string_assignment (string, quoted)
-     char *string;
-     int quoted;
-{
-  WORD_DESC td;
-  WORD_LIST *value;
-
-  if (string == 0 || *string == '\0')
-    return ((WORD_LIST *)NULL);
-
-  expand_no_split_dollar_star = 1;
-
-  td.flags = W_ASSIGNRHS;
-  td.word = savestring (string);
-  value = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
-  FREE (td.word);
-
-  expand_no_split_dollar_star = 0;
-
-  if (value)
-    {
-      if (value->word)
-       {
-         remove_quoted_nulls (value->word->word);
-         value->word->flags &= ~W_HASQUOTEDNULL;
-       }
-      dequote_list (value);
-    }
-  return (value);
-}
-
-
-/* Expand one of the PS? prompt strings. This is a sort of combination of
-   expand_string_unsplit and expand_string_internal, but returns the
-   passed string when an error occurs.  Might want to trap other calls
-   to jump_to_top_level here so we don't endlessly loop. */
-WORD_LIST *
-expand_prompt_string (string, quoted, wflags)
-     char *string;
-     int quoted;
-     int wflags;
-{
-  WORD_LIST *value;
-  WORD_DESC td;
-
-  if (string == 0 || *string == 0)
-    return ((WORD_LIST *)NULL);
-
-  td.flags = wflags;
-  td.word = savestring (string);
-
-  no_longjmp_on_fatal_error = 1;
-  value = expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
-  no_longjmp_on_fatal_error = 0;
-
-  if (value == &expand_word_error || value == &expand_word_fatal)
-    {
-      value = make_word_list (make_bare_word (string), (WORD_LIST *)NULL);
-      return value;
-    }
-  FREE (td.word);
-  if (value)
-    {
-      if (value->word)
-       {
-         remove_quoted_nulls (value->word->word);
-         value->word->flags &= ~W_HASQUOTEDNULL;
-       }
-      dequote_list (value);
-    }
-  return (value);
-}
-
-/* Expand STRING just as if you were expanding a word, but do not dequote
-   the resultant WORD_LIST.  This is called only from within this file,
-   and is used to correctly preserve quoted characters when expanding
-   things like ${1+"$@"}.  This does parameter expansion, command
-   substitution, arithmetic expansion, and word splitting. */
-static WORD_LIST *
-expand_string_leave_quoted (string, quoted)
-     char *string;
-     int quoted;
-{
-  WORD_LIST *tlist;
-  WORD_LIST *tresult;
-
-  if (string == 0 || *string == '\0')
-    return ((WORD_LIST *)NULL);
-
-  tlist = expand_string_internal (string, quoted);
-
-  if (tlist)
-    {
-      tresult = word_list_split (tlist);
-      dispose_words (tlist);
-      return (tresult);
-    }
-  return ((WORD_LIST *)NULL);
-}
-
-/* This does not perform word splitting or dequote the WORD_LIST
-   it returns. */
-static WORD_LIST *
-expand_string_for_rhs (string, quoted, dollar_at_p, has_dollar_at)
-     char *string;
-     int quoted, *dollar_at_p, *has_dollar_at;
-{
-  WORD_DESC td;
-  WORD_LIST *tresult;
-
-  if (string == 0 || *string == '\0')
-    return (WORD_LIST *)NULL;
-
-  td.flags = 0;
-  td.word = string;
-  tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, has_dollar_at);
-  return (tresult);
-}
-
-/* Expand STRING just as if you were expanding a word.  This also returns
-   a list of words.  Note that filename globbing is *NOT* done for word
-   or string expansion, just when the shell is expanding a command.  This
-   does parameter expansion, command substitution, arithmetic expansion,
-   and word splitting.  Dequote the resultant WORD_LIST before returning. */
-WORD_LIST *
-expand_string (string, quoted)
-     char *string;
-     int quoted;
-{
-  WORD_LIST *result;
-
-  if (string == 0 || *string == '\0')
-    return ((WORD_LIST *)NULL);
-
-  result = expand_string_leave_quoted (string, quoted);
-  return (result ? dequote_list (result) : result);
-}
-
-/***************************************************
- *                                                *
- *     Functions to handle quoting chars          *
- *                                                *
- ***************************************************/
-
-/* Conventions:
-
-     A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string.
-     The parser passes CTLNUL as CTLESC CTLNUL. */
-
-/* Quote escape characters in string s, but no other characters.  This is
-   used to protect CTLESC and CTLNUL in variable values from the rest of
-   the word expansion process after the variable is expanded (word splitting
-   and filename generation).  If IFS is null, we quote spaces as well, just
-   in case we split on spaces later (in the case of unquoted $@, we will
-   eventually attempt to split the entire word on spaces).  Corresponding
-   code exists in dequote_escapes.  Even if we don't end up splitting on
-   spaces, quoting spaces is not a problem.  This should never be called on
-   a string that is quoted with single or double quotes or part of a here
-   document (effectively double-quoted). */
-char *
-quote_escapes (string)
-     char *string;
-{
-  register char *s, *t;
-  size_t slen;
-  char *result, *send;
-  int quote_spaces, skip_ctlesc, skip_ctlnul;
-  DECLARE_MBSTATE; 
-
-  slen = strlen (string);
-  send = string + slen;
-
-  quote_spaces = (ifs_value && *ifs_value == 0);
-
-  for (skip_ctlesc = skip_ctlnul = 0, s = ifs_value; s && *s; s++)
-    skip_ctlesc |= *s == CTLESC, skip_ctlnul |= *s == CTLNUL;
-
-  t = result = (char *)xmalloc ((slen * 2) + 1);
-  s = string;
-
-  while (*s)
-    {
-      if ((skip_ctlesc == 0 && *s == CTLESC) || (skip_ctlnul == 0 && *s == CTLNUL) || (quote_spaces && *s == ' '))
-       *t++ = CTLESC;
-      COPY_CHAR_P (t, s, send);
-    }
-  *t = '\0';
-  return (result);
-}
-
-static WORD_LIST *
-list_quote_escapes (list)
-     WORD_LIST *list;
-{
-  register WORD_LIST *w;
-  char *t;
-
-  for (w = list; w; w = w->next)
-    {
-      t = w->word->word;
-      w->word->word = quote_escapes (t);
-      free (t);
-    }
-  return list;
-}
-
-/* Inverse of quote_escapes; remove CTLESC protecting CTLESC or CTLNUL.
-
-   The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL.
-   This is necessary to make unquoted CTLESC and CTLNUL characters in the
-   data stream pass through properly.
-
-   We need to remove doubled CTLESC characters inside quoted strings before
-   quoting the entire string, so we do not double the number of CTLESC
-   characters.
-
-   Also used by parts of the pattern substitution code. */
-char *
-dequote_escapes (string)
-     char *string;
-{
-  register char *s, *t, *s1;
-  size_t slen;
-  char *result, *send;
-  int quote_spaces;
-  DECLARE_MBSTATE;
-
-  if (string == 0)
-    return string;
-
-  slen = strlen (string);
-  send = string + slen;
-
-  t = result = (char *)xmalloc (slen + 1);
-
-  if (strchr (string, CTLESC) == 0)
-    return (strcpy (result, string));
-
-  quote_spaces = (ifs_value && *ifs_value == 0);
-
-  s = string;
-  while (*s)
-    {
-      if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL || (quote_spaces && s[1] == ' ')))
-       {
-         s++;
-         if (*s == '\0')
-           break;
-       }
-      COPY_CHAR_P (t, s, send);
-    }
-  *t = '\0';
-  return result;
-}
-
-/* Return a new string with the quoted representation of character C.
-   This turns "" into QUOTED_NULL, so the W_HASQUOTEDNULL flag needs to be
-   set in any resultant WORD_DESC where this value is the word. */
-static char *
-make_quoted_char (c)
-     int c;
-{
-  char *temp;
-
-  temp = (char *)xmalloc (3);
-  if (c == 0)
-    {
-      temp[0] = CTLNUL;
-      temp[1] = '\0';
-    }
-  else
-    {
-      temp[0] = CTLESC;
-      temp[1] = c;
-      temp[2] = '\0';
-    }
-  return (temp);
-}
-
-/* Quote STRING, returning a new string.  This turns "" into QUOTED_NULL, so
-   the W_HASQUOTEDNULL flag needs to be set in any resultant WORD_DESC where
-   this value is the word. */
-char *
-quote_string (string)
-     char *string;
-{
-  register char *t;
-  size_t slen;
-  char *result, *send;
-
-  if (*string == 0)
-    {
-      result = (char *)xmalloc (2);
-      result[0] = CTLNUL;
-      result[1] = '\0';
-    }
-  else
-    {
-      DECLARE_MBSTATE;
-
-      slen = strlen (string);
-      send = string + slen;
-
-      result = (char *)xmalloc ((slen * 2) + 1);
-
-      for (t = result; string < send; )
-       {
-         *t++ = CTLESC;
-         COPY_CHAR_P (t, string, send);
-       }
-      *t = '\0';
-    }
-  return (result);
-}
-
-/* De-quote quoted characters in STRING. */
-char *
-dequote_string (string)
-     char *string;
-{
-  register char *s, *t;
-  size_t slen;
-  char *result, *send;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string);
-
-  t = result = (char *)xmalloc (slen + 1);
-
-  if (QUOTED_NULL (string))
-    {
-      result[0] = '\0';
-      return (result);
-    }
-
-  /* If no character in the string can be quoted, don't bother examining
-     each character.  Just return a copy of the string passed to us. */
-  if (strchr (string, CTLESC) == NULL)
-    return (strcpy (result, string));
-
-  send = string + slen;
-  s = string;
-  while (*s)
-    {
-      if (*s == CTLESC)
-       {
-         s++;
-         if (*s == '\0')
-           break;
-       }
-      COPY_CHAR_P (t, s, send);
-    }
-
-  *t = '\0';
-  return (result);
-}
-
-/* Quote the entire WORD_LIST list. */
-static WORD_LIST *
-quote_list (list)
-     WORD_LIST *list;
-{
-  register WORD_LIST *w;
-  char *t;
-
-  for (w = list; w; w = w->next)
-    {
-      t = w->word->word;
-      w->word->word = quote_string (t);
-      if (*t == 0)
-       w->word->flags |= W_HASQUOTEDNULL;      /* XXX - turn on W_HASQUOTEDNULL here? */
-      w->word->flags |= W_QUOTED;
-      free (t);
-    }
-  return list;
-}
-
-/* De-quote quoted characters in each word in LIST. */
-WORD_LIST *
-dequote_list (list)
-     WORD_LIST *list;
-{
-  register char *s;
-  register WORD_LIST *tlist;
-
-  for (tlist = list; tlist; tlist = tlist->next)
-    {
-      s = dequote_string (tlist->word->word);
-      if (QUOTED_NULL (tlist->word->word))
-       tlist->word->flags &= ~W_HASQUOTEDNULL;
-      free (tlist->word->word);
-      tlist->word->word = s;
-    }
-  return list;
-}
-
-/* Remove CTLESC protecting a CTLESC or CTLNUL in place.  Return the passed
-   string. */
-char *
-remove_quoted_escapes (string)
-     char *string;
-{
-  char *t;
-
-  if (string)
-    {
-      t = dequote_escapes (string);
-      strcpy (string, t);
-      free (t);
-    }
-
-  return (string);
-}
-
-/* Perform quoted null character removal on STRING.  We don't allow any
-   quoted null characters in the middle or at the ends of strings because
-   of how expand_word_internal works.  remove_quoted_nulls () turns
-   STRING into an empty string iff it only consists of a quoted null,
-   and removes all unquoted CTLNUL characters. */
-char *
-remove_quoted_nulls (string)
-     char *string;
-{
-  register size_t slen;
-  register int i, j, prev_i;
-  DECLARE_MBSTATE;
-
-  if (strchr (string, CTLNUL) == 0)            /* XXX */
-    return string;                             /* XXX */
-
-  slen = strlen (string);
-  i = j = 0;
-
-  while (i < slen)
-    {
-      if (string[i] == CTLESC)
-       {
-         /* Old code had j++, but we cannot assume that i == j at this
-            point -- what if a CTLNUL has already been removed from the
-            string?  We don't want to drop the CTLESC or recopy characters
-            that we've already copied down. */
-         i++; string[j++] = CTLESC;
-         if (i == slen)
-           break;
-       }
-      else if (string[i] == CTLNUL)
-       i++;
-
-      prev_i = i;
-      ADVANCE_CHAR (string, slen, i);
-      if (j < prev_i)
-       {
-         do string[j++] = string[prev_i++]; while (prev_i < i);
-       }
-      else
-       j = i;
-    }
-  string[j] = '\0';
-
-  return (string);
-}
-
-/* Perform quoted null character removal on each element of LIST.
-   This modifies LIST. */
-void
-word_list_remove_quoted_nulls (list)
-     WORD_LIST *list;
-{
-  register WORD_LIST *t;
-
-  for (t = list; t; t = t->next)
-    {
-      remove_quoted_nulls (t->word->word);
-      t->word->flags &= ~W_HASQUOTEDNULL;
-    }
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*        Functions for Matching and Removing Patterns             */
-/*                                                                 */
-/* **************************************************************** */
-
-#if defined (HANDLE_MULTIBYTE)
-#if 0 /* Currently unused */
-static unsigned char *
-mb_getcharlens (string, len)
-     char *string;
-     int len;
-{
-  int i, offset, last;
-  unsigned char *ret;
-  char *p;
-  DECLARE_MBSTATE;
-
-  i = offset = 0;
-  last = 0;
-  ret = (unsigned char *)xmalloc (len);
-  memset (ret, 0, len);
-  while (string[last])
-    {
-      ADVANCE_CHAR (string, len, offset);
-      ret[last] = offset - last;
-      last = offset;
-    }
-  return ret;
-}
-#endif
-#endif
-
-/* Remove the portion of PARAM matched by PATTERN according to OP, where OP
-   can have one of 4 values:
-       RP_LONG_LEFT    remove longest matching portion at start of PARAM
-       RP_SHORT_LEFT   remove shortest matching portion at start of PARAM
-       RP_LONG_RIGHT   remove longest matching portion at end of PARAM
-       RP_SHORT_RIGHT  remove shortest matching portion at end of PARAM
-*/
-
-#define RP_LONG_LEFT   1
-#define RP_SHORT_LEFT  2
-#define RP_LONG_RIGHT  3
-#define RP_SHORT_RIGHT 4
-
-static char *
-remove_upattern (param, pattern, op)
-     char *param, *pattern;
-     int op;
-{
-  register int len;
-  register char *end;
-  register char *p, *ret, c;
-
-  len = STRLEN (param);
-  end = param + len;
-
-  switch (op)
-    {
-      case RP_LONG_LEFT:       /* remove longest match at start */
-       for (p = end; p >= param; p--)
-         {
-           c = *p; *p = '\0';
-           if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               *p = c;
-               return (savestring (p));
-             }
-           *p = c;
-
-         }
-       break;
-
-      case RP_SHORT_LEFT:      /* remove shortest match at start */
-       for (p = param; p <= end; p++)
-         {
-           c = *p; *p = '\0';
-           if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               *p = c;
-               return (savestring (p));
-             }
-           *p = c;
-         }
-       break;
-
-      case RP_LONG_RIGHT:      /* remove longest match at end */
-       for (p = param; p <= end; p++)
-         {
-           if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               c = *p; *p = '\0';
-               ret = savestring (param);
-               *p = c;
-               return (ret);
-             }
-         }
-       break;
-
-      case RP_SHORT_RIGHT:     /* remove shortest match at end */
-       for (p = end; p >= param; p--)
-         {
-           if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               c = *p; *p = '\0';
-               ret = savestring (param);
-               *p = c;
-               return (ret);
-             }
-         }
-       break;
-    }
-
-  return (savestring (param)); /* no match, return original string */
-}
-
-#if defined (HANDLE_MULTIBYTE)
-static wchar_t *
-remove_wpattern (wparam, wstrlen, wpattern, op)
-     wchar_t *wparam;
-     size_t wstrlen;
-     wchar_t *wpattern;
-     int op;
-{
-  wchar_t wc, *ret;
-  int n;
-
-  switch (op)
-    {
-      case RP_LONG_LEFT:       /* remove longest match at start */
-        for (n = wstrlen; n >= 0; n--)
-         {
-           wc = wparam[n]; wparam[n] = L'\0';
-           if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               wparam[n] = wc;
-               return (wcsdup (wparam + n));
-             }
-           wparam[n] = wc;
-         }
-       break;
-
-      case RP_SHORT_LEFT:      /* remove shortest match at start */
-       for (n = 0; n <= wstrlen; n++)
-         {
-           wc = wparam[n]; wparam[n] = L'\0';
-           if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               wparam[n] = wc;
-               return (wcsdup (wparam + n));
-             }
-           wparam[n] = wc;
-         }
-       break;
-
-      case RP_LONG_RIGHT:      /* remove longest match at end */
-        for (n = 0; n <= wstrlen; n++)
-         {
-           if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               wc = wparam[n]; wparam[n] = L'\0';
-               ret = wcsdup (wparam);
-               wparam[n] = wc;
-               return (ret);
-             }
-         }
-       break;
-
-      case RP_SHORT_RIGHT:     /* remove shortest match at end */
-       for (n = wstrlen; n >= 0; n--)
-         {
-           if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               wc = wparam[n]; wparam[n] = L'\0';
-               ret = wcsdup (wparam);
-               wparam[n] = wc;
-               return (ret);
-             }
-         }
-       break;
-    }
-
-  return (wcsdup (wparam));    /* no match, return original string */
-}
-#endif /* HANDLE_MULTIBYTE */
-
-static char *
-remove_pattern (param, pattern, op)
-     char *param, *pattern;
-     int op;
-{
-  if (param == NULL)
-    return (param);
-  if (*param == '\0' || pattern == NULL || *pattern == '\0')   /* minor optimization */
-    return (savestring (param));
-
-#if defined (HANDLE_MULTIBYTE)
-  if (MB_CUR_MAX > 1)
-    {
-      wchar_t *ret, *oret;
-      size_t n;
-      wchar_t *wparam, *wpattern;
-      mbstate_t ps;
-      char *xret;
-
-      n = xdupmbstowcs (&wpattern, NULL, pattern);
-      if (n == (size_t)-1)
-       return (remove_upattern (param, pattern, op));
-      n = xdupmbstowcs (&wparam, NULL, param);
-      if (n == (size_t)-1)
-       {
-         free (wpattern);
-         return (remove_upattern (param, pattern, op));
-       }
-      oret = ret = remove_wpattern (wparam, n, wpattern, op);
-
-      free (wparam);
-      free (wpattern);
-
-      n = strlen (param);
-      xret = (char *)xmalloc (n + 1);
-      memset (&ps, '\0', sizeof (mbstate_t));
-      n = wcsrtombs (xret, (const wchar_t **)&ret, n, &ps);
-      xret[n] = '\0';          /* just to make sure */
-      free (oret);
-      return xret;      
-    }
-  else
-#endif
-    return (remove_upattern (param, pattern, op));
-}
-
-/* Return 1 of the first character of STRING could match the first
-   character of pattern PAT.  Used to avoid n2 calls to strmatch(). */
-static int
-match_pattern_char (pat, string)
-     char *pat, *string;
-{
-  char c;
-
-  if (*string == 0)
-    return (0);
-
-  switch (c = *pat++)
-    {
-    default:
-      return (*string == c);
-    case '\\':
-      return (*string == *pat);
-    case '?':
-      return (*pat == LPAREN ? 1 : (*string != '\0'));
-    case '*':
-      return (1);
-    case '+':
-    case '!':
-    case '@':
-      return (*pat == LPAREN ? 1 : (*string == c));
-    case '[':
-      return (*string != '\0');
-    }
-}
-
-/* Match PAT anywhere in STRING and return the match boundaries.
-   This returns 1 in case of a successful match, 0 otherwise.  SP
-   and EP are pointers into the string where the match begins and
-   ends, respectively.  MTYPE controls what kind of match is attempted.
-   MATCH_BEG and MATCH_END anchor the match at the beginning and end
-   of the string, respectively.  The longest match is returned. */
-static int
-match_upattern (string, pat, mtype, sp, ep)
-     char *string, *pat;
-     int mtype;
-     char **sp, **ep;
-{
-  int c, len;
-  register char *p, *p1, *npat;
-  char *end;
-
-  /* If the pattern doesn't match anywhere in the string, go ahead and
-     short-circuit right away.  A minor optimization, saves a bunch of
-     unnecessary calls to strmatch (up to N calls for a string of N
-     characters) if the match is unsuccessful.  To preserve the semantics
-     of the substring matches below, we make sure that the pattern has
-     `*' as first and last character, making a new pattern if necessary. */
-  /* XXX - check this later if I ever implement `**' with special meaning,
-     since this will potentially result in `**' at the beginning or end */
-  len = STRLEN (pat);
-  if (pat[0] != '*' || (pat[0] == '*' && pat[1] == '(' && extended_glob) || pat[len - 1] != '*')       /*)*/
-    {
-      p = npat = (char *)xmalloc (len + 3);
-      p1 = pat;
-      if (*p1 != '*' || (*p1 == '*' && p1[1] == '(' && extended_glob)) /*)*/
-       *p++ = '*';
-      while (*p1)
-       *p++ = *p1++;
-      if (p1[-1] != '*' || p[-2] == '\\')
-       *p++ = '*';
-      *p = '\0';
-    }
-  else
-    npat = pat;
-  c = strmatch (npat, string, FNMATCH_EXTFLAG);
-  if (npat != pat)
-    free (npat);
-  if (c == FNM_NOMATCH)
-    return (0);
-
-  len = STRLEN (string);
-  end = string + len;
-
-  switch (mtype)
-    {
-    case MATCH_ANY:
-      for (p = string; p <= end; p++)
-       {
-         if (match_pattern_char (pat, p))
-           {
-             for (p1 = end; p1 >= p; p1--)
-               {
-                 c = *p1; *p1 = '\0';
-                 if (strmatch (pat, p, FNMATCH_EXTFLAG) == 0)
-                   {
-                     *p1 = c;
-                     *sp = p;
-                     *ep = p1;
-                     return 1;
-                   }
-                 *p1 = c;
-               }
-           }
-       }
-
-      return (0);
-
-    case MATCH_BEG:
-      if (match_pattern_char (pat, string) == 0)
-       return (0);
-
-      for (p = end; p >= string; p--)
-       {
-         c = *p; *p = '\0';
-         if (strmatch (pat, string, FNMATCH_EXTFLAG) == 0)
-           {
-             *p = c;
-             *sp = string;
-             *ep = p;
-             return 1;
-           }
-         *p = c;
-       }
-
-      return (0);
-
-    case MATCH_END:
-      for (p = string; p <= end; p++)
-       {
-         if (strmatch (pat, p, FNMATCH_EXTFLAG) == 0)
-           {
-             *sp = p;
-             *ep = end;
-             return 1;
-           }
-
-       }
-
-      return (0);
-    }
-
-  return (0);
-}
-
-#if defined (HANDLE_MULTIBYTE)
-/* Return 1 of the first character of WSTRING could match the first
-   character of pattern WPAT.  Wide character version. */
-static int
-match_pattern_wchar (wpat, wstring)
-     wchar_t *wpat, *wstring;
-{
-  wchar_t wc;
-
-  if (*wstring == 0)
-    return (0);
-
-  switch (wc = *wpat++)
-    {
-    default:
-      return (*wstring == wc);
-    case L'\\':
-      return (*wstring == *wpat);
-    case L'?':
-      return (*wpat == LPAREN ? 1 : (*wstring != L'\0'));
-    case L'*':
-      return (1);
-    case L'+':
-    case L'!':
-    case L'@':
-      return (*wpat == LPAREN ? 1 : (*wstring == wc));
-    case L'[':
-      return (*wstring != L'\0');
-    }
-}
-
-/* Match WPAT anywhere in WSTRING and return the match boundaries.
-   This returns 1 in case of a successful match, 0 otherwise.  Wide
-   character version. */
-static int
-match_wpattern (wstring, indices, wstrlen, wpat, mtype, sp, ep)
-     wchar_t *wstring;
-     char **indices;
-     size_t wstrlen;
-     wchar_t *wpat;
-     int mtype;
-     char **sp, **ep;
-{
-  wchar_t wc, *wp, *nwpat, *wp1;
-  int len;
-#if 0
-  size_t n, n1;        /* Apple's gcc seems to miscompile this badly */
-#else
-  int n, n1;
-#endif
-
-  /* If the pattern doesn't match anywhere in the string, go ahead and
-     short-circuit right away.  A minor optimization, saves a bunch of
-     unnecessary calls to strmatch (up to N calls for a string of N
-     characters) if the match is unsuccessful.  To preserve the semantics
-     of the substring matches below, we make sure that the pattern has
-     `*' as first and last character, making a new pattern if necessary. */
-  /* XXX - check this later if I ever implement `**' with special meaning,
-     since this will potentially result in `**' at the beginning or end */
-  len = wcslen (wpat);
-  if (wpat[0] != L'*' || (wpat[0] == L'*' && wpat[1] == L'(' && extended_glob) || wpat[len - 1] != L'*')       /*)*/
-    {
-      wp = nwpat = (wchar_t *)xmalloc ((len + 3) * sizeof (wchar_t));
-      wp1 = wpat;
-      if (*wp1 != L'*' || (*wp1 == '*' && wp1[1] == '(' && extended_glob))     /*)*/
-       *wp++ = L'*';
-      while (*wp1 != L'\0')
-       *wp++ = *wp1++;
-      if (wp1[-1] != L'*' || wp1[-2] == L'\\')
-        *wp++ = L'*';
-      *wp = '\0';
-    }
-  else
-    nwpat = wpat;
-  len = wcsmatch (nwpat, wstring, FNMATCH_EXTFLAG);
-  if (nwpat != wpat)
-    free (nwpat);
-  if (len == FNM_NOMATCH)
-    return (0);
-
-  switch (mtype)
-    {
-    case MATCH_ANY:
-      for (n = 0; n <= wstrlen; n++)
-       {
-         if (match_pattern_wchar (wpat, wstring + n))
-           {
-             for (n1 = wstrlen; n1 >= n; n1--)
-               {
-                 wc = wstring[n1]; wstring[n1] = L'\0';
-                 if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG) == 0)
-                   {
-                     wstring[n1] = wc;
-                     *sp = indices[n];
-                     *ep = indices[n1];
-                     return 1;
-                   }
-                 wstring[n1] = wc;
-               }
-           }
-       }
-
-      return (0);
-
-    case MATCH_BEG:
-      if (match_pattern_wchar (wpat, wstring) == 0)
-       return (0);
-
-      for (n = wstrlen; n >= 0; n--)
-       {
-         wc = wstring[n]; wstring[n] = L'\0';
-         if (wcsmatch (wpat, wstring, FNMATCH_EXTFLAG) == 0)
-           {
-             wstring[n] = wc;
-             *sp = indices[0];
-             *ep = indices[n];
-             return 1;
-           }
-         wstring[n] = wc;
-       }
-
-      return (0);
-
-    case MATCH_END:
-      for (n = 0; n <= wstrlen; n++)
-       {
-         if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG) == 0)
-           {
-             *sp = indices[n];
-             *ep = indices[wstrlen];
-             return 1;
-           }
-       }
-
-      return (0);
-    }
-
-  return (0);
-}
-#endif /* HANDLE_MULTIBYTE */
-
-static int
-match_pattern (string, pat, mtype, sp, ep)
-     char *string, *pat;
-     int mtype;
-     char **sp, **ep;
-{
-#if defined (HANDLE_MULTIBYTE)
-  int ret;
-  size_t n;
-  wchar_t *wstring, *wpat;
-  char **indices;
-#endif
-
-  if (string == 0 || *string == 0 || pat == 0 || *pat == 0)
-    return (0);
-
-#if defined (HANDLE_MULTIBYTE)
-  if (MB_CUR_MAX > 1)
-    {
-      n = xdupmbstowcs (&wpat, NULL, pat);
-      if (n == (size_t)-1)
-       return (match_upattern (string, pat, mtype, sp, ep));
-      n = xdupmbstowcs (&wstring, &indices, string);
-      if (n == (size_t)-1)
-       {
-         free (wpat);
-         return (match_upattern (string, pat, mtype, sp, ep));
-       }
-      ret = match_wpattern (wstring, indices, n, wpat, mtype, sp, ep);
-
-      free (wpat);
-      free (wstring);
-      free (indices);
-
-      return (ret);
-    }
-  else
-#endif
-    return (match_upattern (string, pat, mtype, sp, ep));
-}
-
-static int
-getpatspec (c, value)
-     int c;
-     char *value;
-{
-  if (c == '#')
-    return ((*value == '#') ? RP_LONG_LEFT : RP_SHORT_LEFT);
-  else /* c == '%' */
-    return ((*value == '%') ? RP_LONG_RIGHT : RP_SHORT_RIGHT);
-}
-
-/* Posix.2 says that the WORD should be run through tilde expansion,
-   parameter expansion, command substitution and arithmetic expansion.
-   This leaves the result quoted, so quote_string_for_globbing () has
-   to be called to fix it up for strmatch ().  If QUOTED is non-zero,
-   it means that the entire expression was enclosed in double quotes.
-   This means that quoting characters in the pattern do not make any
-   special pattern characters quoted.  For example, the `*' in the
-   following retains its special meaning: "${foo#'*'}". */
-static char *
-getpattern (value, quoted, expandpat)
-     char *value;
-     int quoted, expandpat;
-{
-  char *pat, *tword;
-  WORD_LIST *l;
-#if 0
-  int i;
-#endif
-  /* There is a problem here:  how to handle single or double quotes in the
-     pattern string when the whole expression is between double quotes?
-     POSIX.2 says that enclosing double quotes do not cause the pattern to
-     be quoted, but does that leave us a problem with @ and array[@] and their
-     expansions inside a pattern? */
-#if 0
-  if (expandpat && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *tword)
-    {
-      i = 0;
-      pat = string_extract_double_quoted (tword, &i, 1);
-      free (tword);
-      tword = pat;
-    }
-#endif
-
-  /* expand_string_for_rhs () leaves WORD quoted and does not perform
-     word splitting. */
-  l = *value ? expand_string_for_rhs (value,
-                                     (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? Q_PATQUOTE : quoted,
-                                     (int *)NULL, (int *)NULL)
-            : (WORD_LIST *)0;
-  pat = string_list (l);
-  dispose_words (l);
-  if (pat)
-    {
-      tword = quote_string_for_globbing (pat, QGLOB_CVTNULL);
-      free (pat);
-      pat = tword;
-    }
-  return (pat);
-}
-
-#if 0
-/* Handle removing a pattern from a string as a result of ${name%[%]value}
-   or ${name#[#]value}. */
-static char *
-variable_remove_pattern (value, pattern, patspec, quoted)
-     char *value, *pattern;
-     int patspec, quoted;
-{
-  char *tword;
-
-  tword = remove_pattern (value, pattern, patspec);
-
-  return (tword);
-}
-#endif
-
-static char *
-list_remove_pattern (list, pattern, patspec, itype, quoted)
-     WORD_LIST *list;
-     char *pattern;
-     int patspec, itype, quoted;
-{
-  WORD_LIST *new, *l;
-  WORD_DESC *w;
-  char *tword;
-
-  for (new = (WORD_LIST *)NULL, l = list; l; l = l->next)
-    {
-      tword = remove_pattern (l->word->word, pattern, patspec);
-      w = alloc_word_desc ();
-      w->word = tword ? tword : savestring ("");
-      new = make_word_list (w, new);
-    }
-
-  l = REVERSE_LIST (new, WORD_LIST *);
-  tword = string_list_pos_params (itype, l, quoted);
-  dispose_words (l);
-
-  return (tword);
-}
-
-static char *
-parameter_list_remove_pattern (itype, pattern, patspec, quoted)
-     int itype;
-     char *pattern;
-     int patspec, quoted;
-{
-  char *ret;
-  WORD_LIST *list;
-
-  list = list_rest_of_args ();
-  if (list == 0)
-    return ((char *)NULL);
-  ret = list_remove_pattern (list, pattern, patspec, itype, quoted);
-  dispose_words (list);
-  return (ret);
-}
-
-#if defined (ARRAY_VARS)
-static char *
-array_remove_pattern (var, pattern, patspec, varname, quoted)
-     SHELL_VAR *var;
-     char *pattern;
-     int patspec;
-     char *varname;    /* so we can figure out how it's indexed */
-     int quoted;
-{
-  ARRAY *a;
-  HASH_TABLE *h;
-  int itype;
-  char *ret;
-  WORD_LIST *list;
-  SHELL_VAR *v;
-
-  /* compute itype from varname here */
-  v = array_variable_part (varname, &ret, 0);
-  itype = ret[0];
-
-  a = (v && array_p (v)) ? array_cell (v) : 0;
-  h = (v && assoc_p (v)) ? assoc_cell (v) : 0;
-  
-  list = a ? array_to_word_list (a) : (h ? assoc_to_word_list (h) : 0);
-  if (list == 0)
-   return ((char *)NULL);
-  ret = list_remove_pattern (list, pattern, patspec, itype, quoted);
-  dispose_words (list);
-
-  return ret;
-}
-#endif /* ARRAY_VARS */
-
-static char *
-parameter_brace_remove_pattern (varname, value, patstr, rtype, quoted)
-     char *varname, *value, *patstr;
-     int rtype, quoted;
-{
-  int vtype, patspec, starsub;
-  char *temp1, *val, *pattern;
-  SHELL_VAR *v;
-
-  if (value == 0)
-    return ((char *)NULL);
-
-  this_command_name = varname;
-
-  vtype = get_var_and_type (varname, value, quoted, &v, &val);
-  if (vtype == -1)
-    return ((char *)NULL);
-
-  starsub = vtype & VT_STARSUB;
-  vtype &= ~VT_STARSUB;
-
-  patspec = getpatspec (rtype, patstr);
-  if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT)
-    patstr++;
-
-  /* Need to pass getpattern newly-allocated memory in case of expansion --
-     the expansion code will free the passed string on an error. */
-  temp1 = savestring (patstr);
-  pattern = getpattern (temp1, quoted, 1);
-  free (temp1);
-
-  temp1 = (char *)NULL;                /* shut up gcc */
-  switch (vtype)
-    {
-    case VT_VARIABLE:
-    case VT_ARRAYMEMBER:
-      temp1 = remove_pattern (val, pattern, patspec);
-      if (vtype == VT_VARIABLE)
-       FREE (val);
-      if (temp1)
-       {
-         val = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-                       ? quote_string (temp1)
-                       : quote_escapes (temp1);
-         free (temp1);
-         temp1 = val;
-       }
-      break;
-#if defined (ARRAY_VARS)
-    case VT_ARRAYVAR:
-      temp1 = array_remove_pattern (v, pattern, patspec, varname, quoted);
-      if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
-       {
-         val = quote_escapes (temp1);
-         free (temp1);
-         temp1 = val;
-       }
-      break;
-#endif
-    case VT_POSPARMS:
-      temp1 = parameter_list_remove_pattern (varname[0], pattern, patspec, quoted);
-      if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
-       {
-         val = quote_escapes (temp1);
-         free (temp1);
-         temp1 = val;
-       }
-      break;
-    }
-
-  FREE (pattern);
-  return temp1;
-}    
-
-/*******************************************
- *                                        *
- *     Functions to expand WORD_DESCs     *
- *                                        *
- *******************************************/
-
-/* Expand WORD, performing word splitting on the result.  This does
-   parameter expansion, command substitution, arithmetic expansion,
-   word splitting, and quote removal. */
-
-WORD_LIST *
-expand_word (word, quoted)
-     WORD_DESC *word;
-     int quoted;
-{
-  WORD_LIST *result, *tresult;
-
-  tresult = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
-  result = word_list_split (tresult);
-  dispose_words (tresult);
-  return (result ? dequote_list (result) : result);
-}
-
-/* Expand WORD, but do not perform word splitting on the result.  This
-   does parameter expansion, command substitution, arithmetic expansion,
-   and quote removal. */
-WORD_LIST *
-expand_word_unsplit (word, quoted)
-     WORD_DESC *word;
-     int quoted;
-{
-  WORD_LIST *result;
-
-  expand_no_split_dollar_star = 1;
-#if defined (HANDLE_MULTIBYTE)
-  if (ifs_firstc[0] == 0)
-#else
-  if (ifs_firstc == 0)
-#endif
-    word->flags |= W_NOSPLIT;
-  result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
-  expand_no_split_dollar_star = 0;
-
-  return (result ? dequote_list (result) : result);
-}
-
-/* Perform shell expansions on WORD, but do not perform word splitting or
-   quote removal on the result.  Virtually identical to expand_word_unsplit;
-   could be combined if implementations don't diverge. */
-WORD_LIST *
-expand_word_leave_quoted (word, quoted)
-     WORD_DESC *word;
-     int quoted;
-{
-  WORD_LIST *result;
-
-  expand_no_split_dollar_star = 1;
-#if defined (HANDLE_MULTIBYTE)
-  if (ifs_firstc[0] == 0)
-#else
-  if (ifs_firstc == 0)
-#endif
-    word->flags |= W_NOSPLIT;
-  result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
-  expand_no_split_dollar_star = 0;
-
-  return result;
-}
-
-#if defined (PROCESS_SUBSTITUTION)
-
-/*****************************************************************/
-/*                                                              */
-/*                 Hacking Process Substitution                 */
-/*                                                              */
-/*****************************************************************/
-
-#if !defined (HAVE_DEV_FD)
-/* Named pipes must be removed explicitly with `unlink'.  This keeps a list
-   of FIFOs the shell has open.  unlink_fifo_list will walk the list and
-   unlink all of them. add_fifo_list adds the name of an open FIFO to the
-   list.  NFIFO is a count of the number of FIFOs in the list. */
-#define FIFO_INCR 20
-
-struct temp_fifo {
-  char *file;
-  pid_t proc;
-};
-
-static struct temp_fifo *fifo_list = (struct temp_fifo *)NULL;
-static int nfifo;
-static int fifo_list_size;
-
-static void
-add_fifo_list (pathname)
-     char *pathname;
-{
-  if (nfifo >= fifo_list_size - 1)
-    {
-      fifo_list_size += FIFO_INCR;
-      fifo_list = (struct temp_fifo *)xrealloc (fifo_list,
-                               fifo_list_size * sizeof (struct temp_fifo));
-    }
-
-  fifo_list[nfifo].file = savestring (pathname);
-  nfifo++;
-}
-
-void
-unlink_fifo_list ()
-{
-  int saved, i, j;
-
-  if (nfifo == 0)
-    return;
-
-  for (i = saved = 0; i < nfifo; i++)
-    {
-      if ((fifo_list[i].proc == -1) || (kill(fifo_list[i].proc, 0) == -1))
-       {
-         unlink (fifo_list[i].file);
-         free (fifo_list[i].file);
-         fifo_list[i].file = (char *)NULL;
-         fifo_list[i].proc = -1;
-       }
-      else
-       saved++;
-    }
-
-  /* If we didn't remove some of the FIFOs, compact the list. */
-  if (saved)
-    {
-      for (i = j = 0; i < nfifo; i++)
-       if (fifo_list[i].file)
-         {
-           fifo_list[j].file = fifo_list[i].file;
-           fifo_list[j].proc = fifo_list[i].proc;
-           j++;
-         }
-      nfifo = j;
-    }
-  else
-    nfifo = 0;
-}
-
-int
-fifos_pending ()
-{
-  return nfifo;
-}
-
-static char *
-make_named_pipe ()
-{
-  char *tname;
-
-  tname = sh_mktmpname ("sh-np", MT_USERANDOM|MT_USETMPDIR);
-  if (mkfifo (tname, 0600) < 0)
-    {
-      free (tname);
-      return ((char *)NULL);
-    }
-
-  add_fifo_list (tname);
-  return (tname);
-}
-
-#else /* HAVE_DEV_FD */
-
-/* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
-   has open to children.  NFDS is a count of the number of bits currently
-   set in DEV_FD_LIST.  TOTFDS is a count of the highest possible number
-   of open files. */
-static char *dev_fd_list = (char *)NULL;
-static int nfds;
-static int totfds;     /* The highest possible number of open files. */
-
-static void
-add_fifo_list (fd)
-     int fd;
-{
-  if (!dev_fd_list || fd >= totfds)
-    {
-      int ofds;
-
-      ofds = totfds;
-      totfds = getdtablesize ();
-      if (totfds < 0 || totfds > 256)
-       totfds = 256;
-      if (fd >= totfds)
-       totfds = fd + 2;
-
-      dev_fd_list = (char *)xrealloc (dev_fd_list, totfds);
-      memset (dev_fd_list + ofds, '\0', totfds - ofds);
-    }
-
-  dev_fd_list[fd] = 1;
-  nfds++;
-}
-
-int
-fifos_pending ()
-{
-  return 0;    /* used for cleanup; not needed with /dev/fd */
-}
-
-void
-unlink_fifo_list ()
-{
-  register int i;
-
-  if (nfds == 0)
-    return;
-
-  for (i = 0; nfds && i < totfds; i++)
-    if (dev_fd_list[i])
-      {
-       close (i);
-       dev_fd_list[i] = 0;
-       nfds--;
-      }
-
-  nfds = 0;
-}
-
-#if defined (NOTDEF)
-print_dev_fd_list ()
-{
-  register int i;
-
-  fprintf (stderr, "pid %ld: dev_fd_list:", (long)getpid ());
-  fflush (stderr);
-
-  for (i = 0; i < totfds; i++)
-    {
-      if (dev_fd_list[i])
-       fprintf (stderr, " %d", i);
-    }
-  fprintf (stderr, "\n");
-}
-#endif /* NOTDEF */
-
-static char *
-make_dev_fd_filename (fd)
-     int fd;
-{
-  char *ret, intbuf[INT_STRLEN_BOUND (int) + 1], *p;
-
-  ret = (char *)xmalloc (sizeof (DEV_FD_PREFIX) + 8);
-
-  strcpy (ret, DEV_FD_PREFIX);
-  p = inttostr (fd, intbuf, sizeof (intbuf));
-  strcpy (ret + sizeof (DEV_FD_PREFIX) - 1, p);
-
-  add_fifo_list (fd);
-  return (ret);
-}
-
-#endif /* HAVE_DEV_FD */
-
-/* Return a filename that will open a connection to the process defined by
-   executing STRING.  HAVE_DEV_FD, if defined, means open a pipe and return
-   a filename in /dev/fd corresponding to a descriptor that is one of the
-   ends of the pipe.  If not defined, we use named pipes on systems that have
-   them.  Systems without /dev/fd and named pipes are out of luck.
-
-   OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
-   use the read end of the pipe and dup that file descriptor to fd 0 in
-   the child.  If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
-   writing or use the write end of the pipe in the child, and dup that
-   file descriptor to fd 1 in the child.  The parent does the opposite. */
-
-static char *
-process_substitute (string, open_for_read_in_child)
-     char *string;
-     int open_for_read_in_child;
-{
-  char *pathname;
-  int fd, result;
-  pid_t old_pid, pid;
-#if defined (HAVE_DEV_FD)
-  int parent_pipe_fd, child_pipe_fd;
-  int fildes[2];
-#endif /* HAVE_DEV_FD */
-#if defined (JOB_CONTROL)
-  pid_t old_pipeline_pgrp;
-#endif
-
-  if (!string || !*string || wordexp_only)
-    return ((char *)NULL);
-
-#if !defined (HAVE_DEV_FD)
-  pathname = make_named_pipe ();
-#else /* HAVE_DEV_FD */
-  if (pipe (fildes) < 0)
-    {
-      sys_error (_("cannot make pipe for process substitution"));
-      return ((char *)NULL);
-    }
-  /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
-     the pipe in the parent, otherwise the read end. */
-  parent_pipe_fd = fildes[open_for_read_in_child];
-  child_pipe_fd = fildes[1 - open_for_read_in_child];
-  /* Move the parent end of the pipe to some high file descriptor, to
-     avoid clashes with FDs used by the script. */
-  parent_pipe_fd = move_to_high_fd (parent_pipe_fd, 1, 64);
-
-  pathname = make_dev_fd_filename (parent_pipe_fd);
-#endif /* HAVE_DEV_FD */
-
-  if (pathname == 0)
-    {
-      sys_error (_("cannot make pipe for process substitution"));
-      return ((char *)NULL);
-    }
-
-  old_pid = last_made_pid;
-
-#if defined (JOB_CONTROL)
-  old_pipeline_pgrp = pipeline_pgrp;
-  pipeline_pgrp = shell_pgrp;
-  save_pipeline (1);
-#endif /* JOB_CONTROL */
-
-  pid = make_child ((char *)NULL, 1);
-  if (pid == 0)
-    {
-      reset_terminating_signals ();    /* XXX */
-      free_pushed_string_input ();
-      /* Cancel traps, in trap.c. */
-      restore_original_signals ();
-      setup_async_signals ();
-      subshell_environment |= SUBSHELL_COMSUB|SUBSHELL_PROCSUB;
-    }
-
-#if defined (JOB_CONTROL)
-  set_sigchld_handler ();
-  stop_making_children ();
-  /* XXX - should we only do this in the parent? (as in command subst) */
-  pipeline_pgrp = old_pipeline_pgrp;
-#endif /* JOB_CONTROL */
-
-  if (pid < 0)
-    {
-      sys_error (_("cannot make child for process substitution"));
-      free (pathname);
-#if defined (HAVE_DEV_FD)
-      close (parent_pipe_fd);
-      close (child_pipe_fd);
-#endif /* HAVE_DEV_FD */
-      return ((char *)NULL);
-    }
-
-  if (pid > 0)
-    {
-#if defined (JOB_CONTROL)
-      restore_pipeline (1);
-#endif
-
-#if !defined (HAVE_DEV_FD)
-      fifo_list[nfifo-1].proc = pid;
-#endif
-
-      last_made_pid = old_pid;
-
-#if defined (JOB_CONTROL) && defined (PGRP_PIPE)
-      close_pgrp_pipe ();
-#endif /* JOB_CONTROL && PGRP_PIPE */
-
-#if defined (HAVE_DEV_FD)
-      close (child_pipe_fd);
-#endif /* HAVE_DEV_FD */
-
-      return (pathname);
-    }
-
-  set_sigint_handler ();
-
-#if defined (JOB_CONTROL)
-  set_job_control (0);
-#endif /* JOB_CONTROL */
-
-#if !defined (HAVE_DEV_FD)
-  /* Open the named pipe in the child. */
-  fd = open (pathname, open_for_read_in_child ? O_RDONLY|O_NONBLOCK : O_WRONLY);
-  if (fd < 0)
-    {
-      /* Two separate strings for ease of translation. */
-      if (open_for_read_in_child)
-       sys_error (_("cannot open named pipe %s for reading"), pathname);
-      else
-       sys_error (_("cannot open named pipe %s for writing"), pathname);
-
-      exit (127);
-    }
-  if (open_for_read_in_child)
-    {
-      if (sh_unset_nodelay_mode (fd) < 0)
-       {
-         sys_error (_("cannot reset nodelay mode for fd %d"), fd);
-         exit (127);
-       }
-    }
-#else /* HAVE_DEV_FD */
-  fd = child_pipe_fd;
-#endif /* HAVE_DEV_FD */
-
-  if (dup2 (fd, open_for_read_in_child ? 0 : 1) < 0)
-    {
-      sys_error (_("cannot duplicate named pipe %s as fd %d"), pathname,
-       open_for_read_in_child ? 0 : 1);
-      exit (127);
-    }
-
-  if (fd != (open_for_read_in_child ? 0 : 1))
-    close (fd);
-
-  /* Need to close any files that this process has open to pipes inherited
-     from its parent. */
-  if (current_fds_to_close)
-    {
-      close_fd_bitmap (current_fds_to_close);
-      current_fds_to_close = (struct fd_bitmap *)NULL;
-    }
-
-#if defined (HAVE_DEV_FD)
-  /* Make sure we close the parent's end of the pipe and clear the slot
-     in the fd list so it is not closed later, if reallocated by, for
-     instance, pipe(2). */
-  close (parent_pipe_fd);
-  dev_fd_list[parent_pipe_fd] = 0;
-#endif /* HAVE_DEV_FD */
-
-  result = parse_and_execute (string, "process substitution", (SEVAL_NONINT|SEVAL_NOHIST));
-
-#if !defined (HAVE_DEV_FD)
-  /* Make sure we close the named pipe in the child before we exit. */
-  close (open_for_read_in_child ? 0 : 1);
-#endif /* !HAVE_DEV_FD */
-
-  exit (result);
-  /*NOTREACHED*/
-}
-#endif /* PROCESS_SUBSTITUTION */
-
-/***********************************/
-/*                                */
-/*     Command Substitution       */
-/*                                */
-/***********************************/
-
-static char *
-read_comsub (fd, quoted, rflag)
-     int fd, quoted;
-     int *rflag;
-{
-  char *istring, buf[128], *bufp, *s;
-  int istring_index, istring_size, c, tflag, skip_ctlesc, skip_ctlnul;
-  ssize_t bufn;
-
-  istring = (char *)NULL;
-  istring_index = istring_size = bufn = tflag = 0;
-
-  for (skip_ctlesc = skip_ctlnul = 0, s = ifs_value; s && *s; s++)
-    skip_ctlesc |= *s == CTLESC, skip_ctlnul |= *s == CTLNUL;
-
-#ifdef __CYGWIN__
-  setmode (fd, O_TEXT);                /* we don't want CR/LF, we want Unix-style */
-#endif
-
-  /* Read the output of the command through the pipe.  This may need to be
-     changed to understand multibyte characters in the future. */
-  while (1)
-    {
-      if (fd < 0)
-       break;
-      if (--bufn <= 0)
-       {
-         bufn = zread (fd, buf, sizeof (buf));
-         if (bufn <= 0) 
-           break;
-         bufp = buf;
-       }
-      c = *bufp++;
-
-      if (c == 0)
-       {
-#if 0
-         internal_warning ("read_comsub: ignored null byte in input");
-#endif
-         continue;
-       }
-
-      /* Add the character to ISTRING, possibly after resizing it. */
-      RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE);
-
-      /* This is essentially quote_string inline */
-      if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) /* || c == CTLESC || c == CTLNUL */)
-       istring[istring_index++] = CTLESC;
-      /* Escape CTLESC and CTLNUL in the output to protect those characters
-        from the rest of the word expansions (word splitting and globbing.)
-        This is essentially quote_escapes inline. */
-      else if (skip_ctlesc == 0 && c == CTLESC)
-       {
-         tflag |= W_HASCTLESC;
-         istring[istring_index++] = CTLESC;
-       }
-      else if ((skip_ctlnul == 0 && c == CTLNUL) || (c == ' ' && (ifs_value && *ifs_value == 0)))
-       istring[istring_index++] = CTLESC;
-
-      istring[istring_index++] = c;
-
-#if 0
-#if defined (__CYGWIN__)
-      if (c == '\n' && istring_index > 1 && istring[istring_index - 2] == '\r')
-       {
-         istring_index--;
-         istring[istring_index - 1] = '\n';
-       }
-#endif
-#endif
-    }
-
-  if (istring)
-    istring[istring_index] = '\0';
-
-  /* If we read no output, just return now and save ourselves some
-     trouble. */
-  if (istring_index == 0)
-    {
-      FREE (istring);
-      if (rflag)
-       *rflag = tflag;
-      return (char *)NULL;
-    }
-
-  /* Strip trailing newlines from the output of the command. */
-  if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-    {
-      while (istring_index > 0)
-       {
-         if (istring[istring_index - 1] == '\n')
-           {
-             --istring_index;
-
-             /* If the newline was quoted, remove the quoting char. */
-             if (istring[istring_index - 1] == CTLESC)
-               --istring_index;
-           }
-         else
-           break;
-       }
-      istring[istring_index] = '\0';
-    }
-  else
-    strip_trailing (istring, istring_index - 1, 1);
-
-  if (rflag)
-    *rflag = tflag;
-  return istring;
-}
-
-/* Perform command substitution on STRING.  This returns a WORD_DESC * with the
-   contained string possibly quoted. */
-WORD_DESC *
-command_substitute (string, quoted)
-     char *string;
-     int quoted;
-{
-  pid_t pid, old_pid, old_pipeline_pgrp, old_async_pid;
-  char *istring;
-  int result, fildes[2], function_value, pflags, rc, tflag;
-  WORD_DESC *ret;
-
-  istring = (char *)NULL;
-
-  /* Don't fork () if there is no need to.  In the case of no command to
-     run, just return NULL. */
-  if (!string || !*string || (string[0] == '\n' && !string[1]))
-    return ((WORD_DESC *)NULL);
-
-  if (wordexp_only && read_but_dont_execute)
-    {
-      last_command_exit_value = 125;
-      jump_to_top_level (EXITPROG);
-    }
-
-  /* We're making the assumption here that the command substitution will
-     eventually run a command from the file system.  Since we'll run
-     maybe_make_export_env in this subshell before executing that command,
-     the parent shell and any other shells it starts will have to remake
-     the environment.  If we make it before we fork, other shells won't
-     have to.  Don't bother if we have any temporary variable assignments,
-     though, because the export environment will be remade after this
-     command completes anyway, but do it if all the words to be expanded
-     are variable assignments. */
-  if (subst_assign_varlist == 0 || garglist == 0)
-    maybe_make_export_env ();  /* XXX */
-
-  /* Flags to pass to parse_and_execute() */
-  pflags = interactive ? SEVAL_RESETLINE : 0;
-
-  /* Pipe the output of executing STRING into the current shell. */
-  if (pipe (fildes) < 0)
-    {
-      sys_error (_("cannot make pipe for command substitution"));
-      goto error_exit;
-    }
-
-  old_pid = last_made_pid;
-#if defined (JOB_CONTROL)
-  old_pipeline_pgrp = pipeline_pgrp;
-  /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
-  if ((subshell_environment & SUBSHELL_PIPE) == 0)
-    pipeline_pgrp = shell_pgrp;
-  cleanup_the_pipeline ();
-#endif /* JOB_CONTROL */
-
-  old_async_pid = last_asynchronous_pid;
-  pid = make_child ((char *)NULL, subshell_environment&SUBSHELL_ASYNC);
-  last_asynchronous_pid = old_async_pid;
-
-  if (pid == 0)
-    /* Reset the signal handlers in the child, but don't free the
-       trap strings. */
-    reset_signal_handlers ();
-
-#if defined (JOB_CONTROL)
-  /* XXX DO THIS ONLY IN PARENT ? XXX */
-  set_sigchld_handler ();
-  stop_making_children ();
-  if (pid != 0)
-    pipeline_pgrp = old_pipeline_pgrp;
-#else
-  stop_making_children ();
-#endif /* JOB_CONTROL */
-
-  if (pid < 0)
-    {
-      sys_error (_("cannot make child for command substitution"));
-    error_exit:
-
-      FREE (istring);
-      close (fildes[0]);
-      close (fildes[1]);
-      return ((WORD_DESC *)NULL);
-    }
-
-  if (pid == 0)
-    {
-      set_sigint_handler ();   /* XXX */
-
-      free_pushed_string_input ();
-
-      if (dup2 (fildes[1], 1) < 0)
-       {
-         sys_error (_("command_substitute: cannot duplicate pipe as fd 1"));
-         exit (EXECUTION_FAILURE);
-       }
-
-      /* If standard output is closed in the parent shell
-        (such as after `exec >&-'), file descriptor 1 will be
-        the lowest available file descriptor, and end up in
-        fildes[0].  This can happen for stdin and stderr as well,
-        but stdout is more important -- it will cause no output
-        to be generated from this command. */
-      if ((fildes[1] != fileno (stdin)) &&
-         (fildes[1] != fileno (stdout)) &&
-         (fildes[1] != fileno (stderr)))
-       close (fildes[1]);
-
-      if ((fildes[0] != fileno (stdin)) &&
-         (fildes[0] != fileno (stdout)) &&
-         (fildes[0] != fileno (stderr)))
-       close (fildes[0]);
-
-      /* The currently executing shell is not interactive. */
-      interactive = 0;
-
-      /* This is a subshell environment. */
-      subshell_environment |= SUBSHELL_COMSUB;
-
-      /* When not in POSIX mode, command substitution does not inherit
-        the -e flag. */
-      if (posixly_correct == 0)
-       exit_immediately_on_error = 0;
-
-      remove_quoted_escapes (string);
-
-      startup_state = 2;       /* see if we can avoid a fork */
-      /* Give command substitution a place to jump back to on failure,
-        so we don't go back up to main (). */
-      result = setjmp (top_level);
-
-      /* If we're running a command substitution inside a shell function,
-        trap `return' so we don't return from the function in the subshell
-        and go off to never-never land. */
-      if (result == 0 && return_catch_flag)
-       function_value = setjmp (return_catch);
-      else
-       function_value = 0;
-
-      if (result == ERREXIT)
-       rc = last_command_exit_value;
-      else if (result == EXITPROG)
-       rc = last_command_exit_value;
-      else if (result)
-       rc = EXECUTION_FAILURE;
-      else if (function_value)
-       rc = return_catch_value;
-      else
-       {
-         subshell_level++;
-         rc = parse_and_execute (string, "command substitution", pflags|SEVAL_NOHIST);
-         subshell_level--;
-       }
-
-      last_command_exit_value = rc;
-      rc = run_exit_trap ();
-#if defined (PROCESS_SUBSTITUTION)
-      unlink_fifo_list ();
-#endif
-      exit (rc);
-    }
-  else
-    {
-#if defined (JOB_CONTROL) && defined (PGRP_PIPE)
-      close_pgrp_pipe ();
-#endif /* JOB_CONTROL && PGRP_PIPE */
-
-      close (fildes[1]);
-
-      tflag = 0;
-      istring = read_comsub (fildes[0], quoted, &tflag);
-
-      close (fildes[0]);
-
-      current_command_subst_pid = pid;
-      last_command_exit_value = wait_for (pid);
-      last_command_subst_pid = pid;
-      last_made_pid = old_pid;
-
-#if defined (JOB_CONTROL)
-      /* If last_command_exit_value > 128, then the substituted command
-        was terminated by a signal.  If that signal was SIGINT, then send
-        SIGINT to ourselves.  This will break out of loops, for instance. */
-      if (last_command_exit_value == (128 + SIGINT) && last_command_exit_signal == SIGINT)
-       kill (getpid (), SIGINT);
-
-      /* wait_for gives the terminal back to shell_pgrp.  If some other
-        process group should have it, give it away to that group here.
-        pipeline_pgrp is non-zero only while we are constructing a
-        pipline, so what we are concerned about is whether or not that
-        pipeline was started in the background.  A pipeline started in
-        the background should never get the tty back here. */
-#if 0
-      if (interactive && pipeline_pgrp != (pid_t)0 && pipeline_pgrp != last_asynchronous_pid)
-#else
-      if (interactive && pipeline_pgrp != (pid_t)0 && (subshell_environment & SUBSHELL_ASYNC) == 0)
-#endif
-       give_terminal_to (pipeline_pgrp, 0);
-#endif /* JOB_CONTROL */
-
-      ret = alloc_word_desc ();
-      ret->word = istring;
-      ret->flags = tflag;
-
-      return ret;
-    }
-}
-
-/********************************************************
- *                                                     *
- *     Utility functions for parameter expansion       *
- *                                                     *
- ********************************************************/
-
-#if defined (ARRAY_VARS)
-
-static arrayind_t
-array_length_reference (s)
-     char *s;
-{
-  int len;
-  arrayind_t ind;
-  char *akey;
-  char *t, c;
-  ARRAY *array;
-  SHELL_VAR *var;
-
-  var = array_variable_part (s, &t, &len);
-
-  /* If unbound variables should generate an error, report one and return
-     failure. */
-  if ((var == 0 || (assoc_p (var) == 0 && array_p (var) == 0)) && unbound_vars_is_error)
-    {
-      c = *--t;
-      *t = '\0';
-      err_unboundvar (s);
-      *t = c;
-      return (-1);
-    }
-  else if (var == 0)
-    return 0;
-
-  /* We support a couple of expansions for variables that are not arrays.
-     We'll return the length of the value for v[0], and 1 for v[@] or
-     v[*].  Return 0 for everything else. */
-
-  array = array_p (var) ? array_cell (var) : (ARRAY *)NULL;
-
-  if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']')
-    {
-      if (assoc_p (var))
-       return (assoc_num_elements (assoc_cell (var)));
-      else if (array_p (var))
-       return (array_num_elements (array));
-      else
-       return 1;
-    }
-
-  if (assoc_p (var))
-    {
-      t[len - 1] = '\0';
-      akey = expand_assignment_string_to_string (t, 0);        /* [ */
-      t[len - 1] = ']';
-      if (akey == 0 || *akey == 0)
-       {
-         err_badarraysub (t);
-         return (-1);
-       }
-      t = assoc_reference (assoc_cell (var), akey);
-    }
-  else
-    {
-      ind = array_expand_index (t, len);
-      if (ind < 0)
-       {
-         err_badarraysub (t);
-         return (-1);
-       }
-      if (array_p (var))
-       t = array_reference (array, ind);
-      else
-       t = (ind == 0) ? value_cell (var) : (char *)NULL;
-    }
-
-  len = MB_STRLEN (t);
-  return (len);
-}
-#endif /* ARRAY_VARS */
-
-static int
-valid_brace_expansion_word (name, var_is_special)
-     char *name;
-     int var_is_special;
-{
-  if (DIGIT (*name) && all_digits (name))
-    return 1;
-  else if (var_is_special)
-    return 1;
-#if defined (ARRAY_VARS)
-  else if (valid_array_reference (name))
-    return 1;
-#endif /* ARRAY_VARS */
-  else if (legal_identifier (name))
-    return 1;
-  else
-    return 0;
-}
-
-static int
-chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at)
-     char *name;
-     int quoted;
-     int *quoted_dollar_atp, *contains_dollar_at;
-{
-  char *temp1;
-
-  if (name == 0)
-    {
-      if (quoted_dollar_atp)
-       *quoted_dollar_atp = 0;
-      if (contains_dollar_at)
-       *contains_dollar_at = 0;
-      return 0;
-    }
-
-  /* check for $@ and $* */
-  if (name[0] == '@' && name[1] == 0)
-    {
-      if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-       *quoted_dollar_atp = 1;
-      if (contains_dollar_at)
-       *contains_dollar_at = 1;
-      return 1;
-    }
-  else if (name[0] == '*' && name[1] == '\0' && quoted == 0)
-    {
-      if (contains_dollar_at)
-       *contains_dollar_at = 1;
-      return 1;
-    }
-
-  /* Now check for ${array[@]} and ${array[*]} */
-#if defined (ARRAY_VARS)
-  else if (valid_array_reference (name))
-    {
-      temp1 = xstrchr (name, '[');
-      if (temp1 && temp1[1] == '@' && temp1[2] == ']')
-       {
-         if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-           *quoted_dollar_atp = 1;
-         if (contains_dollar_at)
-           *contains_dollar_at = 1;
-         return 1;
-       }       /* [ */
-      /* ${array[*]}, when unquoted, should be treated like ${array[@]},
-        which should result in separate words even when IFS is unset. */
-      if (temp1 && temp1[1] == '*' && temp1[2] == ']' && quoted == 0)
-       {
-         if (contains_dollar_at)
-           *contains_dollar_at = 1;
-         return 1;
-       }
-    }
-#endif
-  return 0;
-}
-
-/* Parameter expand NAME, and return a new string which is the expansion,
-   or NULL if there was no expansion.
-   VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
-   the shell, e.g., "@", "$", "*", etc.  QUOTED, if non-zero, means that
-   NAME was found inside of a double-quoted expression. */
-static WORD_DESC *
-parameter_brace_expand_word (name, var_is_special, quoted, pflags)
-     char *name;
-     int var_is_special, quoted, pflags;
-{
-  WORD_DESC *ret;
-  char *temp, *tt;
-  intmax_t arg_index;
-  SHELL_VAR *var;
-  int atype, rflags;
-
-  ret = 0;
-  temp = 0;
-  rflags = 0;
-
-  /* Handle multiple digit arguments, as in ${11}. */  
-  if (legal_number (name, &arg_index))
-    {
-      tt = get_dollar_var_value (arg_index);
-      if (tt)
-       temp = (*tt && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-                 ? quote_string (tt)
-                 : quote_escapes (tt);
-      else
-        temp = (char *)NULL;
-      FREE (tt);
-    }
-  else if (var_is_special)      /* ${@} */
-    {
-      int sindex;
-      tt = (char *)xmalloc (2 + strlen (name));
-      tt[sindex = 0] = '$';
-      strcpy (tt + 1, name);
-
-      ret = param_expand (tt, &sindex, quoted, (int *)NULL, (int *)NULL,
-                         (int *)NULL, (int *)NULL, pflags);
-      free (tt);
-    }
-#if defined (ARRAY_VARS)
-  else if (valid_array_reference (name))
-    {
-      temp = array_value (name, quoted, &atype);
-      if (atype == 0 && temp)
-       temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-                 ? quote_string (temp)
-                 : quote_escapes (temp);
-      else if (atype == 1 && temp && QUOTED_NULL (temp) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-       rflags |= W_HASQUOTEDNULL;
-    }
-#endif
-  else if (var = find_variable (name))
-    {
-      if (var_isset (var) && invisible_p (var) == 0)
-       {
-#if defined (ARRAY_VARS)
-         if (assoc_p (var))
-           temp = assoc_reference (assoc_cell (var), "0");
-         else if (array_p (var))
-           temp = array_reference (array_cell (var), 0);
-         else
-           temp = value_cell (var);
-#else
-         temp = value_cell (var);
-#endif
-
-         if (temp)
-           temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-                     ? quote_string (temp)
-                     : quote_escapes (temp);
-       }
-      else
-       temp = (char *)NULL;
-    }
-  else
-    temp = (char *)NULL;
-
-  if (ret == 0)
-    {
-      ret = alloc_word_desc ();
-      ret->word = temp;
-      ret->flags |= rflags;
-    }
-  return ret;
-}
-
-/* Expand an indirect reference to a variable: ${!NAME} expands to the
-   value of the variable whose name is the value of NAME. */
-static WORD_DESC *
-parameter_brace_expand_indir (name, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at)
-     char *name;
-     int var_is_special, quoted;
-     int *quoted_dollar_atp, *contains_dollar_at;
-{
-  char *temp, *t;
-  WORD_DESC *w;
-
-  w = parameter_brace_expand_word (name, var_is_special, quoted, PF_IGNUNBOUND);
-  t = w->word;
-  /* Have to dequote here if necessary */
-  if (t)
-    {
-      temp = (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
-               ? dequote_string (t)
-               : dequote_escapes (t);
-      free (t);
-      t = temp;
-    }
-  dispose_word_desc (w);
-
-  chk_atstar (t, quoted, quoted_dollar_atp, contains_dollar_at);
-  if (t == 0)
-    return (WORD_DESC *)NULL;
-
-  w = parameter_brace_expand_word (t, SPECIAL_VAR(t, 0), quoted, 0);
-  free (t);
-
-  return w;
-}
-
-/* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
-   depending on the value of C, the separating character.  C can be one of
-   "-", "+", or "=".  QUOTED is true if the entire brace expression occurs
-   between double quotes. */
-static WORD_DESC *
-parameter_brace_expand_rhs (name, value, c, quoted, qdollaratp, hasdollarat)
-     char *name, *value;
-     int c, quoted, *qdollaratp, *hasdollarat;
-{
-  WORD_DESC *w;
-  WORD_LIST *l;
-  char *t, *t1, *temp;
-  int hasdol;
-
-  /* If the entire expression is between double quotes, we want to treat
-     the value as a double-quoted string, with the exception that we strip
-     embedded unescaped double quotes (for sh backwards compatibility). */
-  if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *value)
-    {
-      hasdol = 0;
-      temp = string_extract_double_quoted (value, &hasdol, 1);
-    }
-  else
-    temp = value;
-
-  w = alloc_word_desc ();
-  hasdol = 0;
-  /* XXX was 0 not quoted */
-  l = *temp ? expand_string_for_rhs (temp, quoted, &hasdol, (int *)NULL)
-           : (WORD_LIST *)0;
-  if (hasdollarat)
-    *hasdollarat = hasdol || (l && l->next);
-  if (temp != value)
-    free (temp);
-  if (l)
-    {
-      /* The expansion of TEMP returned something.  We need to treat things
-         slightly differently if HASDOL is non-zero.  If we have "$@", the
-         individual words have already been quoted.  We need to turn them
-         into a string with the words separated by the first character of
-         $IFS without any additional quoting, so string_list_dollar_at won't
-         do the right thing.  We use string_list_dollar_star instead. */
-      temp = (hasdol || l->next) ? string_list_dollar_star (l) : string_list (l);
-
-      /* If l->next is not null, we know that TEMP contained "$@", since that
-        is the only expansion that creates more than one word. */
-      if (qdollaratp && ((hasdol && quoted) || l->next))
-       *qdollaratp = 1;
-      dispose_words (l);
-    }
-  else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && hasdol)
-    {
-      /* The brace expansion occurred between double quotes and there was
-        a $@ in TEMP.  It does not matter if the $@ is quoted, as long as
-        it does not expand to anything.  In this case, we want to return
-        a quoted empty string. */
-      temp = make_quoted_char ('\0');
-      w->flags |= W_HASQUOTEDNULL;
-    }
-  else
-    temp = (char *)NULL;
-
-  if (c == '-' || c == '+')
-    {
-      w->word = temp;
-      return w;
-    }
-
-  /* c == '=' */
-  t = temp ? savestring (temp) : savestring ("");
-  t1 = dequote_string (t);
-  free (t);
-#if defined (ARRAY_VARS)
-  if (valid_array_reference (name))
-    assign_array_element (name, t1, 0);
-  else
-#endif /* ARRAY_VARS */
-  bind_variable (name, t1, 0);
-  free (t1);
-
-  w->word = temp;
-  return w;
-}
-
-/* Deal with the right hand side of a ${name:?value} expansion in the case
-   that NAME is null or not set.  If VALUE is non-null it is expanded and
-   used as the error message to print, otherwise a standard message is
-   printed. */
-static void
-parameter_brace_expand_error (name, value)
-     char *name, *value;
-{
-  WORD_LIST *l;
-  char *temp;
-
-  if (value && *value)
-    {
-      l = expand_string (value, 0);
-      temp =  string_list (l);
-      report_error ("%s: %s", name, temp ? temp : ""); /* XXX was value not "" */
-      FREE (temp);
-      dispose_words (l);
-    }
-  else
-    report_error (_("%s: parameter null or not set"), name);
-
-  /* Free the data we have allocated during this expansion, since we
-     are about to longjmp out. */
-  free (name);
-  FREE (value);
-}
-
-/* Return 1 if NAME is something for which parameter_brace_expand_length is
-   OK to do. */
-static int
-valid_length_expression (name)
-     char *name;
-{
-  return (name[1] == '\0' ||                                   /* ${#} */
-         ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0') ||  /* special param */
-         (DIGIT (name[1]) && all_digits (name + 1)) || /* ${#11} */
-#if defined (ARRAY_VARS)
-         valid_array_reference (name + 1) ||                   /* ${#a[7]} */
-#endif
-         legal_identifier (name + 1));                         /* ${#PS1} */
-}
-
-#if defined (HANDLE_MULTIBYTE)
-size_t
-mbstrlen (s)
-     const char *s;
-{
-  size_t clen, nc;
-  mbstate_t mbs, mbsbak;
-
-  nc = 0;
-  memset (&mbs, 0, sizeof (mbs));
-  mbsbak = mbs;
-  while ((clen = mbrlen(s, MB_CUR_MAX, &mbs)) != 0)
-    {
-      if (MB_INVALIDCH(clen))
-        {
-         clen = 1;     /* assume single byte */
-         mbs = mbsbak;
-        }
-
-      s += clen;
-      nc++;
-      mbsbak = mbs;
-    }
-  return nc;
-}
-#endif
-      
-
-/* Handle the parameter brace expansion that requires us to return the
-   length of a parameter. */
-static intmax_t
-parameter_brace_expand_length (name)
-     char *name;
-{
-  char *t, *newname;
-  intmax_t number, arg_index;
-  WORD_LIST *list;
-#if defined (ARRAY_VARS)
-  SHELL_VAR *var;
-#endif
-
-  if (name[1] == '\0')                 /* ${#} */
-    number = number_of_args ();
-  else if ((name[1] == '@' || name[1] == '*') && name[2] == '\0')      /* ${#@}, ${#*} */
-    number = number_of_args ();
-  else if ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0')
-    {
-      /* Take the lengths of some of the shell's special parameters. */
-      switch (name[1])
-       {
-       case '-':
-         t = which_set_flags ();
-         break;
-       case '?':
-         t = itos (last_command_exit_value);
-         break;
-       case '$':
-         t = itos (dollar_dollar_pid);
-         break;
-       case '!':
-         if (last_asynchronous_pid == NO_PID)
-           t = (char *)NULL;
-         else
-           t = itos (last_asynchronous_pid);
-         break;
-       case '#':
-         t = itos (number_of_args ());
-         break;
-       }
-      number = STRLEN (t);
-      FREE (t);
-    }
-#if defined (ARRAY_VARS)
-  else if (valid_array_reference (name + 1))
-    number = array_length_reference (name + 1);
-#endif /* ARRAY_VARS */
-  else
-    {
-      number = 0;
-
-      if (legal_number (name + 1, &arg_index))         /* ${#1} */
-       {
-         t = get_dollar_var_value (arg_index);
-         number = MB_STRLEN (t);
-         FREE (t);
-       }
-#if defined (ARRAY_VARS)
-      else if ((var = find_variable (name + 1)) && (invisible_p (var) == 0) && (array_p (var) || assoc_p (var)))
-       {
-         if (assoc_p (var))
-           t = assoc_reference (assoc_cell (var), "0");
-         else
-           t = array_reference (array_cell (var), 0);
-         number = MB_STRLEN (t);
-       }
-#endif
-      else                             /* ${#PS1} */
-       {
-         newname = savestring (name);
-         newname[0] = '$';
-         list = expand_string (newname, Q_DOUBLE_QUOTES);
-         t = list ? string_list (list) : (char *)NULL;
-         free (newname);
-         if (list)
-           dispose_words (list);
-
-         number = MB_STRLEN (t);
-         FREE (t);
-       }
-    }
-
-  return (number);
-}
-
-/* Skip characters in SUBSTR until DELIM.  SUBSTR is an arithmetic expression,
-   so we do some ad-hoc parsing of an arithmetic expression to find
-   the first DELIM, instead of using strchr(3).  Two rules:
-       1.  If the substring contains a `(', read until closing `)'.
-       2.  If the substring contains a `?', read past one `:' for each `?'.
-*/
-
-static char *
-skiparith (substr, delim)
-     char *substr;
-     int delim;
-{
-  size_t sublen;
-  int skipcol, pcount, i;
-  DECLARE_MBSTATE;
-
-  sublen = strlen (substr);
-  i = skipcol = pcount = 0;
-  while (substr[i])
-    {
-      /* Balance parens */
-      if (substr[i] == LPAREN)
-       {
-         pcount++;
-         i++;
-         continue;
-       }
-      if (substr[i] == RPAREN && pcount)
-       {
-         pcount--;
-         i++;
-         continue;
-       }
-      if (pcount)
-       {
-         ADVANCE_CHAR (substr, sublen, i);
-         continue;
-       }
-
-      /* Skip one `:' for each `?' */
-      if (substr[i] == ':' && skipcol)
-       {
-         skipcol--;
-         i++;
-         continue;
-       }
-      if (substr[i] == delim)
-       break;
-      if (substr[i] == '?')
-       {
-         skipcol++;
-         i++;
-         continue;
-       }
-      ADVANCE_CHAR (substr, sublen, i);
-    }
-
-  return (substr + i);
-}
-
-/* Verify and limit the start and end of the desired substring.  If
-   VTYPE == 0, a regular shell variable is being used; if it is 1,
-   then the positional parameters are being used; if it is 2, then
-   VALUE is really a pointer to an array variable that should be used.
-   Return value is 1 if both values were OK, 0 if there was a problem
-   with an invalid expression, or -1 if the values were out of range. */
-static int
-verify_substring_values (v, value, substr, vtype, e1p, e2p)
-     SHELL_VAR *v;
-     char *value, *substr;
-     int vtype;
-     intmax_t *e1p, *e2p;
-{
-  char *t, *temp1, *temp2;
-  arrayind_t len;
-  int expok;
-#if defined (ARRAY_VARS)
- ARRAY *a;
- HASH_TABLE *h;
-#endif
-
-  /* duplicate behavior of strchr(3) */
-  t = skiparith (substr, ':');
-  if (*t && *t == ':')
-    *t = '\0';
-  else
-    t = (char *)0;
-
-  temp1 = expand_arith_string (substr, Q_DOUBLE_QUOTES);
-  *e1p = evalexp (temp1, &expok);
-  free (temp1);
-  if (expok == 0)
-    return (0);
-
-  len = -1;    /* paranoia */
-  switch (vtype)
-    {
-    case VT_VARIABLE:
-    case VT_ARRAYMEMBER:
-      len = MB_STRLEN (value);
-      break;
-    case VT_POSPARMS:
-      len = number_of_args () + 1;
-      if (*e1p == 0)
-       len++;          /* add one arg if counting from $0 */
-      break;
-#if defined (ARRAY_VARS)
-    case VT_ARRAYVAR:
-      /* For arrays, the first value deals with array indices.  Negative
-        offsets count from one past the array's maximum index.  Associative
-        arrays treat the number of elements as the maximum index. */
-      if (assoc_p (v))
-       {
-         h = assoc_cell (v);
-         len = assoc_num_elements (h) + (*e1p < 0);
-       }
-      else
-       {
-         a = (ARRAY *)value;
-         len = array_max_index (a) + (*e1p < 0);       /* arrays index from 0 to n - 1 */
-       }
-      break;
-#endif
-    }
-
-  if (len == -1)       /* paranoia */
-    return -1;
-
-  if (*e1p < 0)                /* negative offsets count from end */
-    *e1p += len;
-
-  if (*e1p > len || *e1p < 0)
-    return (-1);
-
-#if defined (ARRAY_VARS)
-  /* For arrays, the second offset deals with the number of elements. */
-  if (vtype == VT_ARRAYVAR)
-    len = assoc_p (v) ? assoc_num_elements (h) : array_num_elements (a);
-#endif
-
-  if (t)
-    {
-      t++;
-      temp2 = savestring (t);
-      temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES);
-      free (temp2);
-      t[-1] = ':';
-      *e2p = evalexp (temp1, &expok);
-      free (temp1);
-      if (expok == 0)
-       return (0);
-      if (*e2p < 0)
-       {
-         internal_error (_("%s: substring expression < 0"), t);
-         return (0);
-       }
-#if defined (ARRAY_VARS)
-      /* In order to deal with sparse arrays, push the intelligence about how
-        to deal with the number of elements desired down to the array-
-        specific functions.  */
-      if (vtype != VT_ARRAYVAR)
-#endif
-       {
-         *e2p += *e1p;         /* want E2 chars starting at E1 */
-         if (*e2p > len)
-           *e2p = len;
-       }
-    }
-  else
-    *e2p = len;
-
-  return (1);
-}
-
-/* Return the type of variable specified by VARNAME (simple variable,
-   positional param, or array variable).  Also return the value specified
-   by VARNAME (value of a variable or a reference to an array element).
-   If this returns VT_VARIABLE, the caller assumes that CTLESC and CTLNUL
-   characters in the value are quoted with CTLESC and takes appropriate
-   steps.  For convenience, *VALP is set to the dequoted VALUE. */
-static int
-get_var_and_type (varname, value, quoted, varp, valp)
-     char *varname, *value;
-     int quoted;
-     SHELL_VAR **varp;
-     char **valp;
-{
-  int vtype;
-  char *temp;
-#if defined (ARRAY_VARS)
-  SHELL_VAR *v;
-#endif
-
-  /* This sets vtype to VT_VARIABLE or VT_POSPARMS */
-  vtype = (varname[0] == '@' || varname[0] == '*') && varname[1] == '\0';
-  if (vtype == VT_POSPARMS && varname[0] == '*')
-    vtype |= VT_STARSUB;
-  *varp = (SHELL_VAR *)NULL;
-
-#if defined (ARRAY_VARS)
-  if (valid_array_reference (varname))
-    {
-      v = array_variable_part (varname, &temp, (int *)0);
-      if (v && (array_p (v) || assoc_p (v)))
-       { /* [ */
-         if (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']')
-           {
-             /* Callers have to differentiate betwen indexed and associative */
-             vtype = VT_ARRAYVAR;
-             if (temp[0] == '*')
-               vtype |= VT_STARSUB;
-             *valp = array_p (v) ? (char *)array_cell (v) : (char *)assoc_cell (v);
-           }
-         else
-           {
-             vtype = VT_ARRAYMEMBER;
-             *valp = array_value (varname, 1, (int *)NULL);
-           }
-         *varp = v;
-       }
-      else if (v && (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']'))
-       {
-         vtype = VT_VARIABLE;
-         *varp = v;
-         if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
-           *valp = dequote_string (value);
-         else
-           *valp = dequote_escapes (value);
-       }
-      else
-       {
-         vtype = VT_ARRAYMEMBER;
-         *varp = v;
-         *valp = array_value (varname, 1, (int *)NULL);
-       }
-    }
-  else if ((v = find_variable (varname)) && (invisible_p (v) == 0) && (assoc_p (v) || array_p (v)))
-    {
-      vtype = VT_ARRAYMEMBER;
-      *varp = v;
-      *valp = assoc_p (v) ? assoc_reference (assoc_cell (v), "0") : array_reference (array_cell (v), 0);
-    }
-  else
-#endif
-    {
-      if (value && vtype == VT_VARIABLE)
-       {
-         if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
-           *valp = dequote_string (value);
-         else
-           *valp = dequote_escapes (value);
-       }
-      else
-       *valp = value;
-    }
-
-  return vtype;
-}
-
-/******************************************************/
-/*                                                   */
-/* Functions to extract substrings of variable values */
-/*                                                   */
-/******************************************************/
-
-#if defined (HANDLE_MULTIBYTE)
-/* Character-oriented rather than strictly byte-oriented substrings.  S and
-   E, rather being strict indices into STRING, indicate character (possibly
-   multibyte character) positions that require calculation.
-   Used by the ${param:offset[:length]} expansion. */
-static char *
-mb_substring (string, s, e)
-     char *string;
-     int s, e;
-{
-  char *tt;
-  int start, stop, i, slen;
-  DECLARE_MBSTATE;
-
-  start = 0;
-  /* Don't need string length in ADVANCE_CHAR unless multibyte chars possible. */
-  slen = (MB_CUR_MAX > 1) ? STRLEN (string) : 0;
-
-  i = s;
-  while (string[start] && i--)
-    ADVANCE_CHAR (string, slen, start);
-  stop = start;
-  i = e - s;
-  while (string[stop] && i--)
-    ADVANCE_CHAR (string, slen, stop);
-  tt = substring (string, start, stop);
-  return tt;
-}
-#endif
-  
-/* Process a variable substring expansion: ${name:e1[:e2]}.  If VARNAME
-   is `@', use the positional parameters; otherwise, use the value of
-   VARNAME.  If VARNAME is an array variable, use the array elements. */
-
-static char *
-parameter_brace_substring (varname, value, substr, quoted)
-     char *varname, *value, *substr;
-     int quoted;
-{
-  intmax_t e1, e2;
-  int vtype, r, starsub;
-  char *temp, *val, *tt, *oname;
-  SHELL_VAR *v;
-
-  if (value == 0)
-    return ((char *)NULL);
-
-  oname = this_command_name;
-  this_command_name = varname;
-
-  vtype = get_var_and_type (varname, value, quoted, &v, &val);
-  if (vtype == -1)
-    {
-      this_command_name = oname;
-      return ((char *)NULL);
-    }
-
-  starsub = vtype & VT_STARSUB;
-  vtype &= ~VT_STARSUB;
-
-  r = verify_substring_values (v, val, substr, vtype, &e1, &e2);
-  this_command_name = oname;
-  if (r <= 0)
-    return ((r == 0) ? &expand_param_error : (char *)NULL);
-
-  switch (vtype)
-    {
-    case VT_VARIABLE:
-    case VT_ARRAYMEMBER:
-#if defined (HANDLE_MULTIBYTE)
-      if (MB_CUR_MAX > 1)
-       tt = mb_substring (val, e1, e2);
-      else
-#endif
-      tt = substring (val, e1, e2);
-
-      if (vtype == VT_VARIABLE)
-       FREE (val);
-      if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
-       temp = quote_string (tt);
-      else
-       temp = tt ? quote_escapes (tt) : (char *)NULL;
-      FREE (tt);
-      break;
-    case VT_POSPARMS:
-      tt = pos_params (varname, e1, e2, quoted);
-      if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
-       {
-         temp = tt ? quote_escapes (tt) : (char *)NULL;
-         FREE (tt);
-       }
-      else
-       temp = tt;
-      break;
-#if defined (ARRAY_VARS)
-    case VT_ARRAYVAR:
-      if (assoc_p (v))
-       /* we convert to list and take first e2 elements starting at e1th
-          element -- officially undefined for now */   
-       temp = assoc_subrange (assoc_cell (v), e1, e2, starsub, quoted);
-      else
-      /* We want E2 to be the number of elements desired (arrays can be sparse,
-        so verify_substring_values just returns the numbers specified and we
-        rely on array_subrange to understand how to deal with them). */
-       temp = array_subrange (array_cell (v), e1, e2, starsub, quoted);
-      /* array_subrange now calls array_quote_escapes as appropriate, so the
-        caller no longer needs to. */
-      break;
-#endif
-    default:
-      temp = (char *)NULL;
-    }
-
-  return temp;
-}
-
-/****************************************************************/
-/*                                                             */
-/* Functions to perform pattern substitution on variable values */
-/*                                                             */
-/****************************************************************/
-
-char *
-pat_subst (string, pat, rep, mflags)
-     char *string, *pat, *rep;
-     int mflags;
-{
-  char *ret, *s, *e, *str;
-  int rsize, rptr, l, replen, mtype;
-
-  mtype = mflags & MATCH_TYPEMASK;
-
-  /* Special cases:
-   *   1.  A null pattern with mtype == MATCH_BEG means to prefix STRING
-   *       with REP and return the result.
-   *   2.  A null pattern with mtype == MATCH_END means to append REP to
-   *       STRING and return the result.
-   */
-  if ((pat == 0 || *pat == 0) && (mtype == MATCH_BEG || mtype == MATCH_END))
-    {
-      replen = STRLEN (rep);
-      l = strlen (string);
-      ret = (char *)xmalloc (replen + l + 2);
-      if (replen == 0)
-       strcpy (ret, string);
-      else if (mtype == MATCH_BEG)
-       {
-         strcpy (ret, rep);
-         strcpy (ret + replen, string);
-       }
-      else
-       {
-         strcpy (ret, string);
-         strcpy (ret + l, rep);
-       }
-      return (ret);
-    }
-
-  ret = (char *)xmalloc (rsize = 64);
-  ret[0] = '\0';
-
-  for (replen = STRLEN (rep), rptr = 0, str = string;;)
-    {
-      if (match_pattern (str, pat, mtype, &s, &e) == 0)
-       break;
-      l = s - str;
-      RESIZE_MALLOCED_BUFFER (ret, rptr, (l + replen), rsize, 64);
-
-      /* OK, now copy the leading unmatched portion of the string (from
-        str to s) to ret starting at rptr (the current offset).  Then copy
-        the replacement string at ret + rptr + (s - str).  Increment
-        rptr (if necessary) and str and go on. */
-      if (l)
-       {
-         strncpy (ret + rptr, str, l);
-         rptr += l;
-       }
-      if (replen)
-       {
-         strncpy (ret + rptr, rep, replen);
-         rptr += replen;
-       }
-      str = e;         /* e == end of match */
-
-      if (((mflags & MATCH_GLOBREP) == 0) || mtype != MATCH_ANY)
-       break;
-
-      if (s == e)
-       {
-         /* On a zero-length match, make sure we copy one character, since
-            we increment one character below to avoid infinite recursion. */
-         RESIZE_MALLOCED_BUFFER (ret, rptr, 1, rsize, 64);
-         strncpy (ret + rptr, str, 1);
-         rptr += 1;
-         e++, str++;           /* avoid infinite recursion on zero-length match */
-       }
-    }
-
-  /* Now copy the unmatched portion of the input string */
-  if (*str)
-    {
-      RESIZE_MALLOCED_BUFFER (ret, rptr, STRLEN(str) + 1, rsize, 64);
-      strcpy (ret + rptr, str);
-    }
-  else
-    ret[rptr] = '\0';
-
-  return ret;
-}
-
-/* Do pattern match and replacement on the positional parameters. */
-static char *
-pos_params_pat_subst (string, pat, rep, mflags)
-     char *string, *pat, *rep;
-     int mflags;
-{
-  WORD_LIST *save, *params;
-  WORD_DESC *w;
-  char *ret;
-  int pchar, qflags;
-
-  save = params = list_rest_of_args ();
-  if (save == 0)
-    return ((char *)NULL);
-
-  for ( ; params; params = params->next)
-    {
-      ret = pat_subst (params->word->word, pat, rep, mflags);
-      w = alloc_word_desc ();
-      w->word = ret ? ret : savestring ("");
-      dispose_word (params->word);
-      params->word = w;
-    }
-
-  pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@';
-  qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0;
-
-#if 0
-  if ((mflags & (MATCH_QUOTED|MATCH_STARSUB)) == (MATCH_QUOTED|MATCH_STARSUB))
-    ret = string_list_dollar_star (quote_list (save));
-  else if ((mflags & MATCH_STARSUB) == MATCH_STARSUB)
-    ret = string_list_dollar_star (save);
-  else if ((mflags & MATCH_QUOTED) == MATCH_QUOTED)
-    ret = string_list_dollar_at (save, qflags);
-  else
-    ret = string_list_dollar_star (save);
-#else
-  ret = string_list_pos_params (pchar, save, qflags);
-#endif
-
-  dispose_words (save);
-
-  return (ret);
-}
-
-/* Perform pattern substitution on VALUE, which is the expansion of
-   VARNAME.  PATSUB is an expression supplying the pattern to match
-   and the string to substitute.  QUOTED is a flags word containing
-   the type of quoting currently in effect. */
-static char *
-parameter_brace_patsub (varname, value, patsub, quoted)
-     char *varname, *value, *patsub;
-     int quoted;
-{
-  int vtype, mflags, starsub, delim;
-  char *val, *temp, *pat, *rep, *p, *lpatsub, *tt;
-  SHELL_VAR *v;
-
-  if (value == 0)
-    return ((char *)NULL);
-
-  this_command_name = varname;
-
-  vtype = get_var_and_type (varname, value, quoted, &v, &val);
-  if (vtype == -1)
-    return ((char *)NULL);
-
-  starsub = vtype & VT_STARSUB;
-  vtype &= ~VT_STARSUB;
-
-  mflags = 0;
-  if (patsub && *patsub == '/')
-    {
-      mflags |= MATCH_GLOBREP;
-      patsub++;
-    }
-
-  /* Malloc this because expand_string_if_necessary or one of the expansion
-     functions in its call chain may free it on a substitution error. */
-  lpatsub = savestring (patsub);
-
-  if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-    mflags |= MATCH_QUOTED;
-
-  if (starsub)
-    mflags |= MATCH_STARSUB;
-
-  /* If the pattern starts with a `/', make sure we skip over it when looking
-     for the replacement delimiter. */
-#if 0
-  if (rep = quoted_strchr ((*patsub == '/') ? lpatsub+1 : lpatsub, '/', ST_BACKSL))
-    *rep++ = '\0';
-  else
-    rep = (char *)NULL;
-#else
-  delim = skip_to_delim (lpatsub, ((*patsub == '/') ? 1 : 0), "/", 0);
-  if (lpatsub[delim] == '/')
-    {
-      lpatsub[delim] = 0;
-      rep = lpatsub + delim + 1;
-    }
-  else
-    rep = (char *)NULL;
-#endif
-
-  if (rep && *rep == '\0')
-    rep = (char *)NULL;
-
-  /* Perform the same expansions on the pattern as performed by the
-     pattern removal expansions. */
-  pat = getpattern (lpatsub, quoted, 1);
-
-  if (rep)
-    {
-      if ((mflags & MATCH_QUOTED) == 0)
-       rep = expand_string_if_necessary (rep, quoted, expand_string_unsplit);
-      else
-       rep = expand_string_to_string_internal (rep, quoted, expand_string_unsplit);
-    }
-
-  /* ksh93 doesn't allow the match specifier to be a part of the expanded
-     pattern.  This is an extension.  Make sure we don't anchor the pattern
-     at the beginning or end of the string if we're doing global replacement,
-     though. */
-  p = pat;
-  if (mflags & MATCH_GLOBREP)
-    mflags |= MATCH_ANY;
-  else if (pat && pat[0] == '#')
-    {
-      mflags |= MATCH_BEG;
-      p++;
-    }
-  else if (pat && pat[0] == '%')
-    {
-      mflags |= MATCH_END;
-      p++;
-    }
-  else
-    mflags |= MATCH_ANY;
-
-  /* OK, we now want to substitute REP for PAT in VAL.  If
-     flags & MATCH_GLOBREP is non-zero, the substitution is done
-     everywhere, otherwise only the first occurrence of PAT is
-     replaced.  The pattern matching code doesn't understand
-     CTLESC quoting CTLESC and CTLNUL so we use the dequoted variable
-     values passed in (VT_VARIABLE) so the pattern substitution
-     code works right.  We need to requote special chars after
-     we're done for VT_VARIABLE and VT_ARRAYMEMBER, and for the
-     other cases if QUOTED == 0, since the posparams and arrays
-     indexed by * or @ do special things when QUOTED != 0. */
-
-  switch (vtype)
-    {
-    case VT_VARIABLE:
-    case VT_ARRAYMEMBER:
-      temp = pat_subst (val, p, rep, mflags);
-      if (vtype == VT_VARIABLE)
-       FREE (val);
-      if (temp)
-       {
-         tt = (mflags & MATCH_QUOTED) ? quote_string (temp) : quote_escapes (temp);
-         free (temp);
-         temp = tt;
-       }
-      break;
-    case VT_POSPARMS:
-      temp = pos_params_pat_subst (val, p, rep, mflags);
-      if (temp && (mflags & MATCH_QUOTED) == 0)
-       {
-         tt = quote_escapes (temp);
-         free (temp);
-         temp = tt;
-       }
-      break;
-#if defined (ARRAY_VARS)
-    case VT_ARRAYVAR:
-      temp = assoc_p (v) ? assoc_patsub (assoc_cell (v), p, rep, mflags)
-                        : array_patsub (array_cell (v), p, rep, mflags);
-      /* Don't call quote_escapes anymore; array_patsub calls
-        array_quote_escapes as appropriate before adding the
-        space separators; ditto for assoc_patsub. */
-      break;
-#endif
-    }
-
-  FREE (pat);
-  FREE (rep);
-  free (lpatsub);
-
-  return temp;
-}
-
-/****************************************************************/
-/*                                                             */
-/*   Functions to perform case modification on variable values  */
-/*                                                             */
-/****************************************************************/
-
-/* Do case modification on the positional parameters. */
-
-static char *
-pos_params_modcase (string, pat, modop, mflags)
-     char *string, *pat;
-     int modop;
-     int mflags;
-{
-  WORD_LIST *save, *params;
-  WORD_DESC *w;
-  char *ret;
-  int pchar, qflags;
-
-  save = params = list_rest_of_args ();
-  if (save == 0)
-    return ((char *)NULL);
-
-  for ( ; params; params = params->next)
-    {
-      ret = sh_modcase (params->word->word, pat, modop);
-      w = alloc_word_desc ();
-      w->word = ret ? ret : savestring ("");
-      dispose_word (params->word);
-      params->word = w;
-    }
-
-  pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@';
-  qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0;
-
-  ret = string_list_pos_params (pchar, save, qflags);
-  dispose_words (save);
-
-  return (ret);
-}
-
-/* Perform case modification on VALUE, which is the expansion of
-   VARNAME.  MODSPEC is an expression supplying the type of modification
-   to perform.  QUOTED is a flags word containing the type of quoting
-   currently in effect. */
-static char *
-parameter_brace_casemod (varname, value, modspec, patspec, quoted)
-     char *varname, *value;
-     int modspec;
-     char *patspec;
-     int quoted;
-{
-  int vtype, starsub, modop, mflags, x;
-  char *val, *temp, *pat, *p, *lpat, *tt;
-  SHELL_VAR *v;
-
-  if (value == 0)
-    return ((char *)NULL);
-
-  this_command_name = varname;
-
-  vtype = get_var_and_type (varname, value, quoted, &v, &val);
-  if (vtype == -1)
-    return ((char *)NULL);
-
-  starsub = vtype & VT_STARSUB;
-  vtype &= ~VT_STARSUB;
-
-  modop = 0;
-  mflags = 0;
-  if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-    mflags |= MATCH_QUOTED;
-  if (starsub)
-    mflags |= MATCH_STARSUB;
-  
-  p = patspec;
-  if (modspec == '^')
-    {
-      x = p && p[0] == modspec;
-      modop = x ? CASE_UPPER : CASE_UPFIRST;
-      p += x;
-    }
-  else if (modspec == ',')
-    {
-      x = p && p[0] == modspec;
-      modop = x ? CASE_LOWER : CASE_LOWFIRST;
-      p += x;
-    }
-  else if (modspec == '~')
-    {
-      x = p && p[0] == modspec;
-      modop = x ? CASE_TOGGLEALL : CASE_TOGGLE;
-      p += x;
-    }
-    
-  lpat = p ? savestring (p) : 0;
-  /* Perform the same expansions on the pattern as performed by the
-     pattern removal expansions.  FOR LATER */
-  pat = lpat ? getpattern (lpat, quoted, 1) : 0;
-
-  /* OK, now we do the case modification. */
-  switch (vtype)
-    {
-    case VT_VARIABLE:
-    case VT_ARRAYMEMBER:
-      temp = sh_modcase (val, pat, modop);
-      if (vtype == VT_VARIABLE)
-       FREE (val);
-      if (temp)
-       {
-         tt = (mflags & MATCH_QUOTED) ? quote_string (temp) : quote_escapes (temp);
-         free (temp);
-         temp = tt;
-       }
-      break;
-
-    case VT_POSPARMS:
-      temp = pos_params_modcase (val, pat, modop, mflags);
-      if (temp && (mflags & MATCH_QUOTED)  == 0)
-       {
-         tt = quote_escapes (temp);
-         free (temp);
-         temp = tt;
-       }
-      break;
-
-#if defined (ARRAY_VARS)
-    case VT_ARRAYVAR:
-      temp = assoc_p (v) ? assoc_modcase (assoc_cell (v), pat, modop, mflags)
-                        : array_modcase (array_cell (v), pat, modop, mflags);
-      /* Don't call quote_escapes; array_modcase calls array_quote_escapes
-        as appropriate before adding the space separators; ditto for
-        assoc_modcase. */
-      break;
-#endif
-    }
-
-  FREE (pat);
-  free (lpat);
-
-  return temp;
-}
-
-/* Check for unbalanced parens in S, which is the contents of $(( ... )).  If
-   any occur, this must be a nested command substitution, so return 0.
-   Otherwise, return 1.  A valid arithmetic expression must always have a
-   ( before a matching ), so any cases where there are more right parens
-   means that this must not be an arithmetic expression, though the parser
-   will not accept it without a balanced total number of parens. */
-static int
-chk_arithsub (s, len)
-     const char *s;
-     int len;
-{
-  int i, count;
-  DECLARE_MBSTATE;
-
-  i = count = 0;
-  while (i < len)
-    {
-      if (s[i] == '(')
-       count++;
-      else if (s[i] == ')')
-       {
-         count--;
-         if (count < 0)
-           return 0;
-       }
-
-      switch (s[i])
-       {
-       default:
-         ADVANCE_CHAR (s, len, i);
-         break;
-
-       case '\\':
-         i++;
-         if (s[i])
-           ADVANCE_CHAR (s, len, i);
-         break;
-
-       case '\'':
-         i = skip_single_quoted (s, len, ++i);
-         break;
-
-       case '"':
-         i = skip_double_quoted ((char *)s, len, ++i);
-         break;
-       }
-    }
-
-  return (count == 0);
-}
-
-/****************************************************************/
-/*                                                             */
-/*     Functions to perform parameter expansion on a string    */
-/*                                                             */
-/****************************************************************/
-
-/* ${[#][!]name[[:][^[^]][,[,]]#[#]%[%]-=?+[word][:e1[:e2]]]} */
-static WORD_DESC *
-parameter_brace_expand (string, indexp, quoted, quoted_dollar_atp, contains_dollar_at)
-     char *string;
-     int *indexp, quoted, *quoted_dollar_atp, *contains_dollar_at;
-{
-  int check_nullness, var_is_set, var_is_null, var_is_special;
-  int want_substring, want_indir, want_patsub, want_casemod;
-  char *name, *value, *temp, *temp1;
-  WORD_DESC *tdesc, *ret;
-  int t_index, sindex, c, tflag, modspec;
-  intmax_t number;
-
-  temp = temp1 = value = (char *)NULL;
-  var_is_set = var_is_null = var_is_special = check_nullness = 0;
-  want_substring = want_indir = want_patsub = want_casemod = 0;
-
-  sindex = *indexp;
-  t_index = ++sindex;
-  /* ${#var} doesn't have any of the other parameter expansions on it. */
-  if (string[t_index] == '#' && legal_variable_starter (string[t_index+1]))            /* {{ */
-    name = string_extract (string, &t_index, "}", SX_VARNAME);
-  else
-#if defined (CASEMOD_EXPANSIONS)
-    /* To enable case-toggling expansions using the `~' operator character
-       change the 1 to 0. */
-#  if defined (CASEMOD_CAPCASE)
-    name = string_extract (string, &t_index, "#%^,~:-=?+/}", SX_VARNAME);
-#  else
-    name = string_extract (string, &t_index, "#%^,:-=?+/}", SX_VARNAME);
-#  endif /* CASEMOD_CAPCASE */
-#else
-    name = string_extract (string, &t_index, "#%:-=?+/}", SX_VARNAME);
-#endif /* CASEMOD_EXPANSIONS */
-
-  ret = 0;
-  tflag = 0;
-
-  /* If the name really consists of a special variable, then make sure
-     that we have the entire name.  We don't allow indirect references
-     to special variables except `#', `?', `@' and `*'. */
-  if ((sindex == t_index &&
-       (string[t_index] == '-' ||
-        string[t_index] == '?' ||
-        string[t_index] == '#')) ||
-      (sindex == t_index - 1 && string[sindex] == '!' &&
-       (string[t_index] == '#' ||
-        string[t_index] == '?' ||
-        string[t_index] == '@' ||
-        string[t_index] == '*')))
-    {
-      t_index++;
-      free (name);
-      temp1 = string_extract (string, &t_index, "#%:-=?+/}", 0);
-      name = (char *)xmalloc (3 + (strlen (temp1)));
-      *name = string[sindex];
-      if (string[sindex] == '!')
-       {
-         /* indirect reference of $#, $?, $@, or $* */
-         name[1] = string[sindex + 1];
-         strcpy (name + 2, temp1);
-       }
-      else     
-       strcpy (name + 1, temp1);
-      free (temp1);
-    }
-  sindex = t_index;
-
-  /* Find out what character ended the variable name.  Then
-     do the appropriate thing. */
-  if (c = string[sindex])
-    sindex++;
-
-  /* If c is followed by one of the valid parameter expansion
-     characters, move past it as normal.  If not, assume that
-     a substring specification is being given, and do not move
-     past it. */
-  if (c == ':' && VALID_PARAM_EXPAND_CHAR (string[sindex]))
-    {
-      check_nullness++;
-      if (c = string[sindex])
-       sindex++;
-    }
-  else if (c == ':' && string[sindex] != RBRACE)
-    want_substring = 1;
-  else if (c == '/' && string[sindex] != RBRACE)
-    want_patsub = 1;
-#if defined (CASEMOD_EXPANSIONS)
-  else if (c == '^' || c == ',' || c == '~')
-    {
-      modspec = c;
-      want_casemod = 1;
-    }
-#endif
-
-  /* Catch the valid and invalid brace expressions that made it through the
-     tests above. */
-  /* ${#-} is a valid expansion and means to take the length of $-.
-     Similarly for ${#?} and ${##}... */
-  if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
-       VALID_SPECIAL_LENGTH_PARAM (c) && string[sindex] == RBRACE)
-    {
-      name = (char *)xrealloc (name, 3);
-      name[1] = c;
-      name[2] = '\0';
-      c = string[sindex++];
-    }
-
-  /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */
-  if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
-       member (c, "%:=+/") && string[sindex] == RBRACE)
-    {
-      temp = (char *)NULL;
-      goto bad_substitution;
-    }
-
-  /* Indirect expansion begins with a `!'.  A valid indirect expansion is
-     either a variable name, one of the positional parameters or a special
-     variable that expands to one of the positional parameters. */
-  want_indir = *name == '!' &&
-    (legal_variable_starter ((unsigned char)name[1]) || DIGIT (name[1])
-                                       || VALID_INDIR_PARAM (name[1]));
-
-  /* Determine the value of this variable. */
-
-  /* Check for special variables, directly referenced. */
-  if (SPECIAL_VAR (name, want_indir))
-    var_is_special++;
-
-  /* Check for special expansion things, like the length of a parameter */
-  if (*name == '#' && name[1])
-    {
-      /* If we are not pointing at the character just after the
-        closing brace, then we haven't gotten all of the name.
-        Since it begins with a special character, this is a bad
-        substitution.  Also check NAME for validity before trying
-        to go on. */
-      if (string[sindex - 1] != RBRACE || (valid_length_expression (name) == 0))
-       {
-         temp = (char *)NULL;
-         goto bad_substitution;
-       }
-
-      number = parameter_brace_expand_length (name);
-      free (name);
-
-      *indexp = sindex;
-      if (number < 0)
-        return (&expand_wdesc_error);
-      else
-       {
-         ret = alloc_word_desc ();
-         ret->word = itos (number);
-         return ret;
-       }
-    }
-
-  /* ${@} is identical to $@. */
-  if (name[0] == '@' && name[1] == '\0')
-    {
-      if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-       *quoted_dollar_atp = 1;
-
-      if (contains_dollar_at)
-       *contains_dollar_at = 1;
-    }
-
-  /* Process ${!PREFIX*} expansion. */
-  if (want_indir && string[sindex - 1] == RBRACE &&
-      (string[sindex - 2] == '*' || string[sindex - 2] == '@') &&
-      legal_variable_starter ((unsigned char) name[1]))
-    {
-      char **x;
-      WORD_LIST *xlist;
-
-      temp1 = savestring (name + 1);
-      number = strlen (temp1);
-      temp1[number - 1] = '\0';
-      x = all_variables_matching_prefix (temp1);
-      xlist = strvec_to_word_list (x, 0, 0);
-      if (string[sindex - 2] == '*')
-       temp = string_list_dollar_star (xlist);
-      else
-       {
-         temp = string_list_dollar_at (xlist, quoted);
-         if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-           *quoted_dollar_atp = 1;
-         if (contains_dollar_at)
-           *contains_dollar_at = 1;
-       }
-      free (x);
-      free (xlist);
-      free (temp1);
-      *indexp = sindex;
-
-      ret = alloc_word_desc ();
-      ret->word = temp;
-      return ret;
-    }
-
-#if defined (ARRAY_VARS)      
-  /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */ /* [ */
-  if (want_indir && string[sindex - 1] == RBRACE &&
-      string[sindex - 2] == ']' && valid_array_reference (name+1))
-    {
-      char *x, *x1;
-
-      temp1 = savestring (name + 1);
-      x = array_variable_name (temp1, &x1, (int *)0);  /* [ */
-      FREE (x);
-      if (ALL_ELEMENT_SUB (x1[0]) && x1[1] == ']')
-       {
-         temp = array_keys (temp1, quoted);    /* handles assoc vars too */
-         if (x1[0] == '@')
-           {
-             if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-               *quoted_dollar_atp = 1;
-             if (contains_dollar_at)
-               *contains_dollar_at = 1;
-           }       
-
-         free (temp1);
-         *indexp = sindex;
-
-         ret = alloc_word_desc ();
-         ret->word = temp;
-         return ret;
-       }
-
-      free (temp1);
-    }
-#endif /* ARRAY_VARS */
-      
-  /* Make sure that NAME is valid before trying to go on. */
-  if (valid_brace_expansion_word (want_indir ? name + 1 : name,
-                                       var_is_special) == 0)
-    {
-      temp = (char *)NULL;
-      goto bad_substitution;
-    }
-
-  if (want_indir)
-    tdesc = parameter_brace_expand_indir (name + 1, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at);
-  else
-    tdesc = parameter_brace_expand_word (name, var_is_special, quoted, PF_IGNUNBOUND);
-
-  if (tdesc)
-    {
-      temp = tdesc->word;
-      tflag = tdesc->flags;
-      dispose_word_desc (tdesc);
-    }
-  else
-    temp = (char  *)0;
-
-#if defined (ARRAY_VARS)
-  if (valid_array_reference (name))
-    chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at);
-#endif
-
-  var_is_set = temp != (char *)0;
-  var_is_null = check_nullness && (var_is_set == 0 || *temp == 0);
-
-  /* Get the rest of the stuff inside the braces. */
-  if (c && c != RBRACE)
-    {
-      /* Extract the contents of the ${ ... } expansion
-        according to the Posix.2 rules. */
-      value = extract_dollar_brace_string (string, &sindex, quoted, 0);
-      if (string[sindex] == RBRACE)
-       sindex++;
-      else
-       goto bad_substitution;
-    }
-  else
-    value = (char *)NULL;
-
-  *indexp = sindex;
-
-  /* If this is a substring spec, process it and add the result. */
-  if (want_substring)
-    {
-      temp1 = parameter_brace_substring (name, temp, value, quoted);
-      FREE (name);
-      FREE (value);
-      FREE (temp);
-
-      if (temp1 == &expand_param_error)
-       return (&expand_wdesc_error);
-      else if (temp1 == &expand_param_fatal)
-       return (&expand_wdesc_fatal);
-
-      ret = alloc_word_desc ();
-      ret->word = temp1;
-      if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-       ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
-      return ret;
-    }
-  else if (want_patsub)
-    {
-      temp1 = parameter_brace_patsub (name, temp, value, quoted);
-      FREE (name);
-      FREE (value);
-      FREE (temp);
-
-      if (temp1 == &expand_param_error)
-       return (&expand_wdesc_error);
-      else if (temp1 == &expand_param_fatal)
-       return (&expand_wdesc_fatal);
-
-      ret = alloc_word_desc ();
-      ret->word = temp1;
-      ret = alloc_word_desc ();
-      ret->word = temp1;
-      if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-       ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
-      return ret;
-    }
-#if defined (CASEMOD_EXPANSIONS)
-  else if (want_casemod)
-    {
-      temp1 = parameter_brace_casemod (name, temp, modspec, value, quoted);
-      FREE (name);
-      FREE (value);
-      FREE (temp);
-
-      if (temp1 == &expand_param_error)
-       return (&expand_wdesc_error);
-      else if (temp1 == &expand_param_fatal)
-       return (&expand_wdesc_fatal);
-
-      ret = alloc_word_desc ();
-      ret->word = temp1;
-      if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-       ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
-      return ret;
-    }
-#endif
-
-  /* Do the right thing based on which character ended the variable name. */
-  switch (c)
-    {
-    default:
-    case '\0':
-    bad_substitution:
-      report_error (_("%s: bad substitution"), string ? string : "??");
-      FREE (value);
-      FREE (temp);
-      free (name);
-      return &expand_wdesc_error;
-
-    case RBRACE:
-      if (var_is_set == 0 && unbound_vars_is_error)
-       {
-         err_unboundvar (name);
-         FREE (value);
-         FREE (temp);
-         free (name);
-         last_command_exit_value = EXECUTION_FAILURE;
-         return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
-       }
-      break;
-
-    case '#':  /* ${param#[#]pattern} */
-    case '%':  /* ${param%[%]pattern} */
-      if (value == 0 || *value == '\0' || temp == 0 || *temp == '\0')
-       {
-         FREE (value);
-         break;
-       }
-      temp1 = parameter_brace_remove_pattern (name, temp, value, c, quoted);
-      free (temp);
-      free (value);
-
-      ret = alloc_word_desc ();
-      ret->word = temp1;
-      if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-       ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
-      return ret;
-
-    case '-':
-    case '=':
-    case '?':
-    case '+':
-      if (var_is_set && var_is_null == 0)
-       {
-         /* If the operator is `+', we don't want the value of the named
-            variable for anything, just the value of the right hand side. */
-
-         if (c == '+')
-           {
-             /* XXX -- if we're double-quoted and the named variable is "$@",
-                       we want to turn off any special handling of "$@" --
-                       we're not using it, so whatever is on the rhs applies. */
-             if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-               *quoted_dollar_atp = 0;
-             if (contains_dollar_at)
-               *contains_dollar_at = 0;
-
-             FREE (temp);
-             if (value)
-               {
-                 ret = parameter_brace_expand_rhs (name, value, c,
-                                                   quoted,
-                                                   quoted_dollar_atp,
-                                                   contains_dollar_at);
-                 /* XXX - fix up later, esp. noting presence of
-                          W_HASQUOTEDNULL in ret->flags */
-                 free (value);
-               }
-             else
-               temp = (char *)NULL;
-           }
-         else
-           {
-             FREE (value);
-           }
-         /* Otherwise do nothing; just use the value in TEMP. */
-       }
-      else     /* VAR not set or VAR is NULL. */
-       {
-         FREE (temp);
-         temp = (char *)NULL;
-         if (c == '=' && var_is_special)
-           {
-             report_error (_("$%s: cannot assign in this way"), name);
-             free (name);
-             free (value);
-             return &expand_wdesc_error;
-           }
-         else if (c == '?')
-           {
-             parameter_brace_expand_error (name, value);
-             return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
-           }
-         else if (c != '+')
-           {
-             /* XXX -- if we're double-quoted and the named variable is "$@",
-                       we want to turn off any special handling of "$@" --
-                       we're not using it, so whatever is on the rhs applies. */
-             if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-               *quoted_dollar_atp = 0;
-             if (contains_dollar_at)
-               *contains_dollar_at = 0;
-
-             ret = parameter_brace_expand_rhs (name, value, c, quoted,
-                                               quoted_dollar_atp,
-                                               contains_dollar_at);
-             /* XXX - fix up later, esp. noting presence of
-                      W_HASQUOTEDNULL in tdesc->flags */
-           }
-         free (value);
-       }
-
-      break;
-    }
-  free (name);
-
-  if (ret == 0)
-    {
-      ret = alloc_word_desc ();
-      ret->flags = tflag;
-      ret->word = temp;
-    }
-  return (ret);
-}
-
-/* Expand a single ${xxx} expansion.  The braces are optional.  When
-   the braces are used, parameter_brace_expand() does the work,
-   possibly calling param_expand recursively. */
-static WORD_DESC *
-param_expand (string, sindex, quoted, expanded_something,
-             contains_dollar_at, quoted_dollar_at_p, had_quoted_null_p,
-             pflags)
-     char *string;
-     int *sindex, quoted, *expanded_something, *contains_dollar_at;
-     int *quoted_dollar_at_p, *had_quoted_null_p, pflags;
-{
-  char *temp, *temp1, uerror[3];
-  int zindex, t_index, expok;
-  unsigned char c;
-  intmax_t number;
-  SHELL_VAR *var;
-  WORD_LIST *list;
-  WORD_DESC *tdesc, *ret;
-  int tflag;
-
-  zindex = *sindex;
-  c = string[++zindex];
-
-  temp = (char *)NULL;
-  ret = tdesc = (WORD_DESC *)NULL;
-  tflag = 0;
-
-  /* Do simple cases first. Switch on what follows '$'. */
-  switch (c)
-    {
-    /* $0 .. $9? */
-    case '0':
-    case '1':
-    case '2':
-    case '3':
-    case '4':
-    case '5':
-    case '6':
-    case '7':
-    case '8':
-    case '9':
-      temp1 = dollar_vars[TODIGIT (c)];
-      if (unbound_vars_is_error && temp1 == (char *)NULL)
-       {
-         uerror[0] = '$';
-         uerror[1] = c;
-         uerror[2] = '\0';
-         err_unboundvar (uerror);
-         last_command_exit_value = EXECUTION_FAILURE;
-         return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
-       }
-      if (temp1)
-       temp = (*temp1 && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-                 ? quote_string (temp1)
-                 : quote_escapes (temp1);
-      else
-       temp = (char *)NULL;
-
-      break;
-
-    /* $$ -- pid of the invoking shell. */
-    case '$':
-      temp = itos (dollar_dollar_pid);
-      break;
-
-    /* $# -- number of positional parameters. */
-    case '#':
-      temp = itos (number_of_args ());
-      break;
-
-    /* $? -- return value of the last synchronous command. */
-    case '?':
-      temp = itos (last_command_exit_value);
-      break;
-
-    /* $- -- flags supplied to the shell on invocation or by `set'. */
-    case '-':
-      temp = which_set_flags ();
-      break;
-
-      /* $! -- Pid of the last asynchronous command. */
-    case '!':
-      /* If no asynchronous pids have been created, expand to nothing.
-        If `set -u' has been executed, and no async processes have
-        been created, this is an expansion error. */
-      if (last_asynchronous_pid == NO_PID)
-       {
-         if (expanded_something)
-           *expanded_something = 0;
-         temp = (char *)NULL;
-         if (unbound_vars_is_error)
-           {
-             uerror[0] = '$';
-             uerror[1] = c;
-             uerror[2] = '\0';
-             err_unboundvar (uerror);
-             last_command_exit_value = EXECUTION_FAILURE;
-             return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
-           }
-       }
-      else
-       temp = itos (last_asynchronous_pid);
-      break;
-
-    /* The only difference between this and $@ is when the arg is quoted. */
-    case '*':          /* `$*' */
-      list = list_rest_of_args ();
-
-      if (list == 0 && unbound_vars_is_error && (pflags & PF_IGNUNBOUND) == 0)
-       {
-         uerror[0] = '$';
-         uerror[1] = '*';
-         uerror[2] = '\0';
-         err_unboundvar (uerror);
-         last_command_exit_value = EXECUTION_FAILURE;
-         return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
-       }
-
-      /* If there are no command-line arguments, this should just
-        disappear if there are other characters in the expansion,
-        even if it's quoted. */
-      if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && list == 0)
-       temp = (char *)NULL;
-      else if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES|Q_PATQUOTE))
-       {
-         /* If we have "$*" we want to make a string of the positional
-            parameters, separated by the first character of $IFS, and
-            quote the whole string, including the separators.  If IFS
-            is unset, the parameters are separated by ' '; if $IFS is
-            null, the parameters are concatenated. */
-         temp = (quoted & (Q_DOUBLE_QUOTES|Q_PATQUOTE)) ? string_list_dollar_star (list) : string_list (list);
-         temp1 = quote_string (temp);
-         if (*temp == 0)
-           tflag |= W_HASQUOTEDNULL;
-         free (temp);
-         temp = temp1;
-       }
-      else
-       {
-         /* We check whether or not we're eventually going to split $* here,
-            for example when IFS is empty and we are processing the rhs of
-            an assignment statement.  In that case, we don't separate the
-            arguments at all.  Otherwise, if the $* is not quoted it is
-            identical to $@ */
-#if 1
-#  if defined (HANDLE_MULTIBYTE)
-         if (expand_no_split_dollar_star && ifs_firstc[0] == 0)
-#  else
-         if (expand_no_split_dollar_star && ifs_firstc == 0)
-#  endif
-           temp = string_list_dollar_star (list);
-         else
-           temp = string_list_dollar_at (list, quoted);
-#else
-         temp = string_list_dollar_at (list, quoted);
-#endif
-         if (expand_no_split_dollar_star == 0 && contains_dollar_at)
-           *contains_dollar_at = 1;
-       }
-
-      dispose_words (list);
-      break;
-
-    /* When we have "$@" what we want is "$1" "$2" "$3" ... This
-       means that we have to turn quoting off after we split into
-       the individually quoted arguments so that the final split
-       on the first character of $IFS is still done.  */
-    case '@':          /* `$@' */
-      list = list_rest_of_args ();
-
-      if (list == 0 && unbound_vars_is_error && (pflags & PF_IGNUNBOUND) == 0)
-       {
-         uerror[0] = '$';
-         uerror[1] = '@';
-         uerror[2] = '\0';
-         err_unboundvar (uerror);
-         last_command_exit_value = EXECUTION_FAILURE;
-         return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
-       }
-
-      /* We want to flag the fact that we saw this.  We can't turn
-        off quoting entirely, because other characters in the
-        string might need it (consider "\"$@\""), but we need some
-        way to signal that the final split on the first character
-        of $IFS should be done, even though QUOTED is 1. */
-      /* XXX - should this test include Q_PATQUOTE? */
-      if (quoted_dollar_at_p && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-       *quoted_dollar_at_p = 1;
-      if (contains_dollar_at)
-       *contains_dollar_at = 1;
-
-      /* We want to separate the positional parameters with the first
-        character of $IFS in case $IFS is something other than a space.
-        We also want to make sure that splitting is done no matter what --
-        according to POSIX.2, this expands to a list of the positional
-        parameters no matter what IFS is set to. */
-      temp = string_list_dollar_at (list, quoted);
-
-      dispose_words (list);
-      break;
-
-    case LBRACE:
-      tdesc = parameter_brace_expand (string, &zindex, quoted,
-                                     quoted_dollar_at_p,
-                                     contains_dollar_at);
-
-      if (tdesc == &expand_wdesc_error || tdesc == &expand_wdesc_fatal)
-       return (tdesc);
-      temp = tdesc ? tdesc->word : (char *)0;
-
-      /* XXX */
-      /* Quoted nulls should be removed if there is anything else
-        in the string. */
-      /* Note that we saw the quoted null so we can add one back at
-        the end of this function if there are no other characters
-        in the string, discard TEMP, and go on.  The exception to
-        this is when we have "${@}" and $1 is '', since $@ needs
-        special handling. */
-      if (tdesc && tdesc->word && (tdesc->flags & W_HASQUOTEDNULL) && QUOTED_NULL (temp))
-       {
-         if (had_quoted_null_p)
-           *had_quoted_null_p = 1;
-         if (*quoted_dollar_at_p == 0)
-           {
-             free (temp);
-             tdesc->word = temp = (char *)NULL;
-           }
-           
-       }
-
-      ret = tdesc;
-      goto return0;
-
-    /* Do command or arithmetic substitution. */
-    case LPAREN:
-      /* We have to extract the contents of this paren substitution. */
-      t_index = zindex + 1;
-      temp = extract_command_subst (string, &t_index, 0);
-      zindex = t_index;
-
-      /* For Posix.2-style `$(( ))' arithmetic substitution,
-        extract the expression and pass it to the evaluator. */
-      if (temp && *temp == LPAREN)
-       {
-         char *temp2;
-         temp1 = temp + 1;
-         temp2 = savestring (temp1);
-         t_index = strlen (temp2) - 1;
-
-         if (temp2[t_index] != RPAREN)
-           {
-             free (temp2);
-             goto comsub;
-           }
-
-         /* Cut off ending `)' */
-         temp2[t_index] = '\0';
-
-         if (chk_arithsub (temp2, t_index) == 0)
-           {
-             free (temp2);
-             goto comsub;
-           }
-
-         /* Expand variables found inside the expression. */
-         temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES);
-         free (temp2);
-
-arithsub:
-         /* No error messages. */
-         this_command_name = (char *)NULL;
-         number = evalexp (temp1, &expok);
-         free (temp);
-         free (temp1);
-         if (expok == 0)
-           {
-             if (interactive_shell == 0 && posixly_correct)
-               {
-                 last_command_exit_value = EXECUTION_FAILURE;
-                 return (&expand_wdesc_fatal);
-               }
-             else
-               return (&expand_wdesc_error);
-           }
-         temp = itos (number);
-         break;
-       }
-
-comsub:
-      if (pflags & PF_NOCOMSUB)
-       /* we need zindex+1 because string[zindex] == RPAREN */
-       temp1 = substring (string, *sindex, zindex+1);
-      else
-       {
-         tdesc = command_substitute (temp, quoted);
-         temp1 = tdesc ? tdesc->word : (char *)NULL;
-         if (tdesc)
-           dispose_word_desc (tdesc);
-       }
-      FREE (temp);
-      temp = temp1;
-      break;
-
-    /* Do POSIX.2d9-style arithmetic substitution.  This will probably go
-       away in a future bash release. */
-    case '[':
-      /* Extract the contents of this arithmetic substitution. */
-      t_index = zindex + 1;
-      temp = extract_arithmetic_subst (string, &t_index);
-      zindex = t_index;
-      if (temp == 0)
-       {
-         temp = savestring (string);
-         if (expanded_something)
-           *expanded_something = 0;
-         goto return0;
-       }         
-
-       /* Do initial variable expansion. */
-      temp1 = expand_arith_string (temp, Q_DOUBLE_QUOTES);
-
-      goto arithsub;
-
-    default:
-      /* Find the variable in VARIABLE_LIST. */
-      temp = (char *)NULL;
-
-      for (t_index = zindex; (c = string[zindex]) && legal_variable_char (c); zindex++)
-       ;
-      temp1 = (zindex > t_index) ? substring (string, t_index, zindex) : (char *)NULL;
-
-      /* If this isn't a variable name, then just output the `$'. */
-      if (temp1 == 0 || *temp1 == '\0')
-       {
-         FREE (temp1);
-         temp = (char *)xmalloc (2);
-         temp[0] = '$';
-         temp[1] = '\0';
-         if (expanded_something)
-           *expanded_something = 0;
-         goto return0;
-       }
-
-      /* If the variable exists, return its value cell. */
-      var = find_variable (temp1);
-
-      if (var && invisible_p (var) == 0 && var_isset (var))
-       {
-#if defined (ARRAY_VARS)
-         if (assoc_p (var) || array_p (var))
-           {
-             temp = array_p (var) ? array_reference (array_cell (var), 0)
-                                  : assoc_reference (assoc_cell (var), "0");
-             if (temp)
-               temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-                         ? quote_string (temp)
-                         : quote_escapes (temp);
-             else if (unbound_vars_is_error)
-               goto unbound_variable;
-           }
-         else
-#endif
-           {
-             temp = value_cell (var);
-
-             temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-                       ? quote_string (temp)
-                       : quote_escapes (temp);
-           }
-
-         free (temp1);
-
-         goto return0;
-       }
-
-      temp = (char *)NULL;
-
-unbound_variable:
-      if (unbound_vars_is_error)
-       err_unboundvar (temp1);
-      else
-       {
-         free (temp1);
-         goto return0;
-       }
-
-      free (temp1);
-      last_command_exit_value = EXECUTION_FAILURE;
-      return ((unbound_vars_is_error && interactive_shell == 0)
-               ? &expand_wdesc_fatal
-               : &expand_wdesc_error);
-    }
-
-  if (string[zindex])
-    zindex++;
-
-return0:
-  *sindex = zindex;
-
-  if (ret == 0)
-    {
-      ret = alloc_word_desc ();
-      ret->flags = tflag;      /* XXX */
-      ret->word = temp;
-    }
-  return ret;
-}
-
-/* Make a word list which is the result of parameter and variable
-   expansion, command substitution, arithmetic substitution, and
-   quote removal of WORD.  Return a pointer to a WORD_LIST which is
-   the result of the expansion.  If WORD contains a null word, the
-   word list returned is also null.
-
-   QUOTED contains flag values defined in shell.h.
-
-   ISEXP is used to tell expand_word_internal that the word should be
-   treated as the result of an expansion.  This has implications for
-   how IFS characters in the word are treated.
-
-   CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
-   they point to an integer value which receives information about expansion.
-   CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
-   EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
-   else zero.
-
-   This only does word splitting in the case of $@ expansion.  In that
-   case, we split on ' '. */
-
-/* Values for the local variable quoted_state. */
-#define UNQUOTED        0
-#define PARTIALLY_QUOTED 1
-#define WHOLLY_QUOTED    2
-
-static WORD_LIST *
-expand_word_internal (word, quoted, isexp, contains_dollar_at, expanded_something)
-     WORD_DESC *word;
-     int quoted, isexp;
-     int *contains_dollar_at;
-     int *expanded_something;
-{
-  WORD_LIST *list;
-  WORD_DESC *tword;
-
-  /* The intermediate string that we build while expanding. */
-  char *istring;
-
-  /* The current size of the above object. */
-  int istring_size;
-
-  /* Index into ISTRING. */
-  int istring_index;
-
-  /* Temporary string storage. */
-  char *temp, *temp1;
-
-  /* The text of WORD. */
-  register char *string;
-
-  /* The size of STRING. */
-  size_t string_size;
-
-  /* The index into STRING. */
-  int sindex;
-
-  /* This gets 1 if we see a $@ while quoted. */
-  int quoted_dollar_at;
-
-  /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
-     whether WORD contains no quoting characters, a partially quoted
-     string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
-  int quoted_state;
-
-  /* State flags */
-  int had_quoted_null;
-  int has_dollar_at;
-  int tflag;
-
-  int assignoff;               /* If assignment, offset of `=' */
-
-  register unsigned char c;    /* Current character. */
-  int t_index;                 /* For calls to string_extract_xxx. */
-
-  char twochars[2];
-
-  DECLARE_MBSTATE;
-
-  istring = (char *)xmalloc (istring_size = DEFAULT_INITIAL_ARRAY_SIZE);
-  istring[istring_index = 0] = '\0';
-  quoted_dollar_at = had_quoted_null = has_dollar_at = 0;
-  quoted_state = UNQUOTED;
-
-  string = word->word;
-  if (string == 0)
-    goto finished_with_string;
-  /* Don't need the string length for the SADD... and COPY_ macros unless
-     multibyte characters are possible. */
-  string_size = (MB_CUR_MAX > 1) ? strlen (string) : 1;
-
-  if (contains_dollar_at)
-    *contains_dollar_at = 0;
-
-  assignoff = -1;
-
-  /* Begin the expansion. */
-
-  for (sindex = 0; ;)
-    {
-      c = string[sindex];
-
-      /* Case on toplevel character. */
-      switch (c)
-       {
-       case '\0':
-         goto finished_with_string;
-
-       case CTLESC:
-         sindex++;
-#if HANDLE_MULTIBYTE
-         if (MB_CUR_MAX > 1 && string[sindex])
-           {
-             SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
-           }
-         else
-#endif
-           {
-             temp = (char *)xmalloc (3);
-             temp[0] = CTLESC;
-             temp[1] = c = string[sindex];
-             temp[2] = '\0';
-           }
-
-dollar_add_string:
-         if (string[sindex])
-           sindex++;
-
-add_string:
-         if (temp)
-           {
-             istring = sub_append_string (temp, istring, &istring_index, &istring_size);
-             temp = (char *)0;
-           }
-
-         break;
-
-#if defined (PROCESS_SUBSTITUTION)
-         /* Process substitution. */
-       case '<':
-       case '>':
-         {
-           if (string[++sindex] != LPAREN || (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (word->flags & (W_DQUOTE|W_NOPROCSUB)) || posixly_correct)
-             {
-               sindex--;       /* add_character: label increments sindex */
-               goto add_character;
-             }
-           else
-             t_index = sindex + 1; /* skip past both '<' and LPAREN */
-
-           temp1 = extract_process_subst (string, (c == '<') ? "<(" : ">(", &t_index); /*))*/
-           sindex = t_index;
-
-           /* If the process substitution specification is `<()', we want to
-              open the pipe for writing in the child and produce output; if
-              it is `>()', we want to open the pipe for reading in the child
-              and consume input. */
-           temp = temp1 ? process_substitute (temp1, (c == '>')) : (char *)0;
-
-           FREE (temp1);
-
-           goto dollar_add_string;
-         }
-#endif /* PROCESS_SUBSTITUTION */
-
-       case '=':
-         /* Posix.2 section 3.6.1 says that tildes following `=' in words
-            which are not assignment statements are not expanded.  If the
-            shell isn't in posix mode, though, we perform tilde expansion
-            on `likely candidate' unquoted assignment statements (flags
-            include W_ASSIGNMENT but not W_QUOTED).  A likely candidate
-            contains an unquoted :~ or =~.  Something to think about: we
-            now have a flag that says  to perform tilde expansion on arguments
-            to `assignment builtins' like declare and export that look like
-            assignment statements.  We now do tilde expansion on such words
-            even in POSIX mode. */     
-         if (word->flags & (W_ASSIGNRHS|W_NOTILDE))
-           {
-             if (isexp == 0 && isifs (c))
-               goto add_ifs_character;
-             else
-               goto add_character;
-           }
-         /* If we're not in posix mode or forcing assignment-statement tilde
-            expansion, note where the `=' appears in the word and prepare to
-            do tilde expansion following the first `='. */
-         if ((word->flags & W_ASSIGNMENT) &&
-             (posixly_correct == 0 || (word->flags & W_TILDEEXP)) &&
-             assignoff == -1 && sindex > 0)
-           assignoff = sindex;
-         if (sindex == assignoff && string[sindex+1] == '~')   /* XXX */
-           word->flags |= W_ITILDE;
-#if 0
-         else if ((word->flags & W_ASSIGNMENT) &&
-                  (posixly_correct == 0 || (word->flags & W_TILDEEXP)) &&
-                  string[sindex+1] == '~')
-           word->flags |= W_ITILDE;
-#endif
-         if (isexp == 0 && isifs (c))
-           goto add_ifs_character;
-         else
-           goto add_character;
-
-       case ':':
-         if (word->flags & W_NOTILDE)
-           {
-             if (isexp == 0 && isifs (c))
-               goto add_ifs_character;
-             else
-               goto add_character;
-           }
-
-         if ((word->flags & (W_ASSIGNMENT|W_ASSIGNRHS|W_TILDEEXP)) &&
-             string[sindex+1] == '~')
-           word->flags |= W_ITILDE;
-
-         if (isexp == 0 && isifs (c))
-           goto add_ifs_character;
-         else
-           goto add_character;
-
-       case '~':
-         /* If the word isn't supposed to be tilde expanded, or we're not
-            at the start of a word or after an unquoted : or = in an
-            assignment statement, we don't do tilde expansion. */
-         if ((word->flags & (W_NOTILDE|W_DQUOTE)) ||
-             (sindex > 0 && ((word->flags & W_ITILDE) == 0)) ||
-             (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-           {
-             word->flags &= ~W_ITILDE;
-             if (isexp == 0 && isifs (c) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
-               goto add_ifs_character;
-             else
-               goto add_character;
-           }
-
-         if (word->flags & W_ASSIGNRHS)
-           tflag = 2;
-         else if (word->flags & (W_ASSIGNMENT|W_TILDEEXP))
-           tflag = 1;
-         else
-           tflag = 0;
-
-         temp = bash_tilde_find_word (string + sindex, tflag, &t_index);
-           
-         word->flags &= ~W_ITILDE;
-
-         if (temp && *temp && t_index > 0)
-           {
-             temp1 = bash_tilde_expand (temp, tflag);
-             if  (temp1 && *temp1 == '~' && STREQ (temp, temp1))
-               {
-                 FREE (temp);
-                 FREE (temp1);
-                 goto add_character;           /* tilde expansion failed */
-               }
-             free (temp);
-             temp = temp1;
-             sindex += t_index;
-             goto add_quoted_string;           /* XXX was add_string */
-           }
-         else
-           {
-             FREE (temp);
-             goto add_character;
-           }
-       
-       case '$':
-         if (expanded_something)
-           *expanded_something = 1;
-
-         has_dollar_at = 0;
-         tword = param_expand (string, &sindex, quoted, expanded_something,
-                              &has_dollar_at, &quoted_dollar_at,
-                              &had_quoted_null,
-                              (word->flags & W_NOCOMSUB) ? PF_NOCOMSUB : 0);
-
-         if (tword == &expand_wdesc_error || tword == &expand_wdesc_fatal)
-           {
-             free (string);
-             free (istring);
-             return ((tword == &expand_wdesc_error) ? &expand_word_error
-                                                    : &expand_word_fatal);
-           }
-         if (contains_dollar_at && has_dollar_at)
-           *contains_dollar_at = 1;
-
-         if (tword && (tword->flags & W_HASQUOTEDNULL))
-           had_quoted_null = 1;
-
-         temp = tword->word;
-         dispose_word_desc (tword);
-
-         goto add_string;
-         break;
-
-       case '`':               /* Backquoted command substitution. */
-         {
-           t_index = sindex++;
-
-           temp = string_extract (string, &sindex, "`", SX_REQMATCH);
-           /* The test of sindex against t_index is to allow bare instances of
-              ` to pass through, for backwards compatibility. */
-           if (temp == &extract_string_error || temp == &extract_string_fatal)
-             {
-               if (sindex - 1 == t_index)
-                 {
-                   sindex = t_index;
-                   goto add_character;
-                 }
-               report_error (_("bad substitution: no closing \"`\" in %s") , string+t_index);
-               free (string);
-               free (istring);
-               return ((temp == &extract_string_error) ? &expand_word_error
-                                                       : &expand_word_fatal);
-             }
-               
-           if (expanded_something)
-             *expanded_something = 1;
-
-           if (word->flags & W_NOCOMSUB)
-             /* sindex + 1 because string[sindex] == '`' */
-             temp1 = substring (string, t_index, sindex + 1);
-           else
-             {
-               de_backslash (temp);
-               tword = command_substitute (temp, quoted);
-               temp1 = tword ? tword->word : (char *)NULL;
-               if (tword)
-                 dispose_word_desc (tword);
-             }
-           FREE (temp);
-           temp = temp1;
-           goto dollar_add_string;
-         }
-
-       case '\\':
-         if (string[sindex + 1] == '\n')
-           {
-             sindex += 2;
-             continue;
-           }
-
-         c = string[++sindex];
-
-         if (quoted & Q_HERE_DOCUMENT)
-           tflag = CBSHDOC;
-         else if (quoted & Q_DOUBLE_QUOTES)
-           tflag = CBSDQUOTE;
-         else
-           tflag = 0;
-
-         if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && ((sh_syntaxtab[c] & tflag) == 0))
-           {
-             SCOPY_CHAR_I (twochars, '\\', c, string, sindex, string_size);
-           }
-         else if (c == 0)
-           {
-             c = CTLNUL;
-             sindex--;         /* add_character: label increments sindex */
-             goto add_character;
-           }
-         else
-           {
-             SCOPY_CHAR_I (twochars, CTLESC, c, string, sindex, string_size);
-           }
-
-         sindex++;
-add_twochars:
-         /* BEFORE jumping here, we need to increment sindex if appropriate */
-         RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size,
-                                 DEFAULT_ARRAY_SIZE);
-         istring[istring_index++] = twochars[0];
-         istring[istring_index++] = twochars[1];
-         istring[istring_index] = '\0';
-
-         break;
-
-       case '"':
-#if 0
-         if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (word->flags & W_DQUOTE))
-#else
-         if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-#endif
-           goto add_character;
-
-         t_index = ++sindex;
-         temp = string_extract_double_quoted (string, &sindex, 0);
-
-         /* If the quotes surrounded the entire string, then the
-            whole word was quoted. */
-         quoted_state = (t_index == 1 && string[sindex] == '\0')
-                           ? WHOLLY_QUOTED
-                           : PARTIALLY_QUOTED;
-
-         if (temp && *temp)
-           {
-             tword = alloc_word_desc ();
-             tword->word = temp;
-
-             temp = (char *)NULL;
-
-             has_dollar_at = 0;
-             /* Need to get W_HASQUOTEDNULL flag through this function. */
-             list = expand_word_internal (tword, Q_DOUBLE_QUOTES, 0, &has_dollar_at, (int *)NULL);
-
-             if (list == &expand_word_error || list == &expand_word_fatal)
-               {
-                 free (istring);
-                 free (string);
-                 /* expand_word_internal has already freed temp_word->word
-                    for us because of the way it prints error messages. */
-                 tword->word = (char *)NULL;
-                 dispose_word (tword);
-                 return list;
-               }
-
-             dispose_word (tword);
-
-             /* "$@" (a double-quoted dollar-at) expands into nothing,
-                not even a NULL word, when there are no positional
-                parameters. */
-             if (list == 0 && has_dollar_at)
-               {
-                 quoted_dollar_at++;
-                 break;
-               }
-
-             /* If we get "$@", we know we have expanded something, so we
-                need to remember it for the final split on $IFS.  This is
-                a special case; it's the only case where a quoted string
-                can expand into more than one word.  It's going to come back
-                from the above call to expand_word_internal as a list with
-                a single word, in which all characters are quoted and
-                separated by blanks.  What we want to do is to turn it back
-                into a list for the next piece of code. */
-             if (list)
-               dequote_list (list);
-
-             if (list && list->word && (list->word->flags & W_HASQUOTEDNULL))
-               had_quoted_null = 1;
-
-             if (has_dollar_at)
-               {
-                 quoted_dollar_at++;
-                 if (contains_dollar_at)
-                   *contains_dollar_at = 1;
-                 if (expanded_something)
-                   *expanded_something = 1;
-               }
-           }
-         else
-           {
-             /* What we have is "".  This is a minor optimization. */
-             FREE (temp);
-             list = (WORD_LIST *)NULL;
-           }
-
-         /* The code above *might* return a list (consider the case of "$@",
-            where it returns "$1", "$2", etc.).  We can't throw away the
-            rest of the list, and we have to make sure each word gets added
-            as quoted.  We test on tresult->next:  if it is non-NULL, we
-            quote the whole list, save it to a string with string_list, and
-            add that string. We don't need to quote the results of this
-            (and it would be wrong, since that would quote the separators
-            as well), so we go directly to add_string. */
-         if (list)
-           {
-             if (list->next)
-               {
-                 /* Testing quoted_dollar_at makes sure that "$@" is
-                    split correctly when $IFS does not contain a space. */
-                 temp = quoted_dollar_at
-                               ? string_list_dollar_at (list, Q_DOUBLE_QUOTES)
-                               : string_list (quote_list (list));
-                 dispose_words (list);
-                 goto add_string;
-               }
-             else
-               {
-                 temp = savestring (list->word->word);
-                 tflag = list->word->flags;
-                 dispose_words (list);
-
-                 /* If the string is not a quoted null string, we want
-                    to remove any embedded unquoted CTLNUL characters.
-                    We do not want to turn quoted null strings back into
-                    the empty string, though.  We do this because we
-                    want to remove any quoted nulls from expansions that
-                    contain other characters.  For example, if we have
-                    x"$*"y or "x$*y" and there are no positional parameters,
-                    the $* should expand into nothing. */
-                 /* We use the W_HASQUOTEDNULL flag to differentiate the
-                    cases:  a quoted null character as above and when
-                    CTLNUL is contained in the (non-null) expansion
-                    of some variable.  We use the had_quoted_null flag to
-                    pass the value through this function to its caller. */
-                 if ((tflag & W_HASQUOTEDNULL) && QUOTED_NULL (temp) == 0)
-                   remove_quoted_nulls (temp); /* XXX */
-               }
-           }
-         else
-           temp = (char *)NULL;
-
-         /* We do not want to add quoted nulls to strings that are only
-            partially quoted; we can throw them away. */
-         if (temp == 0 && quoted_state == PARTIALLY_QUOTED)
-           continue;
-
-       add_quoted_string:
-
-         if (temp)
-           {
-             temp1 = temp;
-             temp = quote_string (temp);
-             free (temp1);
-             goto add_string;
-           }
-         else
-           {
-             /* Add NULL arg. */
-             c = CTLNUL;
-             sindex--;         /* add_character: label increments sindex */
-             goto add_character;
-           }
-
-         /* break; */
-
-       case '\'':
-#if 0
-         if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (word->flags & W_DQUOTE))
-#else
-         if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-#endif
-           goto add_character;
-
-         t_index = ++sindex;
-         temp = string_extract_single_quoted (string, &sindex);
-
-         /* If the entire STRING was surrounded by single quotes,
-            then the string is wholly quoted. */
-         quoted_state = (t_index == 1 && string[sindex] == '\0')
-                           ? WHOLLY_QUOTED
-                           : PARTIALLY_QUOTED;
-
-         /* If all we had was '', it is a null expansion. */
-         if (*temp == '\0')
-           {
-             free (temp);
-             temp = (char *)NULL;
-           }
-         else
-           remove_quoted_escapes (temp);       /* ??? */
-
-         /* We do not want to add quoted nulls to strings that are only
-            partially quoted; such nulls are discarded. */
-         if (temp == 0 && (quoted_state == PARTIALLY_QUOTED))
-           continue;
-
-         /* If we have a quoted null expansion, add a quoted NULL to istring. */
-         if (temp == 0)
-           {
-             c = CTLNUL;
-             sindex--;         /* add_character: label increments sindex */
-             goto add_character;
-           }
-         else
-           goto add_quoted_string;
-
-         /* break; */
-
-       default:
-         /* This is the fix for " $@ " */
-       add_ifs_character:
-         if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (isexp == 0 && isifs (c)))
-           {
-             if (string[sindex])       /* from old goto dollar_add_string */
-               sindex++;
-             if (c == 0)
-               {
-                 c = CTLNUL;
-                 goto add_character;
-               }
-             else
-               {
-#if HANDLE_MULTIBYTE
-                 if (MB_CUR_MAX > 1)
-                   sindex--;
-
-                 if (MB_CUR_MAX > 1)
-                   {
-                     SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
-                   }
-                 else
-#endif
-                   {
-                     twochars[0] = CTLESC;
-                     twochars[1] = c;
-                     goto add_twochars;
-                   }
-               }
-           }
-
-         SADD_MBCHAR (temp, string, sindex, string_size);
-
-       add_character:
-         RESIZE_MALLOCED_BUFFER (istring, istring_index, 1, istring_size,
-                                 DEFAULT_ARRAY_SIZE);
-         istring[istring_index++] = c;
-         istring[istring_index] = '\0';
-
-         /* Next character. */
-         sindex++;
-       }
-    }
-
-finished_with_string:
-  /* OK, we're ready to return.  If we have a quoted string, and
-     quoted_dollar_at is not set, we do no splitting at all; otherwise
-     we split on ' '.  The routines that call this will handle what to
-     do if nothing has been expanded. */
-
-  /* Partially and wholly quoted strings which expand to the empty
-     string are retained as an empty arguments.  Unquoted strings
-     which expand to the empty string are discarded.  The single
-     exception is the case of expanding "$@" when there are no
-     positional parameters.  In that case, we discard the expansion. */
-
-  /* Because of how the code that handles "" and '' in partially
-     quoted strings works, we need to make ISTRING into a QUOTED_NULL
-     if we saw quoting characters, but the expansion was empty.
-     "" and '' are tossed away before we get to this point when
-     processing partially quoted strings.  This makes "" and $xxx""
-     equivalent when xxx is unset.  We also look to see whether we
-     saw a quoted null from a ${} expansion and add one back if we
-     need to. */
-
-  /* If we expand to nothing and there were no single or double quotes
-     in the word, we throw it away.  Otherwise, we return a NULL word.
-     The single exception is for $@ surrounded by double quotes when
-     there are no positional parameters.  In that case, we also throw
-     the word away. */
-
-  if (*istring == '\0')
-    {
-      if (quoted_dollar_at == 0 && (had_quoted_null || quoted_state == PARTIALLY_QUOTED))
-       {
-         istring[0] = CTLNUL;
-         istring[1] = '\0';
-         tword = make_bare_word (istring);
-         tword->flags |= W_HASQUOTEDNULL;              /* XXX */
-         list = make_word_list (tword, (WORD_LIST *)NULL);
-         if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-           tword->flags |= W_QUOTED;
-       }
-      /* According to sh, ksh, and Posix.2, if a word expands into nothing
-        and a double-quoted "$@" appears anywhere in it, then the entire
-        word is removed. */
-      else  if (quoted_state == UNQUOTED || quoted_dollar_at)
-       list = (WORD_LIST *)NULL;
-#if 0
-      else
-       {
-         tword = make_bare_word (istring);
-         if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-           tword->flags |= W_QUOTED;
-         list = make_word_list (tword, (WORD_LIST *)NULL);
-       }
-#else
-      else
-       list = (WORD_LIST *)NULL;
-#endif
-    }
-  else if (word->flags & W_NOSPLIT)
-    {
-      tword = make_bare_word (istring);
-      if (word->flags & W_ASSIGNMENT)
-       tword->flags |= W_ASSIGNMENT;   /* XXX */
-      if (word->flags & W_COMPASSIGN)
-       tword->flags |= W_COMPASSIGN;   /* XXX */
-      if (word->flags & W_NOGLOB)
-       tword->flags |= W_NOGLOB;       /* XXX */
-      if (word->flags & W_NOEXPAND)
-       tword->flags |= W_NOEXPAND;     /* XXX */
-      if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-       tword->flags |= W_QUOTED;
-      if (had_quoted_null)
-       tword->flags |= W_HASQUOTEDNULL;
-      list = make_word_list (tword, (WORD_LIST *)NULL);
-    }
-  else
-    {
-      char *ifs_chars;
-
-      ifs_chars = (quoted_dollar_at || has_dollar_at) ? ifs_value : (char *)NULL;
-
-      /* If we have $@, we need to split the results no matter what.  If
-        IFS is unset or NULL, string_list_dollar_at has separated the
-        positional parameters with a space, so we split on space (we have
-        set ifs_chars to " \t\n" above if ifs is unset).  If IFS is set,
-        string_list_dollar_at has separated the positional parameters
-        with the first character of $IFS, so we split on $IFS. */
-      if (has_dollar_at && ifs_chars)
-       list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
-      else
-       {
-         tword = make_bare_word (istring);
-         if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED))
-           tword->flags |= W_QUOTED;
-         if (word->flags & W_ASSIGNMENT)
-           tword->flags |= W_ASSIGNMENT;
-         if (word->flags & W_COMPASSIGN)
-           tword->flags |= W_COMPASSIGN;
-         if (word->flags & W_NOGLOB)
-           tword->flags |= W_NOGLOB;
-         if (word->flags & W_NOEXPAND)
-           tword->flags |= W_NOEXPAND;
-         if (had_quoted_null)
-           tword->flags |= W_HASQUOTEDNULL;    /* XXX */
-         list = make_word_list (tword, (WORD_LIST *)NULL);
-       }
-    }
-
-  free (istring);
-  return (list);
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*                Functions for Quote Removal                      */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Perform quote removal on STRING.  If QUOTED > 0, assume we are obeying the
-   backslash quoting rules for within double quotes or a here document. */
-char *
-string_quote_removal (string, quoted)
-     char *string;
-     int quoted;
-{
-  size_t slen;
-  char *r, *result_string, *temp, *send;
-  int sindex, tindex, dquote;
-  unsigned char c;
-  DECLARE_MBSTATE;
-
-  /* The result can be no longer than the original string. */
-  slen = strlen (string);
-  send = string + slen;
-
-  r = result_string = (char *)xmalloc (slen + 1);
-
-  for (dquote = sindex = 0; c = string[sindex];)
-    {
-      switch (c)
-       {
-       case '\\':
-         c = string[++sindex];
-         if (c == 0)
-           {
-             *r++ = '\\';
-             break;
-           }
-         if (((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote) && (sh_syntaxtab[c] & CBSDQUOTE) == 0)
-           *r++ = '\\';
-         /* FALLTHROUGH */
-
-       default:
-         SCOPY_CHAR_M (r, string, send, sindex);
-         break;
-
-       case '\'':
-         if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote)
-           {
-             *r++ = c;
-             sindex++;
-             break;
-           }
-         tindex = sindex + 1;
-         temp = string_extract_single_quoted (string, &tindex);
-         if (temp)
-           {
-             strcpy (r, temp);
-             r += strlen (r);
-             free (temp);
-           }
-         sindex = tindex;
-         break;
-
-       case '"':
-         dquote = 1 - dquote;
-         sindex++;
-         break;
-       }
-    }
-    *r = '\0';
-    return (result_string);
-}
-
-#if 0
-/* UNUSED */
-/* Perform quote removal on word WORD.  This allocates and returns a new
-   WORD_DESC *. */
-WORD_DESC *
-word_quote_removal (word, quoted)
-     WORD_DESC *word;
-     int quoted;
-{
-  WORD_DESC *w;
-  char *t;
-
-  t = string_quote_removal (word->word, quoted);
-  w = alloc_word_desc ();
-  w->word = t ? t : savestring ("");
-  return (w);
-}
-
-/* Perform quote removal on all words in LIST.  If QUOTED is non-zero,
-   the members of the list are treated as if they are surrounded by
-   double quotes.  Return a new list, or NULL if LIST is NULL. */
-WORD_LIST *
-word_list_quote_removal (list, quoted)
-     WORD_LIST *list;
-     int quoted;
-{
-  WORD_LIST *result, *t, *tresult, *e;
-
-  for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
-    {
-      tresult = make_word_list (word_quote_removal (t->word, quoted), (WORD_LIST *)NULL);
-#if 0
-      result = (WORD_LIST *) list_append (result, tresult);
-#else
-      if (result == 0)
-       result = e = tresult;
-      else
-       {
-         e->next = tresult;
-         while (e->next)
-           e = e->next;
-       }
-#endif
-    }
-  return (result);
-}
-#endif
-
-/*******************************************
- *                                        *
- *    Functions to perform word splitting  *
- *                                        *
- *******************************************/
-
-void
-setifs (v)
-     SHELL_VAR *v;
-{
-  char *t;
-  unsigned char uc;
-
-  ifs_var = v;
-  ifs_value = (v && value_cell (v)) ? value_cell (v) : " \t\n";
-
-  /* Should really merge ifs_cmap with sh_syntaxtab.  XXX - doesn't yet
-     handle multibyte chars in IFS */
-  memset (ifs_cmap, '\0', sizeof (ifs_cmap));
-  for (t = ifs_value ; t && *t; t++)
-    {
-      uc = *t;
-      ifs_cmap[uc] = 1;
-    }
-
-#if defined (HANDLE_MULTIBYTE)
-  if (ifs_value == 0)
-    {
-      ifs_firstc[0] = '\0';
-      ifs_firstc_len = 1;
-    }
-  else
-    {
-      size_t ifs_len;
-      ifs_len = strnlen (ifs_value, MB_CUR_MAX);
-      ifs_firstc_len = MBLEN (ifs_value, ifs_len);
-      if (ifs_firstc_len == 1 || ifs_firstc_len == 0 || MB_INVALIDCH (ifs_firstc_len))
-       {
-         ifs_firstc[0] = ifs_value[0];
-         ifs_firstc[1] = '\0';
-         ifs_firstc_len = 1;
-       }
-      else
-       memcpy (ifs_firstc, ifs_value, ifs_firstc_len);
-    }
-#else
-  ifs_firstc = ifs_value ? *ifs_value : 0;
-#endif
-}
-
-char *
-getifs ()
-{
-  return ifs_value;
-}
-
-/* This splits a single word into a WORD LIST on $IFS, but only if the word
-   is not quoted.  list_string () performs quote removal for us, even if we
-   don't do any splitting. */
-WORD_LIST *
-word_split (w, ifs_chars)
-     WORD_DESC *w;
-     char *ifs_chars;
-{
-  WORD_LIST *result;
-
-  if (w)
-    {
-      char *xifs;
-
-      xifs = ((w->flags & W_QUOTED) || ifs_chars == 0) ? "" : ifs_chars;
-      result = list_string (w->word, xifs, w->flags & W_QUOTED);
-    }
-  else
-    result = (WORD_LIST *)NULL;
-
-  return (result);
-}
-
-/* Perform word splitting on LIST and return the RESULT.  It is possible
-   to return (WORD_LIST *)NULL. */
-static WORD_LIST *
-word_list_split (list)
-     WORD_LIST *list;
-{
-  WORD_LIST *result, *t, *tresult, *e;
-
-  for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
-    {
-      tresult = word_split (t->word, ifs_value);
-      if (result == 0)
-        result = e = tresult;
-      else
-       {
-         e->next = tresult;
-         while (e->next)
-           e = e->next;
-       }
-    }
-  return (result);
-}
-
-/**************************************************
- *                                               *
- *    Functions to expand an entire WORD_LIST    *
- *                                               *
- **************************************************/
-
-/* Do any word-expansion-specific cleanup and jump to top_level */
-static void
-exp_jump_to_top_level (v)
-     int v;
-{
-  set_pipestatus_from_exit (last_command_exit_value);
-
-  /* Cleanup code goes here. */
-  expand_no_split_dollar_star = 0;     /* XXX */
-  expanding_redir = 0;
-  assigning_in_environment = 0;
-
-  if (parse_and_execute_level == 0)
-    top_level_cleanup ();                      /* from sig.c */
-
-  jump_to_top_level (v);
-}
-
-/* Put NLIST (which is a WORD_LIST * of only one element) at the front of
-   ELIST, and set ELIST to the new list. */
-#define PREPEND_LIST(nlist, elist) \
-       do { nlist->next = elist; elist = nlist; } while (0)
-
-/* Separate out any initial variable assignments from TLIST.  If set -k has
-   been executed, remove all assignment statements from TLIST.  Initial
-   variable assignments and other environment assignments are placed
-   on SUBST_ASSIGN_VARLIST. */
-static WORD_LIST *
-separate_out_assignments (tlist)
-     WORD_LIST *tlist;
-{
-  register WORD_LIST *vp, *lp;
-
-  if (!tlist)
-    return ((WORD_LIST *)NULL);
-
-  if (subst_assign_varlist)
-    dispose_words (subst_assign_varlist);      /* Clean up after previous error */
-
-  subst_assign_varlist = (WORD_LIST *)NULL;
-  vp = lp = tlist;
-
-  /* Separate out variable assignments at the start of the command.
-     Loop invariant: vp->next == lp
-     Loop postcondition:
-       lp = list of words left after assignment statements skipped
-       tlist = original list of words
-  */
-  while (lp && (lp->word->flags & W_ASSIGNMENT))
-    {
-      vp = lp;
-      lp = lp->next;
-    }
-
-  /* If lp != tlist, we have some initial assignment statements.
-     We make SUBST_ASSIGN_VARLIST point to the list of assignment
-     words and TLIST point to the remaining words.  */
-  if (lp != tlist)
-    {
-      subst_assign_varlist = tlist;
-      /* ASSERT(vp->next == lp); */
-      vp->next = (WORD_LIST *)NULL;    /* terminate variable list */
-      tlist = lp;                      /* remainder of word list */
-    }
-
-  /* vp == end of variable list */
-  /* tlist == remainder of original word list without variable assignments */
-  if (!tlist)
-    /* All the words in tlist were assignment statements */
-    return ((WORD_LIST *)NULL);
-
-  /* ASSERT(tlist != NULL); */
-  /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
-
-  /* If the -k option is in effect, we need to go through the remaining
-     words, separate out the assignment words, and place them on
-     SUBST_ASSIGN_VARLIST. */
-  if (place_keywords_in_env)
-    {
-      WORD_LIST *tp;   /* tp == running pointer into tlist */
-
-      tp = tlist;
-      lp = tlist->next;
-
-      /* Loop Invariant: tp->next == lp */
-      /* Loop postcondition: tlist == word list without assignment statements */
-      while (lp)
-       {
-         if (lp->word->flags & W_ASSIGNMENT)
-           {
-             /* Found an assignment statement, add this word to end of
-                subst_assign_varlist (vp). */
-             if (!subst_assign_varlist)
-               subst_assign_varlist = vp = lp;
-             else
-               {
-                 vp->next = lp;
-                 vp = lp;
-               }
-
-             /* Remove the word pointed to by LP from TLIST. */
-             tp->next = lp->next;
-             /* ASSERT(vp == lp); */
-             lp->next = (WORD_LIST *)NULL;
-             lp = tp->next;
-           }
-         else
-           {
-             tp = lp;
-             lp = lp->next;
-           }
-       }
-    }
-  return (tlist);
-}
-
-#define WEXP_VARASSIGN 0x001
-#define WEXP_BRACEEXP  0x002
-#define WEXP_TILDEEXP  0x004
-#define WEXP_PARAMEXP  0x008
-#define WEXP_PATHEXP   0x010
-
-/* All of the expansions, including variable assignments at the start of
-   the list. */
-#define WEXP_ALL       (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
-
-/* All of the expansions except variable assignments at the start of
-   the list. */
-#define WEXP_NOVARS    (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
-
-/* All of the `shell expansions': brace expansion, tilde expansion, parameter
-   expansion, command substitution, arithmetic expansion, word splitting, and
-   quote removal. */
-#define WEXP_SHELLEXP  (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
-
-/* Take the list of words in LIST and do the various substitutions.  Return
-   a new list of words which is the expanded list, and without things like
-   variable assignments. */
-
-WORD_LIST *
-expand_words (list)
-     WORD_LIST *list;
-{
-  return (expand_word_list_internal (list, WEXP_ALL));
-}
-
-/* Same as expand_words (), but doesn't hack variable or environment
-   variables. */
-WORD_LIST *
-expand_words_no_vars (list)
-     WORD_LIST *list;
-{
-  return (expand_word_list_internal (list, WEXP_NOVARS));
-}
-
-WORD_LIST *
-expand_words_shellexp (list)
-     WORD_LIST *list;
-{
-  return (expand_word_list_internal (list, WEXP_SHELLEXP));
-}
-
-static WORD_LIST *
-glob_expand_word_list (tlist, eflags)
-     WORD_LIST *tlist;
-     int eflags;
-{
-  char **glob_array, *temp_string;
-  register int glob_index;
-  WORD_LIST *glob_list, *output_list, *disposables, *next;
-  WORD_DESC *tword;
-
-  output_list = disposables = (WORD_LIST *)NULL;
-  glob_array = (char **)NULL;
-  while (tlist)
-    {
-      /* For each word, either globbing is attempted or the word is
-        added to orig_list.  If globbing succeeds, the results are
-        added to orig_list and the word (tlist) is added to the list
-        of disposable words.  If globbing fails and failed glob
-        expansions are left unchanged (the shell default), the
-        original word is added to orig_list.  If globbing fails and
-        failed glob expansions are removed, the original word is
-        added to the list of disposable words.  orig_list ends up
-        in reverse order and requires a call to REVERSE_LIST to
-        be set right.  After all words are examined, the disposable
-        words are freed. */
-      next = tlist->next;
-
-      /* If the word isn't an assignment and contains an unquoted
-        pattern matching character, then glob it. */
-      if ((tlist->word->flags & W_NOGLOB) == 0 &&
-         unquoted_glob_pattern_p (tlist->word->word))
-       {
-         glob_array = shell_glob_filename (tlist->word->word);
-
-         /* Handle error cases.
-            I don't think we should report errors like "No such file
-            or directory".  However, I would like to report errors
-            like "Read failed". */
-
-         if (glob_array == 0 || GLOB_FAILED (glob_array))
-           {
-             glob_array = (char **)xmalloc (sizeof (char *));
-             glob_array[0] = (char *)NULL;
-           }
-
-         /* Dequote the current word in case we have to use it. */
-         if (glob_array[0] == NULL)
-           {
-             temp_string = dequote_string (tlist->word->word);
-             free (tlist->word->word);
-             tlist->word->word = temp_string;
-           }
-
-         /* Make the array into a word list. */
-         glob_list = (WORD_LIST *)NULL;
-         for (glob_index = 0; glob_array[glob_index]; glob_index++)
-           {
-             tword = make_bare_word (glob_array[glob_index]);
-             tword->flags |= W_GLOBEXP;        /* XXX */
-             glob_list = make_word_list (tword, glob_list);
-           }
-
-         if (glob_list)
-           {
-             output_list = (WORD_LIST *)list_append (glob_list, output_list);
-             PREPEND_LIST (tlist, disposables);
-           }
-         else if (fail_glob_expansion != 0)
-           {
-             report_error (_("no match: %s"), tlist->word->word);
-             exp_jump_to_top_level (DISCARD);
-           }
-         else if (allow_null_glob_expansion == 0)
-           {
-             /* Failed glob expressions are left unchanged. */
-             PREPEND_LIST (tlist, output_list);
-           }
-         else
-           {
-             /* Failed glob expressions are removed. */
-             PREPEND_LIST (tlist, disposables);
-           }
-       }
-      else
-       {
-         /* Dequote the string. */
-         temp_string = dequote_string (tlist->word->word);
-         free (tlist->word->word);
-         tlist->word->word = temp_string;
-         PREPEND_LIST (tlist, output_list);
-       }
-
-      strvec_dispose (glob_array);
-      glob_array = (char **)NULL;
-
-      tlist = next;
-    }
-
-  if (disposables)
-    dispose_words (disposables);
-
-  if (output_list)
-    output_list = REVERSE_LIST (output_list, WORD_LIST *);
-
-  return (output_list);
-}
-
-#if defined (BRACE_EXPANSION)
-static WORD_LIST *
-brace_expand_word_list (tlist, eflags)
-     WORD_LIST *tlist;
-     int eflags;
-{
-  register char **expansions;
-  char *temp_string;
-  WORD_LIST *disposables, *output_list, *next;
-  WORD_DESC *w;
-  int eindex;
-
-  for (disposables = output_list = (WORD_LIST *)NULL; tlist; tlist = next)
-    {
-      next = tlist->next;
-
-      /* Only do brace expansion if the word has a brace character.  If
-        not, just add the word list element to BRACES and continue.  In
-        the common case, at least when running shell scripts, this will
-        degenerate to a bunch of calls to `xstrchr', and then what is
-        basically a reversal of TLIST into BRACES, which is corrected
-        by a call to REVERSE_LIST () on BRACES when the end of TLIST
-        is reached. */
-      if (xstrchr (tlist->word->word, LBRACE))
-       {
-         expansions = brace_expand (tlist->word->word);
-
-         for (eindex = 0; temp_string = expansions[eindex]; eindex++)
-           {
-             w = make_word (temp_string);
-             /* If brace expansion didn't change the word, preserve
-                the flags.  We may want to preserve the flags
-                unconditionally someday -- XXX */
-             if (STREQ (temp_string, tlist->word->word))
-               w->flags = tlist->word->flags;
-             output_list = make_word_list (w, output_list);
-             free (expansions[eindex]);
-           }
-         free (expansions);
-
-         /* Add TLIST to the list of words to be freed after brace
-            expansion has been performed. */
-         PREPEND_LIST (tlist, disposables);
-       }
-      else
-       PREPEND_LIST (tlist, output_list);
-    }
-
-  if (disposables)
-    dispose_words (disposables);
-
-  if (output_list)
-    output_list = REVERSE_LIST (output_list, WORD_LIST *);
-
-  return (output_list);
-}
-#endif
-
-#if defined (ARRAY_VARS)
-/* Take WORD, a compound associative array assignment, and internally run
-   'declare -A w', where W is the variable name portion of WORD. */
-static int
-make_internal_declare (word, option)
-     char *word;
-     char *option;
-{
-  int t;
-  WORD_LIST *wl;
-  WORD_DESC *w;
-
-  w = make_word (word);
-
-  t = assignment (w->word, 0);
-  w->word[t] = '\0';
-
-  wl = make_word_list (w, (WORD_LIST *)NULL);
-  wl = make_word_list (make_word (option), wl);
-
-  return (declare_builtin (wl));  
-}  
-#endif
-
-static WORD_LIST *
-shell_expand_word_list (tlist, eflags)
-     WORD_LIST *tlist;
-     int eflags;
-{
-  WORD_LIST *expanded, *orig_list, *new_list, *next, *temp_list;
-  int expanded_something, has_dollar_at;
-  char *temp_string;
-
-  /* We do tilde expansion all the time.  This is what 1003.2 says. */
-  new_list = (WORD_LIST *)NULL;
-  for (orig_list = tlist; tlist; tlist = next)
-    {
-      temp_string = tlist->word->word;
-
-      next = tlist->next;
-
-#if defined (ARRAY_VARS)
-      /* If this is a compound array assignment to a builtin that accepts
-         such assignments (e.g., `declare'), take the assignment and perform
-         it separately, handling the semantics of declarations inside shell
-         functions.  This avoids the double-evaluation of such arguments,
-         because `declare' does some evaluation of compound assignments on
-         its own. */
-      if ((tlist->word->flags & (W_COMPASSIGN|W_ASSIGNARG)) == (W_COMPASSIGN|W_ASSIGNARG))
-       {
-         int t;
-
-         if (tlist->word->flags & W_ASSIGNASSOC)
-           make_internal_declare (tlist->word->word, "-A");
-
-         t = do_word_assignment (tlist->word);
-         if (t == 0)
-           {
-             last_command_exit_value = EXECUTION_FAILURE;
-             exp_jump_to_top_level (DISCARD);
-           }
-
-         /* Now transform the word as ksh93 appears to do and go on */
-         t = assignment (tlist->word->word, 0);
-         tlist->word->word[t] = '\0';
-         tlist->word->flags &= ~(W_ASSIGNMENT|W_NOSPLIT|W_COMPASSIGN|W_ASSIGNARG|W_ASSIGNASSOC);
-       }
-#endif
-
-      expanded_something = 0;
-      expanded = expand_word_internal
-       (tlist->word, 0, 0, &has_dollar_at, &expanded_something);
-
-      if (expanded == &expand_word_error || expanded == &expand_word_fatal)
-       {
-         /* By convention, each time this error is returned,
-            tlist->word->word has already been freed. */
-         tlist->word->word = (char *)NULL;
-
-         /* Dispose our copy of the original list. */
-         dispose_words (orig_list);
-         /* Dispose the new list we're building. */
-         dispose_words (new_list);
-
-         last_command_exit_value = EXECUTION_FAILURE;
-         if (expanded == &expand_word_error)
-           exp_jump_to_top_level (DISCARD);
-         else
-           exp_jump_to_top_level (FORCE_EOF);
-       }
-
-      /* Don't split words marked W_NOSPLIT. */
-      if (expanded_something && (tlist->word->flags & W_NOSPLIT) == 0)
-       {
-         temp_list = word_list_split (expanded);
-         dispose_words (expanded);
-       }
-      else
-       {
-         /* If no parameter expansion, command substitution, process
-            substitution, or arithmetic substitution took place, then
-            do not do word splitting.  We still have to remove quoted
-            null characters from the result. */
-         word_list_remove_quoted_nulls (expanded);
-         temp_list = expanded;
-       }
-
-      expanded = REVERSE_LIST (temp_list, WORD_LIST *);
-      new_list = (WORD_LIST *)list_append (expanded, new_list);
-    }
-
-  if (orig_list)  
-    dispose_words (orig_list);
-
-  if (new_list)
-    new_list = REVERSE_LIST (new_list, WORD_LIST *);
-
-  return (new_list);
-}
-
-/* The workhorse for expand_words () and expand_words_no_vars ().
-   First arg is LIST, a WORD_LIST of words.
-   Second arg EFLAGS is a flags word controlling which expansions are
-   performed.
-
-   This does all of the substitutions: brace expansion, tilde expansion,
-   parameter expansion, command substitution, arithmetic expansion,
-   process substitution, word splitting, and pathname expansion, according
-   to the bits set in EFLAGS.  Words with the W_QUOTED or W_NOSPLIT bits
-   set, or for which no expansion is done, do not undergo word splitting.
-   Words with the W_NOGLOB bit set do not undergo pathname expansion. */
-static WORD_LIST *
-expand_word_list_internal (list, eflags)
-     WORD_LIST *list;
-     int eflags;
-{
-  WORD_LIST *new_list, *temp_list;
-  int tint;
-
-  if (list == 0)
-    return ((WORD_LIST *)NULL);
-
-  garglist = new_list = copy_word_list (list);
-  if (eflags & WEXP_VARASSIGN)
-    {
-      garglist = new_list = separate_out_assignments (new_list);
-      if (new_list == 0)
-       {
-         if (subst_assign_varlist)
-           {
-             /* All the words were variable assignments, so they are placed
-                into the shell's environment. */
-             for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
-               {
-                 this_command_name = (char *)NULL;     /* no arithmetic errors */
-                 tint = do_word_assignment (temp_list->word);
-                 /* Variable assignment errors in non-interactive shells
-                    running in Posix.2 mode cause the shell to exit. */
-                 if (tint == 0)
-                   {
-                     last_command_exit_value = EXECUTION_FAILURE;
-                     if (interactive_shell == 0 && posixly_correct)
-                       exp_jump_to_top_level (FORCE_EOF);
-                     else
-                       exp_jump_to_top_level (DISCARD);
-                   }
-               }
-             dispose_words (subst_assign_varlist);
-             subst_assign_varlist = (WORD_LIST *)NULL;
-           }
-         return ((WORD_LIST *)NULL);
-       }
-    }
-
-  /* Begin expanding the words that remain.  The expansions take place on
-     things that aren't really variable assignments. */
-
-#if defined (BRACE_EXPANSION)
-  /* Do brace expansion on this word if there are any brace characters
-     in the string. */
-  if ((eflags & WEXP_BRACEEXP) && brace_expansion && new_list)
-    new_list = brace_expand_word_list (new_list, eflags);
-#endif /* BRACE_EXPANSION */
-
-  /* Perform the `normal' shell expansions: tilde expansion, parameter and
-     variable substitution, command substitution, arithmetic expansion,
-     and word splitting. */
-  new_list = shell_expand_word_list (new_list, eflags);
-
-  /* Okay, we're almost done.  Now let's just do some filename
-     globbing. */
-  if (new_list)
-    {
-      if ((eflags & WEXP_PATHEXP) && disallow_filename_globbing == 0)
-       /* Glob expand the word list unless globbing has been disabled. */
-       new_list = glob_expand_word_list (new_list, eflags);
-      else
-       /* Dequote the words, because we're not performing globbing. */
-       new_list = dequote_list (new_list);
-    }
-
-  if ((eflags & WEXP_VARASSIGN) && subst_assign_varlist)
-    {
-      sh_wassign_func_t *assign_func;
-
-      /* If the remainder of the words expand to nothing, Posix.2 requires
-        that the variable and environment assignments affect the shell's
-        environment. */
-      assign_func = new_list ? assign_in_env : do_word_assignment;
-      tempenv_assign_error = 0;
-
-      for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
-       {
-         this_command_name = (char *)NULL;
-         assigning_in_environment = (assign_func == assign_in_env);
-         tint = (*assign_func) (temp_list->word);
-         assigning_in_environment = 0;
-         /* Variable assignment errors in non-interactive shells running
-            in Posix.2 mode cause the shell to exit. */
-         if (tint == 0)
-           {
-             if (assign_func == do_word_assignment)
-               {
-                 last_command_exit_value = EXECUTION_FAILURE;
-                 if (interactive_shell == 0 && posixly_correct)
-                   exp_jump_to_top_level (FORCE_EOF);
-                 else
-                   exp_jump_to_top_level (DISCARD);
-               }
-             else
-               tempenv_assign_error++;
-           }
-       }
-
-      dispose_words (subst_assign_varlist);
-      subst_assign_varlist = (WORD_LIST *)NULL;
-    }
-
-#if 0
-  tint = list_length (new_list) + 1;
-  RESIZE_MALLOCED_BUFFER (glob_argv_flags, 0, tint, glob_argv_flags_size, 16);
-  for (tint = 0, temp_list = new_list; temp_list; temp_list = temp_list->next)
-    glob_argv_flags[tint++] = (temp_list->word->flags & W_GLOBEXP) ? '1' : '0';
-  glob_argv_flags[tint] = '\0';
-#endif
-
-  return (new_list);
-}
diff --git a/subst.c.save1 b/subst.c.save1
deleted file mode 100644 (file)
index 2963210..0000000
+++ /dev/null
@@ -1,9055 +0,0 @@
-/* subst.c -- The part of the shell that does parameter, command, arithmetic,
-   and globbing substitutions. */
-
-/* ``Have a little faith, there's magic in the night.  You ain't a
-     beauty, but, hey, you're alright.'' */
-
-/* Copyright (C) 1987-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/>.
-*/
-
-#include "config.h"
-
-#include "bashtypes.h"
-#include <stdio.h>
-#include "chartypes.h"
-#if defined (HAVE_PWD_H)
-#  include <pwd.h>
-#endif
-#include <signal.h>
-#include <errno.h>
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include "bashansi.h"
-#include "posixstat.h"
-#include "bashintl.h"
-
-#include "shell.h"
-#include "flags.h"
-#include "jobs.h"
-#include "execute_cmd.h"
-#include "filecntl.h"
-#include "trap.h"
-#include "pathexp.h"
-#include "mailcheck.h"
-
-#include "shmbutil.h"
-
-#include "builtins/getopt.h"
-#include "builtins/common.h"
-
-#include "builtins/builtext.h"
-
-#include <tilde/tilde.h>
-#include <glob/strmatch.h>
-
-#if !defined (errno)
-extern int errno;
-#endif /* !errno */
-
-/* The size that strings change by. */
-#define DEFAULT_INITIAL_ARRAY_SIZE 112
-#define DEFAULT_ARRAY_SIZE 128
-
-/* Variable types. */
-#define VT_VARIABLE    0
-#define VT_POSPARMS    1
-#define VT_ARRAYVAR    2
-#define VT_ARRAYMEMBER 3
-#define VT_ASSOCVAR    4
-
-#define VT_STARSUB     128     /* $* or ${array[*]} -- used to split */
-
-/* Flags for quoted_strchr */
-#define ST_BACKSL      0x01
-#define ST_CTLESC      0x02
-#define ST_SQUOTE      0x04    /* unused yet */
-#define ST_DQUOTE      0x08    /* unused yet */
-
-/* Flags for the `pflags' argument to param_expand() */
-#define PF_NOCOMSUB    0x01    /* Do not perform command substitution */
-#define PF_IGNUNBOUND  0x02    /* ignore unbound vars even if -u set */
-#define PF_NOSPLIT2    0x04    /* same as W_NOSPLIT2 */
-
-/* These defs make it easier to use the editor. */
-#define LBRACE         '{'
-#define RBRACE         '}'
-#define LPAREN         '('
-#define RPAREN         ')'
-
-#if defined (HANDLE_MULTIBYTE)
-#define WLPAREN                L'('
-#define WRPAREN                L')'
-#endif
-
-/* Evaluates to 1 if C is one of the shell's special parameters whose length
-   can be taken, but is also one of the special expansion characters. */
-#define VALID_SPECIAL_LENGTH_PARAM(c) \
-  ((c) == '-' || (c) == '?' || (c) == '#')
-
-/* Evaluates to 1 if C is one of the shell's special parameters for which an
-   indirect variable reference may be made. */
-#define VALID_INDIR_PARAM(c) \
-  ((c) == '#' || (c) == '?' || (c) == '@' || (c) == '*')
-
-/* Evaluates to 1 if C is one of the OP characters that follows the parameter
-   in ${parameter[:]OPword}. */
-#define VALID_PARAM_EXPAND_CHAR(c) (sh_syntaxtab[(unsigned char)c] & CSUBSTOP)
-
-/* Evaluates to 1 if this is one of the shell's special variables. */
-#define SPECIAL_VAR(name, wi) \
- ((DIGIT (*name) && all_digits (name)) || \
-      (name[1] == '\0' && (sh_syntaxtab[(unsigned char)*name] & CSPECVAR)) || \
-      (wi && name[2] == '\0' && VALID_INDIR_PARAM (name[1])))
-
-/* An expansion function that takes a string and a quoted flag and returns
-   a WORD_LIST *.  Used as the type of the third argument to
-   expand_string_if_necessary(). */
-typedef WORD_LIST *EXPFUNC __P((char *, int));
-
-/* Process ID of the last command executed within command substitution. */
-pid_t last_command_subst_pid = NO_PID;
-pid_t current_command_subst_pid = NO_PID;
-
-/* Variables used to keep track of the characters in IFS. */
-SHELL_VAR *ifs_var;
-char *ifs_value;
-unsigned char ifs_cmap[UCHAR_MAX + 1];
-
-#if defined (HANDLE_MULTIBYTE)
-unsigned char ifs_firstc[MB_LEN_MAX];
-size_t ifs_firstc_len;
-#else
-unsigned char ifs_firstc;
-#endif
-
-/* Sentinel to tell when we are performing variable assignments preceding a
-   command name and putting them into the environment.  Used to make sure
-   we use the temporary environment when looking up variable values. */
-int assigning_in_environment;
-
-/* Used to hold a list of variable assignments preceding a command.  Global
-   so the SIGCHLD handler in jobs.c can unwind-protect it when it runs a
-   SIGCHLD trap and so it can be saved and restored by the trap handlers. */
-WORD_LIST *subst_assign_varlist = (WORD_LIST *)NULL;
-
-/* Extern functions and variables from different files. */
-extern int last_command_exit_value, last_command_exit_signal;
-extern int subshell_environment, line_number;
-extern int subshell_level, parse_and_execute_level, sourcelevel;
-extern int eof_encountered;
-extern int return_catch_flag, return_catch_value;
-extern pid_t dollar_dollar_pid;
-extern int posixly_correct;
-extern char *this_command_name;
-extern struct fd_bitmap *current_fds_to_close;
-extern int wordexp_only;
-extern int expanding_redir;
-extern int tempenv_assign_error;
-
-#if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE)
-extern wchar_t *wcsdup __P((const wchar_t *));
-#endif
-
-/* Non-zero means to allow unmatched globbed filenames to expand to
-   a null file. */
-int allow_null_glob_expansion;
-
-/* Non-zero means to throw an error when globbing fails to match anything. */
-int fail_glob_expansion;
-
-#if 0
-/* Variables to keep track of which words in an expanded word list (the
-   output of expand_word_list_internal) are the result of globbing
-   expansions.  GLOB_ARGV_FLAGS is used by execute_cmd.c.
-   (CURRENTLY UNUSED). */
-char *glob_argv_flags;
-static int glob_argv_flags_size;
-#endif
-
-static WORD_LIST expand_word_error, expand_word_fatal;
-static WORD_DESC expand_wdesc_error, expand_wdesc_fatal;
-static char expand_param_error, expand_param_fatal;
-static char extract_string_error, extract_string_fatal;
-
-/* Tell the expansion functions to not longjmp back to top_level on fatal
-   errors.  Enabled when doing completion and prompt string expansion. */
-static int no_longjmp_on_fatal_error = 0;
-
-/* Set by expand_word_unsplit; used to inhibit splitting and re-joining
-   $* on $IFS, primarily when doing assignment statements. */
-static int expand_no_split_dollar_star = 0;
-
-/* A WORD_LIST of words to be expanded by expand_word_list_internal,
-   without any leading variable assignments. */
-static WORD_LIST *garglist = (WORD_LIST *)NULL;
-
-static char *quoted_substring __P((char *, int, int));
-static int quoted_strlen __P((char *));
-static char *quoted_strchr __P((char *, int, int));
-
-static char *expand_string_if_necessary __P((char *, int, EXPFUNC *));
-static inline char *expand_string_to_string_internal __P((char *, int, EXPFUNC *));
-static WORD_LIST *call_expand_word_internal __P((WORD_DESC *, int, int, int *, int *));
-static WORD_LIST *expand_string_internal __P((char *, int));
-static WORD_LIST *expand_string_leave_quoted __P((char *, int));
-static WORD_LIST *expand_string_for_rhs __P((char *, int, int *, int *));
-
-static WORD_LIST *list_quote_escapes __P((WORD_LIST *));
-static char *make_quoted_char __P((int));
-static WORD_LIST *quote_list __P((WORD_LIST *));
-
-static int unquoted_substring __P((char *, char *));
-static int unquoted_member __P((int, char *));
-
-#if defined (ARRAY_VARS)
-static SHELL_VAR *do_compound_assignment __P((char *, char *, int));
-#endif
-static int do_assignment_internal __P((const WORD_DESC *, int));
-
-static char *string_extract_verbatim __P((char *, size_t, int *, char *, int));
-static char *string_extract __P((char *, int *, char *, int));
-static char *string_extract_double_quoted __P((char *, int *, int));
-static inline char *string_extract_single_quoted __P((char *, int *));
-static inline int skip_single_quoted __P((const char *, size_t, int));
-static int skip_double_quoted __P((char *, size_t, int));
-static char *extract_delimited_string __P((char *, int *, char *, char *, char *, int));
-static char *extract_dollar_brace_string __P((char *, int *, int, int));
-static int skip_matched_pair __P((const char *, int, int, int, int));
-
-static char *pos_params __P((char *, int, int, int));
-
-static unsigned char *mb_getcharlens __P((char *, int));
-
-static char *remove_upattern __P((char *, char *, int));
-#if defined (HANDLE_MULTIBYTE) 
-static wchar_t *remove_wpattern __P((wchar_t *, size_t, wchar_t *, int));
-#endif
-static char *remove_pattern __P((char *, char *, int));
-
-static int match_pattern_char __P((char *, char *));
-static int match_upattern __P((char *, char *, int, char **, char **));
-#if defined (HANDLE_MULTIBYTE)
-static int match_pattern_wchar __P((wchar_t *, wchar_t *));
-static int match_wpattern __P((wchar_t *, char **, size_t, wchar_t *, int, char **, char **));
-#endif
-static int match_pattern __P((char *, char *, int, char **, char **));
-static int getpatspec __P((int, char *));
-static char *getpattern __P((char *, int, int));
-static char *variable_remove_pattern __P((char *, char *, int, int));
-static char *list_remove_pattern __P((WORD_LIST *, char *, int, int, int));
-static char *parameter_list_remove_pattern __P((int, char *, int, int));
-#ifdef ARRAY_VARS
-static char *array_remove_pattern __P((SHELL_VAR *, char *, int, char *, int));
-#endif
-static char *parameter_brace_remove_pattern __P((char *, char *, char *, int, int));
-
-static char *process_substitute __P((char *, int));
-
-static char *read_comsub __P((int, int, int *));
-
-#ifdef ARRAY_VARS
-static arrayind_t array_length_reference __P((char *));
-#endif
-
-static int valid_brace_expansion_word __P((char *, int));
-static int chk_atstar __P((char *, int, int *, int *));
-static int chk_arithsub __P((const char *, int));
-
-static WORD_DESC *parameter_brace_expand_word __P((char *, int, int, int));
-static WORD_DESC *parameter_brace_expand_indir __P((char *, int, int, int *, int *));
-static WORD_DESC *parameter_brace_expand_rhs __P((char *, char *, int, int, int *, int *));
-static void parameter_brace_expand_error __P((char *, char *));
-
-static int valid_length_expression __P((char *));
-static intmax_t parameter_brace_expand_length __P((char *));
-
-static char *skiparith __P((char *, int));
-static int verify_substring_values __P((SHELL_VAR *, char *, char *, int, intmax_t *, intmax_t *));
-static int get_var_and_type __P((char *, char *, int, SHELL_VAR **, char **));
-static char *mb_substring __P((char *, int, int));
-static char *parameter_brace_substring __P((char *, char *, char *, int));
-
-static char *pos_params_pat_subst __P((char *, char *, char *, int));
-
-static char *parameter_brace_patsub __P((char *, char *, char *, int));
-
-static char *pos_params_casemod __P((char *, char *, int, int));
-static char *parameter_brace_casemod __P((char *, char *, int, char *, int));
-
-static WORD_DESC *parameter_brace_expand __P((char *, int *, int, int, int *, int *));
-static WORD_DESC *param_expand __P((char *, int *, int, int *, int *, int *, int *, int));
-
-static WORD_LIST *expand_word_internal __P((WORD_DESC *, int, int, int *, int *));
-
-static WORD_LIST *word_list_split __P((WORD_LIST *));
-
-static void exp_jump_to_top_level __P((int));
-
-static WORD_LIST *separate_out_assignments __P((WORD_LIST *));
-static WORD_LIST *glob_expand_word_list __P((WORD_LIST *, int));
-#ifdef BRACE_EXPANSION
-static WORD_LIST *brace_expand_word_list __P((WORD_LIST *, int));
-#endif
-#if defined (ARRAY_VARS)
-static int make_internal_declare __P((char *, char *));
-#endif
-static WORD_LIST *shell_expand_word_list __P((WORD_LIST *, int));
-static WORD_LIST *expand_word_list_internal __P((WORD_LIST *, int));
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Utility Functions                           */
-/*                                                                 */
-/* **************************************************************** */
-
-#if defined (DEBUG)
-void
-dump_word_flags (flags)
-     int flags;
-{
-  int f;
-
-  f = flags;
-  fprintf (stderr, "%d -> ", f);
-  if (f & W_ASSIGNASSOC)
-    {
-      f &= ~W_ASSIGNASSOC;
-      fprintf (stderr, "W_ASSIGNASSOC%s", f ? "|" : "");
-    }
-  if (f & W_HASCTLESC)
-    {
-      f &= ~W_HASCTLESC;
-      fprintf (stderr, "W_HASCTLESC%s", f ? "|" : "");
-    }
-  if (f & W_NOPROCSUB)
-    {
-      f &= ~W_NOPROCSUB;
-      fprintf (stderr, "W_NOPROCSUB%s", f ? "|" : "");
-    }
-  if (f & W_DQUOTE)
-    {
-      f &= ~W_DQUOTE;
-      fprintf (stderr, "W_DQUOTE%s", f ? "|" : "");
-    }
-  if (f & W_HASQUOTEDNULL)
-    {
-      f &= ~W_HASQUOTEDNULL;
-      fprintf (stderr, "W_HASQUOTEDNULL%s", f ? "|" : "");
-    }
-  if (f & W_ASSIGNARG)
-    {
-      f &= ~W_ASSIGNARG;
-      fprintf (stderr, "W_ASSIGNARG%s", f ? "|" : "");
-    }
-  if (f & W_ASSNBLTIN)
-    {
-      f &= ~W_ASSNBLTIN;
-      fprintf (stderr, "W_ASSNBLTIN%s", f ? "|" : "");
-    }
-  if (f & W_COMPASSIGN)
-    {
-      f &= ~W_COMPASSIGN;
-      fprintf (stderr, "W_COMPASSIGN%s", f ? "|" : "");
-    }
-  if (f & W_NOEXPAND)
-    {
-      f &= ~W_NOEXPAND;
-      fprintf (stderr, "W_NOEXPAND%s", f ? "|" : "");
-    }
-  if (f & W_ITILDE)
-    {
-      f &= ~W_ITILDE;
-      fprintf (stderr, "W_ITILDE%s", f ? "|" : "");
-    }
-  if (f & W_NOTILDE)
-    {
-      f &= ~W_NOTILDE;
-      fprintf (stderr, "W_NOTILDE%s", f ? "|" : "");
-    }
-  if (f & W_ASSIGNRHS)
-    {
-      f &= ~W_ASSIGNRHS;
-      fprintf (stderr, "W_ASSIGNRHS%s", f ? "|" : "");
-    }
-  if (f & W_NOCOMSUB)
-    {
-      f &= ~W_NOCOMSUB;
-      fprintf (stderr, "W_NOCOMSUB%s", f ? "|" : "");
-    }
-  if (f & W_DOLLARSTAR)
-    {
-      f &= ~W_DOLLARSTAR;
-      fprintf (stderr, "W_DOLLARSTAR%s", f ? "|" : "");
-    }
-  if (f & W_DOLLARAT)
-    {
-      f &= ~W_DOLLARAT;
-      fprintf (stderr, "W_DOLLARAT%s", f ? "|" : "");
-    }
-  if (f & W_TILDEEXP)
-    {
-      f &= ~W_TILDEEXP;
-      fprintf (stderr, "W_TILDEEXP%s", f ? "|" : "");
-    }
-  if (f & W_NOSPLIT2)
-    {
-      f &= ~W_NOSPLIT2;
-      fprintf (stderr, "W_NOSPLIT2%s", f ? "|" : "");
-    }
-  if (f & W_NOGLOB)
-    {
-      f &= ~W_NOGLOB;
-      fprintf (stderr, "W_NOGLOB%s", f ? "|" : "");
-    }
-  if (f & W_NOSPLIT)
-    {
-      f &= ~W_NOSPLIT;
-      fprintf (stderr, "W_NOSPLIT%s", f ? "|" : "");
-    }
-  if (f & W_GLOBEXP)
-    {
-      f &= ~W_GLOBEXP;
-      fprintf (stderr, "W_GLOBEXP%s", f ? "|" : "");
-    }
-  if (f & W_ASSIGNMENT)
-    {
-      f &= ~W_ASSIGNMENT;
-      fprintf (stderr, "W_ASSIGNMENT%s", f ? "|" : "");
-    }
-  if (f & W_QUOTED)
-    {
-      f &= ~W_QUOTED;
-      fprintf (stderr, "W_QUOTED%s", f ? "|" : "");
-    }
-  if (f & W_HASDOLLAR)
-    {
-      f &= ~W_HASDOLLAR;
-      fprintf (stderr, "W_HASDOLLAR%s", f ? "|" : "");
-    }
-  fprintf (stderr, "\n");
-  fflush (stderr);
-}
-#endif
-
-#ifdef INCLUDE_UNUSED
-static char *
-quoted_substring (string, start, end)
-     char *string;
-     int start, end;
-{
-  register int len, l;
-  register char *result, *s, *r;
-
-  len = end - start;
-
-  /* Move to string[start], skipping quoted characters. */
-  for (s = string, l = 0; *s && l < start; )
-    {
-      if (*s == CTLESC)
-       {
-         s++;
-         continue;
-       }
-      l++;
-      if (*s == 0)
-       break;
-    }
-
-  r = result = (char *)xmalloc (2*len + 1);      /* save room for quotes */
-
-  /* Copy LEN characters, including quote characters. */
-  s = string + l;
-  for (l = 0; l < len; s++)
-    {
-      if (*s == CTLESC)
-       *r++ = *s++;
-      *r++ = *s;
-      l++;
-      if (*s == 0)
-       break;
-    }
-  *r = '\0';
-  return result;
-}
-#endif
-
-#ifdef INCLUDE_UNUSED
-/* Return the length of S, skipping over quoted characters */
-static int
-quoted_strlen (s)
-     char *s;
-{
-  register char *p;
-  int i;
-
-  i = 0;
-  for (p = s; *p; p++)
-    {
-      if (*p == CTLESC)
-       {
-         p++;
-         if (*p == 0)
-           return (i + 1);
-       }
-      i++;
-    }
-
-  return i;
-}
-#endif
-
-/* Find the first occurrence of character C in string S, obeying shell
-   quoting rules.  If (FLAGS & ST_BACKSL) is non-zero, backslash-escaped
-   characters are skipped.  If (FLAGS & ST_CTLESC) is non-zero, characters
-   escaped with CTLESC are skipped. */
-static char *
-quoted_strchr (s, c, flags)
-     char *s;
-     int c, flags;
-{
-  register char *p;
-
-  for (p = s; *p; p++)
-    {
-      if (((flags & ST_BACKSL) && *p == '\\')
-           || ((flags & ST_CTLESC) && *p == CTLESC))
-       {
-         p++;
-         if (*p == '\0')
-           return ((char *)NULL);
-         continue;
-       }
-      else if (*p == c)
-       return p;
-    }
-  return ((char *)NULL);
-}
-
-/* Return 1 if CHARACTER appears in an unquoted portion of
-   STRING.  Return 0 otherwise.  CHARACTER must be a single-byte character. */
-static int
-unquoted_member (character, string)
-     int character;
-     char *string;
-{
-  size_t slen;
-  int sindex, c;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string);
-  sindex = 0;
-  while (c = string[sindex])
-    {
-      if (c == character)
-       return (1);
-
-      switch (c)
-       {
-       default:
-         ADVANCE_CHAR (string, slen, sindex);
-         break;
-
-       case '\\':
-         sindex++;
-         if (string[sindex])
-           ADVANCE_CHAR (string, slen, sindex);
-         break;
-
-       case '\'':
-         sindex = skip_single_quoted (string, slen, ++sindex);
-         break;
-
-       case '"':
-         sindex = skip_double_quoted (string, slen, ++sindex);
-         break;
-       }
-    }
-  return (0);
-}
-
-/* Return 1 if SUBSTR appears in an unquoted portion of STRING. */
-static int
-unquoted_substring (substr, string)
-     char *substr, *string;
-{
-  size_t slen;
-  int sindex, c, sublen;
-  DECLARE_MBSTATE;
-
-  if (substr == 0 || *substr == '\0')
-    return (0);
-
-  slen = strlen (string);
-  sublen = strlen (substr);
-  for (sindex = 0; c = string[sindex]; )
-    {
-      if (STREQN (string + sindex, substr, sublen))
-       return (1);
-
-      switch (c)
-       {
-       case '\\':
-         sindex++;
-
-         if (string[sindex])
-           ADVANCE_CHAR (string, slen, sindex);
-         break;
-
-       case '\'':
-         sindex = skip_single_quoted (string, slen, ++sindex);
-         break;
-
-       case '"':
-         sindex = skip_double_quoted (string, slen, ++sindex);
-         break;
-
-       default:
-         ADVANCE_CHAR (string, slen, sindex);
-         break;
-       }
-    }
-  return (0);
-}
-
-/* Most of the substitutions must be done in parallel.  In order
-   to avoid using tons of unclear goto's, I have some functions
-   for manipulating malloc'ed strings.  They all take INDX, a
-   pointer to an integer which is the offset into the string
-   where manipulation is taking place.  They also take SIZE, a
-   pointer to an integer which is the current length of the
-   character array for this string. */
-
-/* Append SOURCE to TARGET at INDEX.  SIZE is the current amount
-   of space allocated to TARGET.  SOURCE can be NULL, in which
-   case nothing happens.  Gets rid of SOURCE by freeing it.
-   Returns TARGET in case the location has changed. */
-INLINE char *
-sub_append_string (source, target, indx, size)
-     char *source, *target;
-     int *indx, *size;
-{
-  if (source)
-    {
-      int srclen, n;
-
-      srclen = STRLEN (source);
-      if (srclen >= (int)(*size - *indx))
-       {
-         n = srclen + *indx;
-         n = (n + DEFAULT_ARRAY_SIZE) - (n % DEFAULT_ARRAY_SIZE);
-         target = (char *)xrealloc (target, (*size = n));
-       }
-
-      FASTCOPY (source, target + *indx, srclen);
-      *indx += srclen;
-      target[*indx] = '\0';
-
-      free (source);
-    }
-  return (target);
-}
-
-#if 0
-/* UNUSED */
-/* Append the textual representation of NUMBER to TARGET.
-   INDX and SIZE are as in SUB_APPEND_STRING. */
-char *
-sub_append_number (number, target, indx, size)
-     intmax_t number;
-     int *indx, *size;
-     char *target;
-{
-  char *temp;
-
-  temp = itos (number);
-  return (sub_append_string (temp, target, indx, size));
-}
-#endif
-
-/* Extract a substring from STRING, starting at SINDEX and ending with
-   one of the characters in CHARLIST.  Don't make the ending character
-   part of the string.  Leave SINDEX pointing at the ending character.
-   Understand about backslashes in the string.  If (flags & SX_VARNAME)
-   is non-zero, and array variables have been compiled into the shell,
-   everything between a `[' and a corresponding `]' is skipped over.
-   If (flags & SX_NOALLOC) is non-zero, don't return the substring, just
-   update SINDEX.  If (flags & SX_REQMATCH) is non-zero, the string must
-   contain a closing character from CHARLIST. */
-static char *
-string_extract (string, sindex, charlist, flags)
-     char *string;
-     int *sindex;
-     char *charlist;
-     int flags;
-{
-  register int c, i;
-  int found;
-  size_t slen;
-  char *temp;
-  DECLARE_MBSTATE;
-
-  slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0;
-  i = *sindex;
-  found = 0;
-  while (c = string[i])
-    {
-      if (c == '\\')
-       {
-         if (string[i + 1])
-           i++;
-         else
-           break;
-       }
-#if defined (ARRAY_VARS)
-      else if ((flags & SX_VARNAME) && c == '[')
-       {
-         int ni;
-         /* If this is an array subscript, skip over it and continue. */
-         ni = skipsubscript (string, i, 0);
-         if (string[ni] == ']')
-           i = ni;
-       }
-#endif
-      else if (MEMBER (c, charlist))
-       {
-         found = 1;
-         break;
-       }
-
-      ADVANCE_CHAR (string, slen, i);
-    }
-
-  /* If we had to have a matching delimiter and didn't find one, return an
-     error and let the caller deal with it. */
-  if ((flags & SX_REQMATCH) && found == 0)
-    {
-      *sindex = i;
-      return (&extract_string_error);
-    }
-  
-  temp = (flags & SX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i);
-  *sindex = i;
-  
-  return (temp);
-}
-
-/* Extract the contents of STRING as if it is enclosed in double quotes.
-   SINDEX, when passed in, is the offset of the character immediately
-   following the opening double quote; on exit, SINDEX is left pointing after
-   the closing double quote.  If STRIPDQ is non-zero, unquoted double
-   quotes are stripped and the string is terminated by a null byte.
-   Backslashes between the embedded double quotes are processed.  If STRIPDQ
-   is zero, an unquoted `"' terminates the string. */
-static char *
-string_extract_double_quoted (string, sindex, stripdq)
-     char *string;
-     int *sindex, stripdq;
-{
-  size_t slen;
-  char *send;
-  int j, i, t;
-  unsigned char c;
-  char *temp, *ret;            /* The new string we return. */
-  int pass_next, backquote, si;        /* State variables for the machine. */
-  int dquote;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string + *sindex) + *sindex;
-  send = string + slen;
-
-  pass_next = backquote = dquote = 0;
-  temp = (char *)xmalloc (1 + slen - *sindex);
-
-  j = 0;
-  i = *sindex;
-  while (c = string[i])
-    {
-      /* Process a character that was quoted by a backslash. */
-      if (pass_next)
-       {
-         /* Posix.2 sez:
-
-            ``The backslash shall retain its special meaning as an escape
-            character only when followed by one of the characters:
-               $       `       "       \       <newline>''.
-
-            If STRIPDQ is zero, we handle the double quotes here and let
-            expand_word_internal handle the rest.  If STRIPDQ is non-zero,
-            we have already been through one round of backslash stripping,
-            and want to strip these backslashes only if DQUOTE is non-zero,
-            indicating that we are inside an embedded double-quoted string. */
-
-            /* If we are in an embedded quoted string, then don't strip
-               backslashes before characters for which the backslash
-               retains its special meaning, but remove backslashes in
-               front of other characters.  If we are not in an
-               embedded quoted string, don't strip backslashes at all.
-               This mess is necessary because the string was already
-               surrounded by double quotes (and sh has some really weird
-               quoting rules).
-               The returned string will be run through expansion as if
-               it were double-quoted. */
-         if ((stripdq == 0 && c != '"') ||
-             (stripdq && ((dquote && (sh_syntaxtab[c] & CBSDQUOTE)) || dquote == 0)))
-           temp[j++] = '\\';
-         pass_next = 0;
-
-add_one_character:
-         COPY_CHAR_I (temp, j, string, send, i);
-         continue;
-       }
-
-      /* A backslash protects the next character.  The code just above
-        handles preserving the backslash in front of any character but
-        a double quote. */
-      if (c == '\\')
-       {
-         pass_next++;
-         i++;
-         continue;
-       }
-
-      /* Inside backquotes, ``the portion of the quoted string from the
-        initial backquote and the characters up to the next backquote
-        that is not preceded by a backslash, having escape characters
-        removed, defines that command''. */
-      if (backquote)
-       {
-         if (c == '`')
-           backquote = 0;
-         temp[j++] = c;
-         i++;
-         continue;
-       }
-
-      if (c == '`')
-       {
-         temp[j++] = c;
-         backquote++;
-         i++;
-         continue;
-       }
-
-      /* Pass everything between `$(' and the matching `)' or a quoted
-        ${ ... } pair through according to the Posix.2 specification. */
-      if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
-       {
-         int free_ret = 1;
-
-         si = i + 2;
-         if (string[i + 1] == LPAREN)
-           ret = extract_command_subst (string, &si, 0);
-         else
-           ret = extract_dollar_brace_string (string, &si, 1, 0);
-
-         temp[j++] = '$';
-         temp[j++] = string[i + 1];
-
-         /* Just paranoia; ret will not be 0 unless no_longjmp_on_fatal_error
-            is set. */
-         if (ret == 0 && no_longjmp_on_fatal_error)
-           {
-             free_ret = 0;
-             ret = string + i + 2;
-           }
-
-         for (t = 0; ret[t]; t++, j++)
-           temp[j] = ret[t];
-         temp[j] = string[si];
-
-         if (string[si])
-           {
-             j++;
-             i = si + 1;
-           }
-         else
-           i = si;
-
-         if (free_ret)
-           free (ret);
-         continue;
-       }
-
-      /* Add any character but a double quote to the quoted string we're
-        accumulating. */
-      if (c != '"')
-       goto add_one_character;
-
-      /* c == '"' */
-      if (stripdq)
-       {
-         dquote ^= 1;
-         i++;
-         continue;
-       }
-
-      break;
-    }
-  temp[j] = '\0';
-
-  /* Point to after the closing quote. */
-  if (c)
-    i++;
-  *sindex = i;
-
-  return (temp);
-}
-
-/* This should really be another option to string_extract_double_quoted. */
-static int
-skip_double_quoted (string, slen, sind)
-     char *string;
-     size_t slen;
-     int sind;
-{
-  int c, i;
-  char *ret;
-  int pass_next, backquote, si;
-  DECLARE_MBSTATE;
-
-  pass_next = backquote = 0;
-  i = sind;
-  while (c = string[i])
-    {
-      if (pass_next)
-       {
-         pass_next = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (c == '\\')
-       {
-         pass_next++;
-         i++;
-         continue;
-       }
-      else if (backquote)
-       {
-         if (c == '`')
-           backquote = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (c == '`')
-       {
-         backquote++;
-         i++;
-         continue;
-       }
-      else if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
-       {
-         si = i + 2;
-         if (string[i + 1] == LPAREN)
-           ret = extract_command_subst (string, &si, SX_NOALLOC);
-         else
-           ret = extract_dollar_brace_string (string, &si, 1, SX_NOALLOC);
-
-         i = si + 1;
-         continue;
-       }
-      else if (c != '"')
-       {
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else
-       break;
-    }
-
-  if (c)
-    i++;
-
-  return (i);
-}
-
-/* Extract the contents of STRING as if it is enclosed in single quotes.
-   SINDEX, when passed in, is the offset of the character immediately
-   following the opening single quote; on exit, SINDEX is left pointing after
-   the closing single quote. */
-static inline char *
-string_extract_single_quoted (string, sindex)
-     char *string;
-     int *sindex;
-{
-  register int i;
-  size_t slen;
-  char *t;
-  DECLARE_MBSTATE;
-
-  /* Don't need slen for ADVANCE_CHAR unless multibyte chars possible. */
-  slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0;
-  i = *sindex;
-  while (string[i] && string[i] != '\'')
-    ADVANCE_CHAR (string, slen, i);
-
-  t = substring (string, *sindex, i);
-
-  if (string[i])
-    i++;
-  *sindex = i;
-
-  return (t);
-}
-
-static inline int
-skip_single_quoted (string, slen, sind)
-     const char *string;
-     size_t slen;
-     int sind;
-{
-  register int c;
-  DECLARE_MBSTATE;
-
-  c = sind;
-  while (string[c] && string[c] != '\'')
-    ADVANCE_CHAR (string, slen, c);
-
-  if (string[c])
-    c++;
-  return c;
-}
-
-/* Just like string_extract, but doesn't hack backslashes or any of
-   that other stuff.  Obeys CTLESC quoting.  Used to do splitting on $IFS. */
-static char *
-string_extract_verbatim (string, slen, sindex, charlist, flags)
-     char *string;
-     size_t slen;
-     int *sindex;
-     char *charlist;
-     int flags;
-{
-  register int i;
-#if defined (HANDLE_MULTIBYTE)
-  size_t clen;
-  wchar_t *wcharlist;
-#endif
-  int c;
-  char *temp;
-  DECLARE_MBSTATE;
-
-  if (charlist[0] == '\'' && charlist[1] == '\0')
-    {
-      temp = string_extract_single_quoted (string, sindex);
-      --*sindex;       /* leave *sindex at separator character */
-      return temp;
-    }
-
-  i = *sindex;
-#if 0
-  /* See how the MBLEN and ADVANCE_CHAR macros work to understand why we need
-     this only if MB_CUR_MAX > 1. */
-  slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 1;
-#endif
-#if defined (HANDLE_MULTIBYTE)
-  clen = strlen (charlist);
-  wcharlist = 0;
-#endif
-  while (c = string[i])
-    {
-#if defined (HANDLE_MULTIBYTE)
-      size_t mblength;
-#endif
-      if ((flags & SX_NOCTLESC) == 0 && c == CTLESC)
-       {
-         i += 2;
-         continue;
-       }
-      /* Even if flags contains SX_NOCTLESC, we let CTLESC quoting CTLNUL
-        through, to protect the CTLNULs from later calls to
-        remove_quoted_nulls. */
-      else if ((flags & SX_NOESCCTLNUL) == 0 && c == CTLESC && string[i+1] == CTLNUL)
-       {
-         i += 2;
-         continue;
-       }
-
-#if defined (HANDLE_MULTIBYTE)
-      mblength = MBLEN (string + i, slen - i);
-      if (mblength > 1)
-       {
-         wchar_t wc;
-         mblength = mbtowc (&wc, string + i, slen - i);
-         if (MB_INVALIDCH (mblength))
-           {
-             if (MEMBER (c, charlist))
-               break;
-           }
-         else
-           {
-             if (wcharlist == 0)
-               {
-                 size_t len;
-                 len = mbstowcs (wcharlist, charlist, 0);
-                 if (len == -1)
-                   len = 0;
-                 wcharlist = (wchar_t *)xmalloc (sizeof (wchar_t) * (len + 1));
-                 mbstowcs (wcharlist, charlist, len + 1);
-               }
-
-             if (wcschr (wcharlist, wc))
-               break;
-           }
-       }
-      else             
-#endif
-      if (MEMBER (c, charlist))
-       break;
-
-      ADVANCE_CHAR (string, slen, i);
-    }
-
-#if defined (HANDLE_MULTIBYTE)
-  FREE (wcharlist);
-#endif
-
-  temp = substring (string, *sindex, i);
-  *sindex = i;
-
-  return (temp);
-}
-
-/* Extract the $( construct in STRING, and return a new string.
-   Start extracting at (SINDEX) as if we had just seen "$(".
-   Make (SINDEX) get the position of the matching ")". )
-   XFLAGS is additional flags to pass to other extraction functions. */
-char *
-extract_command_subst (string, sindex, xflags)
-     char *string;
-     int *sindex;
-     int xflags;
-{
-  if (string[*sindex] == LPAREN)
-    return (extract_delimited_string (string, sindex, "$(", "(", ")", xflags|SX_COMMAND)); /*)*/
-  else
-    {
-      xflags |= (no_longjmp_on_fatal_error ? SX_NOLONGJMP : 0);
-      return (xparse_dolparen (string, string+*sindex, sindex, xflags));
-    }
-}
-
-/* Extract the $[ construct in STRING, and return a new string. (])
-   Start extracting at (SINDEX) as if we had just seen "$[".
-   Make (SINDEX) get the position of the matching "]". */
-char *
-extract_arithmetic_subst (string, sindex)
-     char *string;
-     int *sindex;
-{
-  return (extract_delimited_string (string, sindex, "$[", "[", "]", 0)); /*]*/
-}
-
-#if defined (PROCESS_SUBSTITUTION)
-/* Extract the <( or >( construct in STRING, and return a new string.
-   Start extracting at (SINDEX) as if we had just seen "<(".
-   Make (SINDEX) get the position of the matching ")". */ /*))*/
-char *
-extract_process_subst (string, starter, sindex)
-     char *string;
-     char *starter;
-     int *sindex;
-{
-  return (extract_delimited_string (string, sindex, starter, "(", ")", 0));
-}
-#endif /* PROCESS_SUBSTITUTION */
-
-#if defined (ARRAY_VARS)
-/* This can be fooled by unquoted right parens in the passed string. If
-   each caller verifies that the last character in STRING is a right paren,
-   we don't even need to call extract_delimited_string. */
-char *
-extract_array_assignment_list (string, sindex)
-     char *string;
-     int *sindex;
-{
-  int slen;
-  char *ret;
-
-  slen = strlen (string);      /* ( */
-  if (string[slen - 1] == ')')
-   {
-      ret = substring (string, *sindex, slen - 1);
-      *sindex = slen - 1;
-      return ret;
-    }
-  return 0;  
-}
-#endif
-
-/* Extract and create a new string from the contents of STRING, a
-   character string delimited with OPENER and CLOSER.  SINDEX is
-   the address of an int describing the current offset in STRING;
-   it should point to just after the first OPENER found.  On exit,
-   SINDEX gets the position of the last character of the matching CLOSER.
-   If OPENER is more than a single character, ALT_OPENER, if non-null,
-   contains a character string that can also match CLOSER and thus
-   needs to be skipped. */
-static char *
-extract_delimited_string (string, sindex, opener, alt_opener, closer, flags)
-     char *string;
-     int *sindex;
-     char *opener, *alt_opener, *closer;
-     int flags;
-{
-  int i, c, si;
-  size_t slen;
-  char *t, *result;
-  int pass_character, nesting_level, in_comment;
-  int len_closer, len_opener, len_alt_opener;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string + *sindex) + *sindex;
-  len_opener = STRLEN (opener);
-  len_alt_opener = STRLEN (alt_opener);
-  len_closer = STRLEN (closer);
-
-  pass_character = in_comment = 0;
-
-  nesting_level = 1;
-  i = *sindex;
-
-  while (nesting_level)
-    {
-      c = string[i];
-
-      if (c == 0)
-       break;
-
-      if (in_comment)
-       {
-         if (c == '\n')
-           in_comment = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-
-      if (pass_character)      /* previous char was backslash */
-       {
-         pass_character = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-
-      /* Not exactly right yet; should handle shell metacharacters and
-        multibyte characters, too.  See COMMENT_BEGIN define in parse.y */
-      if ((flags & SX_COMMAND) && c == '#' && (i == 0 || string[i - 1] == '\n' || shellblank (string[i - 1])))
-       {
-          in_comment = 1;
-          ADVANCE_CHAR (string, slen, i);
-          continue;
-       }
-        
-      if (c == CTLESC || c == '\\')
-       {
-         pass_character++;
-         i++;
-         continue;
-       }
-
-      /* Process a nested OPENER. */
-      if (STREQN (string + i, opener, len_opener))
-       {
-         si = i + len_opener;
-         t = extract_delimited_string (string, &si, opener, alt_opener, closer, flags|SX_NOALLOC);
-         i = si + 1;
-         continue;
-       }
-
-      /* Process a nested ALT_OPENER */
-      if (len_alt_opener && STREQN (string + i, alt_opener, len_alt_opener))
-       {
-         si = i + len_alt_opener;
-         t = extract_delimited_string (string, &si, alt_opener, alt_opener, closer, flags|SX_NOALLOC);
-         i = si + 1;
-         continue;
-       }
-
-      /* If the current substring terminates the delimited string, decrement
-        the nesting level. */
-      if (STREQN (string + i, closer, len_closer))
-       {
-         i += len_closer - 1;  /* move to last byte of the closer */
-         nesting_level--;
-         if (nesting_level == 0)
-           break;
-       }
-
-      /* Pass old-style command substitution through verbatim. */
-      if (c == '`')
-       {
-         si = i + 1;
-         t = string_extract (string, &si, "`", flags|SX_NOALLOC);
-         i = si + 1;
-         continue;
-       }
-
-      /* Pass single-quoted and double-quoted strings through verbatim. */
-      if (c == '\'' || c == '"')
-       {
-         si = i + 1;
-         i = (c == '\'') ? skip_single_quoted (string, slen, si)
-                         : skip_double_quoted (string, slen, si);
-         continue;
-       }
-
-      /* move past this character, which was not special. */
-      ADVANCE_CHAR (string, slen, i);
-    }
-
-  if (c == 0 && nesting_level)
-    {
-      if (no_longjmp_on_fatal_error == 0)
-       {
-         report_error (_("bad substitution: no closing `%s' in %s"), closer, string);
-         last_command_exit_value = EXECUTION_FAILURE;
-         exp_jump_to_top_level (DISCARD);
-       }
-      else
-       {
-         *sindex = i;
-         return (char *)NULL;
-       }
-    }
-
-  si = i - *sindex - len_closer + 1;
-  if (flags & SX_NOALLOC)
-    result = (char *)NULL;
-  else    
-    {
-      result = (char *)xmalloc (1 + si);
-      strncpy (result, string + *sindex, si);
-      result[si] = '\0';
-    }
-  *sindex = i;
-
-  return (result);
-}
-
-/* Extract a parameter expansion expression within ${ and } from STRING.
-   Obey the Posix.2 rules for finding the ending `}': count braces while
-   skipping over enclosed quoted strings and command substitutions.
-   SINDEX is the address of an int describing the current offset in STRING;
-   it should point to just after the first `{' found.  On exit, SINDEX
-   gets the position of the matching `}'.  QUOTED is non-zero if this
-   occurs inside double quotes. */
-/* XXX -- this is very similar to extract_delimited_string -- XXX */
-static char *
-extract_dollar_brace_string (string, sindex, quoted, flags)
-     char *string;
-     int *sindex, quoted, flags;
-{
-  register int i, c;
-  size_t slen;
-  int pass_character, nesting_level, si;
-  char *result, *t;
-  DECLARE_MBSTATE;
-
-  pass_character = 0;
-  nesting_level = 1;
-  slen = strlen (string + *sindex) + *sindex;
-
-  i = *sindex;
-  while (c = string[i])
-    {
-      if (pass_character)
-       {
-         pass_character = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-
-      /* CTLESCs and backslashes quote the next character. */
-      if (c == CTLESC || c == '\\')
-       {
-         pass_character++;
-         i++;
-         continue;
-       }
-
-      if (string[i] == '$' && string[i+1] == LBRACE)
-       {
-         nesting_level++;
-         i += 2;
-         continue;
-       }
-
-      if (c == RBRACE)
-       {
-         nesting_level--;
-         if (nesting_level == 0)
-           break;
-         i++;
-         continue;
-       }
-
-      /* Pass the contents of old-style command substitutions through
-        verbatim. */
-      if (c == '`')
-       {
-         si = i + 1;
-         t = string_extract (string, &si, "`", flags|SX_NOALLOC);
-         i = si + 1;
-         continue;
-       }
-
-      /* Pass the contents of new-style command substitutions and
-        arithmetic substitutions through verbatim. */
-      if (string[i] == '$' && string[i+1] == LPAREN)
-       {
-         si = i + 2;
-         t = extract_command_subst (string, &si, flags|SX_NOALLOC);
-         i = si + 1;
-         continue;
-       }
-
-      /* Pass the contents of single-quoted and double-quoted strings
-        through verbatim. */
-      if (c == '\'' || c == '"')
-       {
-         si = i + 1;
-         i = (c == '\'') ? skip_single_quoted (string, slen, si)
-                         : skip_double_quoted (string, slen, si);
-         /* skip_XXX_quoted leaves index one past close quote */
-         continue;
-       }
-
-      /* move past this character, which was not special. */
-      ADVANCE_CHAR (string, slen, i);
-    }
-
-  if (c == 0 && nesting_level)
-    {
-      if (no_longjmp_on_fatal_error == 0)
-       {                       /* { */
-         report_error (_("bad substitution: no closing `%s' in %s"), "}", string);
-         last_command_exit_value = EXECUTION_FAILURE;
-         exp_jump_to_top_level (DISCARD);
-       }
-      else
-       {
-         *sindex = i;
-         return ((char *)NULL);
-       }
-    }
-
-  result = (flags & SX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i);
-  *sindex = i;
-
-  return (result);
-}
-
-/* Remove backslashes which are quoting backquotes from STRING.  Modifies
-   STRING, and returns a pointer to it. */
-char *
-de_backslash (string)
-     char *string;
-{
-  register size_t slen;
-  register int i, j, prev_i;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string);
-  i = j = 0;
-
-  /* Loop copying string[i] to string[j], i >= j. */
-  while (i < slen)
-    {
-      if (string[i] == '\\' && (string[i + 1] == '`' || string[i + 1] == '\\' ||
-                             string[i + 1] == '$'))
-       i++;
-      prev_i = i;
-      ADVANCE_CHAR (string, slen, i);
-      if (j < prev_i)
-       do string[j++] = string[prev_i++]; while (prev_i < i);
-      else
-       j = i;
-    }
-  string[j] = '\0';
-
-  return (string);
-}
-
-#if 0
-/*UNUSED*/
-/* Replace instances of \! in a string with !. */
-void
-unquote_bang (string)
-     char *string;
-{
-  register int i, j;
-  register char *temp;
-
-  temp = (char *)xmalloc (1 + strlen (string));
-
-  for (i = 0, j = 0; (temp[j] = string[i]); i++, j++)
-    {
-      if (string[i] == '\\' && string[i + 1] == '!')
-       {
-         temp[j] = '!';
-         i++;
-       }
-    }
-  strcpy (string, temp);
-  free (temp);
-}
-#endif
-
-#define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
-
-/* This function assumes s[i] == open; returns with s[ret] == close; used to
-   parse array subscripts.  FLAGS & 1 means to not attempt to skip over
-   matched pairs of quotes or backquotes, or skip word expansions; it is
-   intended to be used after expansion has been performed and during final
-   assignment parsing (see arrayfunc.c:assign_compound_array_list()). */
-static int
-skip_matched_pair (string, start, open, close, flags)
-     const char *string;
-     int start, open, close, flags;
-{
-  int i, pass_next, backq, si, c, count;
-  size_t slen;
-  char *temp, *ss;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string + start) + start;
-  no_longjmp_on_fatal_error = 1;
-
-  i = start + 1;               /* skip over leading bracket */
-  count = 1;
-  pass_next = backq = 0;
-  ss = (char *)string;
-  while (c = string[i])
-    {
-      if (pass_next)
-       {
-         pass_next = 0;
-         if (c == 0)
-           CQ_RETURN(i);
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (c == '\\')
-       {
-         pass_next = 1;
-         i++;
-         continue;
-       }
-      else if (backq)
-       {
-         if (c == '`')
-           backq = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if ((flags & 1) == 0 && c == '`')
-       {
-         backq = 1;
-         i++;
-         continue;
-       }
-      else if ((flags & 1) == 0 && c == open)
-       {
-         count++;
-         i++;
-         continue;
-       }
-      else if (c == close)
-       {
-         count--;
-         if (count == 0)
-           break;
-         i++;
-         continue;
-       }
-      else if ((flags & 1) == 0 && (c == '\'' || c == '"'))
-       {
-         i = (c == '\'') ? skip_single_quoted (ss, slen, ++i)
-                         : skip_double_quoted (ss, slen, ++i);
-         /* no increment, the skip functions increment past the closing quote. */
-       }
-      else if ((flags&1) == 0 && c == '$' && (string[i+1] == LPAREN || string[i+1] == LBRACE))
-       {
-         si = i + 2;
-         if (string[si] == '\0')
-           CQ_RETURN(si);
-
-         if (string[i+1] == LPAREN)
-           temp = extract_delimited_string (ss, &si, "$(", "(", ")", SX_NOALLOC|SX_COMMAND); /* ) */
-         else
-           temp = extract_dollar_brace_string (ss, &si, 0, SX_NOALLOC);
-         i = si;
-         if (string[i] == '\0')        /* don't increment i past EOS in loop */
-           break;
-         i++;
-         continue;
-       }
-      else
-       ADVANCE_CHAR (string, slen, i);
-    }
-
-  CQ_RETURN(i);
-}
-
-#if defined (ARRAY_VARS)
-int
-skipsubscript (string, start, flags)
-     const char *string;
-     int start, flags;
-{
-  return (skip_matched_pair (string, start, '[', ']', flags));
-}
-#endif
-
-/* Skip characters in STRING until we find a character in DELIMS, and return
-   the index of that character.  START is the index into string at which we
-   begin.  This is similar in spirit to strpbrk, but it returns an index into
-   STRING and takes a starting index.  This little piece of code knows quite
-   a lot of shell syntax.  It's very similar to skip_double_quoted and other
-   functions of that ilk. */
-int
-skip_to_delim (string, start, delims, flags)
-     char *string;
-     int start;
-     char *delims;
-     int flags;
-{
-  int i, pass_next, backq, si, c, invert, skipquote, skipcmd;
-  size_t slen;
-  char *temp;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string + start) + start;
-  if (flags & SD_NOJMP)
-    no_longjmp_on_fatal_error = 1;
-  invert = (flags & SD_INVERT);
-  skipcmd = (flags & SD_NOSKIPCMD) == 0;
-
-  i = start;
-  pass_next = backq = 0;
-  while (c = string[i])
-    {
-      /* If this is non-zero, we should not let quote characters be delimiters
-        and the current character is a single or double quote.  We should not
-        test whether or not it's a delimiter until after we skip single- or
-        double-quoted strings. */
-      skipquote = ((flags & SD_NOQUOTEDELIM) && (c == '\'' || c =='"'));
-      if (pass_next)
-       {
-         pass_next = 0;
-         if (c == 0)
-           CQ_RETURN(i);
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (c == '\\')
-       {
-         pass_next = 1;
-         i++;
-         continue;
-       }
-      else if (backq)
-       {
-         if (c == '`')
-           backq = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (c == '`')
-       {
-         backq = 1;
-         i++;
-         continue;
-       }
-      else if (skipquote == 0 && invert == 0 && member (c, delims))
-       break;
-      else if (c == '\'' || c == '"')
-       {
-         i = (c == '\'') ? skip_single_quoted (string, slen, ++i)
-                         : skip_double_quoted (string, slen, ++i);
-         /* no increment, the skip functions increment past the closing quote. */
-       }
-      else if (c == '$' && ((skipcmd && string[i+1] == LPAREN) || string[i+1] == LBRACE))
-       {
-         si = i + 2;
-         if (string[si] == '\0')
-           CQ_RETURN(si);
-
-         if (string[i+1] == LPAREN)
-           temp = extract_delimited_string (string, &si, "$(", "(", ")", SX_NOALLOC|SX_COMMAND); /* ) */
-         else
-           temp = extract_dollar_brace_string (string, &si, 0, SX_NOALLOC);
-         i = si;
-         if (string[i] == '\0')        /* don't increment i past EOS in loop */
-           break;
-         i++;
-         continue;
-       }
-#if defined (PROCESS_SUBSTITUTION)
-      else if (skipcmd && (c == '<' || c == '>') && string[i+1] == LPAREN)
-       {
-         si = i + 2;
-         if (string[si] == '\0')
-           CQ_RETURN(si);
-         temp = extract_process_subst (string, (c == '<') ? "<(" : ">(", &si);
-         i = si;
-         if (string[i] == '\0')
-           break;
-         i++;
-         continue;
-       }
-#endif /* PROCESS_SUBSTITUTION */
-      else if ((skipquote || invert) && (member (c, delims) == 0))
-       break;
-      else
-       ADVANCE_CHAR (string, slen, i);
-    }
-
-  CQ_RETURN(i);
-}
-
-#if defined (READLINE)
-/* Return 1 if the portion of STRING ending at EINDEX is quoted (there is
-   an unclosed quoted string), or if the character at EINDEX is quoted
-   by a backslash. NO_LONGJMP_ON_FATAL_ERROR is used to flag that the various
-   single and double-quoted string parsing functions should not return an
-   error if there are unclosed quotes or braces.  The characters that this
-   recognizes need to be the same as the contents of
-   rl_completer_quote_characters. */
-
-int
-char_is_quoted (string, eindex)
-     char *string;
-     int eindex;
-{
-  int i, pass_next, c;
-  size_t slen;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string);
-  no_longjmp_on_fatal_error = 1;
-  i = pass_next = 0;
-  while (i <= eindex)
-    {
-      c = string[i];
-
-      if (pass_next)
-       {
-         pass_next = 0;
-         if (i >= eindex)      /* XXX was if (i >= eindex - 1) */
-           CQ_RETURN(1);
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (c == '\\')
-       {
-         pass_next = 1;
-         i++;
-         continue;
-       }
-      else if (c == '\'' || c == '"')
-       {
-         i = (c == '\'') ? skip_single_quoted (string, slen, ++i)
-                         : skip_double_quoted (string, slen, ++i);
-         if (i > eindex)
-           CQ_RETURN(1);
-         /* no increment, the skip_xxx functions go one past end */
-       }
-      else
-       ADVANCE_CHAR (string, slen, i);
-    }
-
-  CQ_RETURN(0);
-}
-
-int
-unclosed_pair (string, eindex, openstr)
-     char *string;
-     int eindex;
-     char *openstr;
-{
-  int i, pass_next, openc, olen;
-  size_t slen;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string);
-  olen = strlen (openstr);
-  i = pass_next = openc = 0;
-  while (i <= eindex)
-    {
-      if (pass_next)
-       {
-         pass_next = 0;
-         if (i >= eindex)      /* XXX was if (i >= eindex - 1) */
-           return 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (string[i] == '\\')
-       {
-         pass_next = 1;
-         i++;
-         continue;
-       }
-      else if (STREQN (string + i, openstr, olen))
-       {
-         openc = 1 - openc;
-         i += olen;
-       }
-      else if (string[i] == '\'' || string[i] == '"')
-       {
-         i = (string[i] == '\'') ? skip_single_quoted (string, slen, i)
-                                 : skip_double_quoted (string, slen, i);
-         if (i > eindex)
-           return 0;
-       }
-      else
-       ADVANCE_CHAR (string, slen, i);
-    }
-  return (openc);
-}
-
-/* Split STRING (length SLEN) at DELIMS, and return a WORD_LIST with the
-   individual words.  If DELIMS is NULL, the current value of $IFS is used
-   to split the string, and the function follows the shell field splitting
-   rules.  SENTINEL is an index to look for.  NWP, if non-NULL,
-   gets the number of words in the returned list.  CWP, if non-NULL, gets
-   the index of the word containing SENTINEL.  Non-whitespace chars in
-   DELIMS delimit separate fields. */
-WORD_LIST *
-split_at_delims (string, slen, delims, sentinel, flags, nwp, cwp)
-     char *string;
-     int slen;
-     char *delims;
-     int sentinel, flags;
-     int *nwp, *cwp;
-{
-  int ts, te, i, nw, cw, ifs_split, dflags;
-  char *token, *d, *d2;
-  WORD_LIST *ret, *tl;
-
-  if (string == 0 || *string == '\0')
-    {
-      if (nwp)
-       *nwp = 0;
-      if (cwp)
-       *cwp = 0;       
-      return ((WORD_LIST *)NULL);
-    }
-
-  d = (delims == 0) ? ifs_value : delims;
-  ifs_split = delims == 0;
-
-  /* Make d2 the non-whitespace characters in delims */
-  d2 = 0;
-  if (delims)
-    {
-      size_t slength;
-#if defined (HANDLE_MULTIBYTE)
-      size_t mblength = 1;
-#endif
-      DECLARE_MBSTATE;
-
-      slength = strlen (delims);
-      d2 = (char *)xmalloc (slength + 1);
-      i = ts = 0;
-      while (delims[i])
-       {
-#if defined (HANDLE_MULTIBYTE)
-         mbstate_t state_bak;
-         state_bak = state;
-         mblength = MBRLEN (delims + i, slength, &state);
-         if (MB_INVALIDCH (mblength))
-           state = state_bak;
-         else if (mblength > 1)
-           {
-             memcpy (d2 + ts, delims + i, mblength);
-             ts += mblength;
-             i += mblength;
-             slength -= mblength;
-             continue;
-           }
-#endif
-         if (whitespace (delims[i]) == 0)
-           d2[ts++] = delims[i];
-
-         i++;
-         slength--;
-       }
-      d2[ts] = '\0';
-    }
-
-  ret = (WORD_LIST *)NULL;
-
-  /* Remove sequences of whitespace characters at the start of the string, as
-     long as those characters are delimiters. */
-  for (i = 0; member (string[i], d) && spctabnl (string[i]); i++)
-    ;
-  if (string[i] == '\0')
-    return (ret);
-
-  ts = i;
-  nw = 0;
-  cw = -1;
-  dflags = flags|SD_NOJMP;
-  while (1)
-    {
-      te = skip_to_delim (string, ts, d, dflags);
-
-      /* If we have a non-whitespace delimiter character, use it to make a
-        separate field.  This is just about what $IFS splitting does and
-        is closer to the behavior of the shell parser. */
-      if (ts == te && d2 && member (string[ts], d2))
-       {
-         te = ts + 1;
-         /* If we're using IFS splitting, the non-whitespace delimiter char
-            and any additional IFS whitespace delimits a field. */
-         if (ifs_split)
-           while (member (string[te], d) && spctabnl (string[te]))
-             te++;
-         else
-           while (member (string[te], d2))
-             te++;
-       }
-
-      token = substring (string, ts, te);
-
-      ret = add_string_to_list (token, ret);
-      free (token);
-      nw++;
-
-      if (sentinel >= ts && sentinel <= te)
-       cw = nw;
-
-      /* If the cursor is at whitespace just before word start, set the
-        sentinel word to the current word. */
-      if (cwp && cw == -1 && sentinel == ts-1)
-       cw = nw;
-
-      /* If the cursor is at whitespace between two words, make a new, empty
-        word, add it before (well, after, since the list is in reverse order)
-        the word we just added, and set the current word to that one. */
-      if (cwp && cw == -1 && sentinel < ts)
-       {
-         tl = make_word_list (make_word (""), ret->next);
-         ret->next = tl;
-         cw = nw;
-         nw++;
-       }
-
-      if (string[te] == 0)
-       break;
-
-      i = te;
-      while (member (string[i], d) && (ifs_split || spctabnl(string[i])))
-       i++;
-
-      if (string[i])
-       ts = i;
-      else
-       break;
-    }
-
-  /* Special case for SENTINEL at the end of STRING.  If we haven't found
-     the word containing SENTINEL yet, and the index we're looking for is at
-     the end of STRING (or past the end of the previously-found token,
-     possible if the end of the line is composed solely of IFS whitespace)
-     add an additional null argument and set the current word pointer to that. */
-  if (cwp && cw == -1 && (sentinel >= slen || sentinel >= te))
-    {
-      if (whitespace (string[sentinel - 1]))
-       {
-         token = "";
-         ret = add_string_to_list (token, ret);
-         nw++;
-       }
-      cw = nw;
-    }
-
-  if (nwp)
-    *nwp = nw;
-  if (cwp)
-    *cwp = cw;
-
-  return (REVERSE_LIST (ret, WORD_LIST *));
-}
-#endif /* READLINE */
-
-#if 0
-/* UNUSED */
-/* Extract the name of the variable to bind to from the assignment string. */
-char *
-assignment_name (string)
-     char *string;
-{
-  int offset;
-  char *temp;
-
-  offset = assignment (string, 0);
-  if (offset == 0)
-    return (char *)NULL;
-  temp = substring (string, 0, offset);
-  return (temp);
-}
-#endif
-
-/* **************************************************************** */
-/*                                                                 */
-/*     Functions to convert strings to WORD_LISTs and vice versa    */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Return a single string of all the words in LIST.  SEP is the separator
-   to put between individual elements of LIST in the output string. */
-char *
-string_list_internal (list, sep)
-     WORD_LIST *list;
-     char *sep;
-{
-  register WORD_LIST *t;
-  char *result, *r;
-  int word_len, sep_len, result_size;
-
-  if (list == 0)
-    return ((char *)NULL);
-
-  /* Short-circuit quickly if we don't need to separate anything. */
-  if (list->next == 0)
-    return (savestring (list->word->word));
-
-  /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */
-  sep_len = STRLEN (sep);
-  result_size = 0;
-
-  for (t = list; t; t = t->next)
-    {
-      if (t != list)
-       result_size += sep_len;
-      result_size += strlen (t->word->word);
-    }
-
-  r = result = (char *)xmalloc (result_size + 1);
-
-  for (t = list; t; t = t->next)
-    {
-      if (t != list && sep_len)
-       {
-         if (sep_len > 1)
-           {
-             FASTCOPY (sep, r, sep_len);
-             r += sep_len;
-           }
-         else
-           *r++ = sep[0];
-       }
-
-      word_len = strlen (t->word->word);
-      FASTCOPY (t->word->word, r, word_len);
-      r += word_len;
-    }
-
-  *r = '\0';
-  return (result);
-}
-
-/* Return a single string of all the words present in LIST, separating
-   each word with a space. */
-char *
-string_list (list)
-     WORD_LIST *list;
-{
-  return (string_list_internal (list, " "));
-}
-
-/* An external interface that can be used by the rest of the shell to
-   obtain a string containing the first character in $IFS.  Handles all
-   the multibyte complications.  If LENP is non-null, it is set to the
-   length of the returned string. */
-char *
-ifs_firstchar (lenp)
-     int *lenp;
-{
-  char *ret;
-  int len;
-
-  ret = xmalloc (MB_LEN_MAX + 1);
-#if defined (HANDLE_MULTIBYTE)
-  if (ifs_firstc_len == 1)
-    {
-      ret[0] = ifs_firstc[0];
-      ret[1] = '\0';
-      len = ret[0] ? 1 : 0;
-    }
-  else
-    {
-      memcpy (ret, ifs_firstc, ifs_firstc_len);
-      ret[len = ifs_firstc_len] = '\0';
-    }
-#else
-  ret[0] = ifs_firstc;
-  ret[1] = '\0';
-  len = ret[0] ? 0 : 1;
-#endif
-
-  if (lenp)
-    *lenp = len;
-
-  return ret;
-}
-
-/* Return a single string of all the words present in LIST, obeying the
-   quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the
-   expansion [of $*] appears within a double quoted string, it expands
-   to a single field with the value of each parameter separated by the
-   first character of the IFS variable, or by a <space> if IFS is unset." */
-char *
-string_list_dollar_star (list)
-     WORD_LIST *list;
-{
-  char *ret;
-#if defined (HANDLE_MULTIBYTE)
-#  if defined (__GNUC__)
-  char sep[MB_CUR_MAX + 1];
-#  else
-  char *sep = 0;
-#  endif
-#else
-  char sep[2];
-#endif
-
-#if defined (HANDLE_MULTIBYTE)
-#  if !defined (__GNUC__)
-  sep = (char *)xmalloc (MB_CUR_MAX + 1);
-#  endif /* !__GNUC__ */
-  if (ifs_firstc_len == 1)
-    {
-      sep[0] = ifs_firstc[0];
-      sep[1] = '\0';
-    }
-  else
-    {
-      memcpy (sep, ifs_firstc, ifs_firstc_len);
-      sep[ifs_firstc_len] = '\0';
-    }
-#else
-  sep[0] = ifs_firstc;
-  sep[1] = '\0';
-#endif
-
-  ret = string_list_internal (list, sep);
-#if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
-  free (sep);
-#endif
-  return ret;
-}
-
-/* Turn $@ into a string.  If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-   is non-zero, the $@ appears within double quotes, and we should quote
-   the list before converting it into a string.  If IFS is unset, and the
-   word is not quoted, we just need to quote CTLESC and CTLNUL characters
-   in the words in the list, because the default value of $IFS is
-   <space><tab><newline>, IFS characters in the words in the list should
-   also be split.  If IFS is null, and the word is not quoted, we need
-   to quote the words in the list to preserve the positional parameters
-   exactly. */
-char *
-string_list_dollar_at (list, quoted)
-     WORD_LIST *list;
-     int quoted;
-{
-  char *ifs, *ret;
-#if defined (HANDLE_MULTIBYTE)
-#  if defined (__GNUC__)
-  char sep[MB_CUR_MAX + 1];
-#  else
-  char *sep = 0;
-#  endif /* !__GNUC__ */
-#else
-  char sep[2];
-#endif
-  WORD_LIST *tlist;
-
-  /* XXX this could just be ifs = ifs_value; */
-  ifs = ifs_var ? value_cell (ifs_var) : (char *)0;
-
-#if defined (HANDLE_MULTIBYTE)
-#  if !defined (__GNUC__)
-  sep = (char *)xmalloc (MB_CUR_MAX + 1);
-#  endif /* !__GNUC__ */
-  if (ifs && *ifs)
-    {
-      if (ifs_firstc_len == 1)
-       {
-         sep[0] = ifs_firstc[0];
-         sep[1] = '\0';
-       }
-      else
-       {
-         memcpy (sep, ifs_firstc, ifs_firstc_len);
-         sep[ifs_firstc_len] = '\0';
-       }
-    }
-  else
-    {
-      sep[0] = ' ';
-      sep[1] = '\0';
-    }
-#else
-  sep[0] = (ifs == 0 || *ifs == 0) ? ' ' : *ifs;
-  sep[1] = '\0';
-#endif
-
-  /* XXX -- why call quote_list if ifs == 0?  we can get away without doing
-     it now that quote_escapes quotes spaces */
-#if 0
-  tlist = ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (ifs && *ifs == 0))
-#else
-  tlist = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES|Q_PATQUOTE))
-#endif
-               ? quote_list (list)
-               : list_quote_escapes (list);
-
-  ret = string_list_internal (tlist, sep);
-#if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
-  free (sep);
-#endif
-  return ret;
-}
-
-/* Turn the positional paramters into a string, understanding quoting and
-   the various subtleties of using the first character of $IFS as the
-   separator.  Calls string_list_dollar_at, string_list_dollar_star, and
-   string_list as appropriate. */
-char *
-string_list_pos_params (pchar, list, quoted)
-     int pchar;
-     WORD_LIST *list;
-     int quoted;
-{
-  char *ret;
-  WORD_LIST *tlist;
-
-  if (pchar == '*' && (quoted & Q_DOUBLE_QUOTES))
-    {
-      tlist = quote_list (list);
-      word_list_remove_quoted_nulls (tlist);
-      ret = string_list_dollar_star (tlist);
-    }
-  else if (pchar == '*' && (quoted & Q_HERE_DOCUMENT))
-    {
-      tlist = quote_list (list);
-      word_list_remove_quoted_nulls (tlist);
-      ret = string_list (tlist);
-    }
-  else if (pchar == '*')
-    {
-      /* Even when unquoted, string_list_dollar_star does the right thing
-        making sure that the first character of $IFS is used as the
-        separator. */
-      ret = string_list_dollar_star (list);
-    }
-  else if (pchar == '@' && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-    /* We use string_list_dollar_at, but only if the string is quoted, since
-       that quotes the escapes if it's not, which we don't want.  We could
-       use string_list (the old code did), but that doesn't do the right
-       thing if the first character of $IFS is not a space.  We use
-       string_list_dollar_star if the string is unquoted so we make sure that
-       the elements of $@ are separated by the first character of $IFS for
-       later splitting. */
-    ret = string_list_dollar_at (list, quoted);
-  else if (pchar == '@')
-    ret = string_list_dollar_star (list);
-  else
-    ret = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (list) : list);
-
-  return ret;
-}
-
-/* Return the list of words present in STRING.  Separate the string into
-   words at any of the characters found in SEPARATORS.  If QUOTED is
-   non-zero then word in the list will have its quoted flag set, otherwise
-   the quoted flag is left as make_word () deemed fit.
-
-   This obeys the P1003.2 word splitting semantics.  If `separators' is
-   exactly <space><tab><newline>, then the splitting algorithm is that of
-   the Bourne shell, which treats any sequence of characters from `separators'
-   as a delimiter.  If IFS is unset, which results in `separators' being set
-   to "", no splitting occurs.  If separators has some other value, the
-   following rules are applied (`IFS white space' means zero or more
-   occurrences of <space>, <tab>, or <newline>, as long as those characters
-   are in `separators'):
-
-       1) IFS white space is ignored at the start and the end of the
-          string.
-       2) Each occurrence of a character in `separators' that is not
-          IFS white space, along with any adjacent occurrences of
-          IFS white space delimits a field.
-       3) Any nonzero-length sequence of IFS white space delimits a field.
-   */
-
-/* BEWARE!  list_string strips null arguments.  Don't call it twice and
-   expect to have "" preserved! */
-
-/* This performs word splitting and quoted null character removal on
-   STRING. */
-#define issep(c) \
-       (((separators)[0]) ? ((separators)[1] ? isifs(c) \
-                                             : (c) == (separators)[0]) \
-                          : 0)
-
-WORD_LIST *
-list_string (string, separators, quoted)
-     register char *string, *separators;
-     int quoted;
-{
-  WORD_LIST *result;
-  WORD_DESC *t;
-  char *current_word, *s;
-  int sindex, sh_style_split, whitesep, xflags;
-  size_t slen;
-
-  if (!string || !*string)
-    return ((WORD_LIST *)NULL);
-
-  sh_style_split = separators && separators[0] == ' ' &&
-                                separators[1] == '\t' &&
-                                separators[2] == '\n' &&
-                                separators[3] == '\0';
-  for (xflags = 0, s = ifs_value; s && *s; s++)
-    {
-      if (*s == CTLESC) xflags |= SX_NOCTLESC;
-      else if (*s == CTLNUL) xflags |= SX_NOESCCTLNUL;
-    }
-
-  slen = 0;
-  /* Remove sequences of whitespace at the beginning of STRING, as
-     long as those characters appear in IFS.  Do not do this if
-     STRING is quoted or if there are no separator characters. */
-  if (!quoted || !separators || !*separators)
-    {
-      for (s = string; *s && spctabnl (*s) && issep (*s); s++);
-
-      if (!*s)
-       return ((WORD_LIST *)NULL);
-
-      string = s;
-    }
-
-  /* OK, now STRING points to a word that does not begin with white space.
-     The splitting algorithm is:
-       extract a word, stopping at a separator
-       skip sequences of spc, tab, or nl as long as they are separators
-     This obeys the field splitting rules in Posix.2. */
-  slen = (MB_CUR_MAX > 1) ? strlen (string) : 1;
-  for (result = (WORD_LIST *)NULL, sindex = 0; string[sindex]; )
-    {
-      /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
-        unless multibyte chars are possible. */
-      current_word = string_extract_verbatim (string, slen, &sindex, separators, xflags);
-      if (current_word == 0)
-       break;
-
-      /* If we have a quoted empty string, add a quoted null argument.  We
-        want to preserve the quoted null character iff this is a quoted
-        empty string; otherwise the quoted null characters are removed
-        below. */
-      if (QUOTED_NULL (current_word))
-       {
-         t = alloc_word_desc ();
-         t->word = make_quoted_char ('\0');
-         t->flags |= W_QUOTED|W_HASQUOTEDNULL;
-         result = make_word_list (t, result);
-       }
-      else if (current_word[0] != '\0')
-       {
-         /* If we have something, then add it regardless.  However,
-            perform quoted null character removal on the current word. */
-         remove_quoted_nulls (current_word);
-         result = add_string_to_list (current_word, result);
-         result->word->flags &= ~W_HASQUOTEDNULL;      /* just to be sure */
-         if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
-           result->word->flags |= W_QUOTED;
-       }
-
-      /* If we're not doing sequences of separators in the traditional
-        Bourne shell style, then add a quoted null argument. */
-      else if (!sh_style_split && !spctabnl (string[sindex]))
-       {
-         t = alloc_word_desc ();
-         t->word = make_quoted_char ('\0');
-         t->flags |= W_QUOTED|W_HASQUOTEDNULL;
-         result = make_word_list (t, result);
-       }
-
-      free (current_word);
-
-      /* Note whether or not the separator is IFS whitespace, used later. */
-      whitesep = string[sindex] && spctabnl (string[sindex]);
-
-      /* Move past the current separator character. */
-      if (string[sindex])
-       {
-         DECLARE_MBSTATE;
-         ADVANCE_CHAR (string, slen, sindex);
-       }
-
-      /* Now skip sequences of space, tab, or newline characters if they are
-        in the list of separators. */
-      while (string[sindex] && spctabnl (string[sindex]) && issep (string[sindex]))
-       sindex++;
-
-      /* If the first separator was IFS whitespace and the current character
-        is a non-whitespace IFS character, it should be part of the current
-        field delimiter, not a separate delimiter that would result in an
-        empty field.  Look at POSIX.2, 3.6.5, (3)(b). */
-      if (string[sindex] && whitesep && issep (string[sindex]) && !spctabnl (string[sindex]))
-       {
-         sindex++;
-         /* An IFS character that is not IFS white space, along with any
-            adjacent IFS white space, shall delimit a field. (SUSv3) */
-         while (string[sindex] && spctabnl (string[sindex]) && isifs (string[sindex]))
-           sindex++;
-       }
-    }
-  return (REVERSE_LIST (result, WORD_LIST *));
-}
-
-/* Parse a single word from STRING, using SEPARATORS to separate fields.
-   ENDPTR is set to the first character after the word.  This is used by
-   the `read' builtin.  This is never called with SEPARATORS != $IFS;
-   it should be simplified.
-
-   XXX - this function is very similar to list_string; they should be
-        combined - XXX */
-char *
-get_word_from_string (stringp, separators, endptr)
-     char **stringp, *separators, **endptr;
-{
-  register char *s;
-  char *current_word;
-  int sindex, sh_style_split, whitesep, xflags;
-  size_t slen;
-
-  if (!stringp || !*stringp || !**stringp)
-    return ((char *)NULL);
-
-  sh_style_split = separators && separators[0] == ' ' &&
-                                separators[1] == '\t' &&
-                                separators[2] == '\n' &&
-                                separators[3] == '\0';
-  for (xflags = 0, s = ifs_value; s && *s; s++)
-    {
-      if (*s == CTLESC) xflags |= SX_NOCTLESC;
-      if (*s == CTLNUL) xflags |= SX_NOESCCTLNUL;
-    }
-
-  s = *stringp;
-  slen = 0;
-
-  /* Remove sequences of whitespace at the beginning of STRING, as
-     long as those characters appear in IFS. */
-  if (sh_style_split || !separators || !*separators)
-    {
-      for (; *s && spctabnl (*s) && isifs (*s); s++);
-
-      /* If the string is nothing but whitespace, update it and return. */
-      if (!*s)
-       {
-         *stringp = s;
-         if (endptr)
-           *endptr = s;
-         return ((char *)NULL);
-       }
-    }
-
-  /* OK, S points to a word that does not begin with white space.
-     Now extract a word, stopping at a separator, save a pointer to
-     the first character after the word, then skip sequences of spc,
-     tab, or nl as long as they are separators.
-
-     This obeys the field splitting rules in Posix.2. */
-  sindex = 0;
-  /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
-     unless multibyte chars are possible. */
-  slen = (MB_CUR_MAX > 1) ? strlen (s) : 1;
-  current_word = string_extract_verbatim (s, slen, &sindex, separators, xflags);
-
-  /* Set ENDPTR to the first character after the end of the word. */
-  if (endptr)
-    *endptr = s + sindex;
-
-  /* Note whether or not the separator is IFS whitespace, used later. */
-  whitesep = s[sindex] && spctabnl (s[sindex]);
-
-  /* Move past the current separator character. */
-  if (s[sindex])
-    {
-      DECLARE_MBSTATE;
-      ADVANCE_CHAR (s, slen, sindex);
-    }
-
-  /* Now skip sequences of space, tab, or newline characters if they are
-     in the list of separators. */
-  while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
-    sindex++;
-
-  /* If the first separator was IFS whitespace and the current character is
-     a non-whitespace IFS character, it should be part of the current field
-     delimiter, not a separate delimiter that would result in an empty field.
-     Look at POSIX.2, 3.6.5, (3)(b). */
-  if (s[sindex] && whitesep && isifs (s[sindex]) && !spctabnl (s[sindex]))
-    {
-      sindex++;
-      /* An IFS character that is not IFS white space, along with any adjacent
-        IFS white space, shall delimit a field. */
-      while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
-       sindex++;
-    }
-
-  /* Update STRING to point to the next field. */
-  *stringp = s + sindex;
-  return (current_word);
-}
-
-/* Remove IFS white space at the end of STRING.  Start at the end
-   of the string and walk backwards until the beginning of the string
-   or we find a character that's not IFS white space and not CTLESC.
-   Only let CTLESC escape a white space character if SAW_ESCAPE is
-   non-zero.  */
-char *
-strip_trailing_ifs_whitespace (string, separators, saw_escape)
-     char *string, *separators;
-     int saw_escape;
-{
-  char *s;
-
-  s = string + STRLEN (string) - 1;
-  while (s > string && ((spctabnl (*s) && isifs (*s)) ||
-                       (saw_escape && *s == CTLESC && spctabnl (s[1]))))
-    s--;
-  *++s = '\0';
-  return string;
-}
-
-#if 0
-/* UNUSED */
-/* Split STRING into words at whitespace.  Obeys shell-style quoting with
-   backslashes, single and double quotes. */
-WORD_LIST *
-list_string_with_quotes (string)
-     char *string;
-{
-  WORD_LIST *list;
-  char *token, *s;
-  size_t s_len;
-  int c, i, tokstart, len;
-
-  for (s = string; s && *s && spctabnl (*s); s++)
-    ;
-  if (s == 0 || *s == 0)
-    return ((WORD_LIST *)NULL);
-
-  s_len = strlen (s);
-  tokstart = i = 0;
-  list = (WORD_LIST *)NULL;
-  while (1)
-    {
-      c = s[i];
-      if (c == '\\')
-       {
-         i++;
-         if (s[i])
-           i++;
-       }
-      else if (c == '\'')
-       i = skip_single_quoted (s, s_len, ++i);
-      else if (c == '"')
-       i = skip_double_quoted (s, s_len, ++i);
-      else if (c == 0 || spctabnl (c))
-       {
-         /* We have found the end of a token.  Make a word out of it and
-            add it to the word list. */
-         token = substring (s, tokstart, i);
-         list = add_string_to_list (token, list);
-         free (token);
-         while (spctabnl (s[i]))
-           i++;
-         if (s[i])
-           tokstart = i;
-         else
-           break;
-       }
-      else
-       i++;    /* normal character */
-    }
-  return (REVERSE_LIST (list, WORD_LIST *));
-}
-#endif
-
-/********************************************************/
-/*                                                     */
-/*     Functions to perform assignment statements      */
-/*                                                     */
-/********************************************************/
-
-#if defined (ARRAY_VARS)
-static SHELL_VAR *
-do_compound_assignment (name, value, flags)
-     char *name, *value;
-     int flags;
-{
-  SHELL_VAR *v;
-  int mklocal, mkassoc;
-  WORD_LIST *list;
-
-  mklocal = flags & ASS_MKLOCAL;
-  mkassoc = flags & ASS_MKASSOC;
-
-  if (mklocal && variable_context)
-    {
-      v = find_variable (name);
-      list = expand_compound_array_assignment (v, value, flags);
-      if (mkassoc)
-       v = make_local_assoc_variable (name);
-      else if (v == 0 || (array_p (v) == 0 && assoc_p (v) == 0) || v->context != variable_context)
-        v = make_local_array_variable (name);
-      assign_compound_array_list (v, list, flags);
-    }
-  else
-    v = assign_array_from_string (name, value, flags);
-
-  return (v);
-}
-#endif
-
-/* Given STRING, an assignment string, get the value of the right side
-   of the `=', and bind it to the left side.  If EXPAND is true, then
-   perform parameter expansion, command substitution, and arithmetic
-   expansion on the right-hand side.  Perform tilde expansion in any
-   case.  Do not perform word splitting on the result of expansion. */
-static int
-do_assignment_internal (word, expand)
-     const WORD_DESC *word;
-     int expand;
-{
-  int offset, tlen, appendop, assign_list, aflags, retval;
-  char *name, *value;
-  SHELL_VAR *entry;
-#if defined (ARRAY_VARS)
-  char *t;
-  int ni;
-#endif
-  const char *string;
-
-  if (word == 0 || word->word == 0)
-    return 0;
-
-  appendop = assign_list = aflags = 0;
-  string = word->word;
-  offset = assignment (string, 0);
-  name = savestring (string);
-  value = (char *)NULL;
-
-  if (name[offset] == '=')
-    {
-      char *temp;
-
-      if (name[offset - 1] == '+')
-       {
-         appendop = 1;
-         name[offset - 1] = '\0';
-       }
-
-      name[offset] = 0;                /* might need this set later */
-      temp = name + offset + 1;
-      tlen = STRLEN (temp);
-
-#if defined (ARRAY_VARS)
-      if (expand && (word->flags & W_COMPASSIGN))
-       {
-         assign_list = ni = 1;
-         value = extract_array_assignment_list (temp, &ni);
-       }
-      else
-#endif
-      if (expand && temp[0])
-       value = expand_string_if_necessary (temp, 0, expand_string_assignment);
-      else
-       value = savestring (temp);
-    }
-
-  if (value == 0)
-    {
-      value = (char *)xmalloc (1);
-      value[0] = '\0';
-    }
-
-  if (echo_command_at_execute)
-    {
-      if (appendop)
-       name[offset - 1] = '+';
-      xtrace_print_assignment (name, value, assign_list, 1);
-      if (appendop)
-       name[offset - 1] = '\0';
-    }
-
-#define ASSIGN_RETURN(r)       do { FREE (value); free (name); return (r); } while (0)
-
-  if (appendop)
-    aflags |= ASS_APPEND;
-
-#if defined (ARRAY_VARS)
-  if (t = mbschr (name, '['))  /*]*/
-    {
-      if (assign_list)
-       {
-         report_error (_("%s: cannot assign list to array member"), name);
-         ASSIGN_RETURN (0);
-       }
-      entry = assign_array_element (name, value, aflags);
-      if (entry == 0)
-       ASSIGN_RETURN (0);
-    }
-  else if (assign_list)
-    {
-      if (word->flags & W_ASSIGNARG)
-       aflags |= ASS_MKLOCAL;
-      if (word->flags & W_ASSIGNASSOC)
-       aflags |= ASS_MKASSOC;
-      entry = do_compound_assignment (name, value, aflags);
-    }
-  else
-#endif /* ARRAY_VARS */
-  entry = bind_variable (name, value, aflags);
-
-  stupidly_hack_special_variables (name);
-
-#if 1
-  /* Return 1 if the assignment seems to have been performed correctly. */
-  if (entry == 0 || readonly_p (entry))
-    retval = 0;                /* assignment failure */
-  else if (noassign_p (entry))
-    {
-      last_command_exit_value = EXECUTION_FAILURE;
-      retval = 1;      /* error status, but not assignment failure */
-    }
-  else
-    retval = 1;
-
-  if (entry && retval != 0 && noassign_p (entry) == 0)
-    VUNSETATTR (entry, att_invisible);
-
-  ASSIGN_RETURN (retval);
-#else
-  if (entry)
-    VUNSETATTR (entry, att_invisible);
-
-  ASSIGN_RETURN (entry ? ((readonly_p (entry) == 0) && noassign_p (entry) == 0) : 0);
-#endif
-}
-
-/* Perform the assignment statement in STRING, and expand the
-   right side by doing tilde, command and parameter expansion. */
-int
-do_assignment (string)
-     char *string;
-{
-  WORD_DESC td;
-
-  td.flags = W_ASSIGNMENT;
-  td.word = string;
-
-  return do_assignment_internal (&td, 1);
-}
-
-int
-do_word_assignment (word)
-     WORD_DESC *word;
-{
-  return do_assignment_internal (word, 1);
-}
-
-/* Given STRING, an assignment string, get the value of the right side
-   of the `=', and bind it to the left side.  Do not perform any word
-   expansions on the right hand side. */
-int
-do_assignment_no_expand (string)
-     char *string;
-{
-  WORD_DESC td;
-
-  td.flags = W_ASSIGNMENT;
-  td.word = string;
-
-  return (do_assignment_internal (&td, 0));
-}
-
-/***************************************************
- *                                                *
- *  Functions to manage the positional parameters  *
- *                                                *
- ***************************************************/
-
-/* Return the word list that corresponds to `$*'. */
-WORD_LIST *
-list_rest_of_args ()
-{
-  register WORD_LIST *list, *args;
-  int i;
-
-  /* Break out of the loop as soon as one of the dollar variables is null. */
-  for (i = 1, list = (WORD_LIST *)NULL; i < 10 && dollar_vars[i]; i++)
-    list = make_word_list (make_bare_word (dollar_vars[i]), list);
-
-  for (args = rest_of_args; args; args = args->next)
-    list = make_word_list (make_bare_word (args->word->word), list);
-
-  return (REVERSE_LIST (list, WORD_LIST *));
-}
-
-int
-number_of_args ()
-{
-  register WORD_LIST *list;
-  int n;
-
-  for (n = 0; n < 9 && dollar_vars[n+1]; n++)
-    ;
-  for (list = rest_of_args; list; list = list->next)
-    n++;
-  return n;
-}
-
-/* Return the value of a positional parameter.  This handles values > 10. */
-char *
-get_dollar_var_value (ind)
-     intmax_t ind;
-{
-  char *temp;
-  WORD_LIST *p;
-
-  if (ind < 10)
-    temp = dollar_vars[ind] ? savestring (dollar_vars[ind]) : (char *)NULL;
-  else /* We want something like ${11} */
-    {
-      ind -= 10;
-      for (p = rest_of_args; p && ind--; p = p->next)
-       ;
-      temp = p ? savestring (p->word->word) : (char *)NULL;
-    }
-  return (temp);
-}
-
-/* Make a single large string out of the dollar digit variables,
-   and the rest_of_args.  If DOLLAR_STAR is 1, then obey the special
-   case of "$*" with respect to IFS. */
-char *
-string_rest_of_args (dollar_star)
-     int dollar_star;
-{
-  register WORD_LIST *list;
-  char *string;
-
-  list = list_rest_of_args ();
-  string = dollar_star ? string_list_dollar_star (list) : string_list (list);
-  dispose_words (list);
-  return (string);
-}
-
-/* Return a string containing the positional parameters from START to
-   END, inclusive.  If STRING[0] == '*', we obey the rules for $*,
-   which only makes a difference if QUOTED is non-zero.  If QUOTED includes
-   Q_HERE_DOCUMENT or Q_DOUBLE_QUOTES, this returns a quoted list, otherwise
-   no quoting chars are added. */
-static char *
-pos_params (string, start, end, quoted)
-     char *string;
-     int start, end, quoted;
-{
-  WORD_LIST *save, *params, *h, *t;
-  char *ret;
-  int i;
-
-  /* see if we can short-circuit.  if start == end, we want 0 parameters. */
-  if (start == end)
-    return ((char *)NULL);
-
-  save = params = list_rest_of_args ();
-  if (save == 0)
-    return ((char *)NULL);
-
-  if (start == 0)              /* handle ${@:0[:x]} specially */
-    {
-      t = make_word_list (make_word (dollar_vars[0]), params);
-      save = params = t;
-    }
-
-  for (i = start ? 1 : 0; params && i < start; i++)
-    params = params->next;
-  if (params == 0)
-    return ((char *)NULL);
-  for (h = t = params; params && i < end; i++)
-    {
-      t = params;
-      params = params->next;
-    }
-
-  t->next = (WORD_LIST *)NULL;
-
-  ret = string_list_pos_params (string[0], h, quoted);
-
-  if (t != params)
-    t->next = params;
-
-  dispose_words (save);
-  return (ret);
-}
-
-/******************************************************************/
-/*                                                               */
-/*     Functions to expand strings to strings or WORD_LISTs      */
-/*                                                               */
-/******************************************************************/
-
-#if defined (PROCESS_SUBSTITUTION)
-#define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC || s == '~')
-#else
-#define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
-#endif
-
-/* If there are any characters in STRING that require full expansion,
-   then call FUNC to expand STRING; otherwise just perform quote
-   removal if necessary.  This returns a new string. */
-static char *
-expand_string_if_necessary (string, quoted, func)
-     char *string;
-     int quoted;
-     EXPFUNC *func;
-{
-  WORD_LIST *list;
-  size_t slen;
-  int i, saw_quote;
-  char *ret;
-  DECLARE_MBSTATE;
-
-  /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */
-  slen = (MB_CUR_MAX > 1) ? strlen (string) : 0;
-  i = saw_quote = 0;
-  while (string[i])
-    {
-      if (EXP_CHAR (string[i]))
-       break;
-      else if (string[i] == '\'' || string[i] == '\\' || string[i] == '"')
-       saw_quote = 1;
-      ADVANCE_CHAR (string, slen, i);
-    }
-
-  if (string[i])
-    {
-      list = (*func) (string, quoted);
-      if (list)
-       {
-         ret = string_list (list);
-         dispose_words (list);
-       }
-      else
-       ret = (char *)NULL;
-    }
-  else if (saw_quote && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
-    ret = string_quote_removal (string, quoted);
-  else
-    ret = savestring (string);
-
-  return ret;
-}
-
-static inline char *
-expand_string_to_string_internal (string, quoted, func)
-     char *string;
-     int quoted;
-     EXPFUNC *func;
-{
-  WORD_LIST *list;
-  char *ret;
-
-  if (string == 0 || *string == '\0')
-    return ((char *)NULL);
-
-  list = (*func) (string, quoted);
-  if (list)
-    {
-      ret = string_list (list);
-      dispose_words (list);
-    }
-  else
-    ret = (char *)NULL;
-
-  return (ret);
-}
-
-char *
-expand_string_to_string (string, quoted)
-     char *string;
-     int quoted;
-{
-  return (expand_string_to_string_internal (string, quoted, expand_string));
-}
-
-char *
-expand_string_unsplit_to_string (string, quoted)
-     char *string;
-     int quoted;
-{
-  return (expand_string_to_string_internal (string, quoted, expand_string_unsplit));
-}
-
-char *
-expand_assignment_string_to_string (string, quoted)
-     char *string;
-     int quoted;
-{
-  return (expand_string_to_string_internal (string, quoted, expand_string_assignment));
-}
-
-char *
-expand_arith_string (string, quoted)
-     char *string;
-     int quoted;
-{
-  return (expand_string_if_necessary (string, quoted, expand_string));
-}
-
-#if defined (COND_COMMAND)
-/* Just remove backslashes in STRING.  Returns a new string. */
-char *
-remove_backslashes (string)
-     char *string;
-{
-  char *r, *ret, *s;
-
-  r = ret = (char *)xmalloc (strlen (string) + 1);
-  for (s = string; s && *s; )
-    {
-      if (*s == '\\')
-       s++;
-      if (*s == 0)
-       break;
-      *r++ = *s++;
-    }
-  *r = '\0';
-  return ret;
-}
-
-/* This needs better error handling. */
-/* Expand W for use as an argument to a unary or binary operator in a
-   [[...]] expression.  If SPECIAL is 1, this is the rhs argument
-   to the != or == operator, and should be treated as a pattern.  In
-   this case, we quote the string specially for the globbing code.  If
-   SPECIAL is 2, this is an rhs argument for the =~ operator, and should
-   be quoted appropriately for regcomp/regexec.  The caller is responsible
-   for removing the backslashes if the unquoted word is needed later. */   
-char *
-cond_expand_word (w, special)
-     WORD_DESC *w;
-     int special;
-{
-  char *r, *p;
-  WORD_LIST *l;
-  int qflags;
-
-  if (w->word == 0 || w->word[0] == '\0')
-    return ((char *)NULL);
-
-  w->flags |= W_NOSPLIT2;
-  l = call_expand_word_internal (w, 0, 0, (int *)0, (int *)0);
-  if (l)
-    {
-      if (special == 0)
-       {
-         dequote_list (l);
-         r = string_list (l);
-       }
-      else
-       {
-         qflags = QGLOB_CVTNULL;
-         if (special == 2)
-           qflags |= QGLOB_REGEXP;
-         p = string_list (l);
-         r = quote_string_for_globbing (p, qflags);
-         free (p);
-       }
-      dispose_words (l);
-    }
-  else
-    r = (char *)NULL;
-
-  return r;
-}
-#endif
-
-/* Call expand_word_internal to expand W and handle error returns.
-   A convenience function for functions that don't want to handle
-   any errors or free any memory before aborting. */
-static WORD_LIST *
-call_expand_word_internal (w, q, i, c, e)
-     WORD_DESC *w;
-     int q, i, *c, *e;
-{
-  WORD_LIST *result;
-
-  result = expand_word_internal (w, q, i, c, e);
-  if (result == &expand_word_error || result == &expand_word_fatal)
-    {
-      /* By convention, each time this error is returned, w->word has
-        already been freed (it sometimes may not be in the fatal case,
-        but that doesn't result in a memory leak because we're going
-        to exit in most cases). */
-      w->word = (char *)NULL;
-      last_command_exit_value = EXECUTION_FAILURE;
-      exp_jump_to_top_level ((result == &expand_word_error) ? DISCARD : FORCE_EOF);
-      /* NOTREACHED */
-    }
-  else
-    return (result);
-}
-
-/* Perform parameter expansion, command substitution, and arithmetic
-   expansion on STRING, as if it were a word.  Leave the result quoted. */
-static WORD_LIST *
-expand_string_internal (string, quoted)
-     char *string;
-     int quoted;
-{
-  WORD_DESC td;
-  WORD_LIST *tresult;
-
-  if (string == 0 || *string == 0)
-    return ((WORD_LIST *)NULL);
-
-  td.flags = 0;
-  td.word = savestring (string);
-
-  tresult = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
-
-  FREE (td.word);
-  return (tresult);
-}
-
-/* Expand STRING by performing parameter expansion, command substitution,
-   and arithmetic expansion.  Dequote the resulting WORD_LIST before
-   returning it, but do not perform word splitting.  The call to
-   remove_quoted_nulls () is in here because word splitting normally
-   takes care of quote removal. */
-WORD_LIST *
-expand_string_unsplit (string, quoted)
-     char *string;
-     int quoted;
-{
-  WORD_LIST *value;
-
-  if (string == 0 || *string == '\0')
-    return ((WORD_LIST *)NULL);
-
-  expand_no_split_dollar_star = 1;
-  value = expand_string_internal (string, quoted);
-  expand_no_split_dollar_star = 0;
-
-  if (value)
-    {
-      if (value->word)
-       {
-         remove_quoted_nulls (value->word->word);
-         value->word->flags &= ~W_HASQUOTEDNULL;
-       }
-      dequote_list (value);
-    }
-  return (value);
-}
-
-/* Expand the rhs of an assignment statement */
-WORD_LIST *
-expand_string_assignment (string, quoted)
-     char *string;
-     int quoted;
-{
-  WORD_DESC td;
-  WORD_LIST *value;
-
-  if (string == 0 || *string == '\0')
-    return ((WORD_LIST *)NULL);
-
-  expand_no_split_dollar_star = 1;
-
-  td.flags = W_ASSIGNRHS;
-  td.word = savestring (string);
-  value = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
-  FREE (td.word);
-
-  expand_no_split_dollar_star = 0;
-
-  if (value)
-    {
-      if (value->word)
-       {
-         remove_quoted_nulls (value->word->word);
-         value->word->flags &= ~W_HASQUOTEDNULL;
-       }
-      dequote_list (value);
-    }
-  return (value);
-}
-
-
-/* Expand one of the PS? prompt strings. This is a sort of combination of
-   expand_string_unsplit and expand_string_internal, but returns the
-   passed string when an error occurs.  Might want to trap other calls
-   to jump_to_top_level here so we don't endlessly loop. */
-WORD_LIST *
-expand_prompt_string (string, quoted, wflags)
-     char *string;
-     int quoted;
-     int wflags;
-{
-  WORD_LIST *value;
-  WORD_DESC td;
-
-  if (string == 0 || *string == 0)
-    return ((WORD_LIST *)NULL);
-
-  td.flags = wflags;
-  td.word = savestring (string);
-
-  no_longjmp_on_fatal_error = 1;
-  value = expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
-  no_longjmp_on_fatal_error = 0;
-
-  if (value == &expand_word_error || value == &expand_word_fatal)
-    {
-      value = make_word_list (make_bare_word (string), (WORD_LIST *)NULL);
-      return value;
-    }
-  FREE (td.word);
-  if (value)
-    {
-      if (value->word)
-       {
-         remove_quoted_nulls (value->word->word);
-         value->word->flags &= ~W_HASQUOTEDNULL;
-       }
-      dequote_list (value);
-    }
-  return (value);
-}
-
-/* Expand STRING just as if you were expanding a word, but do not dequote
-   the resultant WORD_LIST.  This is called only from within this file,
-   and is used to correctly preserve quoted characters when expanding
-   things like ${1+"$@"}.  This does parameter expansion, command
-   substitution, arithmetic expansion, and word splitting. */
-static WORD_LIST *
-expand_string_leave_quoted (string, quoted)
-     char *string;
-     int quoted;
-{
-  WORD_LIST *tlist;
-  WORD_LIST *tresult;
-
-  if (string == 0 || *string == '\0')
-    return ((WORD_LIST *)NULL);
-
-  tlist = expand_string_internal (string, quoted);
-
-  if (tlist)
-    {
-      tresult = word_list_split (tlist);
-      dispose_words (tlist);
-      return (tresult);
-    }
-  return ((WORD_LIST *)NULL);
-}
-
-/* This does not perform word splitting or dequote the WORD_LIST
-   it returns. */
-static WORD_LIST *
-expand_string_for_rhs (string, quoted, dollar_at_p, has_dollar_at)
-     char *string;
-     int quoted, *dollar_at_p, *has_dollar_at;
-{
-  WORD_DESC td;
-  WORD_LIST *tresult;
-
-  if (string == 0 || *string == '\0')
-    return (WORD_LIST *)NULL;
-
-  td.flags = 0;
-  td.word = string;
-  tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, has_dollar_at);
-  return (tresult);
-}
-
-/* Expand STRING just as if you were expanding a word.  This also returns
-   a list of words.  Note that filename globbing is *NOT* done for word
-   or string expansion, just when the shell is expanding a command.  This
-   does parameter expansion, command substitution, arithmetic expansion,
-   and word splitting.  Dequote the resultant WORD_LIST before returning. */
-WORD_LIST *
-expand_string (string, quoted)
-     char *string;
-     int quoted;
-{
-  WORD_LIST *result;
-
-  if (string == 0 || *string == '\0')
-    return ((WORD_LIST *)NULL);
-
-  result = expand_string_leave_quoted (string, quoted);
-  return (result ? dequote_list (result) : result);
-}
-
-/***************************************************
- *                                                *
- *     Functions to handle quoting chars          *
- *                                                *
- ***************************************************/
-
-/* Conventions:
-
-     A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string.
-     The parser passes CTLNUL as CTLESC CTLNUL. */
-
-/* Quote escape characters in string s, but no other characters.  This is
-   used to protect CTLESC and CTLNUL in variable values from the rest of
-   the word expansion process after the variable is expanded (word splitting
-   and filename generation).  If IFS is null, we quote spaces as well, just
-   in case we split on spaces later (in the case of unquoted $@, we will
-   eventually attempt to split the entire word on spaces).  Corresponding
-   code exists in dequote_escapes.  Even if we don't end up splitting on
-   spaces, quoting spaces is not a problem.  This should never be called on
-   a string that is quoted with single or double quotes or part of a here
-   document (effectively double-quoted). */
-char *
-quote_escapes (string)
-     char *string;
-{
-  register char *s, *t;
-  size_t slen;
-  char *result, *send;
-  int quote_spaces, skip_ctlesc, skip_ctlnul;
-  DECLARE_MBSTATE; 
-
-  slen = strlen (string);
-  send = string + slen;
-
-  quote_spaces = (ifs_value && *ifs_value == 0);
-
-  for (skip_ctlesc = skip_ctlnul = 0, s = ifs_value; s && *s; s++)
-    skip_ctlesc |= *s == CTLESC, skip_ctlnul |= *s == CTLNUL;
-
-  t = result = (char *)xmalloc ((slen * 2) + 1);
-  s = string;
-
-  while (*s)
-    {
-      if ((skip_ctlesc == 0 && *s == CTLESC) || (skip_ctlnul == 0 && *s == CTLNUL) || (quote_spaces && *s == ' '))
-       *t++ = CTLESC;
-      COPY_CHAR_P (t, s, send);
-    }
-  *t = '\0';
-  return (result);
-}
-
-static WORD_LIST *
-list_quote_escapes (list)
-     WORD_LIST *list;
-{
-  register WORD_LIST *w;
-  char *t;
-
-  for (w = list; w; w = w->next)
-    {
-      t = w->word->word;
-      w->word->word = quote_escapes (t);
-      free (t);
-    }
-  return list;
-}
-
-/* Inverse of quote_escapes; remove CTLESC protecting CTLESC or CTLNUL.
-
-   The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL.
-   This is necessary to make unquoted CTLESC and CTLNUL characters in the
-   data stream pass through properly.
-
-   We need to remove doubled CTLESC characters inside quoted strings before
-   quoting the entire string, so we do not double the number of CTLESC
-   characters.
-
-   Also used by parts of the pattern substitution code. */
-char *
-dequote_escapes (string)
-     char *string;
-{
-  register char *s, *t, *s1;
-  size_t slen;
-  char *result, *send;
-  int quote_spaces;
-  DECLARE_MBSTATE;
-
-  if (string == 0)
-    return string;
-
-  slen = strlen (string);
-  send = string + slen;
-
-  t = result = (char *)xmalloc (slen + 1);
-
-  if (strchr (string, CTLESC) == 0)
-    return (strcpy (result, string));
-
-  quote_spaces = (ifs_value && *ifs_value == 0);
-
-  s = string;
-  while (*s)
-    {
-      if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL || (quote_spaces && s[1] == ' ')))
-       {
-         s++;
-         if (*s == '\0')
-           break;
-       }
-      COPY_CHAR_P (t, s, send);
-    }
-  *t = '\0';
-  return result;
-}
-
-/* Return a new string with the quoted representation of character C.
-   This turns "" into QUOTED_NULL, so the W_HASQUOTEDNULL flag needs to be
-   set in any resultant WORD_DESC where this value is the word. */
-static char *
-make_quoted_char (c)
-     int c;
-{
-  char *temp;
-
-  temp = (char *)xmalloc (3);
-  if (c == 0)
-    {
-      temp[0] = CTLNUL;
-      temp[1] = '\0';
-    }
-  else
-    {
-      temp[0] = CTLESC;
-      temp[1] = c;
-      temp[2] = '\0';
-    }
-  return (temp);
-}
-
-/* Quote STRING, returning a new string.  This turns "" into QUOTED_NULL, so
-   the W_HASQUOTEDNULL flag needs to be set in any resultant WORD_DESC where
-   this value is the word. */
-char *
-quote_string (string)
-     char *string;
-{
-  register char *t;
-  size_t slen;
-  char *result, *send;
-
-  if (*string == 0)
-    {
-      result = (char *)xmalloc (2);
-      result[0] = CTLNUL;
-      result[1] = '\0';
-    }
-  else
-    {
-      DECLARE_MBSTATE;
-
-      slen = strlen (string);
-      send = string + slen;
-
-      result = (char *)xmalloc ((slen * 2) + 1);
-
-      for (t = result; string < send; )
-       {
-         *t++ = CTLESC;
-         COPY_CHAR_P (t, string, send);
-       }
-      *t = '\0';
-    }
-  return (result);
-}
-
-/* De-quote quoted characters in STRING. */
-char *
-dequote_string (string)
-     char *string;
-{
-  register char *s, *t;
-  size_t slen;
-  char *result, *send;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string);
-
-  t = result = (char *)xmalloc (slen + 1);
-
-  if (QUOTED_NULL (string))
-    {
-      result[0] = '\0';
-      return (result);
-    }
-
-  /* If no character in the string can be quoted, don't bother examining
-     each character.  Just return a copy of the string passed to us. */
-  if (strchr (string, CTLESC) == NULL)
-    return (strcpy (result, string));
-
-  send = string + slen;
-  s = string;
-  while (*s)
-    {
-      if (*s == CTLESC)
-       {
-         s++;
-         if (*s == '\0')
-           break;
-       }
-      COPY_CHAR_P (t, s, send);
-    }
-
-  *t = '\0';
-  return (result);
-}
-
-/* Quote the entire WORD_LIST list. */
-static WORD_LIST *
-quote_list (list)
-     WORD_LIST *list;
-{
-  register WORD_LIST *w;
-  char *t;
-
-  for (w = list; w; w = w->next)
-    {
-      t = w->word->word;
-      w->word->word = quote_string (t);
-      if (*t == 0)
-       w->word->flags |= W_HASQUOTEDNULL;      /* XXX - turn on W_HASQUOTEDNULL here? */
-      w->word->flags |= W_QUOTED;
-      free (t);
-    }
-  return list;
-}
-
-/* De-quote quoted characters in each word in LIST. */
-WORD_LIST *
-dequote_list (list)
-     WORD_LIST *list;
-{
-  register char *s;
-  register WORD_LIST *tlist;
-
-  for (tlist = list; tlist; tlist = tlist->next)
-    {
-      s = dequote_string (tlist->word->word);
-      if (QUOTED_NULL (tlist->word->word))
-       tlist->word->flags &= ~W_HASQUOTEDNULL;
-      free (tlist->word->word);
-      tlist->word->word = s;
-    }
-  return list;
-}
-
-/* Remove CTLESC protecting a CTLESC or CTLNUL in place.  Return the passed
-   string. */
-char *
-remove_quoted_escapes (string)
-     char *string;
-{
-  char *t;
-
-  if (string)
-    {
-      t = dequote_escapes (string);
-      strcpy (string, t);
-      free (t);
-    }
-
-  return (string);
-}
-
-/* Perform quoted null character removal on STRING.  We don't allow any
-   quoted null characters in the middle or at the ends of strings because
-   of how expand_word_internal works.  remove_quoted_nulls () turns
-   STRING into an empty string iff it only consists of a quoted null,
-   and removes all unquoted CTLNUL characters. */
-char *
-remove_quoted_nulls (string)
-     char *string;
-{
-  register size_t slen;
-  register int i, j, prev_i;
-  DECLARE_MBSTATE;
-
-  if (strchr (string, CTLNUL) == 0)            /* XXX */
-    return string;                             /* XXX */
-
-  slen = strlen (string);
-  i = j = 0;
-
-  while (i < slen)
-    {
-      if (string[i] == CTLESC)
-       {
-         /* Old code had j++, but we cannot assume that i == j at this
-            point -- what if a CTLNUL has already been removed from the
-            string?  We don't want to drop the CTLESC or recopy characters
-            that we've already copied down. */
-         i++; string[j++] = CTLESC;
-         if (i == slen)
-           break;
-       }
-      else if (string[i] == CTLNUL)
-       i++;
-
-      prev_i = i;
-      ADVANCE_CHAR (string, slen, i);
-      if (j < prev_i)
-       {
-         do string[j++] = string[prev_i++]; while (prev_i < i);
-       }
-      else
-       j = i;
-    }
-  string[j] = '\0';
-
-  return (string);
-}
-
-/* Perform quoted null character removal on each element of LIST.
-   This modifies LIST. */
-void
-word_list_remove_quoted_nulls (list)
-     WORD_LIST *list;
-{
-  register WORD_LIST *t;
-
-  for (t = list; t; t = t->next)
-    {
-      remove_quoted_nulls (t->word->word);
-      t->word->flags &= ~W_HASQUOTEDNULL;
-    }
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*        Functions for Matching and Removing Patterns             */
-/*                                                                 */
-/* **************************************************************** */
-
-#if defined (HANDLE_MULTIBYTE)
-#if 0 /* Currently unused */
-static unsigned char *
-mb_getcharlens (string, len)
-     char *string;
-     int len;
-{
-  int i, offset, last;
-  unsigned char *ret;
-  char *p;
-  DECLARE_MBSTATE;
-
-  i = offset = 0;
-  last = 0;
-  ret = (unsigned char *)xmalloc (len);
-  memset (ret, 0, len);
-  while (string[last])
-    {
-      ADVANCE_CHAR (string, len, offset);
-      ret[last] = offset - last;
-      last = offset;
-    }
-  return ret;
-}
-#endif
-#endif
-
-/* Remove the portion of PARAM matched by PATTERN according to OP, where OP
-   can have one of 4 values:
-       RP_LONG_LEFT    remove longest matching portion at start of PARAM
-       RP_SHORT_LEFT   remove shortest matching portion at start of PARAM
-       RP_LONG_RIGHT   remove longest matching portion at end of PARAM
-       RP_SHORT_RIGHT  remove shortest matching portion at end of PARAM
-*/
-
-#define RP_LONG_LEFT   1
-#define RP_SHORT_LEFT  2
-#define RP_LONG_RIGHT  3
-#define RP_SHORT_RIGHT 4
-
-static char *
-remove_upattern (param, pattern, op)
-     char *param, *pattern;
-     int op;
-{
-  register int len;
-  register char *end;
-  register char *p, *ret, c;
-
-  len = STRLEN (param);
-  end = param + len;
-
-  switch (op)
-    {
-      case RP_LONG_LEFT:       /* remove longest match at start */
-       for (p = end; p >= param; p--)
-         {
-           c = *p; *p = '\0';
-           if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               *p = c;
-               return (savestring (p));
-             }
-           *p = c;
-
-         }
-       break;
-
-      case RP_SHORT_LEFT:      /* remove shortest match at start */
-       for (p = param; p <= end; p++)
-         {
-           c = *p; *p = '\0';
-           if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               *p = c;
-               return (savestring (p));
-             }
-           *p = c;
-         }
-       break;
-
-      case RP_LONG_RIGHT:      /* remove longest match at end */
-       for (p = param; p <= end; p++)
-         {
-           if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               c = *p; *p = '\0';
-               ret = savestring (param);
-               *p = c;
-               return (ret);
-             }
-         }
-       break;
-
-      case RP_SHORT_RIGHT:     /* remove shortest match at end */
-       for (p = end; p >= param; p--)
-         {
-           if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               c = *p; *p = '\0';
-               ret = savestring (param);
-               *p = c;
-               return (ret);
-             }
-         }
-       break;
-    }
-
-  return (savestring (param)); /* no match, return original string */
-}
-
-#if defined (HANDLE_MULTIBYTE)
-static wchar_t *
-remove_wpattern (wparam, wstrlen, wpattern, op)
-     wchar_t *wparam;
-     size_t wstrlen;
-     wchar_t *wpattern;
-     int op;
-{
-  wchar_t wc, *ret;
-  int n;
-
-  switch (op)
-    {
-      case RP_LONG_LEFT:       /* remove longest match at start */
-        for (n = wstrlen; n >= 0; n--)
-         {
-           wc = wparam[n]; wparam[n] = L'\0';
-           if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               wparam[n] = wc;
-               return (wcsdup (wparam + n));
-             }
-           wparam[n] = wc;
-         }
-       break;
-
-      case RP_SHORT_LEFT:      /* remove shortest match at start */
-       for (n = 0; n <= wstrlen; n++)
-         {
-           wc = wparam[n]; wparam[n] = L'\0';
-           if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               wparam[n] = wc;
-               return (wcsdup (wparam + n));
-             }
-           wparam[n] = wc;
-         }
-       break;
-
-      case RP_LONG_RIGHT:      /* remove longest match at end */
-        for (n = 0; n <= wstrlen; n++)
-         {
-           if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               wc = wparam[n]; wparam[n] = L'\0';
-               ret = wcsdup (wparam);
-               wparam[n] = wc;
-               return (ret);
-             }
-         }
-       break;
-
-      case RP_SHORT_RIGHT:     /* remove shortest match at end */
-       for (n = wstrlen; n >= 0; n--)
-         {
-           if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               wc = wparam[n]; wparam[n] = L'\0';
-               ret = wcsdup (wparam);
-               wparam[n] = wc;
-               return (ret);
-             }
-         }
-       break;
-    }
-
-  return (wcsdup (wparam));    /* no match, return original string */
-}
-#endif /* HANDLE_MULTIBYTE */
-
-static char *
-remove_pattern (param, pattern, op)
-     char *param, *pattern;
-     int op;
-{
-  if (param == NULL)
-    return (param);
-  if (*param == '\0' || pattern == NULL || *pattern == '\0')   /* minor optimization */
-    return (savestring (param));
-
-#if defined (HANDLE_MULTIBYTE)
-  if (MB_CUR_MAX > 1)
-    {
-      wchar_t *ret, *oret;
-      size_t n;
-      wchar_t *wparam, *wpattern;
-      mbstate_t ps;
-      char *xret;
-
-      n = xdupmbstowcs (&wpattern, NULL, pattern);
-      if (n == (size_t)-1)
-       return (remove_upattern (param, pattern, op));
-      n = xdupmbstowcs (&wparam, NULL, param);
-      if (n == (size_t)-1)
-       {
-         free (wpattern);
-         return (remove_upattern (param, pattern, op));
-       }
-      oret = ret = remove_wpattern (wparam, n, wpattern, op);
-
-      free (wparam);
-      free (wpattern);
-
-      n = strlen (param);
-      xret = (char *)xmalloc (n + 1);
-      memset (&ps, '\0', sizeof (mbstate_t));
-      n = wcsrtombs (xret, (const wchar_t **)&ret, n, &ps);
-      xret[n] = '\0';          /* just to make sure */
-      free (oret);
-      return xret;      
-    }
-  else
-#endif
-    return (remove_upattern (param, pattern, op));
-}
-
-/* Return 1 of the first character of STRING could match the first
-   character of pattern PAT.  Used to avoid n2 calls to strmatch(). */
-static int
-match_pattern_char (pat, string)
-     char *pat, *string;
-{
-  char c;
-
-  if (*string == 0)
-    return (0);
-
-  switch (c = *pat++)
-    {
-    default:
-      return (*string == c);
-    case '\\':
-      return (*string == *pat);
-    case '?':
-      return (*pat == LPAREN ? 1 : (*string != '\0'));
-    case '*':
-      return (1);
-    case '+':
-    case '!':
-    case '@':
-      return (*pat == LPAREN ? 1 : (*string == c));
-    case '[':
-      return (*string != '\0');
-    }
-}
-
-/* Match PAT anywhere in STRING and return the match boundaries.
-   This returns 1 in case of a successful match, 0 otherwise.  SP
-   and EP are pointers into the string where the match begins and
-   ends, respectively.  MTYPE controls what kind of match is attempted.
-   MATCH_BEG and MATCH_END anchor the match at the beginning and end
-   of the string, respectively.  The longest match is returned. */
-static int
-match_upattern (string, pat, mtype, sp, ep)
-     char *string, *pat;
-     int mtype;
-     char **sp, **ep;
-{
-  int c, len;
-  register char *p, *p1, *npat;
-  char *end;
-
-  /* If the pattern doesn't match anywhere in the string, go ahead and
-     short-circuit right away.  A minor optimization, saves a bunch of
-     unnecessary calls to strmatch (up to N calls for a string of N
-     characters) if the match is unsuccessful.  To preserve the semantics
-     of the substring matches below, we make sure that the pattern has
-     `*' as first and last character, making a new pattern if necessary. */
-  /* XXX - check this later if I ever implement `**' with special meaning,
-     since this will potentially result in `**' at the beginning or end */
-  len = STRLEN (pat);
-  if (pat[0] != '*' || (pat[0] == '*' && pat[1] == LPAREN && extended_glob) || pat[len - 1] != '*')
-    {
-      p = npat = (char *)xmalloc (len + 3);
-      p1 = pat;
-      if (*p1 != '*' || (*p1 == '*' && p1[1] == LPAREN && extended_glob))
-       *p++ = '*';
-      while (*p1)
-       *p++ = *p1++;
-      if (p1[-1] != '*' || p[-2] == '\\')
-       *p++ = '*';
-      *p = '\0';
-    }
-  else
-    npat = pat;
-  c = strmatch (npat, string, FNMATCH_EXTFLAG);
-  if (npat != pat)
-    free (npat);
-  if (c == FNM_NOMATCH)
-    return (0);
-
-  len = STRLEN (string);
-  end = string + len;
-
-  switch (mtype)
-    {
-    case MATCH_ANY:
-      for (p = string; p <= end; p++)
-       {
-         if (match_pattern_char (pat, p))
-           {
-             for (p1 = end; p1 >= p; p1--)
-               {
-                 c = *p1; *p1 = '\0';
-                 if (strmatch (pat, p, FNMATCH_EXTFLAG) == 0)
-                   {
-                     *p1 = c;
-                     *sp = p;
-                     *ep = p1;
-                     return 1;
-                   }
-                 *p1 = c;
-               }
-           }
-       }
-
-      return (0);
-
-    case MATCH_BEG:
-      if (match_pattern_char (pat, string) == 0)
-       return (0);
-
-      for (p = end; p >= string; p--)
-       {
-         c = *p; *p = '\0';
-         if (strmatch (pat, string, FNMATCH_EXTFLAG) == 0)
-           {
-             *p = c;
-             *sp = string;
-             *ep = p;
-             return 1;
-           }
-         *p = c;
-       }
-
-      return (0);
-
-    case MATCH_END:
-      for (p = string; p <= end; p++)
-       {
-         if (strmatch (pat, p, FNMATCH_EXTFLAG) == 0)
-           {
-             *sp = p;
-             *ep = end;
-             return 1;
-           }
-
-       }
-
-      return (0);
-    }
-
-  return (0);
-}
-
-#if defined (HANDLE_MULTIBYTE)
-/* Return 1 of the first character of WSTRING could match the first
-   character of pattern WPAT.  Wide character version. */
-static int
-match_pattern_wchar (wpat, wstring)
-     wchar_t *wpat, *wstring;
-{
-  wchar_t wc;
-
-  if (*wstring == 0)
-    return (0);
-
-  switch (wc = *wpat++)
-    {
-    default:
-      return (*wstring == wc);
-    case L'\\':
-      return (*wstring == *wpat);
-    case L'?':
-      return (*wpat == LPAREN ? 1 : (*wstring != L'\0'));
-    case L'*':
-      return (1);
-    case L'+':
-    case L'!':
-    case L'@':
-      return (*wpat == LPAREN ? 1 : (*wstring == wc));
-    case L'[':
-      return (*wstring != L'\0');
-    }
-}
-
-/* Match WPAT anywhere in WSTRING and return the match boundaries.
-   This returns 1 in case of a successful match, 0 otherwise.  Wide
-   character version. */
-static int
-match_wpattern (wstring, indices, wstrlen, wpat, mtype, sp, ep)
-     wchar_t *wstring;
-     char **indices;
-     size_t wstrlen;
-     wchar_t *wpat;
-     int mtype;
-     char **sp, **ep;
-{
-  wchar_t wc, *wp, *nwpat, *wp1;
-  int len;
-#if 0
-  size_t n, n1;        /* Apple's gcc seems to miscompile this badly */
-#else
-  int n, n1;
-#endif
-
-  /* If the pattern doesn't match anywhere in the string, go ahead and
-     short-circuit right away.  A minor optimization, saves a bunch of
-     unnecessary calls to strmatch (up to N calls for a string of N
-     characters) if the match is unsuccessful.  To preserve the semantics
-     of the substring matches below, we make sure that the pattern has
-     `*' as first and last character, making a new pattern if necessary. */
-  /* XXX - check this later if I ever implement `**' with special meaning,
-     since this will potentially result in `**' at the beginning or end */
-  len = wcslen (wpat);
-  if (wpat[0] != L'*' || (wpat[0] == L'*' && wpat[1] == WLPAREN && extended_glob) || wpat[len - 1] != L'*')
-    {
-      wp = nwpat = (wchar_t *)xmalloc ((len + 3) * sizeof (wchar_t));
-      wp1 = wpat;
-      if (*wp1 != L'*' || (*wp1 == '*' && wp1[1] == WLPAREN && extended_glob))
-       *wp++ = L'*';
-      while (*wp1 != L'\0')
-       *wp++ = *wp1++;
-      if (wp1[-1] != L'*' || wp1[-2] == L'\\')
-        *wp++ = L'*';
-      *wp = '\0';
-    }
-  else
-    nwpat = wpat;
-  len = wcsmatch (nwpat, wstring, FNMATCH_EXTFLAG);
-  if (nwpat != wpat)
-    free (nwpat);
-  if (len == FNM_NOMATCH)
-    return (0);
-
-  switch (mtype)
-    {
-    case MATCH_ANY:
-      for (n = 0; n <= wstrlen; n++)
-       {
-         if (match_pattern_wchar (wpat, wstring + n))
-           {
-             for (n1 = wstrlen; n1 >= n; n1--)
-               {
-                 wc = wstring[n1]; wstring[n1] = L'\0';
-                 if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG) == 0)
-                   {
-                     wstring[n1] = wc;
-                     *sp = indices[n];
-                     *ep = indices[n1];
-                     return 1;
-                   }
-                 wstring[n1] = wc;
-               }
-           }
-       }
-
-      return (0);
-
-    case MATCH_BEG:
-      if (match_pattern_wchar (wpat, wstring) == 0)
-       return (0);
-
-      for (n = wstrlen; n >= 0; n--)
-       {
-         wc = wstring[n]; wstring[n] = L'\0';
-         if (wcsmatch (wpat, wstring, FNMATCH_EXTFLAG) == 0)
-           {
-             wstring[n] = wc;
-             *sp = indices[0];
-             *ep = indices[n];
-             return 1;
-           }
-         wstring[n] = wc;
-       }
-
-      return (0);
-
-    case MATCH_END:
-      for (n = 0; n <= wstrlen; n++)
-       {
-         if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG) == 0)
-           {
-             *sp = indices[n];
-             *ep = indices[wstrlen];
-             return 1;
-           }
-       }
-
-      return (0);
-    }
-
-  return (0);
-}
-#endif /* HANDLE_MULTIBYTE */
-
-static int
-match_pattern (string, pat, mtype, sp, ep)
-     char *string, *pat;
-     int mtype;
-     char **sp, **ep;
-{
-#if defined (HANDLE_MULTIBYTE)
-  int ret;
-  size_t n;
-  wchar_t *wstring, *wpat;
-  char **indices;
-#endif
-
-  if (string == 0 || *string == 0 || pat == 0 || *pat == 0)
-    return (0);
-
-#if defined (HANDLE_MULTIBYTE)
-  if (MB_CUR_MAX > 1)
-    {
-      n = xdupmbstowcs (&wpat, NULL, pat);
-      if (n == (size_t)-1)
-       return (match_upattern (string, pat, mtype, sp, ep));
-      n = xdupmbstowcs (&wstring, &indices, string);
-      if (n == (size_t)-1)
-       {
-         free (wpat);
-         return (match_upattern (string, pat, mtype, sp, ep));
-       }
-      ret = match_wpattern (wstring, indices, n, wpat, mtype, sp, ep);
-
-      free (wpat);
-      free (wstring);
-      free (indices);
-
-      return (ret);
-    }
-  else
-#endif
-    return (match_upattern (string, pat, mtype, sp, ep));
-}
-
-static int
-getpatspec (c, value)
-     int c;
-     char *value;
-{
-  if (c == '#')
-    return ((*value == '#') ? RP_LONG_LEFT : RP_SHORT_LEFT);
-  else /* c == '%' */
-    return ((*value == '%') ? RP_LONG_RIGHT : RP_SHORT_RIGHT);
-}
-
-/* Posix.2 says that the WORD should be run through tilde expansion,
-   parameter expansion, command substitution and arithmetic expansion.
-   This leaves the result quoted, so quote_string_for_globbing () has
-   to be called to fix it up for strmatch ().  If QUOTED is non-zero,
-   it means that the entire expression was enclosed in double quotes.
-   This means that quoting characters in the pattern do not make any
-   special pattern characters quoted.  For example, the `*' in the
-   following retains its special meaning: "${foo#'*'}". */
-static char *
-getpattern (value, quoted, expandpat)
-     char *value;
-     int quoted, expandpat;
-{
-  char *pat, *tword;
-  WORD_LIST *l;
-#if 0
-  int i;
-#endif
-  /* There is a problem here:  how to handle single or double quotes in the
-     pattern string when the whole expression is between double quotes?
-     POSIX.2 says that enclosing double quotes do not cause the pattern to
-     be quoted, but does that leave us a problem with @ and array[@] and their
-     expansions inside a pattern? */
-#if 0
-  if (expandpat && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *tword)
-    {
-      i = 0;
-      pat = string_extract_double_quoted (tword, &i, 1);
-      free (tword);
-      tword = pat;
-    }
-#endif
-
-  /* expand_string_for_rhs () leaves WORD quoted and does not perform
-     word splitting. */
-  l = *value ? expand_string_for_rhs (value,
-                                     (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? Q_PATQUOTE : quoted,
-                                     (int *)NULL, (int *)NULL)
-            : (WORD_LIST *)0;
-  pat = string_list (l);
-  dispose_words (l);
-  if (pat)
-    {
-      tword = quote_string_for_globbing (pat, QGLOB_CVTNULL);
-      free (pat);
-      pat = tword;
-    }
-  return (pat);
-}
-
-#if 0
-/* Handle removing a pattern from a string as a result of ${name%[%]value}
-   or ${name#[#]value}. */
-static char *
-variable_remove_pattern (value, pattern, patspec, quoted)
-     char *value, *pattern;
-     int patspec, quoted;
-{
-  char *tword;
-
-  tword = remove_pattern (value, pattern, patspec);
-
-  return (tword);
-}
-#endif
-
-static char *
-list_remove_pattern (list, pattern, patspec, itype, quoted)
-     WORD_LIST *list;
-     char *pattern;
-     int patspec, itype, quoted;
-{
-  WORD_LIST *new, *l;
-  WORD_DESC *w;
-  char *tword;
-
-  for (new = (WORD_LIST *)NULL, l = list; l; l = l->next)
-    {
-      tword = remove_pattern (l->word->word, pattern, patspec);
-      w = alloc_word_desc ();
-      w->word = tword ? tword : savestring ("");
-      new = make_word_list (w, new);
-    }
-
-  l = REVERSE_LIST (new, WORD_LIST *);
-  tword = string_list_pos_params (itype, l, quoted);
-  dispose_words (l);
-
-  return (tword);
-}
-
-static char *
-parameter_list_remove_pattern (itype, pattern, patspec, quoted)
-     int itype;
-     char *pattern;
-     int patspec, quoted;
-{
-  char *ret;
-  WORD_LIST *list;
-
-  list = list_rest_of_args ();
-  if (list == 0)
-    return ((char *)NULL);
-  ret = list_remove_pattern (list, pattern, patspec, itype, quoted);
-  dispose_words (list);
-  return (ret);
-}
-
-#if defined (ARRAY_VARS)
-static char *
-array_remove_pattern (var, pattern, patspec, varname, quoted)
-     SHELL_VAR *var;
-     char *pattern;
-     int patspec;
-     char *varname;    /* so we can figure out how it's indexed */
-     int quoted;
-{
-  ARRAY *a;
-  HASH_TABLE *h;
-  int itype;
-  char *ret;
-  WORD_LIST *list;
-  SHELL_VAR *v;
-
-  /* compute itype from varname here */
-  v = array_variable_part (varname, &ret, 0);
-  itype = ret[0];
-
-  a = (v && array_p (v)) ? array_cell (v) : 0;
-  h = (v && assoc_p (v)) ? assoc_cell (v) : 0;
-  
-  list = a ? array_to_word_list (a) : (h ? assoc_to_word_list (h) : 0);
-  if (list == 0)
-   return ((char *)NULL);
-  ret = list_remove_pattern (list, pattern, patspec, itype, quoted);
-  dispose_words (list);
-
-  return ret;
-}
-#endif /* ARRAY_VARS */
-
-static char *
-parameter_brace_remove_pattern (varname, value, patstr, rtype, quoted)
-     char *varname, *value, *patstr;
-     int rtype, quoted;
-{
-  int vtype, patspec, starsub;
-  char *temp1, *val, *pattern;
-  SHELL_VAR *v;
-
-  if (value == 0)
-    return ((char *)NULL);
-
-  this_command_name = varname;
-
-  vtype = get_var_and_type (varname, value, quoted, &v, &val);
-  if (vtype == -1)
-    return ((char *)NULL);
-
-  starsub = vtype & VT_STARSUB;
-  vtype &= ~VT_STARSUB;
-
-  patspec = getpatspec (rtype, patstr);
-  if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT)
-    patstr++;
-
-  /* Need to pass getpattern newly-allocated memory in case of expansion --
-     the expansion code will free the passed string on an error. */
-  temp1 = savestring (patstr);
-  pattern = getpattern (temp1, quoted, 1);
-  free (temp1);
-
-  temp1 = (char *)NULL;                /* shut up gcc */
-  switch (vtype)
-    {
-    case VT_VARIABLE:
-    case VT_ARRAYMEMBER:
-      temp1 = remove_pattern (val, pattern, patspec);
-      if (vtype == VT_VARIABLE)
-       FREE (val);
-      if (temp1)
-       {
-         val = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-                       ? quote_string (temp1)
-                       : quote_escapes (temp1);
-         free (temp1);
-         temp1 = val;
-       }
-      break;
-#if defined (ARRAY_VARS)
-    case VT_ARRAYVAR:
-      temp1 = array_remove_pattern (v, pattern, patspec, varname, quoted);
-      if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
-       {
-         val = quote_escapes (temp1);
-         free (temp1);
-         temp1 = val;
-       }
-      break;
-#endif
-    case VT_POSPARMS:
-      temp1 = parameter_list_remove_pattern (varname[0], pattern, patspec, quoted);
-      if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
-       {
-         val = quote_escapes (temp1);
-         free (temp1);
-         temp1 = val;
-       }
-      break;
-    }
-
-  FREE (pattern);
-  return temp1;
-}    
-
-/*******************************************
- *                                        *
- *     Functions to expand WORD_DESCs     *
- *                                        *
- *******************************************/
-
-/* Expand WORD, performing word splitting on the result.  This does
-   parameter expansion, command substitution, arithmetic expansion,
-   word splitting, and quote removal. */
-
-WORD_LIST *
-expand_word (word, quoted)
-     WORD_DESC *word;
-     int quoted;
-{
-  WORD_LIST *result, *tresult;
-
-  tresult = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
-  result = word_list_split (tresult);
-  dispose_words (tresult);
-  return (result ? dequote_list (result) : result);
-}
-
-/* Expand WORD, but do not perform word splitting on the result.  This
-   does parameter expansion, command substitution, arithmetic expansion,
-   and quote removal. */
-WORD_LIST *
-expand_word_unsplit (word, quoted)
-     WORD_DESC *word;
-     int quoted;
-{
-  WORD_LIST *result;
-
-  expand_no_split_dollar_star = 1;
-#if defined (HANDLE_MULTIBYTE)
-  if (ifs_firstc[0] == 0)
-#else
-  if (ifs_firstc == 0)
-#endif
-    word->flags |= W_NOSPLIT;
-  result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
-  expand_no_split_dollar_star = 0;
-
-  return (result ? dequote_list (result) : result);
-}
-
-/* Perform shell expansions on WORD, but do not perform word splitting or
-   quote removal on the result.  Virtually identical to expand_word_unsplit;
-   could be combined if implementations don't diverge. */
-WORD_LIST *
-expand_word_leave_quoted (word, quoted)
-     WORD_DESC *word;
-     int quoted;
-{
-  WORD_LIST *result;
-
-  expand_no_split_dollar_star = 1;
-#if defined (HANDLE_MULTIBYTE)
-  if (ifs_firstc[0] == 0)
-#else
-  if (ifs_firstc == 0)
-#endif
-    word->flags |= W_NOSPLIT;
-  word->flags |= W_NOSPLIT2;
-  result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
-  expand_no_split_dollar_star = 0;
-
-  return result;
-}
-
-#if defined (PROCESS_SUBSTITUTION)
-
-/*****************************************************************/
-/*                                                              */
-/*                 Hacking Process Substitution                 */
-/*                                                              */
-/*****************************************************************/
-
-#if !defined (HAVE_DEV_FD)
-/* Named pipes must be removed explicitly with `unlink'.  This keeps a list
-   of FIFOs the shell has open.  unlink_fifo_list will walk the list and
-   unlink all of them. add_fifo_list adds the name of an open FIFO to the
-   list.  NFIFO is a count of the number of FIFOs in the list. */
-#define FIFO_INCR 20
-
-struct temp_fifo {
-  char *file;
-  pid_t proc;
-};
-
-static struct temp_fifo *fifo_list = (struct temp_fifo *)NULL;
-static int nfifo;
-static int fifo_list_size;
-
-static void
-add_fifo_list (pathname)
-     char *pathname;
-{
-  if (nfifo >= fifo_list_size - 1)
-    {
-      fifo_list_size += FIFO_INCR;
-      fifo_list = (struct temp_fifo *)xrealloc (fifo_list,
-                               fifo_list_size * sizeof (struct temp_fifo));
-    }
-
-  fifo_list[nfifo].file = savestring (pathname);
-  nfifo++;
-}
-
-void
-unlink_fifo_list ()
-{
-  int saved, i, j;
-
-  if (nfifo == 0)
-    return;
-
-  for (i = saved = 0; i < nfifo; i++)
-    {
-      if ((fifo_list[i].proc == -1) || (kill(fifo_list[i].proc, 0) == -1))
-       {
-         unlink (fifo_list[i].file);
-         free (fifo_list[i].file);
-         fifo_list[i].file = (char *)NULL;
-         fifo_list[i].proc = -1;
-       }
-      else
-       saved++;
-    }
-
-  /* If we didn't remove some of the FIFOs, compact the list. */
-  if (saved)
-    {
-      for (i = j = 0; i < nfifo; i++)
-       if (fifo_list[i].file)
-         {
-           fifo_list[j].file = fifo_list[i].file;
-           fifo_list[j].proc = fifo_list[i].proc;
-           j++;
-         }
-      nfifo = j;
-    }
-  else
-    nfifo = 0;
-}
-
-int
-fifos_pending ()
-{
-  return nfifo;
-}
-
-static char *
-make_named_pipe ()
-{
-  char *tname;
-
-  tname = sh_mktmpname ("sh-np", MT_USERANDOM|MT_USETMPDIR);
-  if (mkfifo (tname, 0600) < 0)
-    {
-      free (tname);
-      return ((char *)NULL);
-    }
-
-  add_fifo_list (tname);
-  return (tname);
-}
-
-#else /* HAVE_DEV_FD */
-
-/* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
-   has open to children.  NFDS is a count of the number of bits currently
-   set in DEV_FD_LIST.  TOTFDS is a count of the highest possible number
-   of open files. */
-static char *dev_fd_list = (char *)NULL;
-static int nfds;
-static int totfds;     /* The highest possible number of open files. */
-
-static void
-add_fifo_list (fd)
-     int fd;
-{
-  if (!dev_fd_list || fd >= totfds)
-    {
-      int ofds;
-
-      ofds = totfds;
-      totfds = getdtablesize ();
-      if (totfds < 0 || totfds > 256)
-       totfds = 256;
-      if (fd >= totfds)
-       totfds = fd + 2;
-
-      dev_fd_list = (char *)xrealloc (dev_fd_list, totfds);
-      memset (dev_fd_list + ofds, '\0', totfds - ofds);
-    }
-
-  dev_fd_list[fd] = 1;
-  nfds++;
-}
-
-int
-fifos_pending ()
-{
-  return 0;    /* used for cleanup; not needed with /dev/fd */
-}
-
-void
-unlink_fifo_list ()
-{
-  register int i;
-
-  if (nfds == 0)
-    return;
-
-  for (i = 0; nfds && i < totfds; i++)
-    if (dev_fd_list[i])
-      {
-       close (i);
-       dev_fd_list[i] = 0;
-       nfds--;
-      }
-
-  nfds = 0;
-}
-
-#if defined (NOTDEF)
-print_dev_fd_list ()
-{
-  register int i;
-
-  fprintf (stderr, "pid %ld: dev_fd_list:", (long)getpid ());
-  fflush (stderr);
-
-  for (i = 0; i < totfds; i++)
-    {
-      if (dev_fd_list[i])
-       fprintf (stderr, " %d", i);
-    }
-  fprintf (stderr, "\n");
-}
-#endif /* NOTDEF */
-
-static char *
-make_dev_fd_filename (fd)
-     int fd;
-{
-  char *ret, intbuf[INT_STRLEN_BOUND (int) + 1], *p;
-
-  ret = (char *)xmalloc (sizeof (DEV_FD_PREFIX) + 8);
-
-  strcpy (ret, DEV_FD_PREFIX);
-  p = inttostr (fd, intbuf, sizeof (intbuf));
-  strcpy (ret + sizeof (DEV_FD_PREFIX) - 1, p);
-
-  add_fifo_list (fd);
-  return (ret);
-}
-
-#endif /* HAVE_DEV_FD */
-
-/* Return a filename that will open a connection to the process defined by
-   executing STRING.  HAVE_DEV_FD, if defined, means open a pipe and return
-   a filename in /dev/fd corresponding to a descriptor that is one of the
-   ends of the pipe.  If not defined, we use named pipes on systems that have
-   them.  Systems without /dev/fd and named pipes are out of luck.
-
-   OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
-   use the read end of the pipe and dup that file descriptor to fd 0 in
-   the child.  If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
-   writing or use the write end of the pipe in the child, and dup that
-   file descriptor to fd 1 in the child.  The parent does the opposite. */
-
-static char *
-process_substitute (string, open_for_read_in_child)
-     char *string;
-     int open_for_read_in_child;
-{
-  char *pathname;
-  int fd, result;
-  pid_t old_pid, pid;
-#if defined (HAVE_DEV_FD)
-  int parent_pipe_fd, child_pipe_fd;
-  int fildes[2];
-#endif /* HAVE_DEV_FD */
-#if defined (JOB_CONTROL)
-  pid_t old_pipeline_pgrp;
-#endif
-
-  if (!string || !*string || wordexp_only)
-    return ((char *)NULL);
-
-#if !defined (HAVE_DEV_FD)
-  pathname = make_named_pipe ();
-#else /* HAVE_DEV_FD */
-  if (pipe (fildes) < 0)
-    {
-      sys_error (_("cannot make pipe for process substitution"));
-      return ((char *)NULL);
-    }
-  /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
-     the pipe in the parent, otherwise the read end. */
-  parent_pipe_fd = fildes[open_for_read_in_child];
-  child_pipe_fd = fildes[1 - open_for_read_in_child];
-  /* Move the parent end of the pipe to some high file descriptor, to
-     avoid clashes with FDs used by the script. */
-  parent_pipe_fd = move_to_high_fd (parent_pipe_fd, 1, 64);
-
-  pathname = make_dev_fd_filename (parent_pipe_fd);
-#endif /* HAVE_DEV_FD */
-
-  if (pathname == 0)
-    {
-      sys_error (_("cannot make pipe for process substitution"));
-      return ((char *)NULL);
-    }
-
-  old_pid = last_made_pid;
-
-#if defined (JOB_CONTROL)
-  old_pipeline_pgrp = pipeline_pgrp;
-  pipeline_pgrp = shell_pgrp;
-  save_pipeline (1);
-#endif /* JOB_CONTROL */
-
-  pid = make_child ((char *)NULL, 1);
-  if (pid == 0)
-    {
-      reset_terminating_signals ();    /* XXX */
-      free_pushed_string_input ();
-      /* Cancel traps, in trap.c. */
-      restore_original_signals ();
-      setup_async_signals ();
-      subshell_environment |= SUBSHELL_COMSUB|SUBSHELL_PROCSUB;
-    }
-
-#if defined (JOB_CONTROL)
-  set_sigchld_handler ();
-  stop_making_children ();
-  /* XXX - should we only do this in the parent? (as in command subst) */
-  pipeline_pgrp = old_pipeline_pgrp;
-#endif /* JOB_CONTROL */
-
-  if (pid < 0)
-    {
-      sys_error (_("cannot make child for process substitution"));
-      free (pathname);
-#if defined (HAVE_DEV_FD)
-      close (parent_pipe_fd);
-      close (child_pipe_fd);
-#endif /* HAVE_DEV_FD */
-      return ((char *)NULL);
-    }
-
-  if (pid > 0)
-    {
-#if defined (JOB_CONTROL)
-      restore_pipeline (1);
-#endif
-
-#if !defined (HAVE_DEV_FD)
-      fifo_list[nfifo-1].proc = pid;
-#endif
-
-      last_made_pid = old_pid;
-
-#if defined (JOB_CONTROL) && defined (PGRP_PIPE)
-      close_pgrp_pipe ();
-#endif /* JOB_CONTROL && PGRP_PIPE */
-
-#if defined (HAVE_DEV_FD)
-      close (child_pipe_fd);
-#endif /* HAVE_DEV_FD */
-
-      return (pathname);
-    }
-
-  set_sigint_handler ();
-
-#if defined (JOB_CONTROL)
-  set_job_control (0);
-#endif /* JOB_CONTROL */
-
-#if !defined (HAVE_DEV_FD)
-  /* Open the named pipe in the child. */
-  fd = open (pathname, open_for_read_in_child ? O_RDONLY|O_NONBLOCK : O_WRONLY);
-  if (fd < 0)
-    {
-      /* Two separate strings for ease of translation. */
-      if (open_for_read_in_child)
-       sys_error (_("cannot open named pipe %s for reading"), pathname);
-      else
-       sys_error (_("cannot open named pipe %s for writing"), pathname);
-
-      exit (127);
-    }
-  if (open_for_read_in_child)
-    {
-      if (sh_unset_nodelay_mode (fd) < 0)
-       {
-         sys_error (_("cannot reset nodelay mode for fd %d"), fd);
-         exit (127);
-       }
-    }
-#else /* HAVE_DEV_FD */
-  fd = child_pipe_fd;
-#endif /* HAVE_DEV_FD */
-
-  if (dup2 (fd, open_for_read_in_child ? 0 : 1) < 0)
-    {
-      sys_error (_("cannot duplicate named pipe %s as fd %d"), pathname,
-       open_for_read_in_child ? 0 : 1);
-      exit (127);
-    }
-
-  if (fd != (open_for_read_in_child ? 0 : 1))
-    close (fd);
-
-  /* Need to close any files that this process has open to pipes inherited
-     from its parent. */
-  if (current_fds_to_close)
-    {
-      close_fd_bitmap (current_fds_to_close);
-      current_fds_to_close = (struct fd_bitmap *)NULL;
-    }
-
-#if defined (HAVE_DEV_FD)
-  /* Make sure we close the parent's end of the pipe and clear the slot
-     in the fd list so it is not closed later, if reallocated by, for
-     instance, pipe(2). */
-  close (parent_pipe_fd);
-  dev_fd_list[parent_pipe_fd] = 0;
-#endif /* HAVE_DEV_FD */
-
-  result = parse_and_execute (string, "process substitution", (SEVAL_NONINT|SEVAL_NOHIST));
-
-#if !defined (HAVE_DEV_FD)
-  /* Make sure we close the named pipe in the child before we exit. */
-  close (open_for_read_in_child ? 0 : 1);
-#endif /* !HAVE_DEV_FD */
-
-  exit (result);
-  /*NOTREACHED*/
-}
-#endif /* PROCESS_SUBSTITUTION */
-
-/***********************************/
-/*                                */
-/*     Command Substitution       */
-/*                                */
-/***********************************/
-
-static char *
-read_comsub (fd, quoted, rflag)
-     int fd, quoted;
-     int *rflag;
-{
-  char *istring, buf[128], *bufp, *s;
-  int istring_index, istring_size, c, tflag, skip_ctlesc, skip_ctlnul;
-  ssize_t bufn;
-
-  istring = (char *)NULL;
-  istring_index = istring_size = bufn = tflag = 0;
-
-  for (skip_ctlesc = skip_ctlnul = 0, s = ifs_value; s && *s; s++)
-    skip_ctlesc |= *s == CTLESC, skip_ctlnul |= *s == CTLNUL;
-
-#ifdef __CYGWIN__
-  setmode (fd, O_TEXT);                /* we don't want CR/LF, we want Unix-style */
-#endif
-
-  /* Read the output of the command through the pipe.  This may need to be
-     changed to understand multibyte characters in the future. */
-  while (1)
-    {
-      if (fd < 0)
-       break;
-      if (--bufn <= 0)
-       {
-         bufn = zread (fd, buf, sizeof (buf));
-         if (bufn <= 0) 
-           break;
-         bufp = buf;
-       }
-      c = *bufp++;
-
-      if (c == 0)
-       {
-#if 0
-         internal_warning ("read_comsub: ignored null byte in input");
-#endif
-         continue;
-       }
-
-      /* Add the character to ISTRING, possibly after resizing it. */
-      RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE);
-
-      /* This is essentially quote_string inline */
-      if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) /* || c == CTLESC || c == CTLNUL */)
-       istring[istring_index++] = CTLESC;
-      /* Escape CTLESC and CTLNUL in the output to protect those characters
-        from the rest of the word expansions (word splitting and globbing.)
-        This is essentially quote_escapes inline. */
-      else if (skip_ctlesc == 0 && c == CTLESC)
-       {
-         tflag |= W_HASCTLESC;
-         istring[istring_index++] = CTLESC;
-       }
-      else if ((skip_ctlnul == 0 && c == CTLNUL) || (c == ' ' && (ifs_value && *ifs_value == 0)))
-       istring[istring_index++] = CTLESC;
-
-      istring[istring_index++] = c;
-
-#if 0
-#if defined (__CYGWIN__)
-      if (c == '\n' && istring_index > 1 && istring[istring_index - 2] == '\r')
-       {
-         istring_index--;
-         istring[istring_index - 1] = '\n';
-       }
-#endif
-#endif
-    }
-
-  if (istring)
-    istring[istring_index] = '\0';
-
-  /* If we read no output, just return now and save ourselves some
-     trouble. */
-  if (istring_index == 0)
-    {
-      FREE (istring);
-      if (rflag)
-       *rflag = tflag;
-      return (char *)NULL;
-    }
-
-  /* Strip trailing newlines from the output of the command. */
-  if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-    {
-      while (istring_index > 0)
-       {
-         if (istring[istring_index - 1] == '\n')
-           {
-             --istring_index;
-
-             /* If the newline was quoted, remove the quoting char. */
-             if (istring[istring_index - 1] == CTLESC)
-               --istring_index;
-           }
-         else
-           break;
-       }
-      istring[istring_index] = '\0';
-    }
-  else
-    strip_trailing (istring, istring_index - 1, 1);
-
-  if (rflag)
-    *rflag = tflag;
-  return istring;
-}
-
-/* Perform command substitution on STRING.  This returns a WORD_DESC * with the
-   contained string possibly quoted. */
-WORD_DESC *
-command_substitute (string, quoted)
-     char *string;
-     int quoted;
-{
-  pid_t pid, old_pid, old_pipeline_pgrp, old_async_pid;
-  char *istring;
-  int result, fildes[2], function_value, pflags, rc, tflag;
-  WORD_DESC *ret;
-
-  istring = (char *)NULL;
-
-  /* Don't fork () if there is no need to.  In the case of no command to
-     run, just return NULL. */
-  if (!string || !*string || (string[0] == '\n' && !string[1]))
-    return ((WORD_DESC *)NULL);
-
-  if (wordexp_only && read_but_dont_execute)
-    {
-      last_command_exit_value = EX_WEXPCOMSUB;
-      jump_to_top_level (EXITPROG);
-    }
-
-  /* We're making the assumption here that the command substitution will
-     eventually run a command from the file system.  Since we'll run
-     maybe_make_export_env in this subshell before executing that command,
-     the parent shell and any other shells it starts will have to remake
-     the environment.  If we make it before we fork, other shells won't
-     have to.  Don't bother if we have any temporary variable assignments,
-     though, because the export environment will be remade after this
-     command completes anyway, but do it if all the words to be expanded
-     are variable assignments. */
-  if (subst_assign_varlist == 0 || garglist == 0)
-    maybe_make_export_env ();  /* XXX */
-
-  /* Flags to pass to parse_and_execute() */
-  pflags = (interactive && sourcelevel == 0) ? SEVAL_RESETLINE : 0;
-
-  /* Pipe the output of executing STRING into the current shell. */
-  if (pipe (fildes) < 0)
-    {
-      sys_error (_("cannot make pipe for command substitution"));
-      goto error_exit;
-    }
-
-  old_pid = last_made_pid;
-#if defined (JOB_CONTROL)
-  old_pipeline_pgrp = pipeline_pgrp;
-  /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
-  if ((subshell_environment & SUBSHELL_PIPE) == 0)
-    pipeline_pgrp = shell_pgrp;
-  cleanup_the_pipeline ();
-#endif /* JOB_CONTROL */
-
-  old_async_pid = last_asynchronous_pid;
-  pid = make_child ((char *)NULL, subshell_environment&SUBSHELL_ASYNC);
-  last_asynchronous_pid = old_async_pid;
-
-  if (pid == 0)
-    /* Reset the signal handlers in the child, but don't free the
-       trap strings. */
-    reset_signal_handlers ();
-
-#if defined (JOB_CONTROL)
-  /* XXX DO THIS ONLY IN PARENT ? XXX */
-  set_sigchld_handler ();
-  stop_making_children ();
-  if (pid != 0)
-    pipeline_pgrp = old_pipeline_pgrp;
-#else
-  stop_making_children ();
-#endif /* JOB_CONTROL */
-
-  if (pid < 0)
-    {
-      sys_error (_("cannot make child for command substitution"));
-    error_exit:
-
-      FREE (istring);
-      close (fildes[0]);
-      close (fildes[1]);
-      return ((WORD_DESC *)NULL);
-    }
-
-  if (pid == 0)
-    {
-      set_sigint_handler ();   /* XXX */
-
-      free_pushed_string_input ();
-
-      if (dup2 (fildes[1], 1) < 0)
-       {
-         sys_error (_("command_substitute: cannot duplicate pipe as fd 1"));
-         exit (EXECUTION_FAILURE);
-       }
-
-      /* If standard output is closed in the parent shell
-        (such as after `exec >&-'), file descriptor 1 will be
-        the lowest available file descriptor, and end up in
-        fildes[0].  This can happen for stdin and stderr as well,
-        but stdout is more important -- it will cause no output
-        to be generated from this command. */
-      if ((fildes[1] != fileno (stdin)) &&
-         (fildes[1] != fileno (stdout)) &&
-         (fildes[1] != fileno (stderr)))
-       close (fildes[1]);
-
-      if ((fildes[0] != fileno (stdin)) &&
-         (fildes[0] != fileno (stdout)) &&
-         (fildes[0] != fileno (stderr)))
-       close (fildes[0]);
-
-      /* The currently executing shell is not interactive. */
-      interactive = 0;
-
-      /* This is a subshell environment. */
-      subshell_environment |= SUBSHELL_COMSUB;
-
-      /* When not in POSIX mode, command substitution does not inherit
-        the -e flag. */
-      if (posixly_correct == 0)
-       exit_immediately_on_error = 0;
-
-      remove_quoted_escapes (string);
-
-      startup_state = 2;       /* see if we can avoid a fork */
-      /* Give command substitution a place to jump back to on failure,
-        so we don't go back up to main (). */
-      result = setjmp (top_level);
-
-      /* If we're running a command substitution inside a shell function,
-        trap `return' so we don't return from the function in the subshell
-        and go off to never-never land. */
-      if (result == 0 && return_catch_flag)
-       function_value = setjmp (return_catch);
-      else
-       function_value = 0;
-
-      if (result == ERREXIT)
-       rc = last_command_exit_value;
-      else if (result == EXITPROG)
-       rc = last_command_exit_value;
-      else if (result)
-       rc = EXECUTION_FAILURE;
-      else if (function_value)
-       rc = return_catch_value;
-      else
-       {
-         subshell_level++;
-         rc = parse_and_execute (string, "command substitution", pflags|SEVAL_NOHIST);
-         subshell_level--;
-       }
-
-      last_command_exit_value = rc;
-      rc = run_exit_trap ();
-#if defined (PROCESS_SUBSTITUTION)
-      unlink_fifo_list ();
-#endif
-      exit (rc);
-    }
-  else
-    {
-#if defined (JOB_CONTROL) && defined (PGRP_PIPE)
-      close_pgrp_pipe ();
-#endif /* JOB_CONTROL && PGRP_PIPE */
-
-      close (fildes[1]);
-
-      tflag = 0;
-      istring = read_comsub (fildes[0], quoted, &tflag);
-
-      close (fildes[0]);
-
-      current_command_subst_pid = pid;
-      last_command_exit_value = wait_for (pid);
-      last_command_subst_pid = pid;
-      last_made_pid = old_pid;
-
-#if defined (JOB_CONTROL)
-      /* If last_command_exit_value > 128, then the substituted command
-        was terminated by a signal.  If that signal was SIGINT, then send
-        SIGINT to ourselves.  This will break out of loops, for instance. */
-      if (last_command_exit_value == (128 + SIGINT) && last_command_exit_signal == SIGINT)
-       kill (getpid (), SIGINT);
-
-      /* wait_for gives the terminal back to shell_pgrp.  If some other
-        process group should have it, give it away to that group here.
-        pipeline_pgrp is non-zero only while we are constructing a
-        pipline, so what we are concerned about is whether or not that
-        pipeline was started in the background.  A pipeline started in
-        the background should never get the tty back here. */
-#if 0
-      if (interactive && pipeline_pgrp != (pid_t)0 && pipeline_pgrp != last_asynchronous_pid)
-#else
-      if (interactive && pipeline_pgrp != (pid_t)0 && (subshell_environment & SUBSHELL_ASYNC) == 0)
-#endif
-       give_terminal_to (pipeline_pgrp, 0);
-#endif /* JOB_CONTROL */
-
-      ret = alloc_word_desc ();
-      ret->word = istring;
-      ret->flags = tflag;
-
-      return ret;
-    }
-}
-
-/********************************************************
- *                                                     *
- *     Utility functions for parameter expansion       *
- *                                                     *
- ********************************************************/
-
-#if defined (ARRAY_VARS)
-
-static arrayind_t
-array_length_reference (s)
-     char *s;
-{
-  int len;
-  arrayind_t ind;
-  char *akey;
-  char *t, c;
-  ARRAY *array;
-  SHELL_VAR *var;
-
-  var = array_variable_part (s, &t, &len);
-
-  /* If unbound variables should generate an error, report one and return
-     failure. */
-  if ((var == 0 || (assoc_p (var) == 0 && array_p (var) == 0)) && unbound_vars_is_error)
-    {
-      c = *--t;
-      *t = '\0';
-      last_command_exit_value = EXECUTION_FAILURE;
-      err_unboundvar (s);
-      *t = c;
-      return (-1);
-    }
-  else if (var == 0)
-    return 0;
-
-  /* We support a couple of expansions for variables that are not arrays.
-     We'll return the length of the value for v[0], and 1 for v[@] or
-     v[*].  Return 0 for everything else. */
-
-  array = array_p (var) ? array_cell (var) : (ARRAY *)NULL;
-
-  if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']')
-    {
-      if (assoc_p (var))
-       return (assoc_num_elements (assoc_cell (var)));
-      else if (array_p (var))
-       return (array_num_elements (array));
-      else
-       return 1;
-    }
-
-  if (assoc_p (var))
-    {
-      t[len - 1] = '\0';
-      akey = expand_assignment_string_to_string (t, 0);        /* [ */
-      t[len - 1] = ']';
-      if (akey == 0 || *akey == 0)
-       {
-         err_badarraysub (t);
-         return (-1);
-       }
-      t = assoc_reference (assoc_cell (var), akey);
-    }
-  else
-    {
-      ind = array_expand_index (t, len);
-      if (ind < 0)
-       {
-         err_badarraysub (t);
-         return (-1);
-       }
-      if (array_p (var))
-       t = array_reference (array, ind);
-      else
-       t = (ind == 0) ? value_cell (var) : (char *)NULL;
-    }
-
-  len = MB_STRLEN (t);
-  return (len);
-}
-#endif /* ARRAY_VARS */
-
-static int
-valid_brace_expansion_word (name, var_is_special)
-     char *name;
-     int var_is_special;
-{
-  if (DIGIT (*name) && all_digits (name))
-    return 1;
-  else if (var_is_special)
-    return 1;
-#if defined (ARRAY_VARS)
-  else if (valid_array_reference (name))
-    return 1;
-#endif /* ARRAY_VARS */
-  else if (legal_identifier (name))
-    return 1;
-  else
-    return 0;
-}
-
-static int
-chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at)
-     char *name;
-     int quoted;
-     int *quoted_dollar_atp, *contains_dollar_at;
-{
-  char *temp1;
-
-  if (name == 0)
-    {
-      if (quoted_dollar_atp)
-       *quoted_dollar_atp = 0;
-      if (contains_dollar_at)
-       *contains_dollar_at = 0;
-      return 0;
-    }
-
-  /* check for $@ and $* */
-  if (name[0] == '@' && name[1] == 0)
-    {
-      if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-       *quoted_dollar_atp = 1;
-      if (contains_dollar_at)
-       *contains_dollar_at = 1;
-      return 1;
-    }
-  else if (name[0] == '*' && name[1] == '\0' && quoted == 0)
-    {
-      if (contains_dollar_at)
-       *contains_dollar_at = 1;
-      return 1;
-    }
-
-  /* Now check for ${array[@]} and ${array[*]} */
-#if defined (ARRAY_VARS)
-  else if (valid_array_reference (name))
-    {
-      temp1 = mbschr (name, '[');
-      if (temp1 && temp1[1] == '@' && temp1[2] == ']')
-       {
-         if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-           *quoted_dollar_atp = 1;
-         if (contains_dollar_at)
-           *contains_dollar_at = 1;
-         return 1;
-       }       /* [ */
-      /* ${array[*]}, when unquoted, should be treated like ${array[@]},
-        which should result in separate words even when IFS is unset. */
-      if (temp1 && temp1[1] == '*' && temp1[2] == ']' && quoted == 0)
-       {
-         if (contains_dollar_at)
-           *contains_dollar_at = 1;
-         return 1;
-       }
-    }
-#endif
-  return 0;
-}
-
-/* Parameter expand NAME, and return a new string which is the expansion,
-   or NULL if there was no expansion.
-   VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
-   the shell, e.g., "@", "$", "*", etc.  QUOTED, if non-zero, means that
-   NAME was found inside of a double-quoted expression. */
-static WORD_DESC *
-parameter_brace_expand_word (name, var_is_special, quoted, pflags)
-     char *name;
-     int var_is_special, quoted, pflags;
-{
-  WORD_DESC *ret;
-  char *temp, *tt;
-  intmax_t arg_index;
-  SHELL_VAR *var;
-  int atype, rflags;
-
-  ret = 0;
-  temp = 0;
-  rflags = 0;
-
-  /* Handle multiple digit arguments, as in ${11}. */  
-  if (legal_number (name, &arg_index))
-    {
-      tt = get_dollar_var_value (arg_index);
-      if (tt)
-       temp = (*tt && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-                 ? quote_string (tt)
-                 : quote_escapes (tt);
-      else
-        temp = (char *)NULL;
-      FREE (tt);
-    }
-  else if (var_is_special)      /* ${@} */
-    {
-      int sindex;
-      tt = (char *)xmalloc (2 + strlen (name));
-      tt[sindex = 0] = '$';
-      strcpy (tt + 1, name);
-
-      ret = param_expand (tt, &sindex, quoted, (int *)NULL, (int *)NULL,
-                         (int *)NULL, (int *)NULL, pflags);
-      free (tt);
-    }
-#if defined (ARRAY_VARS)
-  else if (valid_array_reference (name))
-    {
-      temp = array_value (name, quoted, &atype);
-      if (atype == 0 && temp)
-       temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-                 ? quote_string (temp)
-                 : quote_escapes (temp);
-      else if (atype == 1 && temp && QUOTED_NULL (temp) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-       rflags |= W_HASQUOTEDNULL;
-    }
-#endif
-  else if (var = find_variable (name))
-    {
-      if (var_isset (var) && invisible_p (var) == 0)
-       {
-#if defined (ARRAY_VARS)
-         if (assoc_p (var))
-           temp = assoc_reference (assoc_cell (var), "0");
-         else if (array_p (var))
-           temp = array_reference (array_cell (var), 0);
-         else
-           temp = value_cell (var);
-#else
-         temp = value_cell (var);
-#endif
-
-         if (temp)
-           temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-                     ? quote_string (temp)
-                     : quote_escapes (temp);
-       }
-      else
-       temp = (char *)NULL;
-    }
-  else
-    temp = (char *)NULL;
-
-  if (ret == 0)
-    {
-      ret = alloc_word_desc ();
-      ret->word = temp;
-      ret->flags |= rflags;
-    }
-  return ret;
-}
-
-/* Expand an indirect reference to a variable: ${!NAME} expands to the
-   value of the variable whose name is the value of NAME. */
-static WORD_DESC *
-parameter_brace_expand_indir (name, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at)
-     char *name;
-     int var_is_special, quoted;
-     int *quoted_dollar_atp, *contains_dollar_at;
-{
-  char *temp, *t;
-  WORD_DESC *w;
-
-  w = parameter_brace_expand_word (name, var_is_special, quoted, PF_IGNUNBOUND);
-  t = w->word;
-  /* Have to dequote here if necessary */
-  if (t)
-    {
-      temp = (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
-               ? dequote_string (t)
-               : dequote_escapes (t);
-      free (t);
-      t = temp;
-    }
-  dispose_word_desc (w);
-
-  chk_atstar (t, quoted, quoted_dollar_atp, contains_dollar_at);
-  if (t == 0)
-    return (WORD_DESC *)NULL;
-
-  w = parameter_brace_expand_word (t, SPECIAL_VAR(t, 0), quoted, 0);
-  free (t);
-
-  return w;
-}
-
-/* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
-   depending on the value of C, the separating character.  C can be one of
-   "-", "+", or "=".  QUOTED is true if the entire brace expression occurs
-   between double quotes. */
-static WORD_DESC *
-parameter_brace_expand_rhs (name, value, c, quoted, qdollaratp, hasdollarat)
-     char *name, *value;
-     int c, quoted, *qdollaratp, *hasdollarat;
-{
-  WORD_DESC *w;
-  WORD_LIST *l;
-  char *t, *t1, *temp;
-  int hasdol;
-
-  /* If the entire expression is between double quotes, we want to treat
-     the value as a double-quoted string, with the exception that we strip
-     embedded unescaped double quotes (for sh backwards compatibility). */
-  if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *value)
-    {
-      hasdol = 0;
-      temp = string_extract_double_quoted (value, &hasdol, 1);
-    }
-  else
-    temp = value;
-
-  w = alloc_word_desc ();
-  hasdol = 0;
-  /* XXX was 0 not quoted */
-  l = *temp ? expand_string_for_rhs (temp, quoted, &hasdol, (int *)NULL)
-           : (WORD_LIST *)0;
-  if (hasdollarat)
-    *hasdollarat = hasdol || (l && l->next);
-  if (temp != value)
-    free (temp);
-  if (l)
-    {
-      /* The expansion of TEMP returned something.  We need to treat things
-         slightly differently if HASDOL is non-zero.  If we have "$@", the
-         individual words have already been quoted.  We need to turn them
-         into a string with the words separated by the first character of
-         $IFS without any additional quoting, so string_list_dollar_at won't
-         do the right thing.  We use string_list_dollar_star instead. */
-      temp = (hasdol || l->next) ? string_list_dollar_star (l) : string_list (l);
-
-      /* If l->next is not null, we know that TEMP contained "$@", since that
-        is the only expansion that creates more than one word. */
-      if (qdollaratp && ((hasdol && quoted) || l->next))
-       *qdollaratp = 1;
-      dispose_words (l);
-    }
-  else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && hasdol)
-    {
-      /* The brace expansion occurred between double quotes and there was
-        a $@ in TEMP.  It does not matter if the $@ is quoted, as long as
-        it does not expand to anything.  In this case, we want to return
-        a quoted empty string. */
-      temp = make_quoted_char ('\0');
-      w->flags |= W_HASQUOTEDNULL;
-    }
-  else
-    temp = (char *)NULL;
-
-  if (c == '-' || c == '+')
-    {
-      w->word = temp;
-      return w;
-    }
-
-  /* c == '=' */
-  t = temp ? savestring (temp) : savestring ("");
-  t1 = dequote_string (t);
-  free (t);
-#if defined (ARRAY_VARS)
-  if (valid_array_reference (name))
-    assign_array_element (name, t1, 0);
-  else
-#endif /* ARRAY_VARS */
-  bind_variable (name, t1, 0);
-  free (t1);
-
-  w->word = temp;
-  return w;
-}
-
-/* Deal with the right hand side of a ${name:?value} expansion in the case
-   that NAME is null or not set.  If VALUE is non-null it is expanded and
-   used as the error message to print, otherwise a standard message is
-   printed. */
-static void
-parameter_brace_expand_error (name, value)
-     char *name, *value;
-{
-  WORD_LIST *l;
-  char *temp;
-
-  if (value && *value)
-    {
-      l = expand_string (value, 0);
-      temp =  string_list (l);
-      report_error ("%s: %s", name, temp ? temp : ""); /* XXX was value not "" */
-      FREE (temp);
-      dispose_words (l);
-    }
-  else
-    report_error (_("%s: parameter null or not set"), name);
-
-  /* Free the data we have allocated during this expansion, since we
-     are about to longjmp out. */
-  free (name);
-  FREE (value);
-}
-
-/* Return 1 if NAME is something for which parameter_brace_expand_length is
-   OK to do. */
-static int
-valid_length_expression (name)
-     char *name;
-{
-  return (name[1] == '\0' ||                                   /* ${#} */
-         ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0') ||  /* special param */
-         (DIGIT (name[1]) && all_digits (name + 1)) || /* ${#11} */
-#if defined (ARRAY_VARS)
-         valid_array_reference (name + 1) ||                   /* ${#a[7]} */
-#endif
-         legal_identifier (name + 1));                         /* ${#PS1} */
-}
-
-#if defined (HANDLE_MULTIBYTE)
-size_t
-mbstrlen (s)
-     const char *s;
-{
-  size_t clen, nc;
-  mbstate_t mbs, mbsbak;
-
-  nc = 0;
-  memset (&mbs, 0, sizeof (mbs));
-  mbsbak = mbs;
-  while ((clen = mbrlen(s, MB_CUR_MAX, &mbs)) != 0)
-    {
-      if (MB_INVALIDCH(clen))
-        {
-         clen = 1;     /* assume single byte */
-         mbs = mbsbak;
-        }
-
-      s += clen;
-      nc++;
-      mbsbak = mbs;
-    }
-  return nc;
-}
-#endif
-      
-
-/* Handle the parameter brace expansion that requires us to return the
-   length of a parameter. */
-static intmax_t
-parameter_brace_expand_length (name)
-     char *name;
-{
-  char *t, *newname;
-  intmax_t number, arg_index;
-  WORD_LIST *list;
-#if defined (ARRAY_VARS)
-  SHELL_VAR *var;
-#endif
-
-  if (name[1] == '\0')                 /* ${#} */
-    number = number_of_args ();
-  else if ((name[1] == '@' || name[1] == '*') && name[2] == '\0')      /* ${#@}, ${#*} */
-    number = number_of_args ();
-  else if ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0')
-    {
-      /* Take the lengths of some of the shell's special parameters. */
-      switch (name[1])
-       {
-       case '-':
-         t = which_set_flags ();
-         break;
-       case '?':
-         t = itos (last_command_exit_value);
-         break;
-       case '$':
-         t = itos (dollar_dollar_pid);
-         break;
-       case '!':
-         if (last_asynchronous_pid == NO_PID)
-           t = (char *)NULL;
-         else
-           t = itos (last_asynchronous_pid);
-         break;
-       case '#':
-         t = itos (number_of_args ());
-         break;
-       }
-      number = STRLEN (t);
-      FREE (t);
-    }
-#if defined (ARRAY_VARS)
-  else if (valid_array_reference (name + 1))
-    number = array_length_reference (name + 1);
-#endif /* ARRAY_VARS */
-  else
-    {
-      number = 0;
-
-      if (legal_number (name + 1, &arg_index))         /* ${#1} */
-       {
-         t = get_dollar_var_value (arg_index);
-         number = MB_STRLEN (t);
-         FREE (t);
-       }
-#if defined (ARRAY_VARS)
-      else if ((var = find_variable (name + 1)) && (invisible_p (var) == 0) && (array_p (var) || assoc_p (var)))
-       {
-         if (assoc_p (var))
-           t = assoc_reference (assoc_cell (var), "0");
-         else
-           t = array_reference (array_cell (var), 0);
-         number = MB_STRLEN (t);
-       }
-#endif
-      else                             /* ${#PS1} */
-       {
-         newname = savestring (name);
-         newname[0] = '$';
-         list = expand_string (newname, Q_DOUBLE_QUOTES);
-         t = list ? string_list (list) : (char *)NULL;
-         free (newname);
-         if (list)
-           dispose_words (list);
-
-         number = MB_STRLEN (t);
-         FREE (t);
-       }
-    }
-
-  return (number);
-}
-
-/* Skip characters in SUBSTR until DELIM.  SUBSTR is an arithmetic expression,
-   so we do some ad-hoc parsing of an arithmetic expression to find
-   the first DELIM, instead of using strchr(3).  Two rules:
-       1.  If the substring contains a `(', read until closing `)'.
-       2.  If the substring contains a `?', read past one `:' for each `?'.
-*/
-
-static char *
-skiparith (substr, delim)
-     char *substr;
-     int delim;
-{
-  size_t sublen;
-  int skipcol, pcount, i;
-  DECLARE_MBSTATE;
-
-  sublen = strlen (substr);
-  i = skipcol = pcount = 0;
-  while (substr[i])
-    {
-      /* Balance parens */
-      if (substr[i] == LPAREN)
-       {
-         pcount++;
-         i++;
-         continue;
-       }
-      if (substr[i] == RPAREN && pcount)
-       {
-         pcount--;
-         i++;
-         continue;
-       }
-      if (pcount)
-       {
-         ADVANCE_CHAR (substr, sublen, i);
-         continue;
-       }
-
-      /* Skip one `:' for each `?' */
-      if (substr[i] == ':' && skipcol)
-       {
-         skipcol--;
-         i++;
-         continue;
-       }
-      if (substr[i] == delim)
-       break;
-      if (substr[i] == '?')
-       {
-         skipcol++;
-         i++;
-         continue;
-       }
-      ADVANCE_CHAR (substr, sublen, i);
-    }
-
-  return (substr + i);
-}
-
-/* Verify and limit the start and end of the desired substring.  If
-   VTYPE == 0, a regular shell variable is being used; if it is 1,
-   then the positional parameters are being used; if it is 2, then
-   VALUE is really a pointer to an array variable that should be used.
-   Return value is 1 if both values were OK, 0 if there was a problem
-   with an invalid expression, or -1 if the values were out of range. */
-static int
-verify_substring_values (v, value, substr, vtype, e1p, e2p)
-     SHELL_VAR *v;
-     char *value, *substr;
-     int vtype;
-     intmax_t *e1p, *e2p;
-{
-  char *t, *temp1, *temp2;
-  arrayind_t len;
-  int expok;
-#if defined (ARRAY_VARS)
- ARRAY *a;
- HASH_TABLE *h;
-#endif
-
-  /* duplicate behavior of strchr(3) */
-  t = skiparith (substr, ':');
-  if (*t && *t == ':')
-    *t = '\0';
-  else
-    t = (char *)0;
-
-  temp1 = expand_arith_string (substr, Q_DOUBLE_QUOTES);
-  *e1p = evalexp (temp1, &expok);
-  free (temp1);
-  if (expok == 0)
-    return (0);
-
-  len = -1;    /* paranoia */
-  switch (vtype)
-    {
-    case VT_VARIABLE:
-    case VT_ARRAYMEMBER:
-      len = MB_STRLEN (value);
-      break;
-    case VT_POSPARMS:
-      len = number_of_args () + 1;
-      if (*e1p == 0)
-       len++;          /* add one arg if counting from $0 */
-      break;
-#if defined (ARRAY_VARS)
-    case VT_ARRAYVAR:
-      /* For arrays, the first value deals with array indices.  Negative
-        offsets count from one past the array's maximum index.  Associative
-        arrays treat the number of elements as the maximum index. */
-      if (assoc_p (v))
-       {
-         h = assoc_cell (v);
-         len = assoc_num_elements (h) + (*e1p < 0);
-       }
-      else
-       {
-         a = (ARRAY *)value;
-         len = array_max_index (a) + (*e1p < 0);       /* arrays index from 0 to n - 1 */
-       }
-      break;
-#endif
-    }
-
-  if (len == -1)       /* paranoia */
-    return -1;
-
-  if (*e1p < 0)                /* negative offsets count from end */
-    *e1p += len;
-
-  if (*e1p > len || *e1p < 0)
-    return (-1);
-
-#if defined (ARRAY_VARS)
-  /* For arrays, the second offset deals with the number of elements. */
-  if (vtype == VT_ARRAYVAR)
-    len = assoc_p (v) ? assoc_num_elements (h) : array_num_elements (a);
-#endif
-
-  if (t)
-    {
-      t++;
-      temp2 = savestring (t);
-      temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES);
-      free (temp2);
-      t[-1] = ':';
-      *e2p = evalexp (temp1, &expok);
-      free (temp1);
-      if (expok == 0)
-       return (0);
-      if (*e2p < 0)
-       {
-         internal_error (_("%s: substring expression < 0"), t);
-         return (0);
-       }
-#if defined (ARRAY_VARS)
-      /* In order to deal with sparse arrays, push the intelligence about how
-        to deal with the number of elements desired down to the array-
-        specific functions.  */
-      if (vtype != VT_ARRAYVAR)
-#endif
-       {
-         *e2p += *e1p;         /* want E2 chars starting at E1 */
-         if (*e2p > len)
-           *e2p = len;
-       }
-    }
-  else
-    *e2p = len;
-
-  return (1);
-}
-
-/* Return the type of variable specified by VARNAME (simple variable,
-   positional param, or array variable).  Also return the value specified
-   by VARNAME (value of a variable or a reference to an array element).
-   If this returns VT_VARIABLE, the caller assumes that CTLESC and CTLNUL
-   characters in the value are quoted with CTLESC and takes appropriate
-   steps.  For convenience, *VALP is set to the dequoted VALUE. */
-static int
-get_var_and_type (varname, value, quoted, varp, valp)
-     char *varname, *value;
-     int quoted;
-     SHELL_VAR **varp;
-     char **valp;
-{
-  int vtype;
-  char *temp;
-#if defined (ARRAY_VARS)
-  SHELL_VAR *v;
-#endif
-
-  /* This sets vtype to VT_VARIABLE or VT_POSPARMS */
-  vtype = (varname[0] == '@' || varname[0] == '*') && varname[1] == '\0';
-  if (vtype == VT_POSPARMS && varname[0] == '*')
-    vtype |= VT_STARSUB;
-  *varp = (SHELL_VAR *)NULL;
-
-#if defined (ARRAY_VARS)
-  if (valid_array_reference (varname))
-    {
-      v = array_variable_part (varname, &temp, (int *)0);
-      if (v && (array_p (v) || assoc_p (v)))
-       { /* [ */
-         if (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']')
-           {
-             /* Callers have to differentiate betwen indexed and associative */
-             vtype = VT_ARRAYVAR;
-             if (temp[0] == '*')
-               vtype |= VT_STARSUB;
-             *valp = array_p (v) ? (char *)array_cell (v) : (char *)assoc_cell (v);
-           }
-         else
-           {
-             vtype = VT_ARRAYMEMBER;
-             *valp = array_value (varname, 1, (int *)NULL);
-           }
-         *varp = v;
-       }
-      else if (v && (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']'))
-       {
-         vtype = VT_VARIABLE;
-         *varp = v;
-         if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
-           *valp = dequote_string (value);
-         else
-           *valp = dequote_escapes (value);
-       }
-      else
-       {
-         vtype = VT_ARRAYMEMBER;
-         *varp = v;
-         *valp = array_value (varname, 1, (int *)NULL);
-       }
-    }
-  else if ((v = find_variable (varname)) && (invisible_p (v) == 0) && (assoc_p (v) || array_p (v)))
-    {
-      vtype = VT_ARRAYMEMBER;
-      *varp = v;
-      *valp = assoc_p (v) ? assoc_reference (assoc_cell (v), "0") : array_reference (array_cell (v), 0);
-    }
-  else
-#endif
-    {
-      if (value && vtype == VT_VARIABLE)
-       {
-         if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
-           *valp = dequote_string (value);
-         else
-           *valp = dequote_escapes (value);
-       }
-      else
-       *valp = value;
-    }
-
-  return vtype;
-}
-
-/******************************************************/
-/*                                                   */
-/* Functions to extract substrings of variable values */
-/*                                                   */
-/******************************************************/
-
-#if defined (HANDLE_MULTIBYTE)
-/* Character-oriented rather than strictly byte-oriented substrings.  S and
-   E, rather being strict indices into STRING, indicate character (possibly
-   multibyte character) positions that require calculation.
-   Used by the ${param:offset[:length]} expansion. */
-static char *
-mb_substring (string, s, e)
-     char *string;
-     int s, e;
-{
-  char *tt;
-  int start, stop, i, slen;
-  DECLARE_MBSTATE;
-
-  start = 0;
-  /* Don't need string length in ADVANCE_CHAR unless multibyte chars possible. */
-  slen = (MB_CUR_MAX > 1) ? STRLEN (string) : 0;
-
-  i = s;
-  while (string[start] && i--)
-    ADVANCE_CHAR (string, slen, start);
-  stop = start;
-  i = e - s;
-  while (string[stop] && i--)
-    ADVANCE_CHAR (string, slen, stop);
-  tt = substring (string, start, stop);
-  return tt;
-}
-#endif
-  
-/* Process a variable substring expansion: ${name:e1[:e2]}.  If VARNAME
-   is `@', use the positional parameters; otherwise, use the value of
-   VARNAME.  If VARNAME is an array variable, use the array elements. */
-
-static char *
-parameter_brace_substring (varname, value, substr, quoted)
-     char *varname, *value, *substr;
-     int quoted;
-{
-  intmax_t e1, e2;
-  int vtype, r, starsub;
-  char *temp, *val, *tt, *oname;
-  SHELL_VAR *v;
-
-  if (value == 0)
-    return ((char *)NULL);
-
-  oname = this_command_name;
-  this_command_name = varname;
-
-  vtype = get_var_and_type (varname, value, quoted, &v, &val);
-  if (vtype == -1)
-    {
-      this_command_name = oname;
-      return ((char *)NULL);
-    }
-
-  starsub = vtype & VT_STARSUB;
-  vtype &= ~VT_STARSUB;
-
-  r = verify_substring_values (v, val, substr, vtype, &e1, &e2);
-  this_command_name = oname;
-  if (r <= 0)
-    return ((r == 0) ? &expand_param_error : (char *)NULL);
-
-  switch (vtype)
-    {
-    case VT_VARIABLE:
-    case VT_ARRAYMEMBER:
-#if defined (HANDLE_MULTIBYTE)
-      if (MB_CUR_MAX > 1)
-       tt = mb_substring (val, e1, e2);
-      else
-#endif
-      tt = substring (val, e1, e2);
-
-      if (vtype == VT_VARIABLE)
-       FREE (val);
-      if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
-       temp = quote_string (tt);
-      else
-       temp = tt ? quote_escapes (tt) : (char *)NULL;
-      FREE (tt);
-      break;
-    case VT_POSPARMS:
-      tt = pos_params (varname, e1, e2, quoted);
-      if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
-       {
-         temp = tt ? quote_escapes (tt) : (char *)NULL;
-         FREE (tt);
-       }
-      else
-       temp = tt;
-      break;
-#if defined (ARRAY_VARS)
-    case VT_ARRAYVAR:
-      if (assoc_p (v))
-       /* we convert to list and take first e2 elements starting at e1th
-          element -- officially undefined for now */   
-       temp = assoc_subrange (assoc_cell (v), e1, e2, starsub, quoted);
-      else
-      /* We want E2 to be the number of elements desired (arrays can be sparse,
-        so verify_substring_values just returns the numbers specified and we
-        rely on array_subrange to understand how to deal with them). */
-       temp = array_subrange (array_cell (v), e1, e2, starsub, quoted);
-      /* array_subrange now calls array_quote_escapes as appropriate, so the
-        caller no longer needs to. */
-      break;
-#endif
-    default:
-      temp = (char *)NULL;
-    }
-
-  return temp;
-}
-
-/****************************************************************/
-/*                                                             */
-/* Functions to perform pattern substitution on variable values */
-/*                                                             */
-/****************************************************************/
-
-char *
-pat_subst (string, pat, rep, mflags)
-     char *string, *pat, *rep;
-     int mflags;
-{
-  char *ret, *s, *e, *str;
-  int rsize, rptr, l, replen, mtype;
-
-  mtype = mflags & MATCH_TYPEMASK;
-
-  /* Special cases:
-   *   1.  A null pattern with mtype == MATCH_BEG means to prefix STRING
-   *       with REP and return the result.
-   *   2.  A null pattern with mtype == MATCH_END means to append REP to
-   *       STRING and return the result.
-   */
-  if ((pat == 0 || *pat == 0) && (mtype == MATCH_BEG || mtype == MATCH_END))
-    {
-      replen = STRLEN (rep);
-      l = strlen (string);
-      ret = (char *)xmalloc (replen + l + 2);
-      if (replen == 0)
-       strcpy (ret, string);
-      else if (mtype == MATCH_BEG)
-       {
-         strcpy (ret, rep);
-         strcpy (ret + replen, string);
-       }
-      else
-       {
-         strcpy (ret, string);
-         strcpy (ret + l, rep);
-       }
-      return (ret);
-    }
-
-  ret = (char *)xmalloc (rsize = 64);
-  ret[0] = '\0';
-
-  for (replen = STRLEN (rep), rptr = 0, str = string;;)
-    {
-      if (match_pattern (str, pat, mtype, &s, &e) == 0)
-       break;
-      l = s - str;
-      RESIZE_MALLOCED_BUFFER (ret, rptr, (l + replen), rsize, 64);
-
-      /* OK, now copy the leading unmatched portion of the string (from
-        str to s) to ret starting at rptr (the current offset).  Then copy
-        the replacement string at ret + rptr + (s - str).  Increment
-        rptr (if necessary) and str and go on. */
-      if (l)
-       {
-         strncpy (ret + rptr, str, l);
-         rptr += l;
-       }
-      if (replen)
-       {
-         strncpy (ret + rptr, rep, replen);
-         rptr += replen;
-       }
-      str = e;         /* e == end of match */
-
-      if (((mflags & MATCH_GLOBREP) == 0) || mtype != MATCH_ANY)
-       break;
-
-      if (s == e)
-       {
-         /* On a zero-length match, make sure we copy one character, since
-            we increment one character to avoid infinite recursion. */
-         RESIZE_MALLOCED_BUFFER (ret, rptr, 1, rsize, 64);
-         ret[rptr++] = *str++;
-         e++;          /* avoid infinite recursion on zero-length match */
-       }
-    }
-
-  /* Now copy the unmatched portion of the input string */
-  if (*str)
-    {
-      RESIZE_MALLOCED_BUFFER (ret, rptr, STRLEN(str) + 1, rsize, 64);
-      strcpy (ret + rptr, str);
-    }
-  else
-    ret[rptr] = '\0';
-
-  return ret;
-}
-
-/* Do pattern match and replacement on the positional parameters. */
-static char *
-pos_params_pat_subst (string, pat, rep, mflags)
-     char *string, *pat, *rep;
-     int mflags;
-{
-  WORD_LIST *save, *params;
-  WORD_DESC *w;
-  char *ret;
-  int pchar, qflags;
-
-  save = params = list_rest_of_args ();
-  if (save == 0)
-    return ((char *)NULL);
-
-  for ( ; params; params = params->next)
-    {
-      ret = pat_subst (params->word->word, pat, rep, mflags);
-      w = alloc_word_desc ();
-      w->word = ret ? ret : savestring ("");
-      dispose_word (params->word);
-      params->word = w;
-    }
-
-  pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@';
-  qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0;
-
-#if 0
-  if ((mflags & (MATCH_QUOTED|MATCH_STARSUB)) == (MATCH_QUOTED|MATCH_STARSUB))
-    ret = string_list_dollar_star (quote_list (save));
-  else if ((mflags & MATCH_STARSUB) == MATCH_STARSUB)
-    ret = string_list_dollar_star (save);
-  else if ((mflags & MATCH_QUOTED) == MATCH_QUOTED)
-    ret = string_list_dollar_at (save, qflags);
-  else
-    ret = string_list_dollar_star (save);
-#else
-  ret = string_list_pos_params (pchar, save, qflags);
-#endif
-
-  dispose_words (save);
-
-  return (ret);
-}
-
-/* Perform pattern substitution on VALUE, which is the expansion of
-   VARNAME.  PATSUB is an expression supplying the pattern to match
-   and the string to substitute.  QUOTED is a flags word containing
-   the type of quoting currently in effect. */
-static char *
-parameter_brace_patsub (varname, value, patsub, quoted)
-     char *varname, *value, *patsub;
-     int quoted;
-{
-  int vtype, mflags, starsub, delim;
-  char *val, *temp, *pat, *rep, *p, *lpatsub, *tt;
-  SHELL_VAR *v;
-
-  if (value == 0)
-    return ((char *)NULL);
-
-  this_command_name = varname;
-
-  vtype = get_var_and_type (varname, value, quoted, &v, &val);
-  if (vtype == -1)
-    return ((char *)NULL);
-
-  starsub = vtype & VT_STARSUB;
-  vtype &= ~VT_STARSUB;
-
-  mflags = 0;
-  if (patsub && *patsub == '/')
-    {
-      mflags |= MATCH_GLOBREP;
-      patsub++;
-    }
-
-  /* Malloc this because expand_string_if_necessary or one of the expansion
-     functions in its call chain may free it on a substitution error. */
-  lpatsub = savestring (patsub);
-
-  if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-    mflags |= MATCH_QUOTED;
-
-  if (starsub)
-    mflags |= MATCH_STARSUB;
-
-  /* If the pattern starts with a `/', make sure we skip over it when looking
-     for the replacement delimiter. */
-#if 0
-  if (rep = quoted_strchr ((*patsub == '/') ? lpatsub+1 : lpatsub, '/', ST_BACKSL))
-    *rep++ = '\0';
-  else
-    rep = (char *)NULL;
-#else
-  delim = skip_to_delim (lpatsub, ((*patsub == '/') ? 1 : 0), "/", 0);
-  if (lpatsub[delim] == '/')
-    {
-      lpatsub[delim] = 0;
-      rep = lpatsub + delim + 1;
-    }
-  else
-    rep = (char *)NULL;
-#endif
-
-  if (rep && *rep == '\0')
-    rep = (char *)NULL;
-
-  /* Perform the same expansions on the pattern as performed by the
-     pattern removal expansions. */
-  pat = getpattern (lpatsub, quoted, 1);
-
-  if (rep)
-    {
-      if ((mflags & MATCH_QUOTED) == 0)
-       rep = expand_string_if_necessary (rep, quoted, expand_string_unsplit);
-      else
-       rep = expand_string_to_string_internal (rep, quoted, expand_string_unsplit);
-    }
-
-  /* ksh93 doesn't allow the match specifier to be a part of the expanded
-     pattern.  This is an extension.  Make sure we don't anchor the pattern
-     at the beginning or end of the string if we're doing global replacement,
-     though. */
-  p = pat;
-  if (mflags & MATCH_GLOBREP)
-    mflags |= MATCH_ANY;
-  else if (pat && pat[0] == '#')
-    {
-      mflags |= MATCH_BEG;
-      p++;
-    }
-  else if (pat && pat[0] == '%')
-    {
-      mflags |= MATCH_END;
-      p++;
-    }
-  else
-    mflags |= MATCH_ANY;
-
-  /* OK, we now want to substitute REP for PAT in VAL.  If
-     flags & MATCH_GLOBREP is non-zero, the substitution is done
-     everywhere, otherwise only the first occurrence of PAT is
-     replaced.  The pattern matching code doesn't understand
-     CTLESC quoting CTLESC and CTLNUL so we use the dequoted variable
-     values passed in (VT_VARIABLE) so the pattern substitution
-     code works right.  We need to requote special chars after
-     we're done for VT_VARIABLE and VT_ARRAYMEMBER, and for the
-     other cases if QUOTED == 0, since the posparams and arrays
-     indexed by * or @ do special things when QUOTED != 0. */
-
-  switch (vtype)
-    {
-    case VT_VARIABLE:
-    case VT_ARRAYMEMBER:
-      temp = pat_subst (val, p, rep, mflags);
-      if (vtype == VT_VARIABLE)
-       FREE (val);
-      if (temp)
-       {
-         tt = (mflags & MATCH_QUOTED) ? quote_string (temp) : quote_escapes (temp);
-         free (temp);
-         temp = tt;
-       }
-      break;
-    case VT_POSPARMS:
-      temp = pos_params_pat_subst (val, p, rep, mflags);
-      if (temp && (mflags & MATCH_QUOTED) == 0)
-       {
-         tt = quote_escapes (temp);
-         free (temp);
-         temp = tt;
-       }
-      break;
-#if defined (ARRAY_VARS)
-    case VT_ARRAYVAR:
-      temp = assoc_p (v) ? assoc_patsub (assoc_cell (v), p, rep, mflags)
-                        : array_patsub (array_cell (v), p, rep, mflags);
-      /* Don't call quote_escapes anymore; array_patsub calls
-        array_quote_escapes as appropriate before adding the
-        space separators; ditto for assoc_patsub. */
-      break;
-#endif
-    }
-
-  FREE (pat);
-  FREE (rep);
-  free (lpatsub);
-
-  return temp;
-}
-
-/****************************************************************/
-/*                                                             */
-/*   Functions to perform case modification on variable values  */
-/*                                                             */
-/****************************************************************/
-
-/* Do case modification on the positional parameters. */
-
-static char *
-pos_params_modcase (string, pat, modop, mflags)
-     char *string, *pat;
-     int modop;
-     int mflags;
-{
-  WORD_LIST *save, *params;
-  WORD_DESC *w;
-  char *ret;
-  int pchar, qflags;
-
-  save = params = list_rest_of_args ();
-  if (save == 0)
-    return ((char *)NULL);
-
-  for ( ; params; params = params->next)
-    {
-      ret = sh_modcase (params->word->word, pat, modop);
-      w = alloc_word_desc ();
-      w->word = ret ? ret : savestring ("");
-      dispose_word (params->word);
-      params->word = w;
-    }
-
-  pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@';
-  qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0;
-
-  ret = string_list_pos_params (pchar, save, qflags);
-  dispose_words (save);
-
-  return (ret);
-}
-
-/* Perform case modification on VALUE, which is the expansion of
-   VARNAME.  MODSPEC is an expression supplying the type of modification
-   to perform.  QUOTED is a flags word containing the type of quoting
-   currently in effect. */
-static char *
-parameter_brace_casemod (varname, value, modspec, patspec, quoted)
-     char *varname, *value;
-     int modspec;
-     char *patspec;
-     int quoted;
-{
-  int vtype, starsub, modop, mflags, x;
-  char *val, *temp, *pat, *p, *lpat, *tt;
-  SHELL_VAR *v;
-
-  if (value == 0)
-    return ((char *)NULL);
-
-  this_command_name = varname;
-
-  vtype = get_var_and_type (varname, value, quoted, &v, &val);
-  if (vtype == -1)
-    return ((char *)NULL);
-
-  starsub = vtype & VT_STARSUB;
-  vtype &= ~VT_STARSUB;
-
-  modop = 0;
-  mflags = 0;
-  if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-    mflags |= MATCH_QUOTED;
-  if (starsub)
-    mflags |= MATCH_STARSUB;
-  
-  p = patspec;
-  if (modspec == '^')
-    {
-      x = p && p[0] == modspec;
-      modop = x ? CASE_UPPER : CASE_UPFIRST;
-      p += x;
-    }
-  else if (modspec == ',')
-    {
-      x = p && p[0] == modspec;
-      modop = x ? CASE_LOWER : CASE_LOWFIRST;
-      p += x;
-    }
-  else if (modspec == '~')
-    {
-      x = p && p[0] == modspec;
-      modop = x ? CASE_TOGGLEALL : CASE_TOGGLE;
-      p += x;
-    }
-    
-  lpat = p ? savestring (p) : 0;
-  /* Perform the same expansions on the pattern as performed by the
-     pattern removal expansions.  FOR LATER */
-  pat = lpat ? getpattern (lpat, quoted, 1) : 0;
-
-  /* OK, now we do the case modification. */
-  switch (vtype)
-    {
-    case VT_VARIABLE:
-    case VT_ARRAYMEMBER:
-      temp = sh_modcase (val, pat, modop);
-      if (vtype == VT_VARIABLE)
-       FREE (val);
-      if (temp)
-       {
-         tt = (mflags & MATCH_QUOTED) ? quote_string (temp) : quote_escapes (temp);
-         free (temp);
-         temp = tt;
-       }
-      break;
-
-    case VT_POSPARMS:
-      temp = pos_params_modcase (val, pat, modop, mflags);
-      if (temp && (mflags & MATCH_QUOTED)  == 0)
-       {
-         tt = quote_escapes (temp);
-         free (temp);
-         temp = tt;
-       }
-      break;
-
-#if defined (ARRAY_VARS)
-    case VT_ARRAYVAR:
-      temp = assoc_p (v) ? assoc_modcase (assoc_cell (v), pat, modop, mflags)
-                        : array_modcase (array_cell (v), pat, modop, mflags);
-      /* Don't call quote_escapes; array_modcase calls array_quote_escapes
-        as appropriate before adding the space separators; ditto for
-        assoc_modcase. */
-      break;
-#endif
-    }
-
-  FREE (pat);
-  free (lpat);
-
-  return temp;
-}
-
-/* Check for unbalanced parens in S, which is the contents of $(( ... )).  If
-   any occur, this must be a nested command substitution, so return 0.
-   Otherwise, return 1.  A valid arithmetic expression must always have a
-   ( before a matching ), so any cases where there are more right parens
-   means that this must not be an arithmetic expression, though the parser
-   will not accept it without a balanced total number of parens. */
-static int
-chk_arithsub (s, len)
-     const char *s;
-     int len;
-{
-  int i, count;
-  DECLARE_MBSTATE;
-
-  i = count = 0;
-  while (i < len)
-    {
-      if (s[i] == LPAREN)
-       count++;
-      else if (s[i] == RPAREN)
-       {
-         count--;
-         if (count < 0)
-           return 0;
-       }
-
-      switch (s[i])
-       {
-       default:
-         ADVANCE_CHAR (s, len, i);
-         break;
-
-       case '\\':
-         i++;
-         if (s[i])
-           ADVANCE_CHAR (s, len, i);
-         break;
-
-       case '\'':
-         i = skip_single_quoted (s, len, ++i);
-         break;
-
-       case '"':
-         i = skip_double_quoted ((char *)s, len, ++i);
-         break;
-       }
-    }
-
-  return (count == 0);
-}
-
-/****************************************************************/
-/*                                                             */
-/*     Functions to perform parameter expansion on a string    */
-/*                                                             */
-/****************************************************************/
-
-/* ${[#][!]name[[:][^[^]][,[,]]#[#]%[%]-=?+[word][:e1[:e2]]]} */
-static WORD_DESC *
-parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, contains_dollar_at)
-     char *string;
-     int *indexp, quoted, *quoted_dollar_atp, *contains_dollar_at, pflags;
-{
-  int check_nullness, var_is_set, var_is_null, var_is_special;
-  int want_substring, want_indir, want_patsub, want_casemod;
-  char *name, *value, *temp, *temp1;
-  WORD_DESC *tdesc, *ret;
-  int t_index, sindex, c, tflag, modspec;
-  intmax_t number;
-
-  temp = temp1 = value = (char *)NULL;
-  var_is_set = var_is_null = var_is_special = check_nullness = 0;
-  want_substring = want_indir = want_patsub = want_casemod = 0;
-
-  sindex = *indexp;
-  t_index = ++sindex;
-  /* ${#var} doesn't have any of the other parameter expansions on it. */
-  if (string[t_index] == '#' && legal_variable_starter (string[t_index+1]))            /* {{ */
-    name = string_extract (string, &t_index, "}", SX_VARNAME);
-  else
-#if defined (CASEMOD_EXPANSIONS)
-    /* To enable case-toggling expansions using the `~' operator character
-       change the 1 to 0. */
-#  if defined (CASEMOD_CAPCASE)
-    name = string_extract (string, &t_index, "#%^,~:-=?+/}", SX_VARNAME);
-#  else
-    name = string_extract (string, &t_index, "#%^,:-=?+/}", SX_VARNAME);
-#  endif /* CASEMOD_CAPCASE */
-#else
-    name = string_extract (string, &t_index, "#%:-=?+/}", SX_VARNAME);
-#endif /* CASEMOD_EXPANSIONS */
-
-  ret = 0;
-  tflag = 0;
-
-  /* If the name really consists of a special variable, then make sure
-     that we have the entire name.  We don't allow indirect references
-     to special variables except `#', `?', `@' and `*'. */
-  if ((sindex == t_index &&
-       (string[t_index] == '-' ||
-        string[t_index] == '?' ||
-        string[t_index] == '#')) ||
-      (sindex == t_index - 1 && string[sindex] == '!' &&
-       (string[t_index] == '#' ||
-        string[t_index] == '?' ||
-        string[t_index] == '@' ||
-        string[t_index] == '*')))
-    {
-      t_index++;
-      free (name);
-      temp1 = string_extract (string, &t_index, "#%:-=?+/}", 0);
-      name = (char *)xmalloc (3 + (strlen (temp1)));
-      *name = string[sindex];
-      if (string[sindex] == '!')
-       {
-         /* indirect reference of $#, $?, $@, or $* */
-         name[1] = string[sindex + 1];
-         strcpy (name + 2, temp1);
-       }
-      else     
-       strcpy (name + 1, temp1);
-      free (temp1);
-    }
-  sindex = t_index;
-
-  /* Find out what character ended the variable name.  Then
-     do the appropriate thing. */
-  if (c = string[sindex])
-    sindex++;
-
-  /* If c is followed by one of the valid parameter expansion
-     characters, move past it as normal.  If not, assume that
-     a substring specification is being given, and do not move
-     past it. */
-  if (c == ':' && VALID_PARAM_EXPAND_CHAR (string[sindex]))
-    {
-      check_nullness++;
-      if (c = string[sindex])
-       sindex++;
-    }
-  else if (c == ':' && string[sindex] != RBRACE)
-    want_substring = 1;
-  else if (c == '/' && string[sindex] != RBRACE)
-    want_patsub = 1;
-#if defined (CASEMOD_EXPANSIONS)
-  else if (c == '^' || c == ',' || c == '~')
-    {
-      modspec = c;
-      want_casemod = 1;
-    }
-#endif
-
-  /* Catch the valid and invalid brace expressions that made it through the
-     tests above. */
-  /* ${#-} is a valid expansion and means to take the length of $-.
-     Similarly for ${#?} and ${##}... */
-  if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
-       VALID_SPECIAL_LENGTH_PARAM (c) && string[sindex] == RBRACE)
-    {
-      name = (char *)xrealloc (name, 3);
-      name[1] = c;
-      name[2] = '\0';
-      c = string[sindex++];
-    }
-
-  /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */
-  if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
-       member (c, "%:=+/") && string[sindex] == RBRACE)
-    {
-      temp = (char *)NULL;
-      goto bad_substitution;
-    }
-
-  /* Indirect expansion begins with a `!'.  A valid indirect expansion is
-     either a variable name, one of the positional parameters or a special
-     variable that expands to one of the positional parameters. */
-  want_indir = *name == '!' &&
-    (legal_variable_starter ((unsigned char)name[1]) || DIGIT (name[1])
-                                       || VALID_INDIR_PARAM (name[1]));
-
-  /* Determine the value of this variable. */
-
-  /* Check for special variables, directly referenced. */
-  if (SPECIAL_VAR (name, want_indir))
-    var_is_special++;
-
-  /* Check for special expansion things, like the length of a parameter */
-  if (*name == '#' && name[1])
-    {
-      /* If we are not pointing at the character just after the
-        closing brace, then we haven't gotten all of the name.
-        Since it begins with a special character, this is a bad
-        substitution.  Also check NAME for validity before trying
-        to go on. */
-      if (string[sindex - 1] != RBRACE || (valid_length_expression (name) == 0))
-       {
-         temp = (char *)NULL;
-         goto bad_substitution;
-       }
-
-      number = parameter_brace_expand_length (name);
-      free (name);
-
-      *indexp = sindex;
-      if (number < 0)
-        return (&expand_wdesc_error);
-      else
-       {
-         ret = alloc_word_desc ();
-         ret->word = itos (number);
-         return ret;
-       }
-    }
-
-  /* ${@} is identical to $@. */
-  if (name[0] == '@' && name[1] == '\0')
-    {
-      if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-       *quoted_dollar_atp = 1;
-
-      if (contains_dollar_at)
-       *contains_dollar_at = 1;
-    }
-
-  /* Process ${!PREFIX*} expansion. */
-  if (want_indir && string[sindex - 1] == RBRACE &&
-      (string[sindex - 2] == '*' || string[sindex - 2] == '@') &&
-      legal_variable_starter ((unsigned char) name[1]))
-    {
-      char **x;
-      WORD_LIST *xlist;
-
-      temp1 = savestring (name + 1);
-      number = strlen (temp1);
-      temp1[number - 1] = '\0';
-      x = all_variables_matching_prefix (temp1);
-      xlist = strvec_to_word_list (x, 0, 0);
-      if (string[sindex - 2] == '*')
-       temp = string_list_dollar_star (xlist);
-      else
-       {
-         temp = string_list_dollar_at (xlist, quoted);
-         if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-           *quoted_dollar_atp = 1;
-         if (contains_dollar_at)
-           *contains_dollar_at = 1;
-       }
-      free (x);
-      dispose_words (xlist);
-      free (temp1);
-      *indexp = sindex;
-
-      ret = alloc_word_desc ();
-      ret->word = temp;
-      return ret;
-    }
-
-#if defined (ARRAY_VARS)      
-  /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */ /* [ */
-  if (want_indir && string[sindex - 1] == RBRACE &&
-      string[sindex - 2] == ']' && valid_array_reference (name+1))
-    {
-      char *x, *x1;
-
-      temp1 = savestring (name + 1);
-      x = array_variable_name (temp1, &x1, (int *)0);  /* [ */
-      FREE (x);
-      if (ALL_ELEMENT_SUB (x1[0]) && x1[1] == ']')
-       {
-         temp = array_keys (temp1, quoted);    /* handles assoc vars too */
-         if (x1[0] == '@')
-           {
-             if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-               *quoted_dollar_atp = 1;
-             if (contains_dollar_at)
-               *contains_dollar_at = 1;
-           }       
-
-         free (temp1);
-         *indexp = sindex;
-
-         ret = alloc_word_desc ();
-         ret->word = temp;
-         return ret;
-       }
-
-      free (temp1);
-    }
-#endif /* ARRAY_VARS */
-      
-  /* Make sure that NAME is valid before trying to go on. */
-  if (valid_brace_expansion_word (want_indir ? name + 1 : name,
-                                       var_is_special) == 0)
-    {
-      temp = (char *)NULL;
-      goto bad_substitution;
-    }
-
-  if (want_indir)
-    tdesc = parameter_brace_expand_indir (name + 1, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at);
-  else
-    tdesc = parameter_brace_expand_word (name, var_is_special, quoted, PF_IGNUNBOUND|(pflags&PF_NOSPLIT2));
-
-  if (tdesc)
-    {
-      temp = tdesc->word;
-      tflag = tdesc->flags;
-      dispose_word_desc (tdesc);
-    }
-  else
-    temp = (char  *)0;
-
-#if defined (ARRAY_VARS)
-  if (valid_array_reference (name))
-    chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at);
-#endif
-
-  var_is_set = temp != (char *)0;
-  var_is_null = check_nullness && (var_is_set == 0 || *temp == 0);
-
-  /* Get the rest of the stuff inside the braces. */
-  if (c && c != RBRACE)
-    {
-      /* Extract the contents of the ${ ... } expansion
-        according to the Posix.2 rules. */
-      value = extract_dollar_brace_string (string, &sindex, quoted, 0);
-      if (string[sindex] == RBRACE)
-       sindex++;
-      else
-       goto bad_substitution;
-    }
-  else
-    value = (char *)NULL;
-
-  *indexp = sindex;
-
-  /* If this is a substring spec, process it and add the result. */
-  if (want_substring)
-    {
-      temp1 = parameter_brace_substring (name, temp, value, quoted);
-      FREE (name);
-      FREE (value);
-      FREE (temp);
-
-      if (temp1 == &expand_param_error)
-       return (&expand_wdesc_error);
-      else if (temp1 == &expand_param_fatal)
-       return (&expand_wdesc_fatal);
-
-      ret = alloc_word_desc ();
-      ret->word = temp1;
-      if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-       ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
-      return ret;
-    }
-  else if (want_patsub)
-    {
-      temp1 = parameter_brace_patsub (name, temp, value, quoted);
-      FREE (name);
-      FREE (value);
-      FREE (temp);
-
-      if (temp1 == &expand_param_error)
-       return (&expand_wdesc_error);
-      else if (temp1 == &expand_param_fatal)
-       return (&expand_wdesc_fatal);
-
-      ret = alloc_word_desc ();
-      ret->word = temp1;
-      ret = alloc_word_desc ();
-      ret->word = temp1;
-      if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-       ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
-      return ret;
-    }
-#if defined (CASEMOD_EXPANSIONS)
-  else if (want_casemod)
-    {
-      temp1 = parameter_brace_casemod (name, temp, modspec, value, quoted);
-      FREE (name);
-      FREE (value);
-      FREE (temp);
-
-      if (temp1 == &expand_param_error)
-       return (&expand_wdesc_error);
-      else if (temp1 == &expand_param_fatal)
-       return (&expand_wdesc_fatal);
-
-      ret = alloc_word_desc ();
-      ret->word = temp1;
-      if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-       ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
-      return ret;
-    }
-#endif
-
-  /* Do the right thing based on which character ended the variable name. */
-  switch (c)
-    {
-    default:
-    case '\0':
-    bad_substitution:
-      report_error (_("%s: bad substitution"), string ? string : "??");
-      FREE (value);
-      FREE (temp);
-      free (name);
-      return &expand_wdesc_error;
-
-    case RBRACE:
-      if (var_is_set == 0 && unbound_vars_is_error && ((name[0] != '@' && name[0] != '*') || name[1]))
-       {
-         last_command_exit_value = EXECUTION_FAILURE;
-         err_unboundvar (name);
-         FREE (value);
-         FREE (temp);
-         free (name);
-         return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
-       }
-      break;
-
-    case '#':  /* ${param#[#]pattern} */
-    case '%':  /* ${param%[%]pattern} */
-      if (value == 0 || *value == '\0' || temp == 0 || *temp == '\0')
-       {
-         FREE (value);
-         break;
-       }
-      temp1 = parameter_brace_remove_pattern (name, temp, value, c, quoted);
-      free (temp);
-      free (value);
-
-      ret = alloc_word_desc ();
-      ret->word = temp1;
-      if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-       ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
-      return ret;
-
-    case '-':
-    case '=':
-    case '?':
-    case '+':
-      if (var_is_set && var_is_null == 0)
-       {
-         /* If the operator is `+', we don't want the value of the named
-            variable for anything, just the value of the right hand side. */
-
-         if (c == '+')
-           {
-             /* XXX -- if we're double-quoted and the named variable is "$@",
-                       we want to turn off any special handling of "$@" --
-                       we're not using it, so whatever is on the rhs applies. */
-             if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-               *quoted_dollar_atp = 0;
-             if (contains_dollar_at)
-               *contains_dollar_at = 0;
-
-             FREE (temp);
-             if (value)
-               {
-                 ret = parameter_brace_expand_rhs (name, value, c,
-                                                   quoted,
-                                                   quoted_dollar_atp,
-                                                   contains_dollar_at);
-                 /* XXX - fix up later, esp. noting presence of
-                          W_HASQUOTEDNULL in ret->flags */
-                 free (value);
-               }
-             else
-               temp = (char *)NULL;
-           }
-         else
-           {
-             FREE (value);
-           }
-         /* Otherwise do nothing; just use the value in TEMP. */
-       }
-      else     /* VAR not set or VAR is NULL. */
-       {
-         FREE (temp);
-         temp = (char *)NULL;
-         if (c == '=' && var_is_special)
-           {
-             report_error (_("$%s: cannot assign in this way"), name);
-             free (name);
-             free (value);
-             return &expand_wdesc_error;
-           }
-         else if (c == '?')
-           {
-             parameter_brace_expand_error (name, value);
-             return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
-           }
-         else if (c != '+')
-           {
-             /* XXX -- if we're double-quoted and the named variable is "$@",
-                       we want to turn off any special handling of "$@" --
-                       we're not using it, so whatever is on the rhs applies. */
-             if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-               *quoted_dollar_atp = 0;
-             if (contains_dollar_at)
-               *contains_dollar_at = 0;
-
-             ret = parameter_brace_expand_rhs (name, value, c, quoted,
-                                               quoted_dollar_atp,
-                                               contains_dollar_at);
-             /* XXX - fix up later, esp. noting presence of
-                      W_HASQUOTEDNULL in tdesc->flags */
-           }
-         free (value);
-       }
-
-      break;
-    }
-  free (name);
-
-  if (ret == 0)
-    {
-      ret = alloc_word_desc ();
-      ret->flags = tflag;
-      ret->word = temp;
-    }
-  return (ret);
-}
-
-/* Expand a single ${xxx} expansion.  The braces are optional.  When
-   the braces are used, parameter_brace_expand() does the work,
-   possibly calling param_expand recursively. */
-static WORD_DESC *
-param_expand (string, sindex, quoted, expanded_something,
-             contains_dollar_at, quoted_dollar_at_p, had_quoted_null_p,
-             pflags)
-     char *string;
-     int *sindex, quoted, *expanded_something, *contains_dollar_at;
-     int *quoted_dollar_at_p, *had_quoted_null_p, pflags;
-{
-  char *temp, *temp1, uerror[3];
-  int zindex, t_index, expok;
-  unsigned char c;
-  intmax_t number;
-  SHELL_VAR *var;
-  WORD_LIST *list;
-  WORD_DESC *tdesc, *ret;
-  int tflag;
-
-  zindex = *sindex;
-  c = string[++zindex];
-
-  temp = (char *)NULL;
-  ret = tdesc = (WORD_DESC *)NULL;
-  tflag = 0;
-
-  /* Do simple cases first. Switch on what follows '$'. */
-  switch (c)
-    {
-    /* $0 .. $9? */
-    case '0':
-    case '1':
-    case '2':
-    case '3':
-    case '4':
-    case '5':
-    case '6':
-    case '7':
-    case '8':
-    case '9':
-      temp1 = dollar_vars[TODIGIT (c)];
-      if (unbound_vars_is_error && temp1 == (char *)NULL)
-       {
-         uerror[0] = '$';
-         uerror[1] = c;
-         uerror[2] = '\0';
-         last_command_exit_value = EXECUTION_FAILURE;
-         err_unboundvar (uerror);
-         return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
-       }
-      if (temp1)
-       temp = (*temp1 && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-                 ? quote_string (temp1)
-                 : quote_escapes (temp1);
-      else
-       temp = (char *)NULL;
-
-      break;
-
-    /* $$ -- pid of the invoking shell. */
-    case '$':
-      temp = itos (dollar_dollar_pid);
-      break;
-
-    /* $# -- number of positional parameters. */
-    case '#':
-      temp = itos (number_of_args ());
-      break;
-
-    /* $? -- return value of the last synchronous command. */
-    case '?':
-      temp = itos (last_command_exit_value);
-      break;
-
-    /* $- -- flags supplied to the shell on invocation or by `set'. */
-    case '-':
-      temp = which_set_flags ();
-      break;
-
-      /* $! -- Pid of the last asynchronous command. */
-    case '!':
-      /* If no asynchronous pids have been created, expand to nothing.
-        If `set -u' has been executed, and no async processes have
-        been created, this is an expansion error. */
-      if (last_asynchronous_pid == NO_PID)
-       {
-         if (expanded_something)
-           *expanded_something = 0;
-         temp = (char *)NULL;
-         if (unbound_vars_is_error)
-           {
-             uerror[0] = '$';
-             uerror[1] = c;
-             uerror[2] = '\0';
-             last_command_exit_value = EXECUTION_FAILURE;
-             err_unboundvar (uerror);
-             return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
-           }
-       }
-      else
-       temp = itos (last_asynchronous_pid);
-      break;
-
-    /* The only difference between this and $@ is when the arg is quoted. */
-    case '*':          /* `$*' */
-      list = list_rest_of_args ();
-
-#if 0
-      /* According to austin-group posix proposal by Geoff Clare in
-        <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
-
-       "The shell shall write a message to standard error and
-        immediately exit when it tries to expand an unset parameter
-        other than the '@' and '*' special parameters."
-      */
-
-      if (list == 0 && unbound_vars_is_error && (pflags & PF_IGNUNBOUND) == 0)
-       {
-         uerror[0] = '$';
-         uerror[1] = '*';
-         uerror[2] = '\0';
-         last_command_exit_value = EXECUTION_FAILURE;
-         err_unboundvar (uerror);
-         return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
-       }
-#endif
-
-      /* If there are no command-line arguments, this should just
-        disappear if there are other characters in the expansion,
-        even if it's quoted. */
-      if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && list == 0)
-       temp = (char *)NULL;
-      else if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES|Q_PATQUOTE))
-       {
-         /* If we have "$*" we want to make a string of the positional
-            parameters, separated by the first character of $IFS, and
-            quote the whole string, including the separators.  If IFS
-            is unset, the parameters are separated by ' '; if $IFS is
-            null, the parameters are concatenated. */
-         temp = (quoted & (Q_DOUBLE_QUOTES|Q_PATQUOTE)) ? string_list_dollar_star (list) : string_list (list);
-         temp1 = quote_string (temp);
-         if (*temp == 0)
-           tflag |= W_HASQUOTEDNULL;
-         free (temp);
-         temp = temp1;
-       }
-      else
-       {
-         /* We check whether or not we're eventually going to split $* here,
-            for example when IFS is empty and we are processing the rhs of
-            an assignment statement.  In that case, we don't separate the
-            arguments at all.  Otherwise, if the $* is not quoted it is
-            identical to $@ */
-#if 1
-#  if defined (HANDLE_MULTIBYTE)
-         if (expand_no_split_dollar_star && ifs_firstc[0] == 0)
-#  else
-         if (expand_no_split_dollar_star && ifs_firstc == 0)
-#  endif
-           temp = string_list_dollar_star (list);
-         else
-           temp = string_list_dollar_at (list, quoted);
-#else
-         temp = string_list_dollar_at (list, quoted);
-#endif
-         if (expand_no_split_dollar_star == 0 && contains_dollar_at)
-           *contains_dollar_at = 1;
-       }
-
-      dispose_words (list);
-      break;
-
-    /* When we have "$@" what we want is "$1" "$2" "$3" ... This
-       means that we have to turn quoting off after we split into
-       the individually quoted arguments so that the final split
-       on the first character of $IFS is still done.  */
-    case '@':          /* `$@' */
-      list = list_rest_of_args ();
-
-#if 0
-      /* According to austin-group posix proposal by Geoff Clare in
-        <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
-
-       "The shell shall write a message to standard error and
-        immediately exit when it tries to expand an unset parameter
-        other than the '@' and '*' special parameters."
-      */
-
-      if (list == 0 && unbound_vars_is_error && (pflags & PF_IGNUNBOUND) == 0)
-       {
-         uerror[0] = '$';
-         uerror[1] = '@';
-         uerror[2] = '\0';
-         last_command_exit_value = EXECUTION_FAILURE;
-         err_unboundvar (uerror);
-         return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
-       }
-#endif
-
-      /* We want to flag the fact that we saw this.  We can't turn
-        off quoting entirely, because other characters in the
-        string might need it (consider "\"$@\""), but we need some
-        way to signal that the final split on the first character
-        of $IFS should be done, even though QUOTED is 1. */
-      /* XXX - should this test include Q_PATQUOTE? */
-      if (quoted_dollar_at_p && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-       *quoted_dollar_at_p = 1;
-      if (contains_dollar_at)
-       *contains_dollar_at = 1;
-
-#if 0
-      if (pflags & PF_NOSPLIT2)
-       temp = string_list_internal (quoted ? quote_list (list) : list, " ");
-      else
-#endif
-      /* We want to separate the positional parameters with the first
-        character of $IFS in case $IFS is something other than a space.
-        We also want to make sure that splitting is done no matter what --
-        according to POSIX.2, this expands to a list of the positional
-        parameters no matter what IFS is set to. */
-      temp = string_list_dollar_at (list, quoted);
-
-      dispose_words (list);
-      break;
-
-    case LBRACE:
-      tdesc = parameter_brace_expand (string, &zindex, quoted, pflags,
-                                     quoted_dollar_at_p,
-                                     contains_dollar_at);
-
-      if (tdesc == &expand_wdesc_error || tdesc == &expand_wdesc_fatal)
-       return (tdesc);
-      temp = tdesc ? tdesc->word : (char *)0;
-
-      /* XXX */
-      /* Quoted nulls should be removed if there is anything else
-        in the string. */
-      /* Note that we saw the quoted null so we can add one back at
-        the end of this function if there are no other characters
-        in the string, discard TEMP, and go on.  The exception to
-        this is when we have "${@}" and $1 is '', since $@ needs
-        special handling. */
-      if (tdesc && tdesc->word && (tdesc->flags & W_HASQUOTEDNULL) && QUOTED_NULL (temp))
-       {
-         if (had_quoted_null_p)
-           *had_quoted_null_p = 1;
-         if (*quoted_dollar_at_p == 0)
-           {
-             free (temp);
-             tdesc->word = temp = (char *)NULL;
-           }
-           
-       }
-
-      ret = tdesc;
-      goto return0;
-
-    /* Do command or arithmetic substitution. */
-    case LPAREN:
-      /* We have to extract the contents of this paren substitution. */
-      t_index = zindex + 1;
-      temp = extract_command_subst (string, &t_index, 0);
-      zindex = t_index;
-
-      /* For Posix.2-style `$(( ))' arithmetic substitution,
-        extract the expression and pass it to the evaluator. */
-      if (temp && *temp == LPAREN)
-       {
-         char *temp2;
-         temp1 = temp + 1;
-         temp2 = savestring (temp1);
-         t_index = strlen (temp2) - 1;
-
-         if (temp2[t_index] != RPAREN)
-           {
-             free (temp2);
-             goto comsub;
-           }
-
-         /* Cut off ending `)' */
-         temp2[t_index] = '\0';
-
-         if (chk_arithsub (temp2, t_index) == 0)
-           {
-             free (temp2);
-             goto comsub;
-           }
-
-         /* Expand variables found inside the expression. */
-         temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES);
-         free (temp2);
-
-arithsub:
-         /* No error messages. */
-         this_command_name = (char *)NULL;
-         number = evalexp (temp1, &expok);
-         free (temp);
-         free (temp1);
-         if (expok == 0)
-           {
-             if (interactive_shell == 0 && posixly_correct)
-               {
-                 last_command_exit_value = EXECUTION_FAILURE;
-                 return (&expand_wdesc_fatal);
-               }
-             else
-               return (&expand_wdesc_error);
-           }
-         temp = itos (number);
-         break;
-       }
-
-comsub:
-      if (pflags & PF_NOCOMSUB)
-       /* we need zindex+1 because string[zindex] == RPAREN */
-       temp1 = substring (string, *sindex, zindex+1);
-      else
-       {
-         tdesc = command_substitute (temp, quoted);
-         temp1 = tdesc ? tdesc->word : (char *)NULL;
-         if (tdesc)
-           dispose_word_desc (tdesc);
-       }
-      FREE (temp);
-      temp = temp1;
-      break;
-
-    /* Do POSIX.2d9-style arithmetic substitution.  This will probably go
-       away in a future bash release. */
-    case '[':
-      /* Extract the contents of this arithmetic substitution. */
-      t_index = zindex + 1;
-      temp = extract_arithmetic_subst (string, &t_index);
-      zindex = t_index;
-      if (temp == 0)
-       {
-         temp = savestring (string);
-         if (expanded_something)
-           *expanded_something = 0;
-         goto return0;
-       }         
-
-       /* Do initial variable expansion. */
-      temp1 = expand_arith_string (temp, Q_DOUBLE_QUOTES);
-
-      goto arithsub;
-
-    default:
-      /* Find the variable in VARIABLE_LIST. */
-      temp = (char *)NULL;
-
-      for (t_index = zindex; (c = string[zindex]) && legal_variable_char (c); zindex++)
-       ;
-      temp1 = (zindex > t_index) ? substring (string, t_index, zindex) : (char *)NULL;
-
-      /* If this isn't a variable name, then just output the `$'. */
-      if (temp1 == 0 || *temp1 == '\0')
-       {
-         FREE (temp1);
-         temp = (char *)xmalloc (2);
-         temp[0] = '$';
-         temp[1] = '\0';
-         if (expanded_something)
-           *expanded_something = 0;
-         goto return0;
-       }
-
-      /* If the variable exists, return its value cell. */
-      var = find_variable (temp1);
-
-      if (var && invisible_p (var) == 0 && var_isset (var))
-       {
-#if defined (ARRAY_VARS)
-         if (assoc_p (var) || array_p (var))
-           {
-             temp = array_p (var) ? array_reference (array_cell (var), 0)
-                                  : assoc_reference (assoc_cell (var), "0");
-             if (temp)
-               temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-                         ? quote_string (temp)
-                         : quote_escapes (temp);
-             else if (unbound_vars_is_error)
-               goto unbound_variable;
-           }
-         else
-#endif
-           {
-             temp = value_cell (var);
-
-             temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-                       ? quote_string (temp)
-                       : quote_escapes (temp);
-           }
-
-         free (temp1);
-
-         goto return0;
-       }
-
-      temp = (char *)NULL;
-
-unbound_variable:
-      if (unbound_vars_is_error)
-       {
-         last_command_exit_value = EXECUTION_FAILURE;
-         err_unboundvar (temp1);
-       }
-      else
-       {
-         free (temp1);
-         goto return0;
-       }
-
-      free (temp1);
-      last_command_exit_value = EXECUTION_FAILURE;
-      return ((unbound_vars_is_error && interactive_shell == 0)
-               ? &expand_wdesc_fatal
-               : &expand_wdesc_error);
-    }
-
-  if (string[zindex])
-    zindex++;
-
-return0:
-  *sindex = zindex;
-
-  if (ret == 0)
-    {
-      ret = alloc_word_desc ();
-      ret->flags = tflag;      /* XXX */
-      ret->word = temp;
-    }
-  return ret;
-}
-
-/* Make a word list which is the result of parameter and variable
-   expansion, command substitution, arithmetic substitution, and
-   quote removal of WORD.  Return a pointer to a WORD_LIST which is
-   the result of the expansion.  If WORD contains a null word, the
-   word list returned is also null.
-
-   QUOTED contains flag values defined in shell.h.
-
-   ISEXP is used to tell expand_word_internal that the word should be
-   treated as the result of an expansion.  This has implications for
-   how IFS characters in the word are treated.
-
-   CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
-   they point to an integer value which receives information about expansion.
-   CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
-   EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
-   else zero.
-
-   This only does word splitting in the case of $@ expansion.  In that
-   case, we split on ' '. */
-
-/* Values for the local variable quoted_state. */
-#define UNQUOTED        0
-#define PARTIALLY_QUOTED 1
-#define WHOLLY_QUOTED    2
-
-static WORD_LIST *
-expand_word_internal (word, quoted, isexp, contains_dollar_at, expanded_something)
-     WORD_DESC *word;
-     int quoted, isexp;
-     int *contains_dollar_at;
-     int *expanded_something;
-{
-  WORD_LIST *list;
-  WORD_DESC *tword;
-
-  /* The intermediate string that we build while expanding. */
-  char *istring;
-
-  /* The current size of the above object. */
-  int istring_size;
-
-  /* Index into ISTRING. */
-  int istring_index;
-
-  /* Temporary string storage. */
-  char *temp, *temp1;
-
-  /* The text of WORD. */
-  register char *string;
-
-  /* The size of STRING. */
-  size_t string_size;
-
-  /* The index into STRING. */
-  int sindex;
-
-  /* This gets 1 if we see a $@ while quoted. */
-  int quoted_dollar_at;
-
-  /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
-     whether WORD contains no quoting characters, a partially quoted
-     string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
-  int quoted_state;
-
-  /* State flags */
-  int had_quoted_null;
-  int has_dollar_at;
-  int tflag;
-  int pflags;                  /* flags passed to param_expand */
-
-  int assignoff;               /* If assignment, offset of `=' */
-
-  register unsigned char c;    /* Current character. */
-  int t_index;                 /* For calls to string_extract_xxx. */
-
-  char twochars[2];
-
-  DECLARE_MBSTATE;
-
-  istring = (char *)xmalloc (istring_size = DEFAULT_INITIAL_ARRAY_SIZE);
-  istring[istring_index = 0] = '\0';
-  quoted_dollar_at = had_quoted_null = has_dollar_at = 0;
-  quoted_state = UNQUOTED;
-
-  string = word->word;
-  if (string == 0)
-    goto finished_with_string;
-  /* Don't need the string length for the SADD... and COPY_ macros unless
-     multibyte characters are possible. */
-  string_size = (MB_CUR_MAX > 1) ? strlen (string) : 1;
-
-  if (contains_dollar_at)
-    *contains_dollar_at = 0;
-
-  assignoff = -1;
-
-  /* Begin the expansion. */
-
-  for (sindex = 0; ;)
-    {
-      c = string[sindex];
-
-      /* Case on toplevel character. */
-      switch (c)
-       {
-       case '\0':
-         goto finished_with_string;
-
-       case CTLESC:
-         sindex++;
-#if HANDLE_MULTIBYTE
-         if (MB_CUR_MAX > 1 && string[sindex])
-           {
-             SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
-           }
-         else
-#endif
-           {
-             temp = (char *)xmalloc (3);
-             temp[0] = CTLESC;
-             temp[1] = c = string[sindex];
-             temp[2] = '\0';
-           }
-
-dollar_add_string:
-         if (string[sindex])
-           sindex++;
-
-add_string:
-         if (temp)
-           {
-             istring = sub_append_string (temp, istring, &istring_index, &istring_size);
-             temp = (char *)0;
-           }
-
-         break;
-
-#if defined (PROCESS_SUBSTITUTION)
-         /* Process substitution. */
-       case '<':
-       case '>':
-         {
-           if (string[++sindex] != LPAREN || (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (word->flags & (W_DQUOTE|W_NOPROCSUB)) || posixly_correct)
-             {
-               sindex--;       /* add_character: label increments sindex */
-               goto add_character;
-             }
-           else
-             t_index = sindex + 1; /* skip past both '<' and LPAREN */
-
-           temp1 = extract_process_subst (string, (c == '<') ? "<(" : ">(", &t_index); /*))*/
-           sindex = t_index;
-
-           /* If the process substitution specification is `<()', we want to
-              open the pipe for writing in the child and produce output; if
-              it is `>()', we want to open the pipe for reading in the child
-              and consume input. */
-           temp = temp1 ? process_substitute (temp1, (c == '>')) : (char *)0;
-
-           FREE (temp1);
-
-           goto dollar_add_string;
-         }
-#endif /* PROCESS_SUBSTITUTION */
-
-       case '=':
-         /* Posix.2 section 3.6.1 says that tildes following `=' in words
-            which are not assignment statements are not expanded.  If the
-            shell isn't in posix mode, though, we perform tilde expansion
-            on `likely candidate' unquoted assignment statements (flags
-            include W_ASSIGNMENT but not W_QUOTED).  A likely candidate
-            contains an unquoted :~ or =~.  Something to think about: we
-            now have a flag that says  to perform tilde expansion on arguments
-            to `assignment builtins' like declare and export that look like
-            assignment statements.  We now do tilde expansion on such words
-            even in POSIX mode. */     
-         if (word->flags & (W_ASSIGNRHS|W_NOTILDE))
-           {
-             if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c))
-               goto add_ifs_character;
-             else
-               goto add_character;
-           }
-         /* If we're not in posix mode or forcing assignment-statement tilde
-            expansion, note where the `=' appears in the word and prepare to
-            do tilde expansion following the first `='. */
-         if ((word->flags & W_ASSIGNMENT) &&
-             (posixly_correct == 0 || (word->flags & W_TILDEEXP)) &&
-             assignoff == -1 && sindex > 0)
-           assignoff = sindex;
-         if (sindex == assignoff && string[sindex+1] == '~')   /* XXX */
-           word->flags |= W_ITILDE;
-#if 0
-         else if ((word->flags & W_ASSIGNMENT) &&
-                  (posixly_correct == 0 || (word->flags & W_TILDEEXP)) &&
-                  string[sindex+1] == '~')
-           word->flags |= W_ITILDE;
-#endif
-         if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c))
-           goto add_ifs_character;
-         else
-           goto add_character;
-
-       case ':':
-         if (word->flags & W_NOTILDE)
-           {
-             if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c))
-               goto add_ifs_character;
-             else
-               goto add_character;
-           }
-
-         if ((word->flags & (W_ASSIGNMENT|W_ASSIGNRHS|W_TILDEEXP)) &&
-             string[sindex+1] == '~')
-           word->flags |= W_ITILDE;
-
-         if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c))
-           goto add_ifs_character;
-         else
-           goto add_character;
-
-       case '~':
-         /* If the word isn't supposed to be tilde expanded, or we're not
-            at the start of a word or after an unquoted : or = in an
-            assignment statement, we don't do tilde expansion. */
-         if ((word->flags & (W_NOTILDE|W_DQUOTE)) ||
-             (sindex > 0 && ((word->flags & W_ITILDE) == 0)) ||
-             (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-           {
-             word->flags &= ~W_ITILDE;
-             if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
-               goto add_ifs_character;
-             else
-               goto add_character;
-           }
-
-         if (word->flags & W_ASSIGNRHS)
-           tflag = 2;
-         else if (word->flags & (W_ASSIGNMENT|W_TILDEEXP))
-           tflag = 1;
-         else
-           tflag = 0;
-
-         temp = bash_tilde_find_word (string + sindex, tflag, &t_index);
-           
-         word->flags &= ~W_ITILDE;
-
-         if (temp && *temp && t_index > 0)
-           {
-             temp1 = bash_tilde_expand (temp, tflag);
-             if  (temp1 && *temp1 == '~' && STREQ (temp, temp1))
-               {
-                 FREE (temp);
-                 FREE (temp1);
-                 goto add_character;           /* tilde expansion failed */
-               }
-             free (temp);
-             temp = temp1;
-             sindex += t_index;
-             goto add_quoted_string;           /* XXX was add_string */
-           }
-         else
-           {
-             FREE (temp);
-             goto add_character;
-           }
-       
-       case '$':
-         if (expanded_something)
-           *expanded_something = 1;
-
-         has_dollar_at = 0;
-         pflags = (word->flags & W_NOCOMSUB) ? PF_NOCOMSUB : 0;
-         if (word->flags & W_NOSPLIT2)
-           pflags |= PF_NOSPLIT2;
-         tword = param_expand (string, &sindex, quoted, expanded_something,
-                              &has_dollar_at, &quoted_dollar_at,
-                              &had_quoted_null, pflags);
-
-         if (tword == &expand_wdesc_error || tword == &expand_wdesc_fatal)
-           {
-             free (string);
-             free (istring);
-             return ((tword == &expand_wdesc_error) ? &expand_word_error
-                                                    : &expand_word_fatal);
-           }
-         if (contains_dollar_at && has_dollar_at)
-           *contains_dollar_at = 1;
-
-         if (tword && (tword->flags & W_HASQUOTEDNULL))
-           had_quoted_null = 1;
-
-         temp = tword->word;
-         dispose_word_desc (tword);
-
-         goto add_string;
-         break;
-
-       case '`':               /* Backquoted command substitution. */
-         {
-           t_index = sindex++;
-
-           temp = string_extract (string, &sindex, "`", SX_REQMATCH);
-           /* The test of sindex against t_index is to allow bare instances of
-              ` to pass through, for backwards compatibility. */
-           if (temp == &extract_string_error || temp == &extract_string_fatal)
-             {
-               if (sindex - 1 == t_index)
-                 {
-                   sindex = t_index;
-                   goto add_character;
-                 }
-               report_error (_("bad substitution: no closing \"`\" in %s") , string+t_index);
-               free (string);
-               free (istring);
-               return ((temp == &extract_string_error) ? &expand_word_error
-                                                       : &expand_word_fatal);
-             }
-               
-           if (expanded_something)
-             *expanded_something = 1;
-
-           if (word->flags & W_NOCOMSUB)
-             /* sindex + 1 because string[sindex] == '`' */
-             temp1 = substring (string, t_index, sindex + 1);
-           else
-             {
-               de_backslash (temp);
-               tword = command_substitute (temp, quoted);
-               temp1 = tword ? tword->word : (char *)NULL;
-               if (tword)
-                 dispose_word_desc (tword);
-             }
-           FREE (temp);
-           temp = temp1;
-           goto dollar_add_string;
-         }
-
-       case '\\':
-         if (string[sindex + 1] == '\n')
-           {
-             sindex += 2;
-             continue;
-           }
-
-         c = string[++sindex];
-
-         if (quoted & Q_HERE_DOCUMENT)
-           tflag = CBSHDOC;
-         else if (quoted & Q_DOUBLE_QUOTES)
-           tflag = CBSDQUOTE;
-         else
-           tflag = 0;
-
-         if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && ((sh_syntaxtab[c] & tflag) == 0))
-           {
-             SCOPY_CHAR_I (twochars, '\\', c, string, sindex, string_size);
-           }
-         else if (c == 0)
-           {
-             c = CTLNUL;
-             sindex--;         /* add_character: label increments sindex */
-             goto add_character;
-           }
-         else
-           {
-             SCOPY_CHAR_I (twochars, CTLESC, c, string, sindex, string_size);
-           }
-
-         sindex++;
-add_twochars:
-         /* BEFORE jumping here, we need to increment sindex if appropriate */
-         RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size,
-                                 DEFAULT_ARRAY_SIZE);
-         istring[istring_index++] = twochars[0];
-         istring[istring_index++] = twochars[1];
-         istring[istring_index] = '\0';
-
-         break;
-
-       case '"':
-#if 0
-         if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (word->flags & W_DQUOTE))
-#else
-         if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-#endif
-           goto add_character;
-
-         t_index = ++sindex;
-         temp = string_extract_double_quoted (string, &sindex, 0);
-
-         /* If the quotes surrounded the entire string, then the
-            whole word was quoted. */
-         quoted_state = (t_index == 1 && string[sindex] == '\0')
-                           ? WHOLLY_QUOTED
-                           : PARTIALLY_QUOTED;
-
-         if (temp && *temp)
-           {
-             tword = alloc_word_desc ();
-             tword->word = temp;
-
-             temp = (char *)NULL;
-
-             has_dollar_at = 0;
-             /* Need to get W_HASQUOTEDNULL flag through this function. */
-             list = expand_word_internal (tword, Q_DOUBLE_QUOTES, 0, &has_dollar_at, (int *)NULL);
-
-             if (list == &expand_word_error || list == &expand_word_fatal)
-               {
-                 free (istring);
-                 free (string);
-                 /* expand_word_internal has already freed temp_word->word
-                    for us because of the way it prints error messages. */
-                 tword->word = (char *)NULL;
-                 dispose_word (tword);
-                 return list;
-               }
-
-             dispose_word (tword);
-
-             /* "$@" (a double-quoted dollar-at) expands into nothing,
-                not even a NULL word, when there are no positional
-                parameters. */
-             if (list == 0 && has_dollar_at)
-               {
-                 quoted_dollar_at++;
-                 break;
-               }
-
-             /* If we get "$@", we know we have expanded something, so we
-                need to remember it for the final split on $IFS.  This is
-                a special case; it's the only case where a quoted string
-                can expand into more than one word.  It's going to come back
-                from the above call to expand_word_internal as a list with
-                a single word, in which all characters are quoted and
-                separated by blanks.  What we want to do is to turn it back
-                into a list for the next piece of code. */
-             if (list)
-               dequote_list (list);
-
-             if (list && list->word && (list->word->flags & W_HASQUOTEDNULL))
-               had_quoted_null = 1;
-
-             if (has_dollar_at)
-               {
-                 quoted_dollar_at++;
-                 if (contains_dollar_at)
-                   *contains_dollar_at = 1;
-                 if (expanded_something)
-                   *expanded_something = 1;
-               }
-           }
-         else
-           {
-             /* What we have is "".  This is a minor optimization. */
-             FREE (temp);
-             list = (WORD_LIST *)NULL;
-           }
-
-         /* The code above *might* return a list (consider the case of "$@",
-            where it returns "$1", "$2", etc.).  We can't throw away the
-            rest of the list, and we have to make sure each word gets added
-            as quoted.  We test on tresult->next:  if it is non-NULL, we
-            quote the whole list, save it to a string with string_list, and
-            add that string. We don't need to quote the results of this
-            (and it would be wrong, since that would quote the separators
-            as well), so we go directly to add_string. */
-         if (list)
-           {
-             if (list->next)
-               {
-#if 0
-                 if (quoted_dollar_at && word->flags & W_NOSPLIT2)
-                   temp = string_list_internal (quote_list (list), " ");
-                 else
-#endif
-                 /* Testing quoted_dollar_at makes sure that "$@" is
-                    split correctly when $IFS does not contain a space. */
-                 temp = quoted_dollar_at
-                               ? string_list_dollar_at (list, Q_DOUBLE_QUOTES)
-                               : string_list (quote_list (list));
-                 dispose_words (list);
-                 goto add_string;
-               }
-             else
-               {
-                 temp = savestring (list->word->word);
-                 tflag = list->word->flags;
-                 dispose_words (list);
-
-                 /* If the string is not a quoted null string, we want
-                    to remove any embedded unquoted CTLNUL characters.
-                    We do not want to turn quoted null strings back into
-                    the empty string, though.  We do this because we
-                    want to remove any quoted nulls from expansions that
-                    contain other characters.  For example, if we have
-                    x"$*"y or "x$*y" and there are no positional parameters,
-                    the $* should expand into nothing. */
-                 /* We use the W_HASQUOTEDNULL flag to differentiate the
-                    cases:  a quoted null character as above and when
-                    CTLNUL is contained in the (non-null) expansion
-                    of some variable.  We use the had_quoted_null flag to
-                    pass the value through this function to its caller. */
-                 if ((tflag & W_HASQUOTEDNULL) && QUOTED_NULL (temp) == 0)
-                   remove_quoted_nulls (temp); /* XXX */
-               }
-           }
-         else
-           temp = (char *)NULL;
-
-         /* We do not want to add quoted nulls to strings that are only
-            partially quoted; we can throw them away. */
-         if (temp == 0 && quoted_state == PARTIALLY_QUOTED)
-           continue;
-
-       add_quoted_string:
-
-         if (temp)
-           {
-             temp1 = temp;
-             temp = quote_string (temp);
-             free (temp1);
-             goto add_string;
-           }
-         else
-           {
-             /* Add NULL arg. */
-             c = CTLNUL;
-             sindex--;         /* add_character: label increments sindex */
-             goto add_character;
-           }
-
-         /* break; */
-
-       case '\'':
-#if 0
-         if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (word->flags & W_DQUOTE))
-#else
-         if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-#endif
-           goto add_character;
-
-         t_index = ++sindex;
-         temp = string_extract_single_quoted (string, &sindex);
-
-         /* If the entire STRING was surrounded by single quotes,
-            then the string is wholly quoted. */
-         quoted_state = (t_index == 1 && string[sindex] == '\0')
-                           ? WHOLLY_QUOTED
-                           : PARTIALLY_QUOTED;
-
-         /* If all we had was '', it is a null expansion. */
-         if (*temp == '\0')
-           {
-             free (temp);
-             temp = (char *)NULL;
-           }
-         else
-           remove_quoted_escapes (temp);       /* ??? */
-
-         /* We do not want to add quoted nulls to strings that are only
-            partially quoted; such nulls are discarded. */
-         if (temp == 0 && (quoted_state == PARTIALLY_QUOTED))
-           continue;
-
-         /* If we have a quoted null expansion, add a quoted NULL to istring. */
-         if (temp == 0)
-           {
-             c = CTLNUL;
-             sindex--;         /* add_character: label increments sindex */
-             goto add_character;
-           }
-         else
-           goto add_quoted_string;
-
-         /* break; */
-
-       default:
-         /* This is the fix for " $@ " */
-       add_ifs_character:
-         if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (isexp == 0 && isifs (c)))
-           {
-             if (string[sindex])       /* from old goto dollar_add_string */
-               sindex++;
-             if (c == 0)
-               {
-                 c = CTLNUL;
-                 goto add_character;
-               }
-             else
-               {
-#if HANDLE_MULTIBYTE
-                 if (MB_CUR_MAX > 1)
-                   sindex--;
-
-                 if (MB_CUR_MAX > 1)
-                   {
-                     SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
-                   }
-                 else
-#endif
-                   {
-                     twochars[0] = CTLESC;
-                     twochars[1] = c;
-                     goto add_twochars;
-                   }
-               }
-           }
-
-         SADD_MBCHAR (temp, string, sindex, string_size);
-
-       add_character:
-         RESIZE_MALLOCED_BUFFER (istring, istring_index, 1, istring_size,
-                                 DEFAULT_ARRAY_SIZE);
-         istring[istring_index++] = c;
-         istring[istring_index] = '\0';
-
-         /* Next character. */
-         sindex++;
-       }
-    }
-
-finished_with_string:
-  /* OK, we're ready to return.  If we have a quoted string, and
-     quoted_dollar_at is not set, we do no splitting at all; otherwise
-     we split on ' '.  The routines that call this will handle what to
-     do if nothing has been expanded. */
-
-  /* Partially and wholly quoted strings which expand to the empty
-     string are retained as an empty arguments.  Unquoted strings
-     which expand to the empty string are discarded.  The single
-     exception is the case of expanding "$@" when there are no
-     positional parameters.  In that case, we discard the expansion. */
-
-  /* Because of how the code that handles "" and '' in partially
-     quoted strings works, we need to make ISTRING into a QUOTED_NULL
-     if we saw quoting characters, but the expansion was empty.
-     "" and '' are tossed away before we get to this point when
-     processing partially quoted strings.  This makes "" and $xxx""
-     equivalent when xxx is unset.  We also look to see whether we
-     saw a quoted null from a ${} expansion and add one back if we
-     need to. */
-
-  /* If we expand to nothing and there were no single or double quotes
-     in the word, we throw it away.  Otherwise, we return a NULL word.
-     The single exception is for $@ surrounded by double quotes when
-     there are no positional parameters.  In that case, we also throw
-     the word away. */
-
-  if (*istring == '\0')
-    {
-      if (quoted_dollar_at == 0 && (had_quoted_null || quoted_state == PARTIALLY_QUOTED))
-       {
-         istring[0] = CTLNUL;
-         istring[1] = '\0';
-         tword = make_bare_word (istring);
-         tword->flags |= W_HASQUOTEDNULL;              /* XXX */
-         list = make_word_list (tword, (WORD_LIST *)NULL);
-         if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-           tword->flags |= W_QUOTED;
-       }
-      /* According to sh, ksh, and Posix.2, if a word expands into nothing
-        and a double-quoted "$@" appears anywhere in it, then the entire
-        word is removed. */
-      else  if (quoted_state == UNQUOTED || quoted_dollar_at)
-       list = (WORD_LIST *)NULL;
-#if 0
-      else
-       {
-         tword = make_bare_word (istring);
-         if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-           tword->flags |= W_QUOTED;
-         list = make_word_list (tword, (WORD_LIST *)NULL);
-       }
-#else
-      else
-       list = (WORD_LIST *)NULL;
-#endif
-    }
-  else if (word->flags & W_NOSPLIT)
-    {
-      tword = make_bare_word (istring);
-      if (word->flags & W_ASSIGNMENT)
-       tword->flags |= W_ASSIGNMENT;   /* XXX */
-      if (word->flags & W_COMPASSIGN)
-       tword->flags |= W_COMPASSIGN;   /* XXX */
-      if (word->flags & W_NOGLOB)
-       tword->flags |= W_NOGLOB;       /* XXX */
-      if (word->flags & W_NOEXPAND)
-       tword->flags |= W_NOEXPAND;     /* XXX */
-      if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-       tword->flags |= W_QUOTED;
-      if (had_quoted_null)
-       tword->flags |= W_HASQUOTEDNULL;
-      list = make_word_list (tword, (WORD_LIST *)NULL);
-    }
-  else
-    {
-      char *ifs_chars;
-
-      ifs_chars = (quoted_dollar_at || has_dollar_at) ? ifs_value : (char *)NULL;
-
-      /* If we have $@, we need to split the results no matter what.  If
-        IFS is unset or NULL, string_list_dollar_at has separated the
-        positional parameters with a space, so we split on space (we have
-        set ifs_chars to " \t\n" above if ifs is unset).  If IFS is set,
-        string_list_dollar_at has separated the positional parameters
-        with the first character of $IFS, so we split on $IFS. */
-      if (has_dollar_at && ifs_chars)
-       list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
-      else
-       {
-         tword = make_bare_word (istring);
-         if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED))
-           tword->flags |= W_QUOTED;
-         if (word->flags & W_ASSIGNMENT)
-           tword->flags |= W_ASSIGNMENT;
-         if (word->flags & W_COMPASSIGN)
-           tword->flags |= W_COMPASSIGN;
-         if (word->flags & W_NOGLOB)
-           tword->flags |= W_NOGLOB;
-         if (word->flags & W_NOEXPAND)
-           tword->flags |= W_NOEXPAND;
-         if (had_quoted_null)
-           tword->flags |= W_HASQUOTEDNULL;    /* XXX */
-         list = make_word_list (tword, (WORD_LIST *)NULL);
-       }
-    }
-
-  free (istring);
-  return (list);
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*                Functions for Quote Removal                      */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Perform quote removal on STRING.  If QUOTED > 0, assume we are obeying the
-   backslash quoting rules for within double quotes or a here document. */
-char *
-string_quote_removal (string, quoted)
-     char *string;
-     int quoted;
-{
-  size_t slen;
-  char *r, *result_string, *temp, *send;
-  int sindex, tindex, dquote;
-  unsigned char c;
-  DECLARE_MBSTATE;
-
-  /* The result can be no longer than the original string. */
-  slen = strlen (string);
-  send = string + slen;
-
-  r = result_string = (char *)xmalloc (slen + 1);
-
-  for (dquote = sindex = 0; c = string[sindex];)
-    {
-      switch (c)
-       {
-       case '\\':
-         c = string[++sindex];
-         if (c == 0)
-           {
-             *r++ = '\\';
-             break;
-           }
-         if (((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote) && (sh_syntaxtab[c] & CBSDQUOTE) == 0)
-           *r++ = '\\';
-         /* FALLTHROUGH */
-
-       default:
-         SCOPY_CHAR_M (r, string, send, sindex);
-         break;
-
-       case '\'':
-         if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote)
-           {
-             *r++ = c;
-             sindex++;
-             break;
-           }
-         tindex = sindex + 1;
-         temp = string_extract_single_quoted (string, &tindex);
-         if (temp)
-           {
-             strcpy (r, temp);
-             r += strlen (r);
-             free (temp);
-           }
-         sindex = tindex;
-         break;
-
-       case '"':
-         dquote = 1 - dquote;
-         sindex++;
-         break;
-       }
-    }
-    *r = '\0';
-    return (result_string);
-}
-
-#if 0
-/* UNUSED */
-/* Perform quote removal on word WORD.  This allocates and returns a new
-   WORD_DESC *. */
-WORD_DESC *
-word_quote_removal (word, quoted)
-     WORD_DESC *word;
-     int quoted;
-{
-  WORD_DESC *w;
-  char *t;
-
-  t = string_quote_removal (word->word, quoted);
-  w = alloc_word_desc ();
-  w->word = t ? t : savestring ("");
-  return (w);
-}
-
-/* Perform quote removal on all words in LIST.  If QUOTED is non-zero,
-   the members of the list are treated as if they are surrounded by
-   double quotes.  Return a new list, or NULL if LIST is NULL. */
-WORD_LIST *
-word_list_quote_removal (list, quoted)
-     WORD_LIST *list;
-     int quoted;
-{
-  WORD_LIST *result, *t, *tresult, *e;
-
-  for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
-    {
-      tresult = make_word_list (word_quote_removal (t->word, quoted), (WORD_LIST *)NULL);
-#if 0
-      result = (WORD_LIST *) list_append (result, tresult);
-#else
-      if (result == 0)
-       result = e = tresult;
-      else
-       {
-         e->next = tresult;
-         while (e->next)
-           e = e->next;
-       }
-#endif
-    }
-  return (result);
-}
-#endif
-
-/*******************************************
- *                                        *
- *    Functions to perform word splitting  *
- *                                        *
- *******************************************/
-
-void
-setifs (v)
-     SHELL_VAR *v;
-{
-  char *t;
-  unsigned char uc;
-
-  ifs_var = v;
-  ifs_value = (v && value_cell (v)) ? value_cell (v) : " \t\n";
-
-  /* Should really merge ifs_cmap with sh_syntaxtab.  XXX - doesn't yet
-     handle multibyte chars in IFS */
-  memset (ifs_cmap, '\0', sizeof (ifs_cmap));
-  for (t = ifs_value ; t && *t; t++)
-    {
-      uc = *t;
-      ifs_cmap[uc] = 1;
-    }
-
-#if defined (HANDLE_MULTIBYTE)
-  if (ifs_value == 0)
-    {
-      ifs_firstc[0] = '\0';
-      ifs_firstc_len = 1;
-    }
-  else
-    {
-      size_t ifs_len;
-      ifs_len = strnlen (ifs_value, MB_CUR_MAX);
-      ifs_firstc_len = MBLEN (ifs_value, ifs_len);
-      if (ifs_firstc_len == 1 || ifs_firstc_len == 0 || MB_INVALIDCH (ifs_firstc_len))
-       {
-         ifs_firstc[0] = ifs_value[0];
-         ifs_firstc[1] = '\0';
-         ifs_firstc_len = 1;
-       }
-      else
-       memcpy (ifs_firstc, ifs_value, ifs_firstc_len);
-    }
-#else
-  ifs_firstc = ifs_value ? *ifs_value : 0;
-#endif
-}
-
-char *
-getifs ()
-{
-  return ifs_value;
-}
-
-/* This splits a single word into a WORD LIST on $IFS, but only if the word
-   is not quoted.  list_string () performs quote removal for us, even if we
-   don't do any splitting. */
-WORD_LIST *
-word_split (w, ifs_chars)
-     WORD_DESC *w;
-     char *ifs_chars;
-{
-  WORD_LIST *result;
-
-  if (w)
-    {
-      char *xifs;
-
-      xifs = ((w->flags & W_QUOTED) || ifs_chars == 0) ? "" : ifs_chars;
-      result = list_string (w->word, xifs, w->flags & W_QUOTED);
-    }
-  else
-    result = (WORD_LIST *)NULL;
-
-  return (result);
-}
-
-/* Perform word splitting on LIST and return the RESULT.  It is possible
-   to return (WORD_LIST *)NULL. */
-static WORD_LIST *
-word_list_split (list)
-     WORD_LIST *list;
-{
-  WORD_LIST *result, *t, *tresult, *e;
-
-  for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
-    {
-      tresult = word_split (t->word, ifs_value);
-      if (result == 0)
-        result = e = tresult;
-      else
-       {
-         e->next = tresult;
-         while (e->next)
-           e = e->next;
-       }
-    }
-  return (result);
-}
-
-/**************************************************
- *                                               *
- *    Functions to expand an entire WORD_LIST    *
- *                                               *
- **************************************************/
-
-/* Do any word-expansion-specific cleanup and jump to top_level */
-static void
-exp_jump_to_top_level (v)
-     int v;
-{
-  set_pipestatus_from_exit (last_command_exit_value);
-
-  /* Cleanup code goes here. */
-  expand_no_split_dollar_star = 0;     /* XXX */
-  expanding_redir = 0;
-  assigning_in_environment = 0;
-
-  if (parse_and_execute_level == 0)
-    top_level_cleanup ();                      /* from sig.c */
-
-  jump_to_top_level (v);
-}
-
-/* Put NLIST (which is a WORD_LIST * of only one element) at the front of
-   ELIST, and set ELIST to the new list. */
-#define PREPEND_LIST(nlist, elist) \
-       do { nlist->next = elist; elist = nlist; } while (0)
-
-/* Separate out any initial variable assignments from TLIST.  If set -k has
-   been executed, remove all assignment statements from TLIST.  Initial
-   variable assignments and other environment assignments are placed
-   on SUBST_ASSIGN_VARLIST. */
-static WORD_LIST *
-separate_out_assignments (tlist)
-     WORD_LIST *tlist;
-{
-  register WORD_LIST *vp, *lp;
-
-  if (tlist == 0)
-    return ((WORD_LIST *)NULL);
-
-  if (subst_assign_varlist)
-    dispose_words (subst_assign_varlist);      /* Clean up after previous error */
-
-  subst_assign_varlist = (WORD_LIST *)NULL;
-  vp = lp = tlist;
-
-  /* Separate out variable assignments at the start of the command.
-     Loop invariant: vp->next == lp
-     Loop postcondition:
-       lp = list of words left after assignment statements skipped
-       tlist = original list of words
-  */
-  while (lp && (lp->word->flags & W_ASSIGNMENT))
-    {
-      vp = lp;
-      lp = lp->next;
-    }
-
-  /* If lp != tlist, we have some initial assignment statements.
-     We make SUBST_ASSIGN_VARLIST point to the list of assignment
-     words and TLIST point to the remaining words.  */
-  if (lp != tlist)
-    {
-      subst_assign_varlist = tlist;
-      /* ASSERT(vp->next == lp); */
-      vp->next = (WORD_LIST *)NULL;    /* terminate variable list */
-      tlist = lp;                      /* remainder of word list */
-    }
-
-  /* vp == end of variable list */
-  /* tlist == remainder of original word list without variable assignments */
-  if (!tlist)
-    /* All the words in tlist were assignment statements */
-    return ((WORD_LIST *)NULL);
-
-  /* ASSERT(tlist != NULL); */
-  /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
-
-  /* If the -k option is in effect, we need to go through the remaining
-     words, separate out the assignment words, and place them on
-     SUBST_ASSIGN_VARLIST. */
-  if (place_keywords_in_env)
-    {
-      WORD_LIST *tp;   /* tp == running pointer into tlist */
-
-      tp = tlist;
-      lp = tlist->next;
-
-      /* Loop Invariant: tp->next == lp */
-      /* Loop postcondition: tlist == word list without assignment statements */
-      while (lp)
-       {
-         if (lp->word->flags & W_ASSIGNMENT)
-           {
-             /* Found an assignment statement, add this word to end of
-                subst_assign_varlist (vp). */
-             if (!subst_assign_varlist)
-               subst_assign_varlist = vp = lp;
-             else
-               {
-                 vp->next = lp;
-                 vp = lp;
-               }
-
-             /* Remove the word pointed to by LP from TLIST. */
-             tp->next = lp->next;
-             /* ASSERT(vp == lp); */
-             lp->next = (WORD_LIST *)NULL;
-             lp = tp->next;
-           }
-         else
-           {
-             tp = lp;
-             lp = lp->next;
-           }
-       }
-    }
-  return (tlist);
-}
-
-#define WEXP_VARASSIGN 0x001
-#define WEXP_BRACEEXP  0x002
-#define WEXP_TILDEEXP  0x004
-#define WEXP_PARAMEXP  0x008
-#define WEXP_PATHEXP   0x010
-
-/* All of the expansions, including variable assignments at the start of
-   the list. */
-#define WEXP_ALL       (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
-
-/* All of the expansions except variable assignments at the start of
-   the list. */
-#define WEXP_NOVARS    (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
-
-/* All of the `shell expansions': brace expansion, tilde expansion, parameter
-   expansion, command substitution, arithmetic expansion, word splitting, and
-   quote removal. */
-#define WEXP_SHELLEXP  (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
-
-/* Take the list of words in LIST and do the various substitutions.  Return
-   a new list of words which is the expanded list, and without things like
-   variable assignments. */
-
-WORD_LIST *
-expand_words (list)
-     WORD_LIST *list;
-{
-  return (expand_word_list_internal (list, WEXP_ALL));
-}
-
-/* Same as expand_words (), but doesn't hack variable or environment
-   variables. */
-WORD_LIST *
-expand_words_no_vars (list)
-     WORD_LIST *list;
-{
-  return (expand_word_list_internal (list, WEXP_NOVARS));
-}
-
-WORD_LIST *
-expand_words_shellexp (list)
-     WORD_LIST *list;
-{
-  return (expand_word_list_internal (list, WEXP_SHELLEXP));
-}
-
-static WORD_LIST *
-glob_expand_word_list (tlist, eflags)
-     WORD_LIST *tlist;
-     int eflags;
-{
-  char **glob_array, *temp_string;
-  register int glob_index;
-  WORD_LIST *glob_list, *output_list, *disposables, *next;
-  WORD_DESC *tword;
-
-  output_list = disposables = (WORD_LIST *)NULL;
-  glob_array = (char **)NULL;
-  while (tlist)
-    {
-      /* For each word, either globbing is attempted or the word is
-        added to orig_list.  If globbing succeeds, the results are
-        added to orig_list and the word (tlist) is added to the list
-        of disposable words.  If globbing fails and failed glob
-        expansions are left unchanged (the shell default), the
-        original word is added to orig_list.  If globbing fails and
-        failed glob expansions are removed, the original word is
-        added to the list of disposable words.  orig_list ends up
-        in reverse order and requires a call to REVERSE_LIST to
-        be set right.  After all words are examined, the disposable
-        words are freed. */
-      next = tlist->next;
-
-      /* If the word isn't an assignment and contains an unquoted
-        pattern matching character, then glob it. */
-      if ((tlist->word->flags & W_NOGLOB) == 0 &&
-         unquoted_glob_pattern_p (tlist->word->word))
-       {
-         glob_array = shell_glob_filename (tlist->word->word);
-
-         /* Handle error cases.
-            I don't think we should report errors like "No such file
-            or directory".  However, I would like to report errors
-            like "Read failed". */
-
-         if (glob_array == 0 || GLOB_FAILED (glob_array))
-           {
-             glob_array = (char **)xmalloc (sizeof (char *));
-             glob_array[0] = (char *)NULL;
-           }
-
-         /* Dequote the current word in case we have to use it. */
-         if (glob_array[0] == NULL)
-           {
-             temp_string = dequote_string (tlist->word->word);
-             free (tlist->word->word);
-             tlist->word->word = temp_string;
-           }
-
-         /* Make the array into a word list. */
-         glob_list = (WORD_LIST *)NULL;
-         for (glob_index = 0; glob_array[glob_index]; glob_index++)
-           {
-             tword = make_bare_word (glob_array[glob_index]);
-             tword->flags |= W_GLOBEXP;        /* XXX */
-             glob_list = make_word_list (tword, glob_list);
-           }
-
-         if (glob_list)
-           {
-             output_list = (WORD_LIST *)list_append (glob_list, output_list);
-             PREPEND_LIST (tlist, disposables);
-           }
-         else if (fail_glob_expansion != 0)
-           {
-             report_error (_("no match: %s"), tlist->word->word);
-             exp_jump_to_top_level (DISCARD);
-           }
-         else if (allow_null_glob_expansion == 0)
-           {
-             /* Failed glob expressions are left unchanged. */
-             PREPEND_LIST (tlist, output_list);
-           }
-         else
-           {
-             /* Failed glob expressions are removed. */
-             PREPEND_LIST (tlist, disposables);
-           }
-       }
-      else
-       {
-         /* Dequote the string. */
-         temp_string = dequote_string (tlist->word->word);
-         free (tlist->word->word);
-         tlist->word->word = temp_string;
-         PREPEND_LIST (tlist, output_list);
-       }
-
-      strvec_dispose (glob_array);
-      glob_array = (char **)NULL;
-
-      tlist = next;
-    }
-
-  if (disposables)
-    dispose_words (disposables);
-
-  if (output_list)
-    output_list = REVERSE_LIST (output_list, WORD_LIST *);
-
-  return (output_list);
-}
-
-#if defined (BRACE_EXPANSION)
-static WORD_LIST *
-brace_expand_word_list (tlist, eflags)
-     WORD_LIST *tlist;
-     int eflags;
-{
-  register char **expansions;
-  char *temp_string;
-  WORD_LIST *disposables, *output_list, *next;
-  WORD_DESC *w;
-  int eindex;
-
-  for (disposables = output_list = (WORD_LIST *)NULL; tlist; tlist = next)
-    {
-      next = tlist->next;
-
-      if ((tlist->word->flags & (W_COMPASSIGN|W_ASSIGNARG)) == (W_COMPASSIGN|W_ASSIGNARG))
-        {
-/*itrace("brace_expand_word_list: %s: W_COMPASSIGN|W_ASSIGNARG", tlist->word->word);*/
-         PREPEND_LIST (tlist, output_list);
-         continue;
-        }
-          
-      /* Only do brace expansion if the word has a brace character.  If
-        not, just add the word list element to BRACES and continue.  In
-        the common case, at least when running shell scripts, this will
-        degenerate to a bunch of calls to `mbschr', and then what is
-        basically a reversal of TLIST into BRACES, which is corrected
-        by a call to REVERSE_LIST () on BRACES when the end of TLIST
-        is reached. */
-      if (mbschr (tlist->word->word, LBRACE))
-       {
-         expansions = brace_expand (tlist->word->word);
-
-         for (eindex = 0; temp_string = expansions[eindex]; eindex++)
-           {
-             w = make_word (temp_string);
-             /* If brace expansion didn't change the word, preserve
-                the flags.  We may want to preserve the flags
-                unconditionally someday -- XXX */
-             if (STREQ (temp_string, tlist->word->word))
-               w->flags = tlist->word->flags;
-             output_list = make_word_list (w, output_list);
-             free (expansions[eindex]);
-           }
-         free (expansions);
-
-         /* Add TLIST to the list of words to be freed after brace
-            expansion has been performed. */
-         PREPEND_LIST (tlist, disposables);
-       }
-      else
-       PREPEND_LIST (tlist, output_list);
-    }
-
-  if (disposables)
-    dispose_words (disposables);
-
-  if (output_list)
-    output_list = REVERSE_LIST (output_list, WORD_LIST *);
-
-  return (output_list);
-}
-#endif
-
-#if defined (ARRAY_VARS)
-/* Take WORD, a compound associative array assignment, and internally run
-   'declare -A w', where W is the variable name portion of WORD. */
-static int
-make_internal_declare (word, option)
-     char *word;
-     char *option;
-{
-  int t;
-  WORD_LIST *wl;
-  WORD_DESC *w;
-
-  w = make_word (word);
-
-  t = assignment (w->word, 0);
-  w->word[t] = '\0';
-
-  wl = make_word_list (w, (WORD_LIST *)NULL);
-  wl = make_word_list (make_word (option), wl);
-
-  return (declare_builtin (wl));  
-}  
-#endif
-
-static WORD_LIST *
-shell_expand_word_list (tlist, eflags)
-     WORD_LIST *tlist;
-     int eflags;
-{
-  WORD_LIST *expanded, *orig_list, *new_list, *next, *temp_list;
-  int expanded_something, has_dollar_at;
-  char *temp_string;
-
-  /* We do tilde expansion all the time.  This is what 1003.2 says. */
-  new_list = (WORD_LIST *)NULL;
-  for (orig_list = tlist; tlist; tlist = next)
-    {
-      temp_string = tlist->word->word;
-
-      next = tlist->next;
-
-#if defined (ARRAY_VARS)
-      /* If this is a compound array assignment to a builtin that accepts
-         such assignments (e.g., `declare'), take the assignment and perform
-         it separately, handling the semantics of declarations inside shell
-         functions.  This avoids the double-evaluation of such arguments,
-         because `declare' does some evaluation of compound assignments on
-         its own. */
-      if ((tlist->word->flags & (W_COMPASSIGN|W_ASSIGNARG)) == (W_COMPASSIGN|W_ASSIGNARG))
-       {
-         int t;
-
-         if (tlist->word->flags & W_ASSIGNASSOC)
-           make_internal_declare (tlist->word->word, "-A");
-
-         t = do_word_assignment (tlist->word);
-         if (t == 0)
-           {
-             last_command_exit_value = EXECUTION_FAILURE;
-             exp_jump_to_top_level (DISCARD);
-           }
-
-         /* Now transform the word as ksh93 appears to do and go on */
-         t = assignment (tlist->word->word, 0);
-         tlist->word->word[t] = '\0';
-         tlist->word->flags &= ~(W_ASSIGNMENT|W_NOSPLIT|W_COMPASSIGN|W_ASSIGNARG|W_ASSIGNASSOC);
-       }
-#endif
-
-      expanded_something = 0;
-      expanded = expand_word_internal
-       (tlist->word, 0, 0, &has_dollar_at, &expanded_something);
-
-      if (expanded == &expand_word_error || expanded == &expand_word_fatal)
-       {
-         /* By convention, each time this error is returned,
-            tlist->word->word has already been freed. */
-         tlist->word->word = (char *)NULL;
-
-         /* Dispose our copy of the original list. */
-         dispose_words (orig_list);
-         /* Dispose the new list we're building. */
-         dispose_words (new_list);
-
-         last_command_exit_value = EXECUTION_FAILURE;
-         if (expanded == &expand_word_error)
-           exp_jump_to_top_level (DISCARD);
-         else
-           exp_jump_to_top_level (FORCE_EOF);
-       }
-
-      /* Don't split words marked W_NOSPLIT. */
-      if (expanded_something && (tlist->word->flags & W_NOSPLIT) == 0)
-       {
-         temp_list = word_list_split (expanded);
-         dispose_words (expanded);
-       }
-      else
-       {
-         /* If no parameter expansion, command substitution, process
-            substitution, or arithmetic substitution took place, then
-            do not do word splitting.  We still have to remove quoted
-            null characters from the result. */
-         word_list_remove_quoted_nulls (expanded);
-         temp_list = expanded;
-       }
-
-      expanded = REVERSE_LIST (temp_list, WORD_LIST *);
-      new_list = (WORD_LIST *)list_append (expanded, new_list);
-    }
-
-  if (orig_list)  
-    dispose_words (orig_list);
-
-  if (new_list)
-    new_list = REVERSE_LIST (new_list, WORD_LIST *);
-
-  return (new_list);
-}
-
-/* The workhorse for expand_words () and expand_words_no_vars ().
-   First arg is LIST, a WORD_LIST of words.
-   Second arg EFLAGS is a flags word controlling which expansions are
-   performed.
-
-   This does all of the substitutions: brace expansion, tilde expansion,
-   parameter expansion, command substitution, arithmetic expansion,
-   process substitution, word splitting, and pathname expansion, according
-   to the bits set in EFLAGS.  Words with the W_QUOTED or W_NOSPLIT bits
-   set, or for which no expansion is done, do not undergo word splitting.
-   Words with the W_NOGLOB bit set do not undergo pathname expansion. */
-static WORD_LIST *
-expand_word_list_internal (list, eflags)
-     WORD_LIST *list;
-     int eflags;
-{
-  WORD_LIST *new_list, *temp_list;
-  int tint;
-
-  if (list == 0)
-    return ((WORD_LIST *)NULL);
-
-  garglist = new_list = copy_word_list (list);
-  if (eflags & WEXP_VARASSIGN)
-    {
-      garglist = new_list = separate_out_assignments (new_list);
-      if (new_list == 0)
-       {
-         if (subst_assign_varlist)
-           {
-             /* All the words were variable assignments, so they are placed
-                into the shell's environment. */
-             for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
-               {
-                 this_command_name = (char *)NULL;     /* no arithmetic errors */
-                 tint = do_word_assignment (temp_list->word);
-                 /* Variable assignment errors in non-interactive shells
-                    running in Posix.2 mode cause the shell to exit. */
-                 if (tint == 0)
-                   {
-                     last_command_exit_value = EXECUTION_FAILURE;
-                     if (interactive_shell == 0 && posixly_correct)
-                       exp_jump_to_top_level (FORCE_EOF);
-                     else
-                       exp_jump_to_top_level (DISCARD);
-                   }
-               }
-             dispose_words (subst_assign_varlist);
-             subst_assign_varlist = (WORD_LIST *)NULL;
-           }
-         return ((WORD_LIST *)NULL);
-       }
-    }
-
-  /* Begin expanding the words that remain.  The expansions take place on
-     things that aren't really variable assignments. */
-
-#if defined (BRACE_EXPANSION)
-  /* Do brace expansion on this word if there are any brace characters
-     in the string. */
-  if ((eflags & WEXP_BRACEEXP) && brace_expansion && new_list)
-    new_list = brace_expand_word_list (new_list, eflags);
-#endif /* BRACE_EXPANSION */
-
-  /* Perform the `normal' shell expansions: tilde expansion, parameter and
-     variable substitution, command substitution, arithmetic expansion,
-     and word splitting. */
-  new_list = shell_expand_word_list (new_list, eflags);
-
-  /* Okay, we're almost done.  Now let's just do some filename
-     globbing. */
-  if (new_list)
-    {
-      if ((eflags & WEXP_PATHEXP) && disallow_filename_globbing == 0)
-       /* Glob expand the word list unless globbing has been disabled. */
-       new_list = glob_expand_word_list (new_list, eflags);
-      else
-       /* Dequote the words, because we're not performing globbing. */
-       new_list = dequote_list (new_list);
-    }
-
-  if ((eflags & WEXP_VARASSIGN) && subst_assign_varlist)
-    {
-      sh_wassign_func_t *assign_func;
-
-      /* If the remainder of the words expand to nothing, Posix.2 requires
-        that the variable and environment assignments affect the shell's
-        environment. */
-      assign_func = new_list ? assign_in_env : do_word_assignment;
-      tempenv_assign_error = 0;
-
-      for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
-       {
-         this_command_name = (char *)NULL;
-         assigning_in_environment = (assign_func == assign_in_env);
-         tint = (*assign_func) (temp_list->word);
-         assigning_in_environment = 0;
-         /* Variable assignment errors in non-interactive shells running
-            in Posix.2 mode cause the shell to exit. */
-         if (tint == 0)
-           {
-             if (assign_func == do_word_assignment)
-               {
-                 last_command_exit_value = EXECUTION_FAILURE;
-                 if (interactive_shell == 0 && posixly_correct)
-                   exp_jump_to_top_level (FORCE_EOF);
-                 else
-                   exp_jump_to_top_level (DISCARD);
-               }
-             else
-               tempenv_assign_error++;
-           }
-       }
-
-      dispose_words (subst_assign_varlist);
-      subst_assign_varlist = (WORD_LIST *)NULL;
-    }
-
-#if 0
-  tint = list_length (new_list) + 1;
-  RESIZE_MALLOCED_BUFFER (glob_argv_flags, 0, tint, glob_argv_flags_size, 16);
-  for (tint = 0, temp_list = new_list; temp_list; temp_list = temp_list->next)
-    glob_argv_flags[tint++] = (temp_list->word->flags & W_GLOBEXP) ? '1' : '0';
-  glob_argv_flags[tint] = '\0';
-#endif
-
-  return (new_list);
-}
diff --git a/subst.c~ b/subst.c~
deleted file mode 100644 (file)
index 24d69ff..0000000
--- a/subst.c~
+++ /dev/null
@@ -1,9068 +0,0 @@
-/* subst.c -- The part of the shell that does parameter, command, arithmetic,
-   and globbing substitutions. */
-
-/* ``Have a little faith, there's magic in the night.  You ain't a
-     beauty, but, hey, you're alright.'' */
-
-/* Copyright (C) 1987-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/>.
-*/
-
-#include "config.h"
-
-#include "bashtypes.h"
-#include <stdio.h>
-#include "chartypes.h"
-#if defined (HAVE_PWD_H)
-#  include <pwd.h>
-#endif
-#include <signal.h>
-#include <errno.h>
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include "bashansi.h"
-#include "posixstat.h"
-#include "bashintl.h"
-
-#include "shell.h"
-#include "flags.h"
-#include "jobs.h"
-#include "execute_cmd.h"
-#include "filecntl.h"
-#include "trap.h"
-#include "pathexp.h"
-#include "mailcheck.h"
-
-#include "shmbutil.h"
-
-#include "builtins/getopt.h"
-#include "builtins/common.h"
-
-#include "builtins/builtext.h"
-
-#include <tilde/tilde.h>
-#include <glob/strmatch.h>
-
-#if !defined (errno)
-extern int errno;
-#endif /* !errno */
-
-/* The size that strings change by. */
-#define DEFAULT_INITIAL_ARRAY_SIZE 112
-#define DEFAULT_ARRAY_SIZE 128
-
-/* Variable types. */
-#define VT_VARIABLE    0
-#define VT_POSPARMS    1
-#define VT_ARRAYVAR    2
-#define VT_ARRAYMEMBER 3
-#define VT_ASSOCVAR    4
-
-#define VT_STARSUB     128     /* $* or ${array[*]} -- used to split */
-
-/* Flags for quoted_strchr */
-#define ST_BACKSL      0x01
-#define ST_CTLESC      0x02
-#define ST_SQUOTE      0x04    /* unused yet */
-#define ST_DQUOTE      0x08    /* unused yet */
-
-/* Flags for the `pflags' argument to param_expand() */
-#define PF_NOCOMSUB    0x01    /* Do not perform command substitution */
-#define PF_IGNUNBOUND  0x02    /* ignore unbound vars even if -u set */
-#define PF_NOSPLIT2    0x04    /* same as W_NOSPLIT2 */
-
-/* These defs make it easier to use the editor. */
-#define LBRACE         '{'
-#define RBRACE         '}'
-#define LPAREN         '('
-#define RPAREN         ')'
-
-#if defined (HANDLE_MULTIBYTE)
-#define WLPAREN                L'('
-#define WRPAREN                L')'
-#endif
-
-/* Evaluates to 1 if C is one of the shell's special parameters whose length
-   can be taken, but is also one of the special expansion characters. */
-#define VALID_SPECIAL_LENGTH_PARAM(c) \
-  ((c) == '-' || (c) == '?' || (c) == '#')
-
-/* Evaluates to 1 if C is one of the shell's special parameters for which an
-   indirect variable reference may be made. */
-#define VALID_INDIR_PARAM(c) \
-  ((c) == '#' || (c) == '?' || (c) == '@' || (c) == '*')
-
-/* Evaluates to 1 if C is one of the OP characters that follows the parameter
-   in ${parameter[:]OPword}. */
-#define VALID_PARAM_EXPAND_CHAR(c) (sh_syntaxtab[(unsigned char)c] & CSUBSTOP)
-
-/* Evaluates to 1 if this is one of the shell's special variables. */
-#define SPECIAL_VAR(name, wi) \
- ((DIGIT (*name) && all_digits (name)) || \
-      (name[1] == '\0' && (sh_syntaxtab[(unsigned char)*name] & CSPECVAR)) || \
-      (wi && name[2] == '\0' && VALID_INDIR_PARAM (name[1])))
-
-/* An expansion function that takes a string and a quoted flag and returns
-   a WORD_LIST *.  Used as the type of the third argument to
-   expand_string_if_necessary(). */
-typedef WORD_LIST *EXPFUNC __P((char *, int));
-
-/* Process ID of the last command executed within command substitution. */
-pid_t last_command_subst_pid = NO_PID;
-pid_t current_command_subst_pid = NO_PID;
-
-/* Variables used to keep track of the characters in IFS. */
-SHELL_VAR *ifs_var;
-char *ifs_value;
-unsigned char ifs_cmap[UCHAR_MAX + 1];
-
-#if defined (HANDLE_MULTIBYTE)
-unsigned char ifs_firstc[MB_LEN_MAX];
-size_t ifs_firstc_len;
-#else
-unsigned char ifs_firstc;
-#endif
-
-/* Sentinel to tell when we are performing variable assignments preceding a
-   command name and putting them into the environment.  Used to make sure
-   we use the temporary environment when looking up variable values. */
-int assigning_in_environment;
-
-/* Used to hold a list of variable assignments preceding a command.  Global
-   so the SIGCHLD handler in jobs.c can unwind-protect it when it runs a
-   SIGCHLD trap and so it can be saved and restored by the trap handlers. */
-WORD_LIST *subst_assign_varlist = (WORD_LIST *)NULL;
-
-/* Extern functions and variables from different files. */
-extern int last_command_exit_value, last_command_exit_signal;
-extern int subshell_environment, line_number;
-extern int subshell_level, parse_and_execute_level, sourcelevel;
-extern int eof_encountered;
-extern int return_catch_flag, return_catch_value;
-extern pid_t dollar_dollar_pid;
-extern int posixly_correct;
-extern char *this_command_name;
-extern struct fd_bitmap *current_fds_to_close;
-extern int wordexp_only;
-extern int expanding_redir;
-extern int tempenv_assign_error;
-
-#if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE)
-extern wchar_t *wcsdup __P((const wchar_t *));
-#endif
-
-/* Non-zero means to allow unmatched globbed filenames to expand to
-   a null file. */
-int allow_null_glob_expansion;
-
-/* Non-zero means to throw an error when globbing fails to match anything. */
-int fail_glob_expansion;
-
-#if 0
-/* Variables to keep track of which words in an expanded word list (the
-   output of expand_word_list_internal) are the result of globbing
-   expansions.  GLOB_ARGV_FLAGS is used by execute_cmd.c.
-   (CURRENTLY UNUSED). */
-char *glob_argv_flags;
-static int glob_argv_flags_size;
-#endif
-
-static WORD_LIST expand_word_error, expand_word_fatal;
-static WORD_DESC expand_wdesc_error, expand_wdesc_fatal;
-static char expand_param_error, expand_param_fatal;
-static char extract_string_error, extract_string_fatal;
-
-/* Tell the expansion functions to not longjmp back to top_level on fatal
-   errors.  Enabled when doing completion and prompt string expansion. */
-static int no_longjmp_on_fatal_error = 0;
-
-/* Set by expand_word_unsplit; used to inhibit splitting and re-joining
-   $* on $IFS, primarily when doing assignment statements. */
-static int expand_no_split_dollar_star = 0;
-
-/* A WORD_LIST of words to be expanded by expand_word_list_internal,
-   without any leading variable assignments. */
-static WORD_LIST *garglist = (WORD_LIST *)NULL;
-
-static char *quoted_substring __P((char *, int, int));
-static int quoted_strlen __P((char *));
-static char *quoted_strchr __P((char *, int, int));
-
-static char *expand_string_if_necessary __P((char *, int, EXPFUNC *));
-static inline char *expand_string_to_string_internal __P((char *, int, EXPFUNC *));
-static WORD_LIST *call_expand_word_internal __P((WORD_DESC *, int, int, int *, int *));
-static WORD_LIST *expand_string_internal __P((char *, int));
-static WORD_LIST *expand_string_leave_quoted __P((char *, int));
-static WORD_LIST *expand_string_for_rhs __P((char *, int, int *, int *));
-
-static WORD_LIST *list_quote_escapes __P((WORD_LIST *));
-static char *make_quoted_char __P((int));
-static WORD_LIST *quote_list __P((WORD_LIST *));
-
-static int unquoted_substring __P((char *, char *));
-static int unquoted_member __P((int, char *));
-
-#if defined (ARRAY_VARS)
-static SHELL_VAR *do_compound_assignment __P((char *, char *, int));
-#endif
-static int do_assignment_internal __P((const WORD_DESC *, int));
-
-static char *string_extract_verbatim __P((char *, size_t, int *, char *, int));
-static char *string_extract __P((char *, int *, char *, int));
-static char *string_extract_double_quoted __P((char *, int *, int));
-static inline char *string_extract_single_quoted __P((char *, int *));
-static inline int skip_single_quoted __P((const char *, size_t, int));
-static int skip_double_quoted __P((char *, size_t, int));
-static char *extract_delimited_string __P((char *, int *, char *, char *, char *, int));
-static char *extract_dollar_brace_string __P((char *, int *, int, int));
-static int skip_matched_pair __P((const char *, int, int, int, int));
-
-static char *pos_params __P((char *, int, int, int));
-
-static unsigned char *mb_getcharlens __P((char *, int));
-
-static char *remove_upattern __P((char *, char *, int));
-#if defined (HANDLE_MULTIBYTE) 
-static wchar_t *remove_wpattern __P((wchar_t *, size_t, wchar_t *, int));
-#endif
-static char *remove_pattern __P((char *, char *, int));
-
-static int match_pattern_char __P((char *, char *));
-static int match_upattern __P((char *, char *, int, char **, char **));
-#if defined (HANDLE_MULTIBYTE)
-static int match_pattern_wchar __P((wchar_t *, wchar_t *));
-static int match_wpattern __P((wchar_t *, char **, size_t, wchar_t *, int, char **, char **));
-#endif
-static int match_pattern __P((char *, char *, int, char **, char **));
-static int getpatspec __P((int, char *));
-static char *getpattern __P((char *, int, int));
-static char *variable_remove_pattern __P((char *, char *, int, int));
-static char *list_remove_pattern __P((WORD_LIST *, char *, int, int, int));
-static char *parameter_list_remove_pattern __P((int, char *, int, int));
-#ifdef ARRAY_VARS
-static char *array_remove_pattern __P((SHELL_VAR *, char *, int, char *, int));
-#endif
-static char *parameter_brace_remove_pattern __P((char *, char *, char *, int, int));
-
-static char *process_substitute __P((char *, int));
-
-static char *read_comsub __P((int, int, int *));
-
-#ifdef ARRAY_VARS
-static arrayind_t array_length_reference __P((char *));
-#endif
-
-static int valid_brace_expansion_word __P((char *, int));
-static int chk_atstar __P((char *, int, int *, int *));
-static int chk_arithsub __P((const char *, int));
-
-static WORD_DESC *parameter_brace_expand_word __P((char *, int, int, int));
-static WORD_DESC *parameter_brace_expand_indir __P((char *, int, int, int *, int *));
-static WORD_DESC *parameter_brace_expand_rhs __P((char *, char *, int, int, int *, int *));
-static void parameter_brace_expand_error __P((char *, char *));
-
-static int valid_length_expression __P((char *));
-static intmax_t parameter_brace_expand_length __P((char *));
-
-static char *skiparith __P((char *, int));
-static int verify_substring_values __P((SHELL_VAR *, char *, char *, int, intmax_t *, intmax_t *));
-static int get_var_and_type __P((char *, char *, int, SHELL_VAR **, char **));
-static char *mb_substring __P((char *, int, int));
-static char *parameter_brace_substring __P((char *, char *, char *, int));
-
-static char *pos_params_pat_subst __P((char *, char *, char *, int));
-
-static char *parameter_brace_patsub __P((char *, char *, char *, int));
-
-static char *pos_params_casemod __P((char *, char *, int, int));
-static char *parameter_brace_casemod __P((char *, char *, int, char *, int));
-
-static WORD_DESC *parameter_brace_expand __P((char *, int *, int, int, int *, int *));
-static WORD_DESC *param_expand __P((char *, int *, int, int *, int *, int *, int *, int));
-
-static WORD_LIST *expand_word_internal __P((WORD_DESC *, int, int, int *, int *));
-
-static WORD_LIST *word_list_split __P((WORD_LIST *));
-
-static void exp_jump_to_top_level __P((int));
-
-static WORD_LIST *separate_out_assignments __P((WORD_LIST *));
-static WORD_LIST *glob_expand_word_list __P((WORD_LIST *, int));
-#ifdef BRACE_EXPANSION
-static WORD_LIST *brace_expand_word_list __P((WORD_LIST *, int));
-#endif
-#if defined (ARRAY_VARS)
-static int make_internal_declare __P((char *, char *));
-#endif
-static WORD_LIST *shell_expand_word_list __P((WORD_LIST *, int));
-static WORD_LIST *expand_word_list_internal __P((WORD_LIST *, int));
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Utility Functions                           */
-/*                                                                 */
-/* **************************************************************** */
-
-#if defined (DEBUG)
-void
-dump_word_flags (flags)
-     int flags;
-{
-  int f;
-
-  f = flags;
-  fprintf (stderr, "%d -> ", f);
-  if (f & W_ASSIGNASSOC)
-    {
-      f &= ~W_ASSIGNASSOC;
-      fprintf (stderr, "W_ASSIGNASSOC%s", f ? "|" : "");
-    }
-  if (f & W_HASCTLESC)
-    {
-      f &= ~W_HASCTLESC;
-      fprintf (stderr, "W_HASCTLESC%s", f ? "|" : "");
-    }
-  if (f & W_NOPROCSUB)
-    {
-      f &= ~W_NOPROCSUB;
-      fprintf (stderr, "W_NOPROCSUB%s", f ? "|" : "");
-    }
-  if (f & W_DQUOTE)
-    {
-      f &= ~W_DQUOTE;
-      fprintf (stderr, "W_DQUOTE%s", f ? "|" : "");
-    }
-  if (f & W_HASQUOTEDNULL)
-    {
-      f &= ~W_HASQUOTEDNULL;
-      fprintf (stderr, "W_HASQUOTEDNULL%s", f ? "|" : "");
-    }
-  if (f & W_ASSIGNARG)
-    {
-      f &= ~W_ASSIGNARG;
-      fprintf (stderr, "W_ASSIGNARG%s", f ? "|" : "");
-    }
-  if (f & W_ASSNBLTIN)
-    {
-      f &= ~W_ASSNBLTIN;
-      fprintf (stderr, "W_ASSNBLTIN%s", f ? "|" : "");
-    }
-  if (f & W_COMPASSIGN)
-    {
-      f &= ~W_COMPASSIGN;
-      fprintf (stderr, "W_COMPASSIGN%s", f ? "|" : "");
-    }
-  if (f & W_NOEXPAND)
-    {
-      f &= ~W_NOEXPAND;
-      fprintf (stderr, "W_NOEXPAND%s", f ? "|" : "");
-    }
-  if (f & W_ITILDE)
-    {
-      f &= ~W_ITILDE;
-      fprintf (stderr, "W_ITILDE%s", f ? "|" : "");
-    }
-  if (f & W_NOTILDE)
-    {
-      f &= ~W_NOTILDE;
-      fprintf (stderr, "W_NOTILDE%s", f ? "|" : "");
-    }
-  if (f & W_ASSIGNRHS)
-    {
-      f &= ~W_ASSIGNRHS;
-      fprintf (stderr, "W_ASSIGNRHS%s", f ? "|" : "");
-    }
-  if (f & W_NOCOMSUB)
-    {
-      f &= ~W_NOCOMSUB;
-      fprintf (stderr, "W_NOCOMSUB%s", f ? "|" : "");
-    }
-  if (f & W_DOLLARSTAR)
-    {
-      f &= ~W_DOLLARSTAR;
-      fprintf (stderr, "W_DOLLARSTAR%s", f ? "|" : "");
-    }
-  if (f & W_DOLLARAT)
-    {
-      f &= ~W_DOLLARAT;
-      fprintf (stderr, "W_DOLLARAT%s", f ? "|" : "");
-    }
-  if (f & W_TILDEEXP)
-    {
-      f &= ~W_TILDEEXP;
-      fprintf (stderr, "W_TILDEEXP%s", f ? "|" : "");
-    }
-  if (f & W_NOSPLIT2)
-    {
-      f &= ~W_NOSPLIT2;
-      fprintf (stderr, "W_NOSPLIT2%s", f ? "|" : "");
-    }
-  if (f & W_NOGLOB)
-    {
-      f &= ~W_NOGLOB;
-      fprintf (stderr, "W_NOGLOB%s", f ? "|" : "");
-    }
-  if (f & W_NOSPLIT)
-    {
-      f &= ~W_NOSPLIT;
-      fprintf (stderr, "W_NOSPLIT%s", f ? "|" : "");
-    }
-  if (f & W_GLOBEXP)
-    {
-      f &= ~W_GLOBEXP;
-      fprintf (stderr, "W_GLOBEXP%s", f ? "|" : "");
-    }
-  if (f & W_ASSIGNMENT)
-    {
-      f &= ~W_ASSIGNMENT;
-      fprintf (stderr, "W_ASSIGNMENT%s", f ? "|" : "");
-    }
-  if (f & W_QUOTED)
-    {
-      f &= ~W_QUOTED;
-      fprintf (stderr, "W_QUOTED%s", f ? "|" : "");
-    }
-  if (f & W_HASDOLLAR)
-    {
-      f &= ~W_HASDOLLAR;
-      fprintf (stderr, "W_HASDOLLAR%s", f ? "|" : "");
-    }
-  fprintf (stderr, "\n");
-  fflush (stderr);
-}
-#endif
-
-#ifdef INCLUDE_UNUSED
-static char *
-quoted_substring (string, start, end)
-     char *string;
-     int start, end;
-{
-  register int len, l;
-  register char *result, *s, *r;
-
-  len = end - start;
-
-  /* Move to string[start], skipping quoted characters. */
-  for (s = string, l = 0; *s && l < start; )
-    {
-      if (*s == CTLESC)
-       {
-         s++;
-         continue;
-       }
-      l++;
-      if (*s == 0)
-       break;
-    }
-
-  r = result = (char *)xmalloc (2*len + 1);      /* save room for quotes */
-
-  /* Copy LEN characters, including quote characters. */
-  s = string + l;
-  for (l = 0; l < len; s++)
-    {
-      if (*s == CTLESC)
-       *r++ = *s++;
-      *r++ = *s;
-      l++;
-      if (*s == 0)
-       break;
-    }
-  *r = '\0';
-  return result;
-}
-#endif
-
-#ifdef INCLUDE_UNUSED
-/* Return the length of S, skipping over quoted characters */
-static int
-quoted_strlen (s)
-     char *s;
-{
-  register char *p;
-  int i;
-
-  i = 0;
-  for (p = s; *p; p++)
-    {
-      if (*p == CTLESC)
-       {
-         p++;
-         if (*p == 0)
-           return (i + 1);
-       }
-      i++;
-    }
-
-  return i;
-}
-#endif
-
-/* Find the first occurrence of character C in string S, obeying shell
-   quoting rules.  If (FLAGS & ST_BACKSL) is non-zero, backslash-escaped
-   characters are skipped.  If (FLAGS & ST_CTLESC) is non-zero, characters
-   escaped with CTLESC are skipped. */
-static char *
-quoted_strchr (s, c, flags)
-     char *s;
-     int c, flags;
-{
-  register char *p;
-
-  for (p = s; *p; p++)
-    {
-      if (((flags & ST_BACKSL) && *p == '\\')
-           || ((flags & ST_CTLESC) && *p == CTLESC))
-       {
-         p++;
-         if (*p == '\0')
-           return ((char *)NULL);
-         continue;
-       }
-      else if (*p == c)
-       return p;
-    }
-  return ((char *)NULL);
-}
-
-/* Return 1 if CHARACTER appears in an unquoted portion of
-   STRING.  Return 0 otherwise.  CHARACTER must be a single-byte character. */
-static int
-unquoted_member (character, string)
-     int character;
-     char *string;
-{
-  size_t slen;
-  int sindex, c;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string);
-  sindex = 0;
-  while (c = string[sindex])
-    {
-      if (c == character)
-       return (1);
-
-      switch (c)
-       {
-       default:
-         ADVANCE_CHAR (string, slen, sindex);
-         break;
-
-       case '\\':
-         sindex++;
-         if (string[sindex])
-           ADVANCE_CHAR (string, slen, sindex);
-         break;
-
-       case '\'':
-         sindex = skip_single_quoted (string, slen, ++sindex);
-         break;
-
-       case '"':
-         sindex = skip_double_quoted (string, slen, ++sindex);
-         break;
-       }
-    }
-  return (0);
-}
-
-/* Return 1 if SUBSTR appears in an unquoted portion of STRING. */
-static int
-unquoted_substring (substr, string)
-     char *substr, *string;
-{
-  size_t slen;
-  int sindex, c, sublen;
-  DECLARE_MBSTATE;
-
-  if (substr == 0 || *substr == '\0')
-    return (0);
-
-  slen = strlen (string);
-  sublen = strlen (substr);
-  for (sindex = 0; c = string[sindex]; )
-    {
-      if (STREQN (string + sindex, substr, sublen))
-       return (1);
-
-      switch (c)
-       {
-       case '\\':
-         sindex++;
-
-         if (string[sindex])
-           ADVANCE_CHAR (string, slen, sindex);
-         break;
-
-       case '\'':
-         sindex = skip_single_quoted (string, slen, ++sindex);
-         break;
-
-       case '"':
-         sindex = skip_double_quoted (string, slen, ++sindex);
-         break;
-
-       default:
-         ADVANCE_CHAR (string, slen, sindex);
-         break;
-       }
-    }
-  return (0);
-}
-
-/* Most of the substitutions must be done in parallel.  In order
-   to avoid using tons of unclear goto's, I have some functions
-   for manipulating malloc'ed strings.  They all take INDX, a
-   pointer to an integer which is the offset into the string
-   where manipulation is taking place.  They also take SIZE, a
-   pointer to an integer which is the current length of the
-   character array for this string. */
-
-/* Append SOURCE to TARGET at INDEX.  SIZE is the current amount
-   of space allocated to TARGET.  SOURCE can be NULL, in which
-   case nothing happens.  Gets rid of SOURCE by freeing it.
-   Returns TARGET in case the location has changed. */
-INLINE char *
-sub_append_string (source, target, indx, size)
-     char *source, *target;
-     int *indx, *size;
-{
-  if (source)
-    {
-      int srclen, n;
-
-      srclen = STRLEN (source);
-      if (srclen >= (int)(*size - *indx))
-       {
-         n = srclen + *indx;
-         n = (n + DEFAULT_ARRAY_SIZE) - (n % DEFAULT_ARRAY_SIZE);
-         target = (char *)xrealloc (target, (*size = n));
-       }
-
-      FASTCOPY (source, target + *indx, srclen);
-      *indx += srclen;
-      target[*indx] = '\0';
-
-      free (source);
-    }
-  return (target);
-}
-
-#if 0
-/* UNUSED */
-/* Append the textual representation of NUMBER to TARGET.
-   INDX and SIZE are as in SUB_APPEND_STRING. */
-char *
-sub_append_number (number, target, indx, size)
-     intmax_t number;
-     int *indx, *size;
-     char *target;
-{
-  char *temp;
-
-  temp = itos (number);
-  return (sub_append_string (temp, target, indx, size));
-}
-#endif
-
-/* Extract a substring from STRING, starting at SINDEX and ending with
-   one of the characters in CHARLIST.  Don't make the ending character
-   part of the string.  Leave SINDEX pointing at the ending character.
-   Understand about backslashes in the string.  If (flags & SX_VARNAME)
-   is non-zero, and array variables have been compiled into the shell,
-   everything between a `[' and a corresponding `]' is skipped over.
-   If (flags & SX_NOALLOC) is non-zero, don't return the substring, just
-   update SINDEX.  If (flags & SX_REQMATCH) is non-zero, the string must
-   contain a closing character from CHARLIST. */
-static char *
-string_extract (string, sindex, charlist, flags)
-     char *string;
-     int *sindex;
-     char *charlist;
-     int flags;
-{
-  register int c, i;
-  int found;
-  size_t slen;
-  char *temp;
-  DECLARE_MBSTATE;
-
-  slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0;
-  i = *sindex;
-  found = 0;
-  while (c = string[i])
-    {
-      if (c == '\\')
-       {
-         if (string[i + 1])
-           i++;
-         else
-           break;
-       }
-#if defined (ARRAY_VARS)
-      else if ((flags & SX_VARNAME) && c == '[')
-       {
-         int ni;
-         /* If this is an array subscript, skip over it and continue. */
-         ni = skipsubscript (string, i, 0);
-         if (string[ni] == ']')
-           i = ni;
-       }
-#endif
-      else if (MEMBER (c, charlist))
-       {
-         found = 1;
-         break;
-       }
-
-      ADVANCE_CHAR (string, slen, i);
-    }
-
-  /* If we had to have a matching delimiter and didn't find one, return an
-     error and let the caller deal with it. */
-  if ((flags & SX_REQMATCH) && found == 0)
-    {
-      *sindex = i;
-      return (&extract_string_error);
-    }
-  
-  temp = (flags & SX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i);
-  *sindex = i;
-  
-  return (temp);
-}
-
-/* Extract the contents of STRING as if it is enclosed in double quotes.
-   SINDEX, when passed in, is the offset of the character immediately
-   following the opening double quote; on exit, SINDEX is left pointing after
-   the closing double quote.  If STRIPDQ is non-zero, unquoted double
-   quotes are stripped and the string is terminated by a null byte.
-   Backslashes between the embedded double quotes are processed.  If STRIPDQ
-   is zero, an unquoted `"' terminates the string. */
-static char *
-string_extract_double_quoted (string, sindex, stripdq)
-     char *string;
-     int *sindex, stripdq;
-{
-  size_t slen;
-  char *send;
-  int j, i, t;
-  unsigned char c;
-  char *temp, *ret;            /* The new string we return. */
-  int pass_next, backquote, si;        /* State variables for the machine. */
-  int dquote;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string + *sindex) + *sindex;
-  send = string + slen;
-
-  pass_next = backquote = dquote = 0;
-  temp = (char *)xmalloc (1 + slen - *sindex);
-
-  j = 0;
-  i = *sindex;
-  while (c = string[i])
-    {
-      /* Process a character that was quoted by a backslash. */
-      if (pass_next)
-       {
-         /* Posix.2 sez:
-
-            ``The backslash shall retain its special meaning as an escape
-            character only when followed by one of the characters:
-               $       `       "       \       <newline>''.
-
-            If STRIPDQ is zero, we handle the double quotes here and let
-            expand_word_internal handle the rest.  If STRIPDQ is non-zero,
-            we have already been through one round of backslash stripping,
-            and want to strip these backslashes only if DQUOTE is non-zero,
-            indicating that we are inside an embedded double-quoted string. */
-
-            /* If we are in an embedded quoted string, then don't strip
-               backslashes before characters for which the backslash
-               retains its special meaning, but remove backslashes in
-               front of other characters.  If we are not in an
-               embedded quoted string, don't strip backslashes at all.
-               This mess is necessary because the string was already
-               surrounded by double quotes (and sh has some really weird
-               quoting rules).
-               The returned string will be run through expansion as if
-               it were double-quoted. */
-         if ((stripdq == 0 && c != '"') ||
-             (stripdq && ((dquote && (sh_syntaxtab[c] & CBSDQUOTE)) || dquote == 0)))
-           temp[j++] = '\\';
-         pass_next = 0;
-
-add_one_character:
-         COPY_CHAR_I (temp, j, string, send, i);
-         continue;
-       }
-
-      /* A backslash protects the next character.  The code just above
-        handles preserving the backslash in front of any character but
-        a double quote. */
-      if (c == '\\')
-       {
-         pass_next++;
-         i++;
-         continue;
-       }
-
-      /* Inside backquotes, ``the portion of the quoted string from the
-        initial backquote and the characters up to the next backquote
-        that is not preceded by a backslash, having escape characters
-        removed, defines that command''. */
-      if (backquote)
-       {
-         if (c == '`')
-           backquote = 0;
-         temp[j++] = c;
-         i++;
-         continue;
-       }
-
-      if (c == '`')
-       {
-         temp[j++] = c;
-         backquote++;
-         i++;
-         continue;
-       }
-
-      /* Pass everything between `$(' and the matching `)' or a quoted
-        ${ ... } pair through according to the Posix.2 specification. */
-      if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
-       {
-         int free_ret = 1;
-
-         si = i + 2;
-         if (string[i + 1] == LPAREN)
-           ret = extract_command_subst (string, &si, 0);
-         else
-           ret = extract_dollar_brace_string (string, &si, 1, 0);
-
-         temp[j++] = '$';
-         temp[j++] = string[i + 1];
-
-         /* Just paranoia; ret will not be 0 unless no_longjmp_on_fatal_error
-            is set. */
-         if (ret == 0 && no_longjmp_on_fatal_error)
-           {
-             free_ret = 0;
-             ret = string + i + 2;
-           }
-
-         for (t = 0; ret[t]; t++, j++)
-           temp[j] = ret[t];
-         temp[j] = string[si];
-
-         if (string[si])
-           {
-             j++;
-             i = si + 1;
-           }
-         else
-           i = si;
-
-         if (free_ret)
-           free (ret);
-         continue;
-       }
-
-      /* Add any character but a double quote to the quoted string we're
-        accumulating. */
-      if (c != '"')
-       goto add_one_character;
-
-      /* c == '"' */
-      if (stripdq)
-       {
-         dquote ^= 1;
-         i++;
-         continue;
-       }
-
-      break;
-    }
-  temp[j] = '\0';
-
-  /* Point to after the closing quote. */
-  if (c)
-    i++;
-  *sindex = i;
-
-  return (temp);
-}
-
-/* This should really be another option to string_extract_double_quoted. */
-static int
-skip_double_quoted (string, slen, sind)
-     char *string;
-     size_t slen;
-     int sind;
-{
-  int c, i;
-  char *ret;
-  int pass_next, backquote, si;
-  DECLARE_MBSTATE;
-
-  pass_next = backquote = 0;
-  i = sind;
-  while (c = string[i])
-    {
-      if (pass_next)
-       {
-         pass_next = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (c == '\\')
-       {
-         pass_next++;
-         i++;
-         continue;
-       }
-      else if (backquote)
-       {
-         if (c == '`')
-           backquote = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (c == '`')
-       {
-         backquote++;
-         i++;
-         continue;
-       }
-      else if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
-       {
-         si = i + 2;
-         if (string[i + 1] == LPAREN)
-           ret = extract_command_subst (string, &si, SX_NOALLOC);
-         else
-           ret = extract_dollar_brace_string (string, &si, 1, SX_NOALLOC);
-
-         i = si + 1;
-         continue;
-       }
-      else if (c != '"')
-       {
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else
-       break;
-    }
-
-  if (c)
-    i++;
-
-  return (i);
-}
-
-/* Extract the contents of STRING as if it is enclosed in single quotes.
-   SINDEX, when passed in, is the offset of the character immediately
-   following the opening single quote; on exit, SINDEX is left pointing after
-   the closing single quote. */
-static inline char *
-string_extract_single_quoted (string, sindex)
-     char *string;
-     int *sindex;
-{
-  register int i;
-  size_t slen;
-  char *t;
-  DECLARE_MBSTATE;
-
-  /* Don't need slen for ADVANCE_CHAR unless multibyte chars possible. */
-  slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0;
-  i = *sindex;
-  while (string[i] && string[i] != '\'')
-    ADVANCE_CHAR (string, slen, i);
-
-  t = substring (string, *sindex, i);
-
-  if (string[i])
-    i++;
-  *sindex = i;
-
-  return (t);
-}
-
-static inline int
-skip_single_quoted (string, slen, sind)
-     const char *string;
-     size_t slen;
-     int sind;
-{
-  register int c;
-  DECLARE_MBSTATE;
-
-  c = sind;
-  while (string[c] && string[c] != '\'')
-    ADVANCE_CHAR (string, slen, c);
-
-  if (string[c])
-    c++;
-  return c;
-}
-
-/* Just like string_extract, but doesn't hack backslashes or any of
-   that other stuff.  Obeys CTLESC quoting.  Used to do splitting on $IFS. */
-static char *
-string_extract_verbatim (string, slen, sindex, charlist, flags)
-     char *string;
-     size_t slen;
-     int *sindex;
-     char *charlist;
-     int flags;
-{
-  register int i;
-#if defined (HANDLE_MULTIBYTE)
-  size_t clen;
-  wchar_t *wcharlist;
-#endif
-  int c;
-  char *temp;
-  DECLARE_MBSTATE;
-
-  if (charlist[0] == '\'' && charlist[1] == '\0')
-    {
-      temp = string_extract_single_quoted (string, sindex);
-      --*sindex;       /* leave *sindex at separator character */
-      return temp;
-    }
-
-  i = *sindex;
-#if 0
-  /* See how the MBLEN and ADVANCE_CHAR macros work to understand why we need
-     this only if MB_CUR_MAX > 1. */
-  slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 1;
-#endif
-#if defined (HANDLE_MULTIBYTE)
-  clen = strlen (charlist);
-  wcharlist = 0;
-#endif
-  while (c = string[i])
-    {
-#if defined (HANDLE_MULTIBYTE)
-      size_t mblength;
-#endif
-      if ((flags & SX_NOCTLESC) == 0 && c == CTLESC)
-       {
-         i += 2;
-         continue;
-       }
-      /* Even if flags contains SX_NOCTLESC, we let CTLESC quoting CTLNUL
-        through, to protect the CTLNULs from later calls to
-        remove_quoted_nulls. */
-      else if ((flags & SX_NOESCCTLNUL) == 0 && c == CTLESC && string[i+1] == CTLNUL)
-       {
-         i += 2;
-         continue;
-       }
-
-#if defined (HANDLE_MULTIBYTE)
-      mblength = MBLEN (string + i, slen - i);
-      if (mblength > 1)
-       {
-         wchar_t wc;
-         mblength = mbtowc (&wc, string + i, slen - i);
-         if (MB_INVALIDCH (mblength))
-           {
-             if (MEMBER (c, charlist))
-               break;
-           }
-         else
-           {
-             if (wcharlist == 0)
-               {
-                 size_t len;
-                 len = mbstowcs (wcharlist, charlist, 0);
-                 if (len == -1)
-                   len = 0;
-                 wcharlist = (wchar_t *)xmalloc (sizeof (wchar_t) * (len + 1));
-                 mbstowcs (wcharlist, charlist, len + 1);
-               }
-
-             if (wcschr (wcharlist, wc))
-               break;
-           }
-       }
-      else             
-#endif
-      if (MEMBER (c, charlist))
-       break;
-
-      ADVANCE_CHAR (string, slen, i);
-    }
-
-#if defined (HANDLE_MULTIBYTE)
-  FREE (wcharlist);
-#endif
-
-  temp = substring (string, *sindex, i);
-  *sindex = i;
-
-  return (temp);
-}
-
-/* Extract the $( construct in STRING, and return a new string.
-   Start extracting at (SINDEX) as if we had just seen "$(".
-   Make (SINDEX) get the position of the matching ")". )
-   XFLAGS is additional flags to pass to other extraction functions. */
-char *
-extract_command_subst (string, sindex, xflags)
-     char *string;
-     int *sindex;
-     int xflags;
-{
-  if (string[*sindex] == LPAREN)
-    return (extract_delimited_string (string, sindex, "$(", "(", ")", xflags|SX_COMMAND)); /*)*/
-  else
-    {
-      xflags |= (no_longjmp_on_fatal_error ? SX_NOLONGJMP : 0);
-      return (xparse_dolparen (string, string+*sindex, sindex, xflags));
-    }
-}
-
-/* Extract the $[ construct in STRING, and return a new string. (])
-   Start extracting at (SINDEX) as if we had just seen "$[".
-   Make (SINDEX) get the position of the matching "]". */
-char *
-extract_arithmetic_subst (string, sindex)
-     char *string;
-     int *sindex;
-{
-  return (extract_delimited_string (string, sindex, "$[", "[", "]", 0)); /*]*/
-}
-
-#if defined (PROCESS_SUBSTITUTION)
-/* Extract the <( or >( construct in STRING, and return a new string.
-   Start extracting at (SINDEX) as if we had just seen "<(".
-   Make (SINDEX) get the position of the matching ")". */ /*))*/
-char *
-extract_process_subst (string, starter, sindex)
-     char *string;
-     char *starter;
-     int *sindex;
-{
-  return (extract_delimited_string (string, sindex, starter, "(", ")", 0));
-}
-#endif /* PROCESS_SUBSTITUTION */
-
-#if defined (ARRAY_VARS)
-/* This can be fooled by unquoted right parens in the passed string. If
-   each caller verifies that the last character in STRING is a right paren,
-   we don't even need to call extract_delimited_string. */
-char *
-extract_array_assignment_list (string, sindex)
-     char *string;
-     int *sindex;
-{
-  int slen;
-  char *ret;
-
-  slen = strlen (string);      /* ( */
-  if (string[slen - 1] == ')')
-   {
-      ret = substring (string, *sindex, slen - 1);
-      *sindex = slen - 1;
-      return ret;
-    }
-  return 0;  
-}
-#endif
-
-/* Extract and create a new string from the contents of STRING, a
-   character string delimited with OPENER and CLOSER.  SINDEX is
-   the address of an int describing the current offset in STRING;
-   it should point to just after the first OPENER found.  On exit,
-   SINDEX gets the position of the last character of the matching CLOSER.
-   If OPENER is more than a single character, ALT_OPENER, if non-null,
-   contains a character string that can also match CLOSER and thus
-   needs to be skipped. */
-static char *
-extract_delimited_string (string, sindex, opener, alt_opener, closer, flags)
-     char *string;
-     int *sindex;
-     char *opener, *alt_opener, *closer;
-     int flags;
-{
-  int i, c, si;
-  size_t slen;
-  char *t, *result;
-  int pass_character, nesting_level, in_comment;
-  int len_closer, len_opener, len_alt_opener;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string + *sindex) + *sindex;
-  len_opener = STRLEN (opener);
-  len_alt_opener = STRLEN (alt_opener);
-  len_closer = STRLEN (closer);
-
-  pass_character = in_comment = 0;
-
-  nesting_level = 1;
-  i = *sindex;
-
-  while (nesting_level)
-    {
-      c = string[i];
-
-      if (c == 0)
-       break;
-
-      if (in_comment)
-       {
-         if (c == '\n')
-           in_comment = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-
-      if (pass_character)      /* previous char was backslash */
-       {
-         pass_character = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-
-      /* Not exactly right yet; should handle shell metacharacters and
-        multibyte characters, too.  See COMMENT_BEGIN define in parse.y */
-      if ((flags & SX_COMMAND) && c == '#' && (i == 0 || string[i - 1] == '\n' || shellblank (string[i - 1])))
-       {
-          in_comment = 1;
-          ADVANCE_CHAR (string, slen, i);
-          continue;
-       }
-        
-      if (c == CTLESC || c == '\\')
-       {
-         pass_character++;
-         i++;
-         continue;
-       }
-
-#if 1
-      /* Process a nested command substitution, but only if we're parsing a
-        command substitution.  XXX - for bash-4.2 */
-      if ((flags & SX_COMMAND) && string[i] == '$' && string[i+1] == LPAREN)
-        {
-          si = i + 2;
-          t = extract_command_subst (string, &si, flags);
-          i = si + 1;
-          continue;
-        }
-#endif
-
-      /* Process a nested OPENER. */
-      if (STREQN (string + i, opener, len_opener))
-       {
-         si = i + len_opener;
-         t = extract_delimited_string (string, &si, opener, alt_opener, closer, flags|SX_NOALLOC);
-         i = si + 1;
-         continue;
-       }
-
-      /* Process a nested ALT_OPENER */
-      if (len_alt_opener && STREQN (string + i, alt_opener, len_alt_opener))
-       {
-         si = i + len_alt_opener;
-         t = extract_delimited_string (string, &si, alt_opener, alt_opener, closer, flags|SX_NOALLOC);
-         i = si + 1;
-         continue;
-       }
-
-      /* If the current substring terminates the delimited string, decrement
-        the nesting level. */
-      if (STREQN (string + i, closer, len_closer))
-       {
-         i += len_closer - 1;  /* move to last byte of the closer */
-         nesting_level--;
-         if (nesting_level == 0)
-           break;
-       }
-
-      /* Pass old-style command substitution through verbatim. */
-      if (c == '`')
-       {
-         si = i + 1;
-         t = string_extract (string, &si, "`", flags|SX_NOALLOC);
-         i = si + 1;
-         continue;
-       }
-
-      /* Pass single-quoted and double-quoted strings through verbatim. */
-      if (c == '\'' || c == '"')
-       {
-         si = i + 1;
-         i = (c == '\'') ? skip_single_quoted (string, slen, si)
-                         : skip_double_quoted (string, slen, si);
-         continue;
-       }
-
-      /* move past this character, which was not special. */
-      ADVANCE_CHAR (string, slen, i);
-    }
-
-  if (c == 0 && nesting_level)
-    {
-      if (no_longjmp_on_fatal_error == 0)
-       {
-         report_error (_("bad substitution: no closing `%s' in %s"), closer, string);
-         last_command_exit_value = EXECUTION_FAILURE;
-         exp_jump_to_top_level (DISCARD);
-       }
-      else
-       {
-         *sindex = i;
-         return (char *)NULL;
-       }
-    }
-
-  si = i - *sindex - len_closer + 1;
-  if (flags & SX_NOALLOC)
-    result = (char *)NULL;
-  else    
-    {
-      result = (char *)xmalloc (1 + si);
-      strncpy (result, string + *sindex, si);
-      result[si] = '\0';
-    }
-  *sindex = i;
-
-  return (result);
-}
-
-/* Extract a parameter expansion expression within ${ and } from STRING.
-   Obey the Posix.2 rules for finding the ending `}': count braces while
-   skipping over enclosed quoted strings and command substitutions.
-   SINDEX is the address of an int describing the current offset in STRING;
-   it should point to just after the first `{' found.  On exit, SINDEX
-   gets the position of the matching `}'.  QUOTED is non-zero if this
-   occurs inside double quotes. */
-/* XXX -- this is very similar to extract_delimited_string -- XXX */
-static char *
-extract_dollar_brace_string (string, sindex, quoted, flags)
-     char *string;
-     int *sindex, quoted, flags;
-{
-  register int i, c;
-  size_t slen;
-  int pass_character, nesting_level, si;
-  char *result, *t;
-  DECLARE_MBSTATE;
-
-  pass_character = 0;
-  nesting_level = 1;
-  slen = strlen (string + *sindex) + *sindex;
-
-  i = *sindex;
-  while (c = string[i])
-    {
-      if (pass_character)
-       {
-         pass_character = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-
-      /* CTLESCs and backslashes quote the next character. */
-      if (c == CTLESC || c == '\\')
-       {
-         pass_character++;
-         i++;
-         continue;
-       }
-
-      if (string[i] == '$' && string[i+1] == LBRACE)
-       {
-         nesting_level++;
-         i += 2;
-         continue;
-       }
-
-      if (c == RBRACE)
-       {
-         nesting_level--;
-         if (nesting_level == 0)
-           break;
-         i++;
-         continue;
-       }
-
-      /* Pass the contents of old-style command substitutions through
-        verbatim. */
-      if (c == '`')
-       {
-         si = i + 1;
-         t = string_extract (string, &si, "`", flags|SX_NOALLOC);
-         i = si + 1;
-         continue;
-       }
-
-      /* Pass the contents of new-style command substitutions and
-        arithmetic substitutions through verbatim. */
-      if (string[i] == '$' && string[i+1] == LPAREN)
-       {
-         si = i + 2;
-         t = extract_command_subst (string, &si, flags|SX_NOALLOC);
-         i = si + 1;
-         continue;
-       }
-
-      /* Pass the contents of single-quoted and double-quoted strings
-        through verbatim. */
-      if (c == '\'' || c == '"')
-       {
-         si = i + 1;
-         i = (c == '\'') ? skip_single_quoted (string, slen, si)
-                         : skip_double_quoted (string, slen, si);
-         /* skip_XXX_quoted leaves index one past close quote */
-         continue;
-       }
-
-      /* move past this character, which was not special. */
-      ADVANCE_CHAR (string, slen, i);
-    }
-
-  if (c == 0 && nesting_level)
-    {
-      if (no_longjmp_on_fatal_error == 0)
-       {                       /* { */
-         report_error (_("bad substitution: no closing `%s' in %s"), "}", string);
-         last_command_exit_value = EXECUTION_FAILURE;
-         exp_jump_to_top_level (DISCARD);
-       }
-      else
-       {
-         *sindex = i;
-         return ((char *)NULL);
-       }
-    }
-
-  result = (flags & SX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i);
-  *sindex = i;
-
-  return (result);
-}
-
-/* Remove backslashes which are quoting backquotes from STRING.  Modifies
-   STRING, and returns a pointer to it. */
-char *
-de_backslash (string)
-     char *string;
-{
-  register size_t slen;
-  register int i, j, prev_i;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string);
-  i = j = 0;
-
-  /* Loop copying string[i] to string[j], i >= j. */
-  while (i < slen)
-    {
-      if (string[i] == '\\' && (string[i + 1] == '`' || string[i + 1] == '\\' ||
-                             string[i + 1] == '$'))
-       i++;
-      prev_i = i;
-      ADVANCE_CHAR (string, slen, i);
-      if (j < prev_i)
-       do string[j++] = string[prev_i++]; while (prev_i < i);
-      else
-       j = i;
-    }
-  string[j] = '\0';
-
-  return (string);
-}
-
-#if 0
-/*UNUSED*/
-/* Replace instances of \! in a string with !. */
-void
-unquote_bang (string)
-     char *string;
-{
-  register int i, j;
-  register char *temp;
-
-  temp = (char *)xmalloc (1 + strlen (string));
-
-  for (i = 0, j = 0; (temp[j] = string[i]); i++, j++)
-    {
-      if (string[i] == '\\' && string[i + 1] == '!')
-       {
-         temp[j] = '!';
-         i++;
-       }
-    }
-  strcpy (string, temp);
-  free (temp);
-}
-#endif
-
-#define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
-
-/* This function assumes s[i] == open; returns with s[ret] == close; used to
-   parse array subscripts.  FLAGS & 1 means to not attempt to skip over
-   matched pairs of quotes or backquotes, or skip word expansions; it is
-   intended to be used after expansion has been performed and during final
-   assignment parsing (see arrayfunc.c:assign_compound_array_list()). */
-static int
-skip_matched_pair (string, start, open, close, flags)
-     const char *string;
-     int start, open, close, flags;
-{
-  int i, pass_next, backq, si, c, count;
-  size_t slen;
-  char *temp, *ss;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string + start) + start;
-  no_longjmp_on_fatal_error = 1;
-
-  i = start + 1;               /* skip over leading bracket */
-  count = 1;
-  pass_next = backq = 0;
-  ss = (char *)string;
-  while (c = string[i])
-    {
-      if (pass_next)
-       {
-         pass_next = 0;
-         if (c == 0)
-           CQ_RETURN(i);
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (c == '\\')
-       {
-         pass_next = 1;
-         i++;
-         continue;
-       }
-      else if (backq)
-       {
-         if (c == '`')
-           backq = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if ((flags & 1) == 0 && c == '`')
-       {
-         backq = 1;
-         i++;
-         continue;
-       }
-      else if ((flags & 1) == 0 && c == open)
-       {
-         count++;
-         i++;
-         continue;
-       }
-      else if (c == close)
-       {
-         count--;
-         if (count == 0)
-           break;
-         i++;
-         continue;
-       }
-      else if ((flags & 1) == 0 && (c == '\'' || c == '"'))
-       {
-         i = (c == '\'') ? skip_single_quoted (ss, slen, ++i)
-                         : skip_double_quoted (ss, slen, ++i);
-         /* no increment, the skip functions increment past the closing quote. */
-       }
-      else if ((flags&1) == 0 && c == '$' && (string[i+1] == LPAREN || string[i+1] == LBRACE))
-       {
-         si = i + 2;
-         if (string[si] == '\0')
-           CQ_RETURN(si);
-
-         if (string[i+1] == LPAREN)
-           temp = extract_delimited_string (ss, &si, "$(", "(", ")", SX_NOALLOC|SX_COMMAND); /* ) */
-         else
-           temp = extract_dollar_brace_string (ss, &si, 0, SX_NOALLOC);
-         i = si;
-         if (string[i] == '\0')        /* don't increment i past EOS in loop */
-           break;
-         i++;
-         continue;
-       }
-      else
-       ADVANCE_CHAR (string, slen, i);
-    }
-
-  CQ_RETURN(i);
-}
-
-#if defined (ARRAY_VARS)
-int
-skipsubscript (string, start, flags)
-     const char *string;
-     int start, flags;
-{
-  return (skip_matched_pair (string, start, '[', ']', flags));
-}
-#endif
-
-/* Skip characters in STRING until we find a character in DELIMS, and return
-   the index of that character.  START is the index into string at which we
-   begin.  This is similar in spirit to strpbrk, but it returns an index into
-   STRING and takes a starting index.  This little piece of code knows quite
-   a lot of shell syntax.  It's very similar to skip_double_quoted and other
-   functions of that ilk. */
-int
-skip_to_delim (string, start, delims, flags)
-     char *string;
-     int start;
-     char *delims;
-     int flags;
-{
-  int i, pass_next, backq, si, c, invert, skipquote, skipcmd;
-  size_t slen;
-  char *temp;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string + start) + start;
-  if (flags & SD_NOJMP)
-    no_longjmp_on_fatal_error = 1;
-  invert = (flags & SD_INVERT);
-  skipcmd = (flags & SD_NOSKIPCMD) == 0;
-
-  i = start;
-  pass_next = backq = 0;
-  while (c = string[i])
-    {
-      /* If this is non-zero, we should not let quote characters be delimiters
-        and the current character is a single or double quote.  We should not
-        test whether or not it's a delimiter until after we skip single- or
-        double-quoted strings. */
-      skipquote = ((flags & SD_NOQUOTEDELIM) && (c == '\'' || c =='"'));
-      if (pass_next)
-       {
-         pass_next = 0;
-         if (c == 0)
-           CQ_RETURN(i);
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (c == '\\')
-       {
-         pass_next = 1;
-         i++;
-         continue;
-       }
-      else if (backq)
-       {
-         if (c == '`')
-           backq = 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (c == '`')
-       {
-         backq = 1;
-         i++;
-         continue;
-       }
-      else if (skipquote == 0 && invert == 0 && member (c, delims))
-       break;
-      else if (c == '\'' || c == '"')
-       {
-         i = (c == '\'') ? skip_single_quoted (string, slen, ++i)
-                         : skip_double_quoted (string, slen, ++i);
-         /* no increment, the skip functions increment past the closing quote. */
-       }
-      else if (c == '$' && ((skipcmd && string[i+1] == LPAREN) || string[i+1] == LBRACE))
-       {
-         si = i + 2;
-         if (string[si] == '\0')
-           CQ_RETURN(si);
-
-         if (string[i+1] == LPAREN)
-           temp = extract_delimited_string (string, &si, "$(", "(", ")", SX_NOALLOC|SX_COMMAND); /* ) */
-         else
-           temp = extract_dollar_brace_string (string, &si, 0, SX_NOALLOC);
-         i = si;
-         if (string[i] == '\0')        /* don't increment i past EOS in loop */
-           break;
-         i++;
-         continue;
-       }
-#if defined (PROCESS_SUBSTITUTION)
-      else if (skipcmd && (c == '<' || c == '>') && string[i+1] == LPAREN)
-       {
-         si = i + 2;
-         if (string[si] == '\0')
-           CQ_RETURN(si);
-         temp = extract_process_subst (string, (c == '<') ? "<(" : ">(", &si);
-         i = si;
-         if (string[i] == '\0')
-           break;
-         i++;
-         continue;
-       }
-#endif /* PROCESS_SUBSTITUTION */
-      else if ((skipquote || invert) && (member (c, delims) == 0))
-       break;
-      else
-       ADVANCE_CHAR (string, slen, i);
-    }
-
-  CQ_RETURN(i);
-}
-
-#if defined (READLINE)
-/* Return 1 if the portion of STRING ending at EINDEX is quoted (there is
-   an unclosed quoted string), or if the character at EINDEX is quoted
-   by a backslash. NO_LONGJMP_ON_FATAL_ERROR is used to flag that the various
-   single and double-quoted string parsing functions should not return an
-   error if there are unclosed quotes or braces.  The characters that this
-   recognizes need to be the same as the contents of
-   rl_completer_quote_characters. */
-
-int
-char_is_quoted (string, eindex)
-     char *string;
-     int eindex;
-{
-  int i, pass_next, c;
-  size_t slen;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string);
-  no_longjmp_on_fatal_error = 1;
-  i = pass_next = 0;
-  while (i <= eindex)
-    {
-      c = string[i];
-
-      if (pass_next)
-       {
-         pass_next = 0;
-         if (i >= eindex)      /* XXX was if (i >= eindex - 1) */
-           CQ_RETURN(1);
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (c == '\\')
-       {
-         pass_next = 1;
-         i++;
-         continue;
-       }
-      else if (c == '\'' || c == '"')
-       {
-         i = (c == '\'') ? skip_single_quoted (string, slen, ++i)
-                         : skip_double_quoted (string, slen, ++i);
-         if (i > eindex)
-           CQ_RETURN(1);
-         /* no increment, the skip_xxx functions go one past end */
-       }
-      else
-       ADVANCE_CHAR (string, slen, i);
-    }
-
-  CQ_RETURN(0);
-}
-
-int
-unclosed_pair (string, eindex, openstr)
-     char *string;
-     int eindex;
-     char *openstr;
-{
-  int i, pass_next, openc, olen;
-  size_t slen;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string);
-  olen = strlen (openstr);
-  i = pass_next = openc = 0;
-  while (i <= eindex)
-    {
-      if (pass_next)
-       {
-         pass_next = 0;
-         if (i >= eindex)      /* XXX was if (i >= eindex - 1) */
-           return 0;
-         ADVANCE_CHAR (string, slen, i);
-         continue;
-       }
-      else if (string[i] == '\\')
-       {
-         pass_next = 1;
-         i++;
-         continue;
-       }
-      else if (STREQN (string + i, openstr, olen))
-       {
-         openc = 1 - openc;
-         i += olen;
-       }
-      else if (string[i] == '\'' || string[i] == '"')
-       {
-         i = (string[i] == '\'') ? skip_single_quoted (string, slen, i)
-                                 : skip_double_quoted (string, slen, i);
-         if (i > eindex)
-           return 0;
-       }
-      else
-       ADVANCE_CHAR (string, slen, i);
-    }
-  return (openc);
-}
-
-/* Split STRING (length SLEN) at DELIMS, and return a WORD_LIST with the
-   individual words.  If DELIMS is NULL, the current value of $IFS is used
-   to split the string, and the function follows the shell field splitting
-   rules.  SENTINEL is an index to look for.  NWP, if non-NULL,
-   gets the number of words in the returned list.  CWP, if non-NULL, gets
-   the index of the word containing SENTINEL.  Non-whitespace chars in
-   DELIMS delimit separate fields. */
-WORD_LIST *
-split_at_delims (string, slen, delims, sentinel, flags, nwp, cwp)
-     char *string;
-     int slen;
-     char *delims;
-     int sentinel, flags;
-     int *nwp, *cwp;
-{
-  int ts, te, i, nw, cw, ifs_split, dflags;
-  char *token, *d, *d2;
-  WORD_LIST *ret, *tl;
-
-  if (string == 0 || *string == '\0')
-    {
-      if (nwp)
-       *nwp = 0;
-      if (cwp)
-       *cwp = 0;       
-      return ((WORD_LIST *)NULL);
-    }
-
-  d = (delims == 0) ? ifs_value : delims;
-  ifs_split = delims == 0;
-
-  /* Make d2 the non-whitespace characters in delims */
-  d2 = 0;
-  if (delims)
-    {
-      size_t slength;
-#if defined (HANDLE_MULTIBYTE)
-      size_t mblength = 1;
-#endif
-      DECLARE_MBSTATE;
-
-      slength = strlen (delims);
-      d2 = (char *)xmalloc (slength + 1);
-      i = ts = 0;
-      while (delims[i])
-       {
-#if defined (HANDLE_MULTIBYTE)
-         mbstate_t state_bak;
-         state_bak = state;
-         mblength = MBRLEN (delims + i, slength, &state);
-         if (MB_INVALIDCH (mblength))
-           state = state_bak;
-         else if (mblength > 1)
-           {
-             memcpy (d2 + ts, delims + i, mblength);
-             ts += mblength;
-             i += mblength;
-             slength -= mblength;
-             continue;
-           }
-#endif
-         if (whitespace (delims[i]) == 0)
-           d2[ts++] = delims[i];
-
-         i++;
-         slength--;
-       }
-      d2[ts] = '\0';
-    }
-
-  ret = (WORD_LIST *)NULL;
-
-  /* Remove sequences of whitespace characters at the start of the string, as
-     long as those characters are delimiters. */
-  for (i = 0; member (string[i], d) && spctabnl (string[i]); i++)
-    ;
-  if (string[i] == '\0')
-    return (ret);
-
-  ts = i;
-  nw = 0;
-  cw = -1;
-  dflags = flags|SD_NOJMP;
-  while (1)
-    {
-      te = skip_to_delim (string, ts, d, dflags);
-
-      /* If we have a non-whitespace delimiter character, use it to make a
-        separate field.  This is just about what $IFS splitting does and
-        is closer to the behavior of the shell parser. */
-      if (ts == te && d2 && member (string[ts], d2))
-       {
-         te = ts + 1;
-         /* If we're using IFS splitting, the non-whitespace delimiter char
-            and any additional IFS whitespace delimits a field. */
-         if (ifs_split)
-           while (member (string[te], d) && spctabnl (string[te]))
-             te++;
-         else
-           while (member (string[te], d2))
-             te++;
-       }
-
-      token = substring (string, ts, te);
-
-      ret = add_string_to_list (token, ret);
-      free (token);
-      nw++;
-
-      if (sentinel >= ts && sentinel <= te)
-       cw = nw;
-
-      /* If the cursor is at whitespace just before word start, set the
-        sentinel word to the current word. */
-      if (cwp && cw == -1 && sentinel == ts-1)
-       cw = nw;
-
-      /* If the cursor is at whitespace between two words, make a new, empty
-        word, add it before (well, after, since the list is in reverse order)
-        the word we just added, and set the current word to that one. */
-      if (cwp && cw == -1 && sentinel < ts)
-       {
-         tl = make_word_list (make_word (""), ret->next);
-         ret->next = tl;
-         cw = nw;
-         nw++;
-       }
-
-      if (string[te] == 0)
-       break;
-
-      i = te;
-      while (member (string[i], d) && (ifs_split || spctabnl(string[i])))
-       i++;
-
-      if (string[i])
-       ts = i;
-      else
-       break;
-    }
-
-  /* Special case for SENTINEL at the end of STRING.  If we haven't found
-     the word containing SENTINEL yet, and the index we're looking for is at
-     the end of STRING (or past the end of the previously-found token,
-     possible if the end of the line is composed solely of IFS whitespace)
-     add an additional null argument and set the current word pointer to that. */
-  if (cwp && cw == -1 && (sentinel >= slen || sentinel >= te))
-    {
-      if (whitespace (string[sentinel - 1]))
-       {
-         token = "";
-         ret = add_string_to_list (token, ret);
-         nw++;
-       }
-      cw = nw;
-    }
-
-  if (nwp)
-    *nwp = nw;
-  if (cwp)
-    *cwp = cw;
-
-  return (REVERSE_LIST (ret, WORD_LIST *));
-}
-#endif /* READLINE */
-
-#if 0
-/* UNUSED */
-/* Extract the name of the variable to bind to from the assignment string. */
-char *
-assignment_name (string)
-     char *string;
-{
-  int offset;
-  char *temp;
-
-  offset = assignment (string, 0);
-  if (offset == 0)
-    return (char *)NULL;
-  temp = substring (string, 0, offset);
-  return (temp);
-}
-#endif
-
-/* **************************************************************** */
-/*                                                                 */
-/*     Functions to convert strings to WORD_LISTs and vice versa    */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Return a single string of all the words in LIST.  SEP is the separator
-   to put between individual elements of LIST in the output string. */
-char *
-string_list_internal (list, sep)
-     WORD_LIST *list;
-     char *sep;
-{
-  register WORD_LIST *t;
-  char *result, *r;
-  int word_len, sep_len, result_size;
-
-  if (list == 0)
-    return ((char *)NULL);
-
-  /* Short-circuit quickly if we don't need to separate anything. */
-  if (list->next == 0)
-    return (savestring (list->word->word));
-
-  /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */
-  sep_len = STRLEN (sep);
-  result_size = 0;
-
-  for (t = list; t; t = t->next)
-    {
-      if (t != list)
-       result_size += sep_len;
-      result_size += strlen (t->word->word);
-    }
-
-  r = result = (char *)xmalloc (result_size + 1);
-
-  for (t = list; t; t = t->next)
-    {
-      if (t != list && sep_len)
-       {
-         if (sep_len > 1)
-           {
-             FASTCOPY (sep, r, sep_len);
-             r += sep_len;
-           }
-         else
-           *r++ = sep[0];
-       }
-
-      word_len = strlen (t->word->word);
-      FASTCOPY (t->word->word, r, word_len);
-      r += word_len;
-    }
-
-  *r = '\0';
-  return (result);
-}
-
-/* Return a single string of all the words present in LIST, separating
-   each word with a space. */
-char *
-string_list (list)
-     WORD_LIST *list;
-{
-  return (string_list_internal (list, " "));
-}
-
-/* An external interface that can be used by the rest of the shell to
-   obtain a string containing the first character in $IFS.  Handles all
-   the multibyte complications.  If LENP is non-null, it is set to the
-   length of the returned string. */
-char *
-ifs_firstchar (lenp)
-     int *lenp;
-{
-  char *ret;
-  int len;
-
-  ret = xmalloc (MB_LEN_MAX + 1);
-#if defined (HANDLE_MULTIBYTE)
-  if (ifs_firstc_len == 1)
-    {
-      ret[0] = ifs_firstc[0];
-      ret[1] = '\0';
-      len = ret[0] ? 1 : 0;
-    }
-  else
-    {
-      memcpy (ret, ifs_firstc, ifs_firstc_len);
-      ret[len = ifs_firstc_len] = '\0';
-    }
-#else
-  ret[0] = ifs_firstc;
-  ret[1] = '\0';
-  len = ret[0] ? 0 : 1;
-#endif
-
-  if (lenp)
-    *lenp = len;
-
-  return ret;
-}
-
-/* Return a single string of all the words present in LIST, obeying the
-   quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the
-   expansion [of $*] appears within a double quoted string, it expands
-   to a single field with the value of each parameter separated by the
-   first character of the IFS variable, or by a <space> if IFS is unset." */
-char *
-string_list_dollar_star (list)
-     WORD_LIST *list;
-{
-  char *ret;
-#if defined (HANDLE_MULTIBYTE)
-#  if defined (__GNUC__)
-  char sep[MB_CUR_MAX + 1];
-#  else
-  char *sep = 0;
-#  endif
-#else
-  char sep[2];
-#endif
-
-#if defined (HANDLE_MULTIBYTE)
-#  if !defined (__GNUC__)
-  sep = (char *)xmalloc (MB_CUR_MAX + 1);
-#  endif /* !__GNUC__ */
-  if (ifs_firstc_len == 1)
-    {
-      sep[0] = ifs_firstc[0];
-      sep[1] = '\0';
-    }
-  else
-    {
-      memcpy (sep, ifs_firstc, ifs_firstc_len);
-      sep[ifs_firstc_len] = '\0';
-    }
-#else
-  sep[0] = ifs_firstc;
-  sep[1] = '\0';
-#endif
-
-  ret = string_list_internal (list, sep);
-#if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
-  free (sep);
-#endif
-  return ret;
-}
-
-/* Turn $@ into a string.  If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-   is non-zero, the $@ appears within double quotes, and we should quote
-   the list before converting it into a string.  If IFS is unset, and the
-   word is not quoted, we just need to quote CTLESC and CTLNUL characters
-   in the words in the list, because the default value of $IFS is
-   <space><tab><newline>, IFS characters in the words in the list should
-   also be split.  If IFS is null, and the word is not quoted, we need
-   to quote the words in the list to preserve the positional parameters
-   exactly. */
-char *
-string_list_dollar_at (list, quoted)
-     WORD_LIST *list;
-     int quoted;
-{
-  char *ifs, *ret;
-#if defined (HANDLE_MULTIBYTE)
-#  if defined (__GNUC__)
-  char sep[MB_CUR_MAX + 1];
-#  else
-  char *sep = 0;
-#  endif /* !__GNUC__ */
-#else
-  char sep[2];
-#endif
-  WORD_LIST *tlist;
-
-  /* XXX this could just be ifs = ifs_value; */
-  ifs = ifs_var ? value_cell (ifs_var) : (char *)0;
-
-#if defined (HANDLE_MULTIBYTE)
-#  if !defined (__GNUC__)
-  sep = (char *)xmalloc (MB_CUR_MAX + 1);
-#  endif /* !__GNUC__ */
-  if (ifs && *ifs)
-    {
-      if (ifs_firstc_len == 1)
-       {
-         sep[0] = ifs_firstc[0];
-         sep[1] = '\0';
-       }
-      else
-       {
-         memcpy (sep, ifs_firstc, ifs_firstc_len);
-         sep[ifs_firstc_len] = '\0';
-       }
-    }
-  else
-    {
-      sep[0] = ' ';
-      sep[1] = '\0';
-    }
-#else
-  sep[0] = (ifs == 0 || *ifs == 0) ? ' ' : *ifs;
-  sep[1] = '\0';
-#endif
-
-  /* XXX -- why call quote_list if ifs == 0?  we can get away without doing
-     it now that quote_escapes quotes spaces */
-#if 0
-  tlist = ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (ifs && *ifs == 0))
-#else
-  tlist = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES|Q_PATQUOTE))
-#endif
-               ? quote_list (list)
-               : list_quote_escapes (list);
-
-  ret = string_list_internal (tlist, sep);
-#if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
-  free (sep);
-#endif
-  return ret;
-}
-
-/* Turn the positional paramters into a string, understanding quoting and
-   the various subtleties of using the first character of $IFS as the
-   separator.  Calls string_list_dollar_at, string_list_dollar_star, and
-   string_list as appropriate. */
-char *
-string_list_pos_params (pchar, list, quoted)
-     int pchar;
-     WORD_LIST *list;
-     int quoted;
-{
-  char *ret;
-  WORD_LIST *tlist;
-
-  if (pchar == '*' && (quoted & Q_DOUBLE_QUOTES))
-    {
-      tlist = quote_list (list);
-      word_list_remove_quoted_nulls (tlist);
-      ret = string_list_dollar_star (tlist);
-    }
-  else if (pchar == '*' && (quoted & Q_HERE_DOCUMENT))
-    {
-      tlist = quote_list (list);
-      word_list_remove_quoted_nulls (tlist);
-      ret = string_list (tlist);
-    }
-  else if (pchar == '*')
-    {
-      /* Even when unquoted, string_list_dollar_star does the right thing
-        making sure that the first character of $IFS is used as the
-        separator. */
-      ret = string_list_dollar_star (list);
-    }
-  else if (pchar == '@' && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-    /* We use string_list_dollar_at, but only if the string is quoted, since
-       that quotes the escapes if it's not, which we don't want.  We could
-       use string_list (the old code did), but that doesn't do the right
-       thing if the first character of $IFS is not a space.  We use
-       string_list_dollar_star if the string is unquoted so we make sure that
-       the elements of $@ are separated by the first character of $IFS for
-       later splitting. */
-    ret = string_list_dollar_at (list, quoted);
-  else if (pchar == '@')
-    ret = string_list_dollar_star (list);
-  else
-    ret = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (list) : list);
-
-  return ret;
-}
-
-/* Return the list of words present in STRING.  Separate the string into
-   words at any of the characters found in SEPARATORS.  If QUOTED is
-   non-zero then word in the list will have its quoted flag set, otherwise
-   the quoted flag is left as make_word () deemed fit.
-
-   This obeys the P1003.2 word splitting semantics.  If `separators' is
-   exactly <space><tab><newline>, then the splitting algorithm is that of
-   the Bourne shell, which treats any sequence of characters from `separators'
-   as a delimiter.  If IFS is unset, which results in `separators' being set
-   to "", no splitting occurs.  If separators has some other value, the
-   following rules are applied (`IFS white space' means zero or more
-   occurrences of <space>, <tab>, or <newline>, as long as those characters
-   are in `separators'):
-
-       1) IFS white space is ignored at the start and the end of the
-          string.
-       2) Each occurrence of a character in `separators' that is not
-          IFS white space, along with any adjacent occurrences of
-          IFS white space delimits a field.
-       3) Any nonzero-length sequence of IFS white space delimits a field.
-   */
-
-/* BEWARE!  list_string strips null arguments.  Don't call it twice and
-   expect to have "" preserved! */
-
-/* This performs word splitting and quoted null character removal on
-   STRING. */
-#define issep(c) \
-       (((separators)[0]) ? ((separators)[1] ? isifs(c) \
-                                             : (c) == (separators)[0]) \
-                          : 0)
-
-WORD_LIST *
-list_string (string, separators, quoted)
-     register char *string, *separators;
-     int quoted;
-{
-  WORD_LIST *result;
-  WORD_DESC *t;
-  char *current_word, *s;
-  int sindex, sh_style_split, whitesep, xflags;
-  size_t slen;
-
-  if (!string || !*string)
-    return ((WORD_LIST *)NULL);
-
-  sh_style_split = separators && separators[0] == ' ' &&
-                                separators[1] == '\t' &&
-                                separators[2] == '\n' &&
-                                separators[3] == '\0';
-  for (xflags = 0, s = ifs_value; s && *s; s++)
-    {
-      if (*s == CTLESC) xflags |= SX_NOCTLESC;
-      else if (*s == CTLNUL) xflags |= SX_NOESCCTLNUL;
-    }
-
-  slen = 0;
-  /* Remove sequences of whitespace at the beginning of STRING, as
-     long as those characters appear in IFS.  Do not do this if
-     STRING is quoted or if there are no separator characters. */
-  if (!quoted || !separators || !*separators)
-    {
-      for (s = string; *s && spctabnl (*s) && issep (*s); s++);
-
-      if (!*s)
-       return ((WORD_LIST *)NULL);
-
-      string = s;
-    }
-
-  /* OK, now STRING points to a word that does not begin with white space.
-     The splitting algorithm is:
-       extract a word, stopping at a separator
-       skip sequences of spc, tab, or nl as long as they are separators
-     This obeys the field splitting rules in Posix.2. */
-  slen = (MB_CUR_MAX > 1) ? strlen (string) : 1;
-  for (result = (WORD_LIST *)NULL, sindex = 0; string[sindex]; )
-    {
-      /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
-        unless multibyte chars are possible. */
-      current_word = string_extract_verbatim (string, slen, &sindex, separators, xflags);
-      if (current_word == 0)
-       break;
-
-      /* If we have a quoted empty string, add a quoted null argument.  We
-        want to preserve the quoted null character iff this is a quoted
-        empty string; otherwise the quoted null characters are removed
-        below. */
-      if (QUOTED_NULL (current_word))
-       {
-         t = alloc_word_desc ();
-         t->word = make_quoted_char ('\0');
-         t->flags |= W_QUOTED|W_HASQUOTEDNULL;
-         result = make_word_list (t, result);
-       }
-      else if (current_word[0] != '\0')
-       {
-         /* If we have something, then add it regardless.  However,
-            perform quoted null character removal on the current word. */
-         remove_quoted_nulls (current_word);
-         result = add_string_to_list (current_word, result);
-         result->word->flags &= ~W_HASQUOTEDNULL;      /* just to be sure */
-         if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
-           result->word->flags |= W_QUOTED;
-       }
-
-      /* If we're not doing sequences of separators in the traditional
-        Bourne shell style, then add a quoted null argument. */
-      else if (!sh_style_split && !spctabnl (string[sindex]))
-       {
-         t = alloc_word_desc ();
-         t->word = make_quoted_char ('\0');
-         t->flags |= W_QUOTED|W_HASQUOTEDNULL;
-         result = make_word_list (t, result);
-       }
-
-      free (current_word);
-
-      /* Note whether or not the separator is IFS whitespace, used later. */
-      whitesep = string[sindex] && spctabnl (string[sindex]);
-
-      /* Move past the current separator character. */
-      if (string[sindex])
-       {
-         DECLARE_MBSTATE;
-         ADVANCE_CHAR (string, slen, sindex);
-       }
-
-      /* Now skip sequences of space, tab, or newline characters if they are
-        in the list of separators. */
-      while (string[sindex] && spctabnl (string[sindex]) && issep (string[sindex]))
-       sindex++;
-
-      /* If the first separator was IFS whitespace and the current character
-        is a non-whitespace IFS character, it should be part of the current
-        field delimiter, not a separate delimiter that would result in an
-        empty field.  Look at POSIX.2, 3.6.5, (3)(b). */
-      if (string[sindex] && whitesep && issep (string[sindex]) && !spctabnl (string[sindex]))
-       {
-         sindex++;
-         /* An IFS character that is not IFS white space, along with any
-            adjacent IFS white space, shall delimit a field. (SUSv3) */
-         while (string[sindex] && spctabnl (string[sindex]) && isifs (string[sindex]))
-           sindex++;
-       }
-    }
-  return (REVERSE_LIST (result, WORD_LIST *));
-}
-
-/* Parse a single word from STRING, using SEPARATORS to separate fields.
-   ENDPTR is set to the first character after the word.  This is used by
-   the `read' builtin.  This is never called with SEPARATORS != $IFS;
-   it should be simplified.
-
-   XXX - this function is very similar to list_string; they should be
-        combined - XXX */
-char *
-get_word_from_string (stringp, separators, endptr)
-     char **stringp, *separators, **endptr;
-{
-  register char *s;
-  char *current_word;
-  int sindex, sh_style_split, whitesep, xflags;
-  size_t slen;
-
-  if (!stringp || !*stringp || !**stringp)
-    return ((char *)NULL);
-
-  sh_style_split = separators && separators[0] == ' ' &&
-                                separators[1] == '\t' &&
-                                separators[2] == '\n' &&
-                                separators[3] == '\0';
-  for (xflags = 0, s = ifs_value; s && *s; s++)
-    {
-      if (*s == CTLESC) xflags |= SX_NOCTLESC;
-      if (*s == CTLNUL) xflags |= SX_NOESCCTLNUL;
-    }
-
-  s = *stringp;
-  slen = 0;
-
-  /* Remove sequences of whitespace at the beginning of STRING, as
-     long as those characters appear in IFS. */
-  if (sh_style_split || !separators || !*separators)
-    {
-      for (; *s && spctabnl (*s) && isifs (*s); s++);
-
-      /* If the string is nothing but whitespace, update it and return. */
-      if (!*s)
-       {
-         *stringp = s;
-         if (endptr)
-           *endptr = s;
-         return ((char *)NULL);
-       }
-    }
-
-  /* OK, S points to a word that does not begin with white space.
-     Now extract a word, stopping at a separator, save a pointer to
-     the first character after the word, then skip sequences of spc,
-     tab, or nl as long as they are separators.
-
-     This obeys the field splitting rules in Posix.2. */
-  sindex = 0;
-  /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
-     unless multibyte chars are possible. */
-  slen = (MB_CUR_MAX > 1) ? strlen (s) : 1;
-  current_word = string_extract_verbatim (s, slen, &sindex, separators, xflags);
-
-  /* Set ENDPTR to the first character after the end of the word. */
-  if (endptr)
-    *endptr = s + sindex;
-
-  /* Note whether or not the separator is IFS whitespace, used later. */
-  whitesep = s[sindex] && spctabnl (s[sindex]);
-
-  /* Move past the current separator character. */
-  if (s[sindex])
-    {
-      DECLARE_MBSTATE;
-      ADVANCE_CHAR (s, slen, sindex);
-    }
-
-  /* Now skip sequences of space, tab, or newline characters if they are
-     in the list of separators. */
-  while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
-    sindex++;
-
-  /* If the first separator was IFS whitespace and the current character is
-     a non-whitespace IFS character, it should be part of the current field
-     delimiter, not a separate delimiter that would result in an empty field.
-     Look at POSIX.2, 3.6.5, (3)(b). */
-  if (s[sindex] && whitesep && isifs (s[sindex]) && !spctabnl (s[sindex]))
-    {
-      sindex++;
-      /* An IFS character that is not IFS white space, along with any adjacent
-        IFS white space, shall delimit a field. */
-      while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
-       sindex++;
-    }
-
-  /* Update STRING to point to the next field. */
-  *stringp = s + sindex;
-  return (current_word);
-}
-
-/* Remove IFS white space at the end of STRING.  Start at the end
-   of the string and walk backwards until the beginning of the string
-   or we find a character that's not IFS white space and not CTLESC.
-   Only let CTLESC escape a white space character if SAW_ESCAPE is
-   non-zero.  */
-char *
-strip_trailing_ifs_whitespace (string, separators, saw_escape)
-     char *string, *separators;
-     int saw_escape;
-{
-  char *s;
-
-  s = string + STRLEN (string) - 1;
-  while (s > string && ((spctabnl (*s) && isifs (*s)) ||
-                       (saw_escape && *s == CTLESC && spctabnl (s[1]))))
-    s--;
-  *++s = '\0';
-  return string;
-}
-
-#if 0
-/* UNUSED */
-/* Split STRING into words at whitespace.  Obeys shell-style quoting with
-   backslashes, single and double quotes. */
-WORD_LIST *
-list_string_with_quotes (string)
-     char *string;
-{
-  WORD_LIST *list;
-  char *token, *s;
-  size_t s_len;
-  int c, i, tokstart, len;
-
-  for (s = string; s && *s && spctabnl (*s); s++)
-    ;
-  if (s == 0 || *s == 0)
-    return ((WORD_LIST *)NULL);
-
-  s_len = strlen (s);
-  tokstart = i = 0;
-  list = (WORD_LIST *)NULL;
-  while (1)
-    {
-      c = s[i];
-      if (c == '\\')
-       {
-         i++;
-         if (s[i])
-           i++;
-       }
-      else if (c == '\'')
-       i = skip_single_quoted (s, s_len, ++i);
-      else if (c == '"')
-       i = skip_double_quoted (s, s_len, ++i);
-      else if (c == 0 || spctabnl (c))
-       {
-         /* We have found the end of a token.  Make a word out of it and
-            add it to the word list. */
-         token = substring (s, tokstart, i);
-         list = add_string_to_list (token, list);
-         free (token);
-         while (spctabnl (s[i]))
-           i++;
-         if (s[i])
-           tokstart = i;
-         else
-           break;
-       }
-      else
-       i++;    /* normal character */
-    }
-  return (REVERSE_LIST (list, WORD_LIST *));
-}
-#endif
-
-/********************************************************/
-/*                                                     */
-/*     Functions to perform assignment statements      */
-/*                                                     */
-/********************************************************/
-
-#if defined (ARRAY_VARS)
-static SHELL_VAR *
-do_compound_assignment (name, value, flags)
-     char *name, *value;
-     int flags;
-{
-  SHELL_VAR *v;
-  int mklocal, mkassoc;
-  WORD_LIST *list;
-
-  mklocal = flags & ASS_MKLOCAL;
-  mkassoc = flags & ASS_MKASSOC;
-
-  if (mklocal && variable_context)
-    {
-      v = find_variable (name);
-      list = expand_compound_array_assignment (v, value, flags);
-      if (mkassoc)
-       v = make_local_assoc_variable (name);
-      else if (v == 0 || (array_p (v) == 0 && assoc_p (v) == 0) || v->context != variable_context)
-        v = make_local_array_variable (name);
-      assign_compound_array_list (v, list, flags);
-    }
-  else
-    v = assign_array_from_string (name, value, flags);
-
-  return (v);
-}
-#endif
-
-/* Given STRING, an assignment string, get the value of the right side
-   of the `=', and bind it to the left side.  If EXPAND is true, then
-   perform parameter expansion, command substitution, and arithmetic
-   expansion on the right-hand side.  Perform tilde expansion in any
-   case.  Do not perform word splitting on the result of expansion. */
-static int
-do_assignment_internal (word, expand)
-     const WORD_DESC *word;
-     int expand;
-{
-  int offset, tlen, appendop, assign_list, aflags, retval;
-  char *name, *value;
-  SHELL_VAR *entry;
-#if defined (ARRAY_VARS)
-  char *t;
-  int ni;
-#endif
-  const char *string;
-
-  if (word == 0 || word->word == 0)
-    return 0;
-
-  appendop = assign_list = aflags = 0;
-  string = word->word;
-  offset = assignment (string, 0);
-  name = savestring (string);
-  value = (char *)NULL;
-
-  if (name[offset] == '=')
-    {
-      char *temp;
-
-      if (name[offset - 1] == '+')
-       {
-         appendop = 1;
-         name[offset - 1] = '\0';
-       }
-
-      name[offset] = 0;                /* might need this set later */
-      temp = name + offset + 1;
-      tlen = STRLEN (temp);
-
-#if defined (ARRAY_VARS)
-      if (expand && (word->flags & W_COMPASSIGN))
-       {
-         assign_list = ni = 1;
-         value = extract_array_assignment_list (temp, &ni);
-       }
-      else
-#endif
-      if (expand && temp[0])
-       value = expand_string_if_necessary (temp, 0, expand_string_assignment);
-      else
-       value = savestring (temp);
-    }
-
-  if (value == 0)
-    {
-      value = (char *)xmalloc (1);
-      value[0] = '\0';
-    }
-
-  if (echo_command_at_execute)
-    {
-      if (appendop)
-       name[offset - 1] = '+';
-      xtrace_print_assignment (name, value, assign_list, 1);
-      if (appendop)
-       name[offset - 1] = '\0';
-    }
-
-#define ASSIGN_RETURN(r)       do { FREE (value); free (name); return (r); } while (0)
-
-  if (appendop)
-    aflags |= ASS_APPEND;
-
-#if defined (ARRAY_VARS)
-  if (t = mbschr (name, '['))  /*]*/
-    {
-      if (assign_list)
-       {
-         report_error (_("%s: cannot assign list to array member"), name);
-         ASSIGN_RETURN (0);
-       }
-      entry = assign_array_element (name, value, aflags);
-      if (entry == 0)
-       ASSIGN_RETURN (0);
-    }
-  else if (assign_list)
-    {
-      if (word->flags & W_ASSIGNARG)
-       aflags |= ASS_MKLOCAL;
-      if (word->flags & W_ASSIGNASSOC)
-       aflags |= ASS_MKASSOC;
-      entry = do_compound_assignment (name, value, aflags);
-    }
-  else
-#endif /* ARRAY_VARS */
-  entry = bind_variable (name, value, aflags);
-
-  stupidly_hack_special_variables (name);
-
-#if 1
-  /* Return 1 if the assignment seems to have been performed correctly. */
-  if (entry == 0 || readonly_p (entry))
-    retval = 0;                /* assignment failure */
-  else if (noassign_p (entry))
-    {
-      last_command_exit_value = EXECUTION_FAILURE;
-      retval = 1;      /* error status, but not assignment failure */
-    }
-  else
-    retval = 1;
-
-  if (entry && retval != 0 && noassign_p (entry) == 0)
-    VUNSETATTR (entry, att_invisible);
-
-  ASSIGN_RETURN (retval);
-#else
-  if (entry)
-    VUNSETATTR (entry, att_invisible);
-
-  ASSIGN_RETURN (entry ? ((readonly_p (entry) == 0) && noassign_p (entry) == 0) : 0);
-#endif
-}
-
-/* Perform the assignment statement in STRING, and expand the
-   right side by doing tilde, command and parameter expansion. */
-int
-do_assignment (string)
-     char *string;
-{
-  WORD_DESC td;
-
-  td.flags = W_ASSIGNMENT;
-  td.word = string;
-
-  return do_assignment_internal (&td, 1);
-}
-
-int
-do_word_assignment (word)
-     WORD_DESC *word;
-{
-  return do_assignment_internal (word, 1);
-}
-
-/* Given STRING, an assignment string, get the value of the right side
-   of the `=', and bind it to the left side.  Do not perform any word
-   expansions on the right hand side. */
-int
-do_assignment_no_expand (string)
-     char *string;
-{
-  WORD_DESC td;
-
-  td.flags = W_ASSIGNMENT;
-  td.word = string;
-
-  return (do_assignment_internal (&td, 0));
-}
-
-/***************************************************
- *                                                *
- *  Functions to manage the positional parameters  *
- *                                                *
- ***************************************************/
-
-/* Return the word list that corresponds to `$*'. */
-WORD_LIST *
-list_rest_of_args ()
-{
-  register WORD_LIST *list, *args;
-  int i;
-
-  /* Break out of the loop as soon as one of the dollar variables is null. */
-  for (i = 1, list = (WORD_LIST *)NULL; i < 10 && dollar_vars[i]; i++)
-    list = make_word_list (make_bare_word (dollar_vars[i]), list);
-
-  for (args = rest_of_args; args; args = args->next)
-    list = make_word_list (make_bare_word (args->word->word), list);
-
-  return (REVERSE_LIST (list, WORD_LIST *));
-}
-
-int
-number_of_args ()
-{
-  register WORD_LIST *list;
-  int n;
-
-  for (n = 0; n < 9 && dollar_vars[n+1]; n++)
-    ;
-  for (list = rest_of_args; list; list = list->next)
-    n++;
-  return n;
-}
-
-/* Return the value of a positional parameter.  This handles values > 10. */
-char *
-get_dollar_var_value (ind)
-     intmax_t ind;
-{
-  char *temp;
-  WORD_LIST *p;
-
-  if (ind < 10)
-    temp = dollar_vars[ind] ? savestring (dollar_vars[ind]) : (char *)NULL;
-  else /* We want something like ${11} */
-    {
-      ind -= 10;
-      for (p = rest_of_args; p && ind--; p = p->next)
-       ;
-      temp = p ? savestring (p->word->word) : (char *)NULL;
-    }
-  return (temp);
-}
-
-/* Make a single large string out of the dollar digit variables,
-   and the rest_of_args.  If DOLLAR_STAR is 1, then obey the special
-   case of "$*" with respect to IFS. */
-char *
-string_rest_of_args (dollar_star)
-     int dollar_star;
-{
-  register WORD_LIST *list;
-  char *string;
-
-  list = list_rest_of_args ();
-  string = dollar_star ? string_list_dollar_star (list) : string_list (list);
-  dispose_words (list);
-  return (string);
-}
-
-/* Return a string containing the positional parameters from START to
-   END, inclusive.  If STRING[0] == '*', we obey the rules for $*,
-   which only makes a difference if QUOTED is non-zero.  If QUOTED includes
-   Q_HERE_DOCUMENT or Q_DOUBLE_QUOTES, this returns a quoted list, otherwise
-   no quoting chars are added. */
-static char *
-pos_params (string, start, end, quoted)
-     char *string;
-     int start, end, quoted;
-{
-  WORD_LIST *save, *params, *h, *t;
-  char *ret;
-  int i;
-
-  /* see if we can short-circuit.  if start == end, we want 0 parameters. */
-  if (start == end)
-    return ((char *)NULL);
-
-  save = params = list_rest_of_args ();
-  if (save == 0)
-    return ((char *)NULL);
-
-  if (start == 0)              /* handle ${@:0[:x]} specially */
-    {
-      t = make_word_list (make_word (dollar_vars[0]), params);
-      save = params = t;
-    }
-
-  for (i = start ? 1 : 0; params && i < start; i++)
-    params = params->next;
-  if (params == 0)
-    return ((char *)NULL);
-  for (h = t = params; params && i < end; i++)
-    {
-      t = params;
-      params = params->next;
-    }
-
-  t->next = (WORD_LIST *)NULL;
-
-  ret = string_list_pos_params (string[0], h, quoted);
-
-  if (t != params)
-    t->next = params;
-
-  dispose_words (save);
-  return (ret);
-}
-
-/******************************************************************/
-/*                                                               */
-/*     Functions to expand strings to strings or WORD_LISTs      */
-/*                                                               */
-/******************************************************************/
-
-#if defined (PROCESS_SUBSTITUTION)
-#define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC || s == '~')
-#else
-#define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
-#endif
-
-/* If there are any characters in STRING that require full expansion,
-   then call FUNC to expand STRING; otherwise just perform quote
-   removal if necessary.  This returns a new string. */
-static char *
-expand_string_if_necessary (string, quoted, func)
-     char *string;
-     int quoted;
-     EXPFUNC *func;
-{
-  WORD_LIST *list;
-  size_t slen;
-  int i, saw_quote;
-  char *ret;
-  DECLARE_MBSTATE;
-
-  /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */
-  slen = (MB_CUR_MAX > 1) ? strlen (string) : 0;
-  i = saw_quote = 0;
-  while (string[i])
-    {
-      if (EXP_CHAR (string[i]))
-       break;
-      else if (string[i] == '\'' || string[i] == '\\' || string[i] == '"')
-       saw_quote = 1;
-      ADVANCE_CHAR (string, slen, i);
-    }
-
-  if (string[i])
-    {
-      list = (*func) (string, quoted);
-      if (list)
-       {
-         ret = string_list (list);
-         dispose_words (list);
-       }
-      else
-       ret = (char *)NULL;
-    }
-  else if (saw_quote && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
-    ret = string_quote_removal (string, quoted);
-  else
-    ret = savestring (string);
-
-  return ret;
-}
-
-static inline char *
-expand_string_to_string_internal (string, quoted, func)
-     char *string;
-     int quoted;
-     EXPFUNC *func;
-{
-  WORD_LIST *list;
-  char *ret;
-
-  if (string == 0 || *string == '\0')
-    return ((char *)NULL);
-
-  list = (*func) (string, quoted);
-  if (list)
-    {
-      ret = string_list (list);
-      dispose_words (list);
-    }
-  else
-    ret = (char *)NULL;
-
-  return (ret);
-}
-
-char *
-expand_string_to_string (string, quoted)
-     char *string;
-     int quoted;
-{
-  return (expand_string_to_string_internal (string, quoted, expand_string));
-}
-
-char *
-expand_string_unsplit_to_string (string, quoted)
-     char *string;
-     int quoted;
-{
-  return (expand_string_to_string_internal (string, quoted, expand_string_unsplit));
-}
-
-char *
-expand_assignment_string_to_string (string, quoted)
-     char *string;
-     int quoted;
-{
-  return (expand_string_to_string_internal (string, quoted, expand_string_assignment));
-}
-
-char *
-expand_arith_string (string, quoted)
-     char *string;
-     int quoted;
-{
-  return (expand_string_if_necessary (string, quoted, expand_string));
-}
-
-#if defined (COND_COMMAND)
-/* Just remove backslashes in STRING.  Returns a new string. */
-char *
-remove_backslashes (string)
-     char *string;
-{
-  char *r, *ret, *s;
-
-  r = ret = (char *)xmalloc (strlen (string) + 1);
-  for (s = string; s && *s; )
-    {
-      if (*s == '\\')
-       s++;
-      if (*s == 0)
-       break;
-      *r++ = *s++;
-    }
-  *r = '\0';
-  return ret;
-}
-
-/* This needs better error handling. */
-/* Expand W for use as an argument to a unary or binary operator in a
-   [[...]] expression.  If SPECIAL is 1, this is the rhs argument
-   to the != or == operator, and should be treated as a pattern.  In
-   this case, we quote the string specially for the globbing code.  If
-   SPECIAL is 2, this is an rhs argument for the =~ operator, and should
-   be quoted appropriately for regcomp/regexec.  The caller is responsible
-   for removing the backslashes if the unquoted word is needed later. */   
-char *
-cond_expand_word (w, special)
-     WORD_DESC *w;
-     int special;
-{
-  char *r, *p;
-  WORD_LIST *l;
-  int qflags;
-
-  if (w->word == 0 || w->word[0] == '\0')
-    return ((char *)NULL);
-
-  w->flags |= W_NOSPLIT2;
-  l = call_expand_word_internal (w, 0, 0, (int *)0, (int *)0);
-  if (l)
-    {
-      if (special == 0)
-       {
-         dequote_list (l);
-         r = string_list (l);
-       }
-      else
-       {
-         qflags = QGLOB_CVTNULL;
-         if (special == 2)
-           qflags |= QGLOB_REGEXP;
-         p = string_list (l);
-         r = quote_string_for_globbing (p, qflags);
-         free (p);
-       }
-      dispose_words (l);
-    }
-  else
-    r = (char *)NULL;
-
-  return r;
-}
-#endif
-
-/* Call expand_word_internal to expand W and handle error returns.
-   A convenience function for functions that don't want to handle
-   any errors or free any memory before aborting. */
-static WORD_LIST *
-call_expand_word_internal (w, q, i, c, e)
-     WORD_DESC *w;
-     int q, i, *c, *e;
-{
-  WORD_LIST *result;
-
-  result = expand_word_internal (w, q, i, c, e);
-  if (result == &expand_word_error || result == &expand_word_fatal)
-    {
-      /* By convention, each time this error is returned, w->word has
-        already been freed (it sometimes may not be in the fatal case,
-        but that doesn't result in a memory leak because we're going
-        to exit in most cases). */
-      w->word = (char *)NULL;
-      last_command_exit_value = EXECUTION_FAILURE;
-      exp_jump_to_top_level ((result == &expand_word_error) ? DISCARD : FORCE_EOF);
-      /* NOTREACHED */
-    }
-  else
-    return (result);
-}
-
-/* Perform parameter expansion, command substitution, and arithmetic
-   expansion on STRING, as if it were a word.  Leave the result quoted. */
-static WORD_LIST *
-expand_string_internal (string, quoted)
-     char *string;
-     int quoted;
-{
-  WORD_DESC td;
-  WORD_LIST *tresult;
-
-  if (string == 0 || *string == 0)
-    return ((WORD_LIST *)NULL);
-
-  td.flags = 0;
-  td.word = savestring (string);
-
-  tresult = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
-
-  FREE (td.word);
-  return (tresult);
-}
-
-/* Expand STRING by performing parameter expansion, command substitution,
-   and arithmetic expansion.  Dequote the resulting WORD_LIST before
-   returning it, but do not perform word splitting.  The call to
-   remove_quoted_nulls () is in here because word splitting normally
-   takes care of quote removal. */
-WORD_LIST *
-expand_string_unsplit (string, quoted)
-     char *string;
-     int quoted;
-{
-  WORD_LIST *value;
-
-  if (string == 0 || *string == '\0')
-    return ((WORD_LIST *)NULL);
-
-  expand_no_split_dollar_star = 1;
-  value = expand_string_internal (string, quoted);
-  expand_no_split_dollar_star = 0;
-
-  if (value)
-    {
-      if (value->word)
-       {
-         remove_quoted_nulls (value->word->word);
-         value->word->flags &= ~W_HASQUOTEDNULL;
-       }
-      dequote_list (value);
-    }
-  return (value);
-}
-
-/* Expand the rhs of an assignment statement */
-WORD_LIST *
-expand_string_assignment (string, quoted)
-     char *string;
-     int quoted;
-{
-  WORD_DESC td;
-  WORD_LIST *value;
-
-  if (string == 0 || *string == '\0')
-    return ((WORD_LIST *)NULL);
-
-  expand_no_split_dollar_star = 1;
-
-  td.flags = W_ASSIGNRHS;
-  td.word = savestring (string);
-  value = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
-  FREE (td.word);
-
-  expand_no_split_dollar_star = 0;
-
-  if (value)
-    {
-      if (value->word)
-       {
-         remove_quoted_nulls (value->word->word);
-         value->word->flags &= ~W_HASQUOTEDNULL;
-       }
-      dequote_list (value);
-    }
-  return (value);
-}
-
-
-/* Expand one of the PS? prompt strings. This is a sort of combination of
-   expand_string_unsplit and expand_string_internal, but returns the
-   passed string when an error occurs.  Might want to trap other calls
-   to jump_to_top_level here so we don't endlessly loop. */
-WORD_LIST *
-expand_prompt_string (string, quoted, wflags)
-     char *string;
-     int quoted;
-     int wflags;
-{
-  WORD_LIST *value;
-  WORD_DESC td;
-
-  if (string == 0 || *string == 0)
-    return ((WORD_LIST *)NULL);
-
-  td.flags = wflags;
-  td.word = savestring (string);
-
-  no_longjmp_on_fatal_error = 1;
-  value = expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
-  no_longjmp_on_fatal_error = 0;
-
-  if (value == &expand_word_error || value == &expand_word_fatal)
-    {
-      value = make_word_list (make_bare_word (string), (WORD_LIST *)NULL);
-      return value;
-    }
-  FREE (td.word);
-  if (value)
-    {
-      if (value->word)
-       {
-         remove_quoted_nulls (value->word->word);
-         value->word->flags &= ~W_HASQUOTEDNULL;
-       }
-      dequote_list (value);
-    }
-  return (value);
-}
-
-/* Expand STRING just as if you were expanding a word, but do not dequote
-   the resultant WORD_LIST.  This is called only from within this file,
-   and is used to correctly preserve quoted characters when expanding
-   things like ${1+"$@"}.  This does parameter expansion, command
-   substitution, arithmetic expansion, and word splitting. */
-static WORD_LIST *
-expand_string_leave_quoted (string, quoted)
-     char *string;
-     int quoted;
-{
-  WORD_LIST *tlist;
-  WORD_LIST *tresult;
-
-  if (string == 0 || *string == '\0')
-    return ((WORD_LIST *)NULL);
-
-  tlist = expand_string_internal (string, quoted);
-
-  if (tlist)
-    {
-      tresult = word_list_split (tlist);
-      dispose_words (tlist);
-      return (tresult);
-    }
-  return ((WORD_LIST *)NULL);
-}
-
-/* This does not perform word splitting or dequote the WORD_LIST
-   it returns. */
-static WORD_LIST *
-expand_string_for_rhs (string, quoted, dollar_at_p, has_dollar_at)
-     char *string;
-     int quoted, *dollar_at_p, *has_dollar_at;
-{
-  WORD_DESC td;
-  WORD_LIST *tresult;
-
-  if (string == 0 || *string == '\0')
-    return (WORD_LIST *)NULL;
-
-  td.flags = 0;
-  td.word = string;
-  tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, has_dollar_at);
-  return (tresult);
-}
-
-/* Expand STRING just as if you were expanding a word.  This also returns
-   a list of words.  Note that filename globbing is *NOT* done for word
-   or string expansion, just when the shell is expanding a command.  This
-   does parameter expansion, command substitution, arithmetic expansion,
-   and word splitting.  Dequote the resultant WORD_LIST before returning. */
-WORD_LIST *
-expand_string (string, quoted)
-     char *string;
-     int quoted;
-{
-  WORD_LIST *result;
-
-  if (string == 0 || *string == '\0')
-    return ((WORD_LIST *)NULL);
-
-  result = expand_string_leave_quoted (string, quoted);
-  return (result ? dequote_list (result) : result);
-}
-
-/***************************************************
- *                                                *
- *     Functions to handle quoting chars          *
- *                                                *
- ***************************************************/
-
-/* Conventions:
-
-     A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string.
-     The parser passes CTLNUL as CTLESC CTLNUL. */
-
-/* Quote escape characters in string s, but no other characters.  This is
-   used to protect CTLESC and CTLNUL in variable values from the rest of
-   the word expansion process after the variable is expanded (word splitting
-   and filename generation).  If IFS is null, we quote spaces as well, just
-   in case we split on spaces later (in the case of unquoted $@, we will
-   eventually attempt to split the entire word on spaces).  Corresponding
-   code exists in dequote_escapes.  Even if we don't end up splitting on
-   spaces, quoting spaces is not a problem.  This should never be called on
-   a string that is quoted with single or double quotes or part of a here
-   document (effectively double-quoted). */
-char *
-quote_escapes (string)
-     char *string;
-{
-  register char *s, *t;
-  size_t slen;
-  char *result, *send;
-  int quote_spaces, skip_ctlesc, skip_ctlnul;
-  DECLARE_MBSTATE; 
-
-  slen = strlen (string);
-  send = string + slen;
-
-  quote_spaces = (ifs_value && *ifs_value == 0);
-
-  for (skip_ctlesc = skip_ctlnul = 0, s = ifs_value; s && *s; s++)
-    skip_ctlesc |= *s == CTLESC, skip_ctlnul |= *s == CTLNUL;
-
-  t = result = (char *)xmalloc ((slen * 2) + 1);
-  s = string;
-
-  while (*s)
-    {
-      if ((skip_ctlesc == 0 && *s == CTLESC) || (skip_ctlnul == 0 && *s == CTLNUL) || (quote_spaces && *s == ' '))
-       *t++ = CTLESC;
-      COPY_CHAR_P (t, s, send);
-    }
-  *t = '\0';
-  return (result);
-}
-
-static WORD_LIST *
-list_quote_escapes (list)
-     WORD_LIST *list;
-{
-  register WORD_LIST *w;
-  char *t;
-
-  for (w = list; w; w = w->next)
-    {
-      t = w->word->word;
-      w->word->word = quote_escapes (t);
-      free (t);
-    }
-  return list;
-}
-
-/* Inverse of quote_escapes; remove CTLESC protecting CTLESC or CTLNUL.
-
-   The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL.
-   This is necessary to make unquoted CTLESC and CTLNUL characters in the
-   data stream pass through properly.
-
-   We need to remove doubled CTLESC characters inside quoted strings before
-   quoting the entire string, so we do not double the number of CTLESC
-   characters.
-
-   Also used by parts of the pattern substitution code. */
-char *
-dequote_escapes (string)
-     char *string;
-{
-  register char *s, *t, *s1;
-  size_t slen;
-  char *result, *send;
-  int quote_spaces;
-  DECLARE_MBSTATE;
-
-  if (string == 0)
-    return string;
-
-  slen = strlen (string);
-  send = string + slen;
-
-  t = result = (char *)xmalloc (slen + 1);
-
-  if (strchr (string, CTLESC) == 0)
-    return (strcpy (result, string));
-
-  quote_spaces = (ifs_value && *ifs_value == 0);
-
-  s = string;
-  while (*s)
-    {
-      if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL || (quote_spaces && s[1] == ' ')))
-       {
-         s++;
-         if (*s == '\0')
-           break;
-       }
-      COPY_CHAR_P (t, s, send);
-    }
-  *t = '\0';
-  return result;
-}
-
-/* Return a new string with the quoted representation of character C.
-   This turns "" into QUOTED_NULL, so the W_HASQUOTEDNULL flag needs to be
-   set in any resultant WORD_DESC where this value is the word. */
-static char *
-make_quoted_char (c)
-     int c;
-{
-  char *temp;
-
-  temp = (char *)xmalloc (3);
-  if (c == 0)
-    {
-      temp[0] = CTLNUL;
-      temp[1] = '\0';
-    }
-  else
-    {
-      temp[0] = CTLESC;
-      temp[1] = c;
-      temp[2] = '\0';
-    }
-  return (temp);
-}
-
-/* Quote STRING, returning a new string.  This turns "" into QUOTED_NULL, so
-   the W_HASQUOTEDNULL flag needs to be set in any resultant WORD_DESC where
-   this value is the word. */
-char *
-quote_string (string)
-     char *string;
-{
-  register char *t;
-  size_t slen;
-  char *result, *send;
-
-  if (*string == 0)
-    {
-      result = (char *)xmalloc (2);
-      result[0] = CTLNUL;
-      result[1] = '\0';
-    }
-  else
-    {
-      DECLARE_MBSTATE;
-
-      slen = strlen (string);
-      send = string + slen;
-
-      result = (char *)xmalloc ((slen * 2) + 1);
-
-      for (t = result; string < send; )
-       {
-         *t++ = CTLESC;
-         COPY_CHAR_P (t, string, send);
-       }
-      *t = '\0';
-    }
-  return (result);
-}
-
-/* De-quote quoted characters in STRING. */
-char *
-dequote_string (string)
-     char *string;
-{
-  register char *s, *t;
-  size_t slen;
-  char *result, *send;
-  DECLARE_MBSTATE;
-
-  slen = strlen (string);
-
-  t = result = (char *)xmalloc (slen + 1);
-
-  if (QUOTED_NULL (string))
-    {
-      result[0] = '\0';
-      return (result);
-    }
-
-  /* If no character in the string can be quoted, don't bother examining
-     each character.  Just return a copy of the string passed to us. */
-  if (strchr (string, CTLESC) == NULL)
-    return (strcpy (result, string));
-
-  send = string + slen;
-  s = string;
-  while (*s)
-    {
-      if (*s == CTLESC)
-       {
-         s++;
-         if (*s == '\0')
-           break;
-       }
-      COPY_CHAR_P (t, s, send);
-    }
-
-  *t = '\0';
-  return (result);
-}
-
-/* Quote the entire WORD_LIST list. */
-static WORD_LIST *
-quote_list (list)
-     WORD_LIST *list;
-{
-  register WORD_LIST *w;
-  char *t;
-
-  for (w = list; w; w = w->next)
-    {
-      t = w->word->word;
-      w->word->word = quote_string (t);
-      if (*t == 0)
-       w->word->flags |= W_HASQUOTEDNULL;      /* XXX - turn on W_HASQUOTEDNULL here? */
-      w->word->flags |= W_QUOTED;
-      free (t);
-    }
-  return list;
-}
-
-/* De-quote quoted characters in each word in LIST. */
-WORD_LIST *
-dequote_list (list)
-     WORD_LIST *list;
-{
-  register char *s;
-  register WORD_LIST *tlist;
-
-  for (tlist = list; tlist; tlist = tlist->next)
-    {
-      s = dequote_string (tlist->word->word);
-      if (QUOTED_NULL (tlist->word->word))
-       tlist->word->flags &= ~W_HASQUOTEDNULL;
-      free (tlist->word->word);
-      tlist->word->word = s;
-    }
-  return list;
-}
-
-/* Remove CTLESC protecting a CTLESC or CTLNUL in place.  Return the passed
-   string. */
-char *
-remove_quoted_escapes (string)
-     char *string;
-{
-  char *t;
-
-  if (string)
-    {
-      t = dequote_escapes (string);
-      strcpy (string, t);
-      free (t);
-    }
-
-  return (string);
-}
-
-/* Perform quoted null character removal on STRING.  We don't allow any
-   quoted null characters in the middle or at the ends of strings because
-   of how expand_word_internal works.  remove_quoted_nulls () turns
-   STRING into an empty string iff it only consists of a quoted null,
-   and removes all unquoted CTLNUL characters. */
-char *
-remove_quoted_nulls (string)
-     char *string;
-{
-  register size_t slen;
-  register int i, j, prev_i;
-  DECLARE_MBSTATE;
-
-  if (strchr (string, CTLNUL) == 0)            /* XXX */
-    return string;                             /* XXX */
-
-  slen = strlen (string);
-  i = j = 0;
-
-  while (i < slen)
-    {
-      if (string[i] == CTLESC)
-       {
-         /* Old code had j++, but we cannot assume that i == j at this
-            point -- what if a CTLNUL has already been removed from the
-            string?  We don't want to drop the CTLESC or recopy characters
-            that we've already copied down. */
-         i++; string[j++] = CTLESC;
-         if (i == slen)
-           break;
-       }
-      else if (string[i] == CTLNUL)
-       i++;
-
-      prev_i = i;
-      ADVANCE_CHAR (string, slen, i);
-      if (j < prev_i)
-       {
-         do string[j++] = string[prev_i++]; while (prev_i < i);
-       }
-      else
-       j = i;
-    }
-  string[j] = '\0';
-
-  return (string);
-}
-
-/* Perform quoted null character removal on each element of LIST.
-   This modifies LIST. */
-void
-word_list_remove_quoted_nulls (list)
-     WORD_LIST *list;
-{
-  register WORD_LIST *t;
-
-  for (t = list; t; t = t->next)
-    {
-      remove_quoted_nulls (t->word->word);
-      t->word->flags &= ~W_HASQUOTEDNULL;
-    }
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*        Functions for Matching and Removing Patterns             */
-/*                                                                 */
-/* **************************************************************** */
-
-#if defined (HANDLE_MULTIBYTE)
-#if 0 /* Currently unused */
-static unsigned char *
-mb_getcharlens (string, len)
-     char *string;
-     int len;
-{
-  int i, offset, last;
-  unsigned char *ret;
-  char *p;
-  DECLARE_MBSTATE;
-
-  i = offset = 0;
-  last = 0;
-  ret = (unsigned char *)xmalloc (len);
-  memset (ret, 0, len);
-  while (string[last])
-    {
-      ADVANCE_CHAR (string, len, offset);
-      ret[last] = offset - last;
-      last = offset;
-    }
-  return ret;
-}
-#endif
-#endif
-
-/* Remove the portion of PARAM matched by PATTERN according to OP, where OP
-   can have one of 4 values:
-       RP_LONG_LEFT    remove longest matching portion at start of PARAM
-       RP_SHORT_LEFT   remove shortest matching portion at start of PARAM
-       RP_LONG_RIGHT   remove longest matching portion at end of PARAM
-       RP_SHORT_RIGHT  remove shortest matching portion at end of PARAM
-*/
-
-#define RP_LONG_LEFT   1
-#define RP_SHORT_LEFT  2
-#define RP_LONG_RIGHT  3
-#define RP_SHORT_RIGHT 4
-
-static char *
-remove_upattern (param, pattern, op)
-     char *param, *pattern;
-     int op;
-{
-  register int len;
-  register char *end;
-  register char *p, *ret, c;
-
-  len = STRLEN (param);
-  end = param + len;
-
-  switch (op)
-    {
-      case RP_LONG_LEFT:       /* remove longest match at start */
-       for (p = end; p >= param; p--)
-         {
-           c = *p; *p = '\0';
-           if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               *p = c;
-               return (savestring (p));
-             }
-           *p = c;
-
-         }
-       break;
-
-      case RP_SHORT_LEFT:      /* remove shortest match at start */
-       for (p = param; p <= end; p++)
-         {
-           c = *p; *p = '\0';
-           if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               *p = c;
-               return (savestring (p));
-             }
-           *p = c;
-         }
-       break;
-
-      case RP_LONG_RIGHT:      /* remove longest match at end */
-       for (p = param; p <= end; p++)
-         {
-           if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               c = *p; *p = '\0';
-               ret = savestring (param);
-               *p = c;
-               return (ret);
-             }
-         }
-       break;
-
-      case RP_SHORT_RIGHT:     /* remove shortest match at end */
-       for (p = end; p >= param; p--)
-         {
-           if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               c = *p; *p = '\0';
-               ret = savestring (param);
-               *p = c;
-               return (ret);
-             }
-         }
-       break;
-    }
-
-  return (savestring (param)); /* no match, return original string */
-}
-
-#if defined (HANDLE_MULTIBYTE)
-static wchar_t *
-remove_wpattern (wparam, wstrlen, wpattern, op)
-     wchar_t *wparam;
-     size_t wstrlen;
-     wchar_t *wpattern;
-     int op;
-{
-  wchar_t wc, *ret;
-  int n;
-
-  switch (op)
-    {
-      case RP_LONG_LEFT:       /* remove longest match at start */
-        for (n = wstrlen; n >= 0; n--)
-         {
-           wc = wparam[n]; wparam[n] = L'\0';
-           if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               wparam[n] = wc;
-               return (wcsdup (wparam + n));
-             }
-           wparam[n] = wc;
-         }
-       break;
-
-      case RP_SHORT_LEFT:      /* remove shortest match at start */
-       for (n = 0; n <= wstrlen; n++)
-         {
-           wc = wparam[n]; wparam[n] = L'\0';
-           if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               wparam[n] = wc;
-               return (wcsdup (wparam + n));
-             }
-           wparam[n] = wc;
-         }
-       break;
-
-      case RP_LONG_RIGHT:      /* remove longest match at end */
-        for (n = 0; n <= wstrlen; n++)
-         {
-           if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               wc = wparam[n]; wparam[n] = L'\0';
-               ret = wcsdup (wparam);
-               wparam[n] = wc;
-               return (ret);
-             }
-         }
-       break;
-
-      case RP_SHORT_RIGHT:     /* remove shortest match at end */
-       for (n = wstrlen; n >= 0; n--)
-         {
-           if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH)
-             {
-               wc = wparam[n]; wparam[n] = L'\0';
-               ret = wcsdup (wparam);
-               wparam[n] = wc;
-               return (ret);
-             }
-         }
-       break;
-    }
-
-  return (wcsdup (wparam));    /* no match, return original string */
-}
-#endif /* HANDLE_MULTIBYTE */
-
-static char *
-remove_pattern (param, pattern, op)
-     char *param, *pattern;
-     int op;
-{
-  if (param == NULL)
-    return (param);
-  if (*param == '\0' || pattern == NULL || *pattern == '\0')   /* minor optimization */
-    return (savestring (param));
-
-#if defined (HANDLE_MULTIBYTE)
-  if (MB_CUR_MAX > 1)
-    {
-      wchar_t *ret, *oret;
-      size_t n;
-      wchar_t *wparam, *wpattern;
-      mbstate_t ps;
-      char *xret;
-
-      n = xdupmbstowcs (&wpattern, NULL, pattern);
-      if (n == (size_t)-1)
-       return (remove_upattern (param, pattern, op));
-      n = xdupmbstowcs (&wparam, NULL, param);
-      if (n == (size_t)-1)
-       {
-         free (wpattern);
-         return (remove_upattern (param, pattern, op));
-       }
-      oret = ret = remove_wpattern (wparam, n, wpattern, op);
-
-      free (wparam);
-      free (wpattern);
-
-      n = strlen (param);
-      xret = (char *)xmalloc (n + 1);
-      memset (&ps, '\0', sizeof (mbstate_t));
-      n = wcsrtombs (xret, (const wchar_t **)&ret, n, &ps);
-      xret[n] = '\0';          /* just to make sure */
-      free (oret);
-      return xret;      
-    }
-  else
-#endif
-    return (remove_upattern (param, pattern, op));
-}
-
-/* Return 1 of the first character of STRING could match the first
-   character of pattern PAT.  Used to avoid n2 calls to strmatch(). */
-static int
-match_pattern_char (pat, string)
-     char *pat, *string;
-{
-  char c;
-
-  if (*string == 0)
-    return (0);
-
-  switch (c = *pat++)
-    {
-    default:
-      return (*string == c);
-    case '\\':
-      return (*string == *pat);
-    case '?':
-      return (*pat == LPAREN ? 1 : (*string != '\0'));
-    case '*':
-      return (1);
-    case '+':
-    case '!':
-    case '@':
-      return (*pat == LPAREN ? 1 : (*string == c));
-    case '[':
-      return (*string != '\0');
-    }
-}
-
-/* Match PAT anywhere in STRING and return the match boundaries.
-   This returns 1 in case of a successful match, 0 otherwise.  SP
-   and EP are pointers into the string where the match begins and
-   ends, respectively.  MTYPE controls what kind of match is attempted.
-   MATCH_BEG and MATCH_END anchor the match at the beginning and end
-   of the string, respectively.  The longest match is returned. */
-static int
-match_upattern (string, pat, mtype, sp, ep)
-     char *string, *pat;
-     int mtype;
-     char **sp, **ep;
-{
-  int c, len;
-  register char *p, *p1, *npat;
-  char *end;
-
-  /* If the pattern doesn't match anywhere in the string, go ahead and
-     short-circuit right away.  A minor optimization, saves a bunch of
-     unnecessary calls to strmatch (up to N calls for a string of N
-     characters) if the match is unsuccessful.  To preserve the semantics
-     of the substring matches below, we make sure that the pattern has
-     `*' as first and last character, making a new pattern if necessary. */
-  /* XXX - check this later if I ever implement `**' with special meaning,
-     since this will potentially result in `**' at the beginning or end */
-  len = STRLEN (pat);
-  if (pat[0] != '*' || (pat[0] == '*' && pat[1] == LPAREN && extended_glob) || pat[len - 1] != '*')
-    {
-      p = npat = (char *)xmalloc (len + 3);
-      p1 = pat;
-      if (*p1 != '*' || (*p1 == '*' && p1[1] == LPAREN && extended_glob))
-       *p++ = '*';
-      while (*p1)
-       *p++ = *p1++;
-      if (p1[-1] != '*' || p[-2] == '\\')
-       *p++ = '*';
-      *p = '\0';
-    }
-  else
-    npat = pat;
-  c = strmatch (npat, string, FNMATCH_EXTFLAG);
-  if (npat != pat)
-    free (npat);
-  if (c == FNM_NOMATCH)
-    return (0);
-
-  len = STRLEN (string);
-  end = string + len;
-
-  switch (mtype)
-    {
-    case MATCH_ANY:
-      for (p = string; p <= end; p++)
-       {
-         if (match_pattern_char (pat, p))
-           {
-             for (p1 = end; p1 >= p; p1--)
-               {
-                 c = *p1; *p1 = '\0';
-                 if (strmatch (pat, p, FNMATCH_EXTFLAG) == 0)
-                   {
-                     *p1 = c;
-                     *sp = p;
-                     *ep = p1;
-                     return 1;
-                   }
-                 *p1 = c;
-               }
-           }
-       }
-
-      return (0);
-
-    case MATCH_BEG:
-      if (match_pattern_char (pat, string) == 0)
-       return (0);
-
-      for (p = end; p >= string; p--)
-       {
-         c = *p; *p = '\0';
-         if (strmatch (pat, string, FNMATCH_EXTFLAG) == 0)
-           {
-             *p = c;
-             *sp = string;
-             *ep = p;
-             return 1;
-           }
-         *p = c;
-       }
-
-      return (0);
-
-    case MATCH_END:
-      for (p = string; p <= end; p++)
-       {
-         if (strmatch (pat, p, FNMATCH_EXTFLAG) == 0)
-           {
-             *sp = p;
-             *ep = end;
-             return 1;
-           }
-
-       }
-
-      return (0);
-    }
-
-  return (0);
-}
-
-#if defined (HANDLE_MULTIBYTE)
-/* Return 1 of the first character of WSTRING could match the first
-   character of pattern WPAT.  Wide character version. */
-static int
-match_pattern_wchar (wpat, wstring)
-     wchar_t *wpat, *wstring;
-{
-  wchar_t wc;
-
-  if (*wstring == 0)
-    return (0);
-
-  switch (wc = *wpat++)
-    {
-    default:
-      return (*wstring == wc);
-    case L'\\':
-      return (*wstring == *wpat);
-    case L'?':
-      return (*wpat == LPAREN ? 1 : (*wstring != L'\0'));
-    case L'*':
-      return (1);
-    case L'+':
-    case L'!':
-    case L'@':
-      return (*wpat == LPAREN ? 1 : (*wstring == wc));
-    case L'[':
-      return (*wstring != L'\0');
-    }
-}
-
-/* Match WPAT anywhere in WSTRING and return the match boundaries.
-   This returns 1 in case of a successful match, 0 otherwise.  Wide
-   character version. */
-static int
-match_wpattern (wstring, indices, wstrlen, wpat, mtype, sp, ep)
-     wchar_t *wstring;
-     char **indices;
-     size_t wstrlen;
-     wchar_t *wpat;
-     int mtype;
-     char **sp, **ep;
-{
-  wchar_t wc, *wp, *nwpat, *wp1;
-  int len;
-#if 0
-  size_t n, n1;        /* Apple's gcc seems to miscompile this badly */
-#else
-  int n, n1;
-#endif
-
-  /* If the pattern doesn't match anywhere in the string, go ahead and
-     short-circuit right away.  A minor optimization, saves a bunch of
-     unnecessary calls to strmatch (up to N calls for a string of N
-     characters) if the match is unsuccessful.  To preserve the semantics
-     of the substring matches below, we make sure that the pattern has
-     `*' as first and last character, making a new pattern if necessary. */
-  /* XXX - check this later if I ever implement `**' with special meaning,
-     since this will potentially result in `**' at the beginning or end */
-  len = wcslen (wpat);
-  if (wpat[0] != L'*' || (wpat[0] == L'*' && wpat[1] == WLPAREN && extended_glob) || wpat[len - 1] != L'*')
-    {
-      wp = nwpat = (wchar_t *)xmalloc ((len + 3) * sizeof (wchar_t));
-      wp1 = wpat;
-      if (*wp1 != L'*' || (*wp1 == '*' && wp1[1] == WLPAREN && extended_glob))
-       *wp++ = L'*';
-      while (*wp1 != L'\0')
-       *wp++ = *wp1++;
-      if (wp1[-1] != L'*' || wp1[-2] == L'\\')
-        *wp++ = L'*';
-      *wp = '\0';
-    }
-  else
-    nwpat = wpat;
-  len = wcsmatch (nwpat, wstring, FNMATCH_EXTFLAG);
-  if (nwpat != wpat)
-    free (nwpat);
-  if (len == FNM_NOMATCH)
-    return (0);
-
-  switch (mtype)
-    {
-    case MATCH_ANY:
-      for (n = 0; n <= wstrlen; n++)
-       {
-         if (match_pattern_wchar (wpat, wstring + n))
-           {
-             for (n1 = wstrlen; n1 >= n; n1--)
-               {
-                 wc = wstring[n1]; wstring[n1] = L'\0';
-                 if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG) == 0)
-                   {
-                     wstring[n1] = wc;
-                     *sp = indices[n];
-                     *ep = indices[n1];
-                     return 1;
-                   }
-                 wstring[n1] = wc;
-               }
-           }
-       }
-
-      return (0);
-
-    case MATCH_BEG:
-      if (match_pattern_wchar (wpat, wstring) == 0)
-       return (0);
-
-      for (n = wstrlen; n >= 0; n--)
-       {
-         wc = wstring[n]; wstring[n] = L'\0';
-         if (wcsmatch (wpat, wstring, FNMATCH_EXTFLAG) == 0)
-           {
-             wstring[n] = wc;
-             *sp = indices[0];
-             *ep = indices[n];
-             return 1;
-           }
-         wstring[n] = wc;
-       }
-
-      return (0);
-
-    case MATCH_END:
-      for (n = 0; n <= wstrlen; n++)
-       {
-         if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG) == 0)
-           {
-             *sp = indices[n];
-             *ep = indices[wstrlen];
-             return 1;
-           }
-       }
-
-      return (0);
-    }
-
-  return (0);
-}
-#endif /* HANDLE_MULTIBYTE */
-
-static int
-match_pattern (string, pat, mtype, sp, ep)
-     char *string, *pat;
-     int mtype;
-     char **sp, **ep;
-{
-#if defined (HANDLE_MULTIBYTE)
-  int ret;
-  size_t n;
-  wchar_t *wstring, *wpat;
-  char **indices;
-#endif
-
-  if (string == 0 || *string == 0 || pat == 0 || *pat == 0)
-    return (0);
-
-#if defined (HANDLE_MULTIBYTE)
-  if (MB_CUR_MAX > 1)
-    {
-      n = xdupmbstowcs (&wpat, NULL, pat);
-      if (n == (size_t)-1)
-       return (match_upattern (string, pat, mtype, sp, ep));
-      n = xdupmbstowcs (&wstring, &indices, string);
-      if (n == (size_t)-1)
-       {
-         free (wpat);
-         return (match_upattern (string, pat, mtype, sp, ep));
-       }
-      ret = match_wpattern (wstring, indices, n, wpat, mtype, sp, ep);
-
-      free (wpat);
-      free (wstring);
-      free (indices);
-
-      return (ret);
-    }
-  else
-#endif
-    return (match_upattern (string, pat, mtype, sp, ep));
-}
-
-static int
-getpatspec (c, value)
-     int c;
-     char *value;
-{
-  if (c == '#')
-    return ((*value == '#') ? RP_LONG_LEFT : RP_SHORT_LEFT);
-  else /* c == '%' */
-    return ((*value == '%') ? RP_LONG_RIGHT : RP_SHORT_RIGHT);
-}
-
-/* Posix.2 says that the WORD should be run through tilde expansion,
-   parameter expansion, command substitution and arithmetic expansion.
-   This leaves the result quoted, so quote_string_for_globbing () has
-   to be called to fix it up for strmatch ().  If QUOTED is non-zero,
-   it means that the entire expression was enclosed in double quotes.
-   This means that quoting characters in the pattern do not make any
-   special pattern characters quoted.  For example, the `*' in the
-   following retains its special meaning: "${foo#'*'}". */
-static char *
-getpattern (value, quoted, expandpat)
-     char *value;
-     int quoted, expandpat;
-{
-  char *pat, *tword;
-  WORD_LIST *l;
-#if 0
-  int i;
-#endif
-  /* There is a problem here:  how to handle single or double quotes in the
-     pattern string when the whole expression is between double quotes?
-     POSIX.2 says that enclosing double quotes do not cause the pattern to
-     be quoted, but does that leave us a problem with @ and array[@] and their
-     expansions inside a pattern? */
-#if 0
-  if (expandpat && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *tword)
-    {
-      i = 0;
-      pat = string_extract_double_quoted (tword, &i, 1);
-      free (tword);
-      tword = pat;
-    }
-#endif
-
-  /* expand_string_for_rhs () leaves WORD quoted and does not perform
-     word splitting. */
-  l = *value ? expand_string_for_rhs (value,
-                                     (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? Q_PATQUOTE : quoted,
-                                     (int *)NULL, (int *)NULL)
-            : (WORD_LIST *)0;
-  pat = string_list (l);
-  dispose_words (l);
-  if (pat)
-    {
-      tword = quote_string_for_globbing (pat, QGLOB_CVTNULL);
-      free (pat);
-      pat = tword;
-    }
-  return (pat);
-}
-
-#if 0
-/* Handle removing a pattern from a string as a result of ${name%[%]value}
-   or ${name#[#]value}. */
-static char *
-variable_remove_pattern (value, pattern, patspec, quoted)
-     char *value, *pattern;
-     int patspec, quoted;
-{
-  char *tword;
-
-  tword = remove_pattern (value, pattern, patspec);
-
-  return (tword);
-}
-#endif
-
-static char *
-list_remove_pattern (list, pattern, patspec, itype, quoted)
-     WORD_LIST *list;
-     char *pattern;
-     int patspec, itype, quoted;
-{
-  WORD_LIST *new, *l;
-  WORD_DESC *w;
-  char *tword;
-
-  for (new = (WORD_LIST *)NULL, l = list; l; l = l->next)
-    {
-      tword = remove_pattern (l->word->word, pattern, patspec);
-      w = alloc_word_desc ();
-      w->word = tword ? tword : savestring ("");
-      new = make_word_list (w, new);
-    }
-
-  l = REVERSE_LIST (new, WORD_LIST *);
-  tword = string_list_pos_params (itype, l, quoted);
-  dispose_words (l);
-
-  return (tword);
-}
-
-static char *
-parameter_list_remove_pattern (itype, pattern, patspec, quoted)
-     int itype;
-     char *pattern;
-     int patspec, quoted;
-{
-  char *ret;
-  WORD_LIST *list;
-
-  list = list_rest_of_args ();
-  if (list == 0)
-    return ((char *)NULL);
-  ret = list_remove_pattern (list, pattern, patspec, itype, quoted);
-  dispose_words (list);
-  return (ret);
-}
-
-#if defined (ARRAY_VARS)
-static char *
-array_remove_pattern (var, pattern, patspec, varname, quoted)
-     SHELL_VAR *var;
-     char *pattern;
-     int patspec;
-     char *varname;    /* so we can figure out how it's indexed */
-     int quoted;
-{
-  ARRAY *a;
-  HASH_TABLE *h;
-  int itype;
-  char *ret;
-  WORD_LIST *list;
-  SHELL_VAR *v;
-
-  /* compute itype from varname here */
-  v = array_variable_part (varname, &ret, 0);
-  itype = ret[0];
-
-  a = (v && array_p (v)) ? array_cell (v) : 0;
-  h = (v && assoc_p (v)) ? assoc_cell (v) : 0;
-  
-  list = a ? array_to_word_list (a) : (h ? assoc_to_word_list (h) : 0);
-  if (list == 0)
-   return ((char *)NULL);
-  ret = list_remove_pattern (list, pattern, patspec, itype, quoted);
-  dispose_words (list);
-
-  return ret;
-}
-#endif /* ARRAY_VARS */
-
-static char *
-parameter_brace_remove_pattern (varname, value, patstr, rtype, quoted)
-     char *varname, *value, *patstr;
-     int rtype, quoted;
-{
-  int vtype, patspec, starsub;
-  char *temp1, *val, *pattern;
-  SHELL_VAR *v;
-
-  if (value == 0)
-    return ((char *)NULL);
-
-  this_command_name = varname;
-
-  vtype = get_var_and_type (varname, value, quoted, &v, &val);
-  if (vtype == -1)
-    return ((char *)NULL);
-
-  starsub = vtype & VT_STARSUB;
-  vtype &= ~VT_STARSUB;
-
-  patspec = getpatspec (rtype, patstr);
-  if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT)
-    patstr++;
-
-  /* Need to pass getpattern newly-allocated memory in case of expansion --
-     the expansion code will free the passed string on an error. */
-  temp1 = savestring (patstr);
-  pattern = getpattern (temp1, quoted, 1);
-  free (temp1);
-
-  temp1 = (char *)NULL;                /* shut up gcc */
-  switch (vtype)
-    {
-    case VT_VARIABLE:
-    case VT_ARRAYMEMBER:
-      temp1 = remove_pattern (val, pattern, patspec);
-      if (vtype == VT_VARIABLE)
-       FREE (val);
-      if (temp1)
-       {
-         val = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-                       ? quote_string (temp1)
-                       : quote_escapes (temp1);
-         free (temp1);
-         temp1 = val;
-       }
-      break;
-#if defined (ARRAY_VARS)
-    case VT_ARRAYVAR:
-      temp1 = array_remove_pattern (v, pattern, patspec, varname, quoted);
-      if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
-       {
-         val = quote_escapes (temp1);
-         free (temp1);
-         temp1 = val;
-       }
-      break;
-#endif
-    case VT_POSPARMS:
-      temp1 = parameter_list_remove_pattern (varname[0], pattern, patspec, quoted);
-      if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
-       {
-         val = quote_escapes (temp1);
-         free (temp1);
-         temp1 = val;
-       }
-      break;
-    }
-
-  FREE (pattern);
-  return temp1;
-}    
-
-/*******************************************
- *                                        *
- *     Functions to expand WORD_DESCs     *
- *                                        *
- *******************************************/
-
-/* Expand WORD, performing word splitting on the result.  This does
-   parameter expansion, command substitution, arithmetic expansion,
-   word splitting, and quote removal. */
-
-WORD_LIST *
-expand_word (word, quoted)
-     WORD_DESC *word;
-     int quoted;
-{
-  WORD_LIST *result, *tresult;
-
-  tresult = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
-  result = word_list_split (tresult);
-  dispose_words (tresult);
-  return (result ? dequote_list (result) : result);
-}
-
-/* Expand WORD, but do not perform word splitting on the result.  This
-   does parameter expansion, command substitution, arithmetic expansion,
-   and quote removal. */
-WORD_LIST *
-expand_word_unsplit (word, quoted)
-     WORD_DESC *word;
-     int quoted;
-{
-  WORD_LIST *result;
-
-  expand_no_split_dollar_star = 1;
-#if defined (HANDLE_MULTIBYTE)
-  if (ifs_firstc[0] == 0)
-#else
-  if (ifs_firstc == 0)
-#endif
-    word->flags |= W_NOSPLIT;
-  result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
-  expand_no_split_dollar_star = 0;
-
-  return (result ? dequote_list (result) : result);
-}
-
-/* Perform shell expansions on WORD, but do not perform word splitting or
-   quote removal on the result.  Virtually identical to expand_word_unsplit;
-   could be combined if implementations don't diverge. */
-WORD_LIST *
-expand_word_leave_quoted (word, quoted)
-     WORD_DESC *word;
-     int quoted;
-{
-  WORD_LIST *result;
-
-  expand_no_split_dollar_star = 1;
-#if defined (HANDLE_MULTIBYTE)
-  if (ifs_firstc[0] == 0)
-#else
-  if (ifs_firstc == 0)
-#endif
-    word->flags |= W_NOSPLIT;
-  word->flags |= W_NOSPLIT2;
-  result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
-  expand_no_split_dollar_star = 0;
-
-  return result;
-}
-
-#if defined (PROCESS_SUBSTITUTION)
-
-/*****************************************************************/
-/*                                                              */
-/*                 Hacking Process Substitution                 */
-/*                                                              */
-/*****************************************************************/
-
-#if !defined (HAVE_DEV_FD)
-/* Named pipes must be removed explicitly with `unlink'.  This keeps a list
-   of FIFOs the shell has open.  unlink_fifo_list will walk the list and
-   unlink all of them. add_fifo_list adds the name of an open FIFO to the
-   list.  NFIFO is a count of the number of FIFOs in the list. */
-#define FIFO_INCR 20
-
-struct temp_fifo {
-  char *file;
-  pid_t proc;
-};
-
-static struct temp_fifo *fifo_list = (struct temp_fifo *)NULL;
-static int nfifo;
-static int fifo_list_size;
-
-static void
-add_fifo_list (pathname)
-     char *pathname;
-{
-  if (nfifo >= fifo_list_size - 1)
-    {
-      fifo_list_size += FIFO_INCR;
-      fifo_list = (struct temp_fifo *)xrealloc (fifo_list,
-                               fifo_list_size * sizeof (struct temp_fifo));
-    }
-
-  fifo_list[nfifo].file = savestring (pathname);
-  nfifo++;
-}
-
-void
-unlink_fifo_list ()
-{
-  int saved, i, j;
-
-  if (nfifo == 0)
-    return;
-
-  for (i = saved = 0; i < nfifo; i++)
-    {
-      if ((fifo_list[i].proc == -1) || (kill(fifo_list[i].proc, 0) == -1))
-       {
-         unlink (fifo_list[i].file);
-         free (fifo_list[i].file);
-         fifo_list[i].file = (char *)NULL;
-         fifo_list[i].proc = -1;
-       }
-      else
-       saved++;
-    }
-
-  /* If we didn't remove some of the FIFOs, compact the list. */
-  if (saved)
-    {
-      for (i = j = 0; i < nfifo; i++)
-       if (fifo_list[i].file)
-         {
-           fifo_list[j].file = fifo_list[i].file;
-           fifo_list[j].proc = fifo_list[i].proc;
-           j++;
-         }
-      nfifo = j;
-    }
-  else
-    nfifo = 0;
-}
-
-int
-fifos_pending ()
-{
-  return nfifo;
-}
-
-static char *
-make_named_pipe ()
-{
-  char *tname;
-
-  tname = sh_mktmpname ("sh-np", MT_USERANDOM|MT_USETMPDIR);
-  if (mkfifo (tname, 0600) < 0)
-    {
-      free (tname);
-      return ((char *)NULL);
-    }
-
-  add_fifo_list (tname);
-  return (tname);
-}
-
-#else /* HAVE_DEV_FD */
-
-/* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
-   has open to children.  NFDS is a count of the number of bits currently
-   set in DEV_FD_LIST.  TOTFDS is a count of the highest possible number
-   of open files. */
-static char *dev_fd_list = (char *)NULL;
-static int nfds;
-static int totfds;     /* The highest possible number of open files. */
-
-static void
-add_fifo_list (fd)
-     int fd;
-{
-  if (!dev_fd_list || fd >= totfds)
-    {
-      int ofds;
-
-      ofds = totfds;
-      totfds = getdtablesize ();
-      if (totfds < 0 || totfds > 256)
-       totfds = 256;
-      if (fd >= totfds)
-       totfds = fd + 2;
-
-      dev_fd_list = (char *)xrealloc (dev_fd_list, totfds);
-      memset (dev_fd_list + ofds, '\0', totfds - ofds);
-    }
-
-  dev_fd_list[fd] = 1;
-  nfds++;
-}
-
-int
-fifos_pending ()
-{
-  return 0;    /* used for cleanup; not needed with /dev/fd */
-}
-
-void
-unlink_fifo_list ()
-{
-  register int i;
-
-  if (nfds == 0)
-    return;
-
-  for (i = 0; nfds && i < totfds; i++)
-    if (dev_fd_list[i])
-      {
-       close (i);
-       dev_fd_list[i] = 0;
-       nfds--;
-      }
-
-  nfds = 0;
-}
-
-#if defined (NOTDEF)
-print_dev_fd_list ()
-{
-  register int i;
-
-  fprintf (stderr, "pid %ld: dev_fd_list:", (long)getpid ());
-  fflush (stderr);
-
-  for (i = 0; i < totfds; i++)
-    {
-      if (dev_fd_list[i])
-       fprintf (stderr, " %d", i);
-    }
-  fprintf (stderr, "\n");
-}
-#endif /* NOTDEF */
-
-static char *
-make_dev_fd_filename (fd)
-     int fd;
-{
-  char *ret, intbuf[INT_STRLEN_BOUND (int) + 1], *p;
-
-  ret = (char *)xmalloc (sizeof (DEV_FD_PREFIX) + 8);
-
-  strcpy (ret, DEV_FD_PREFIX);
-  p = inttostr (fd, intbuf, sizeof (intbuf));
-  strcpy (ret + sizeof (DEV_FD_PREFIX) - 1, p);
-
-  add_fifo_list (fd);
-  return (ret);
-}
-
-#endif /* HAVE_DEV_FD */
-
-/* Return a filename that will open a connection to the process defined by
-   executing STRING.  HAVE_DEV_FD, if defined, means open a pipe and return
-   a filename in /dev/fd corresponding to a descriptor that is one of the
-   ends of the pipe.  If not defined, we use named pipes on systems that have
-   them.  Systems without /dev/fd and named pipes are out of luck.
-
-   OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
-   use the read end of the pipe and dup that file descriptor to fd 0 in
-   the child.  If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
-   writing or use the write end of the pipe in the child, and dup that
-   file descriptor to fd 1 in the child.  The parent does the opposite. */
-
-static char *
-process_substitute (string, open_for_read_in_child)
-     char *string;
-     int open_for_read_in_child;
-{
-  char *pathname;
-  int fd, result;
-  pid_t old_pid, pid;
-#if defined (HAVE_DEV_FD)
-  int parent_pipe_fd, child_pipe_fd;
-  int fildes[2];
-#endif /* HAVE_DEV_FD */
-#if defined (JOB_CONTROL)
-  pid_t old_pipeline_pgrp;
-#endif
-
-  if (!string || !*string || wordexp_only)
-    return ((char *)NULL);
-
-#if !defined (HAVE_DEV_FD)
-  pathname = make_named_pipe ();
-#else /* HAVE_DEV_FD */
-  if (pipe (fildes) < 0)
-    {
-      sys_error (_("cannot make pipe for process substitution"));
-      return ((char *)NULL);
-    }
-  /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
-     the pipe in the parent, otherwise the read end. */
-  parent_pipe_fd = fildes[open_for_read_in_child];
-  child_pipe_fd = fildes[1 - open_for_read_in_child];
-  /* Move the parent end of the pipe to some high file descriptor, to
-     avoid clashes with FDs used by the script. */
-  parent_pipe_fd = move_to_high_fd (parent_pipe_fd, 1, 64);
-
-  pathname = make_dev_fd_filename (parent_pipe_fd);
-#endif /* HAVE_DEV_FD */
-
-  if (pathname == 0)
-    {
-      sys_error (_("cannot make pipe for process substitution"));
-      return ((char *)NULL);
-    }
-
-  old_pid = last_made_pid;
-
-#if defined (JOB_CONTROL)
-  old_pipeline_pgrp = pipeline_pgrp;
-  pipeline_pgrp = shell_pgrp;
-  save_pipeline (1);
-#endif /* JOB_CONTROL */
-
-  pid = make_child ((char *)NULL, 1);
-  if (pid == 0)
-    {
-      reset_terminating_signals ();    /* XXX */
-      free_pushed_string_input ();
-      /* Cancel traps, in trap.c. */
-      restore_original_signals ();
-      setup_async_signals ();
-      subshell_environment |= SUBSHELL_COMSUB|SUBSHELL_PROCSUB;
-    }
-
-#if defined (JOB_CONTROL)
-  set_sigchld_handler ();
-  stop_making_children ();
-  /* XXX - should we only do this in the parent? (as in command subst) */
-  pipeline_pgrp = old_pipeline_pgrp;
-#endif /* JOB_CONTROL */
-
-  if (pid < 0)
-    {
-      sys_error (_("cannot make child for process substitution"));
-      free (pathname);
-#if defined (HAVE_DEV_FD)
-      close (parent_pipe_fd);
-      close (child_pipe_fd);
-#endif /* HAVE_DEV_FD */
-      return ((char *)NULL);
-    }
-
-  if (pid > 0)
-    {
-#if defined (JOB_CONTROL)
-      restore_pipeline (1);
-#endif
-
-#if !defined (HAVE_DEV_FD)
-      fifo_list[nfifo-1].proc = pid;
-#endif
-
-      last_made_pid = old_pid;
-
-#if defined (JOB_CONTROL) && defined (PGRP_PIPE)
-      close_pgrp_pipe ();
-#endif /* JOB_CONTROL && PGRP_PIPE */
-
-#if defined (HAVE_DEV_FD)
-      close (child_pipe_fd);
-#endif /* HAVE_DEV_FD */
-
-      return (pathname);
-    }
-
-  set_sigint_handler ();
-
-#if defined (JOB_CONTROL)
-  set_job_control (0);
-#endif /* JOB_CONTROL */
-
-#if !defined (HAVE_DEV_FD)
-  /* Open the named pipe in the child. */
-  fd = open (pathname, open_for_read_in_child ? O_RDONLY|O_NONBLOCK : O_WRONLY);
-  if (fd < 0)
-    {
-      /* Two separate strings for ease of translation. */
-      if (open_for_read_in_child)
-       sys_error (_("cannot open named pipe %s for reading"), pathname);
-      else
-       sys_error (_("cannot open named pipe %s for writing"), pathname);
-
-      exit (127);
-    }
-  if (open_for_read_in_child)
-    {
-      if (sh_unset_nodelay_mode (fd) < 0)
-       {
-         sys_error (_("cannot reset nodelay mode for fd %d"), fd);
-         exit (127);
-       }
-    }
-#else /* HAVE_DEV_FD */
-  fd = child_pipe_fd;
-#endif /* HAVE_DEV_FD */
-
-  if (dup2 (fd, open_for_read_in_child ? 0 : 1) < 0)
-    {
-      sys_error (_("cannot duplicate named pipe %s as fd %d"), pathname,
-       open_for_read_in_child ? 0 : 1);
-      exit (127);
-    }
-
-  if (fd != (open_for_read_in_child ? 0 : 1))
-    close (fd);
-
-  /* Need to close any files that this process has open to pipes inherited
-     from its parent. */
-  if (current_fds_to_close)
-    {
-      close_fd_bitmap (current_fds_to_close);
-      current_fds_to_close = (struct fd_bitmap *)NULL;
-    }
-
-#if defined (HAVE_DEV_FD)
-  /* Make sure we close the parent's end of the pipe and clear the slot
-     in the fd list so it is not closed later, if reallocated by, for
-     instance, pipe(2). */
-  close (parent_pipe_fd);
-  dev_fd_list[parent_pipe_fd] = 0;
-#endif /* HAVE_DEV_FD */
-
-  result = parse_and_execute (string, "process substitution", (SEVAL_NONINT|SEVAL_NOHIST));
-
-#if !defined (HAVE_DEV_FD)
-  /* Make sure we close the named pipe in the child before we exit. */
-  close (open_for_read_in_child ? 0 : 1);
-#endif /* !HAVE_DEV_FD */
-
-  exit (result);
-  /*NOTREACHED*/
-}
-#endif /* PROCESS_SUBSTITUTION */
-
-/***********************************/
-/*                                */
-/*     Command Substitution       */
-/*                                */
-/***********************************/
-
-static char *
-read_comsub (fd, quoted, rflag)
-     int fd, quoted;
-     int *rflag;
-{
-  char *istring, buf[128], *bufp, *s;
-  int istring_index, istring_size, c, tflag, skip_ctlesc, skip_ctlnul;
-  ssize_t bufn;
-
-  istring = (char *)NULL;
-  istring_index = istring_size = bufn = tflag = 0;
-
-  for (skip_ctlesc = skip_ctlnul = 0, s = ifs_value; s && *s; s++)
-    skip_ctlesc |= *s == CTLESC, skip_ctlnul |= *s == CTLNUL;
-
-#ifdef __CYGWIN__
-  setmode (fd, O_TEXT);                /* we don't want CR/LF, we want Unix-style */
-#endif
-
-  /* Read the output of the command through the pipe.  This may need to be
-     changed to understand multibyte characters in the future. */
-  while (1)
-    {
-      if (fd < 0)
-       break;
-      if (--bufn <= 0)
-       {
-         bufn = zread (fd, buf, sizeof (buf));
-         if (bufn <= 0) 
-           break;
-         bufp = buf;
-       }
-      c = *bufp++;
-
-      if (c == 0)
-       {
-#if 0
-         internal_warning ("read_comsub: ignored null byte in input");
-#endif
-         continue;
-       }
-
-      /* Add the character to ISTRING, possibly after resizing it. */
-      RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE);
-
-      /* This is essentially quote_string inline */
-      if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) /* || c == CTLESC || c == CTLNUL */)
-       istring[istring_index++] = CTLESC;
-      /* Escape CTLESC and CTLNUL in the output to protect those characters
-        from the rest of the word expansions (word splitting and globbing.)
-        This is essentially quote_escapes inline. */
-      else if (skip_ctlesc == 0 && c == CTLESC)
-       {
-         tflag |= W_HASCTLESC;
-         istring[istring_index++] = CTLESC;
-       }
-      else if ((skip_ctlnul == 0 && c == CTLNUL) || (c == ' ' && (ifs_value && *ifs_value == 0)))
-       istring[istring_index++] = CTLESC;
-
-      istring[istring_index++] = c;
-
-#if 0
-#if defined (__CYGWIN__)
-      if (c == '\n' && istring_index > 1 && istring[istring_index - 2] == '\r')
-       {
-         istring_index--;
-         istring[istring_index - 1] = '\n';
-       }
-#endif
-#endif
-    }
-
-  if (istring)
-    istring[istring_index] = '\0';
-
-  /* If we read no output, just return now and save ourselves some
-     trouble. */
-  if (istring_index == 0)
-    {
-      FREE (istring);
-      if (rflag)
-       *rflag = tflag;
-      return (char *)NULL;
-    }
-
-  /* Strip trailing newlines from the output of the command. */
-  if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-    {
-      while (istring_index > 0)
-       {
-         if (istring[istring_index - 1] == '\n')
-           {
-             --istring_index;
-
-             /* If the newline was quoted, remove the quoting char. */
-             if (istring[istring_index - 1] == CTLESC)
-               --istring_index;
-           }
-         else
-           break;
-       }
-      istring[istring_index] = '\0';
-    }
-  else
-    strip_trailing (istring, istring_index - 1, 1);
-
-  if (rflag)
-    *rflag = tflag;
-  return istring;
-}
-
-/* Perform command substitution on STRING.  This returns a WORD_DESC * with the
-   contained string possibly quoted. */
-WORD_DESC *
-command_substitute (string, quoted)
-     char *string;
-     int quoted;
-{
-  pid_t pid, old_pid, old_pipeline_pgrp, old_async_pid;
-  char *istring;
-  int result, fildes[2], function_value, pflags, rc, tflag;
-  WORD_DESC *ret;
-
-  istring = (char *)NULL;
-
-  /* Don't fork () if there is no need to.  In the case of no command to
-     run, just return NULL. */
-  if (!string || !*string || (string[0] == '\n' && !string[1]))
-    return ((WORD_DESC *)NULL);
-
-  if (wordexp_only && read_but_dont_execute)
-    {
-      last_command_exit_value = EX_WEXPCOMSUB;
-      jump_to_top_level (EXITPROG);
-    }
-
-  /* We're making the assumption here that the command substitution will
-     eventually run a command from the file system.  Since we'll run
-     maybe_make_export_env in this subshell before executing that command,
-     the parent shell and any other shells it starts will have to remake
-     the environment.  If we make it before we fork, other shells won't
-     have to.  Don't bother if we have any temporary variable assignments,
-     though, because the export environment will be remade after this
-     command completes anyway, but do it if all the words to be expanded
-     are variable assignments. */
-  if (subst_assign_varlist == 0 || garglist == 0)
-    maybe_make_export_env ();  /* XXX */
-
-  /* Flags to pass to parse_and_execute() */
-  pflags = (interactive && sourcelevel == 0) ? SEVAL_RESETLINE : 0;
-
-  /* Pipe the output of executing STRING into the current shell. */
-  if (pipe (fildes) < 0)
-    {
-      sys_error (_("cannot make pipe for command substitution"));
-      goto error_exit;
-    }
-
-  old_pid = last_made_pid;
-#if defined (JOB_CONTROL)
-  old_pipeline_pgrp = pipeline_pgrp;
-  /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
-  if ((subshell_environment & SUBSHELL_PIPE) == 0)
-    pipeline_pgrp = shell_pgrp;
-  cleanup_the_pipeline ();
-#endif /* JOB_CONTROL */
-
-  old_async_pid = last_asynchronous_pid;
-  pid = make_child ((char *)NULL, subshell_environment&SUBSHELL_ASYNC);
-  last_asynchronous_pid = old_async_pid;
-
-  if (pid == 0)
-    /* Reset the signal handlers in the child, but don't free the
-       trap strings. */
-    reset_signal_handlers ();
-
-#if defined (JOB_CONTROL)
-  /* XXX DO THIS ONLY IN PARENT ? XXX */
-  set_sigchld_handler ();
-  stop_making_children ();
-  if (pid != 0)
-    pipeline_pgrp = old_pipeline_pgrp;
-#else
-  stop_making_children ();
-#endif /* JOB_CONTROL */
-
-  if (pid < 0)
-    {
-      sys_error (_("cannot make child for command substitution"));
-    error_exit:
-
-      FREE (istring);
-      close (fildes[0]);
-      close (fildes[1]);
-      return ((WORD_DESC *)NULL);
-    }
-
-  if (pid == 0)
-    {
-      set_sigint_handler ();   /* XXX */
-
-      free_pushed_string_input ();
-
-      if (dup2 (fildes[1], 1) < 0)
-       {
-         sys_error (_("command_substitute: cannot duplicate pipe as fd 1"));
-         exit (EXECUTION_FAILURE);
-       }
-
-      /* If standard output is closed in the parent shell
-        (such as after `exec >&-'), file descriptor 1 will be
-        the lowest available file descriptor, and end up in
-        fildes[0].  This can happen for stdin and stderr as well,
-        but stdout is more important -- it will cause no output
-        to be generated from this command. */
-      if ((fildes[1] != fileno (stdin)) &&
-         (fildes[1] != fileno (stdout)) &&
-         (fildes[1] != fileno (stderr)))
-       close (fildes[1]);
-
-      if ((fildes[0] != fileno (stdin)) &&
-         (fildes[0] != fileno (stdout)) &&
-         (fildes[0] != fileno (stderr)))
-       close (fildes[0]);
-
-      /* The currently executing shell is not interactive. */
-      interactive = 0;
-
-      /* This is a subshell environment. */
-      subshell_environment |= SUBSHELL_COMSUB;
-
-      /* When not in POSIX mode, command substitution does not inherit
-        the -e flag. */
-      if (posixly_correct == 0)
-       exit_immediately_on_error = 0;
-
-      remove_quoted_escapes (string);
-
-      startup_state = 2;       /* see if we can avoid a fork */
-      /* Give command substitution a place to jump back to on failure,
-        so we don't go back up to main (). */
-      result = setjmp (top_level);
-
-      /* If we're running a command substitution inside a shell function,
-        trap `return' so we don't return from the function in the subshell
-        and go off to never-never land. */
-      if (result == 0 && return_catch_flag)
-       function_value = setjmp (return_catch);
-      else
-       function_value = 0;
-
-      if (result == ERREXIT)
-       rc = last_command_exit_value;
-      else if (result == EXITPROG)
-       rc = last_command_exit_value;
-      else if (result)
-       rc = EXECUTION_FAILURE;
-      else if (function_value)
-       rc = return_catch_value;
-      else
-       {
-         subshell_level++;
-         rc = parse_and_execute (string, "command substitution", pflags|SEVAL_NOHIST);
-         subshell_level--;
-       }
-
-      last_command_exit_value = rc;
-      rc = run_exit_trap ();
-#if defined (PROCESS_SUBSTITUTION)
-      unlink_fifo_list ();
-#endif
-      exit (rc);
-    }
-  else
-    {
-#if defined (JOB_CONTROL) && defined (PGRP_PIPE)
-      close_pgrp_pipe ();
-#endif /* JOB_CONTROL && PGRP_PIPE */
-
-      close (fildes[1]);
-
-      tflag = 0;
-      istring = read_comsub (fildes[0], quoted, &tflag);
-
-      close (fildes[0]);
-
-      current_command_subst_pid = pid;
-      last_command_exit_value = wait_for (pid);
-      last_command_subst_pid = pid;
-      last_made_pid = old_pid;
-
-#if defined (JOB_CONTROL)
-      /* If last_command_exit_value > 128, then the substituted command
-        was terminated by a signal.  If that signal was SIGINT, then send
-        SIGINT to ourselves.  This will break out of loops, for instance. */
-      if (last_command_exit_value == (128 + SIGINT) && last_command_exit_signal == SIGINT)
-       kill (getpid (), SIGINT);
-
-      /* wait_for gives the terminal back to shell_pgrp.  If some other
-        process group should have it, give it away to that group here.
-        pipeline_pgrp is non-zero only while we are constructing a
-        pipline, so what we are concerned about is whether or not that
-        pipeline was started in the background.  A pipeline started in
-        the background should never get the tty back here. */
-#if 0
-      if (interactive && pipeline_pgrp != (pid_t)0 && pipeline_pgrp != last_asynchronous_pid)
-#else
-      if (interactive && pipeline_pgrp != (pid_t)0 && (subshell_environment & SUBSHELL_ASYNC) == 0)
-#endif
-       give_terminal_to (pipeline_pgrp, 0);
-#endif /* JOB_CONTROL */
-
-      ret = alloc_word_desc ();
-      ret->word = istring;
-      ret->flags = tflag;
-
-      return ret;
-    }
-}
-
-/********************************************************
- *                                                     *
- *     Utility functions for parameter expansion       *
- *                                                     *
- ********************************************************/
-
-#if defined (ARRAY_VARS)
-
-static arrayind_t
-array_length_reference (s)
-     char *s;
-{
-  int len;
-  arrayind_t ind;
-  char *akey;
-  char *t, c;
-  ARRAY *array;
-  SHELL_VAR *var;
-
-  var = array_variable_part (s, &t, &len);
-
-  /* If unbound variables should generate an error, report one and return
-     failure. */
-  if ((var == 0 || (assoc_p (var) == 0 && array_p (var) == 0)) && unbound_vars_is_error)
-    {
-      c = *--t;
-      *t = '\0';
-      last_command_exit_value = EXECUTION_FAILURE;
-      err_unboundvar (s);
-      *t = c;
-      return (-1);
-    }
-  else if (var == 0)
-    return 0;
-
-  /* We support a couple of expansions for variables that are not arrays.
-     We'll return the length of the value for v[0], and 1 for v[@] or
-     v[*].  Return 0 for everything else. */
-
-  array = array_p (var) ? array_cell (var) : (ARRAY *)NULL;
-
-  if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']')
-    {
-      if (assoc_p (var))
-       return (assoc_num_elements (assoc_cell (var)));
-      else if (array_p (var))
-       return (array_num_elements (array));
-      else
-       return 1;
-    }
-
-  if (assoc_p (var))
-    {
-      t[len - 1] = '\0';
-      akey = expand_assignment_string_to_string (t, 0);        /* [ */
-      t[len - 1] = ']';
-      if (akey == 0 || *akey == 0)
-       {
-         err_badarraysub (t);
-         return (-1);
-       }
-      t = assoc_reference (assoc_cell (var), akey);
-    }
-  else
-    {
-      ind = array_expand_index (t, len);
-      if (ind < 0)
-       {
-         err_badarraysub (t);
-         return (-1);
-       }
-      if (array_p (var))
-       t = array_reference (array, ind);
-      else
-       t = (ind == 0) ? value_cell (var) : (char *)NULL;
-    }
-
-  len = MB_STRLEN (t);
-  return (len);
-}
-#endif /* ARRAY_VARS */
-
-static int
-valid_brace_expansion_word (name, var_is_special)
-     char *name;
-     int var_is_special;
-{
-  if (DIGIT (*name) && all_digits (name))
-    return 1;
-  else if (var_is_special)
-    return 1;
-#if defined (ARRAY_VARS)
-  else if (valid_array_reference (name))
-    return 1;
-#endif /* ARRAY_VARS */
-  else if (legal_identifier (name))
-    return 1;
-  else
-    return 0;
-}
-
-static int
-chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at)
-     char *name;
-     int quoted;
-     int *quoted_dollar_atp, *contains_dollar_at;
-{
-  char *temp1;
-
-  if (name == 0)
-    {
-      if (quoted_dollar_atp)
-       *quoted_dollar_atp = 0;
-      if (contains_dollar_at)
-       *contains_dollar_at = 0;
-      return 0;
-    }
-
-  /* check for $@ and $* */
-  if (name[0] == '@' && name[1] == 0)
-    {
-      if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-       *quoted_dollar_atp = 1;
-      if (contains_dollar_at)
-       *contains_dollar_at = 1;
-      return 1;
-    }
-  else if (name[0] == '*' && name[1] == '\0' && quoted == 0)
-    {
-      if (contains_dollar_at)
-       *contains_dollar_at = 1;
-      return 1;
-    }
-
-  /* Now check for ${array[@]} and ${array[*]} */
-#if defined (ARRAY_VARS)
-  else if (valid_array_reference (name))
-    {
-      temp1 = mbschr (name, '[');
-      if (temp1 && temp1[1] == '@' && temp1[2] == ']')
-       {
-         if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-           *quoted_dollar_atp = 1;
-         if (contains_dollar_at)
-           *contains_dollar_at = 1;
-         return 1;
-       }       /* [ */
-      /* ${array[*]}, when unquoted, should be treated like ${array[@]},
-        which should result in separate words even when IFS is unset. */
-      if (temp1 && temp1[1] == '*' && temp1[2] == ']' && quoted == 0)
-       {
-         if (contains_dollar_at)
-           *contains_dollar_at = 1;
-         return 1;
-       }
-    }
-#endif
-  return 0;
-}
-
-/* Parameter expand NAME, and return a new string which is the expansion,
-   or NULL if there was no expansion.
-   VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
-   the shell, e.g., "@", "$", "*", etc.  QUOTED, if non-zero, means that
-   NAME was found inside of a double-quoted expression. */
-static WORD_DESC *
-parameter_brace_expand_word (name, var_is_special, quoted, pflags)
-     char *name;
-     int var_is_special, quoted, pflags;
-{
-  WORD_DESC *ret;
-  char *temp, *tt;
-  intmax_t arg_index;
-  SHELL_VAR *var;
-  int atype, rflags;
-
-  ret = 0;
-  temp = 0;
-  rflags = 0;
-
-  /* Handle multiple digit arguments, as in ${11}. */  
-  if (legal_number (name, &arg_index))
-    {
-      tt = get_dollar_var_value (arg_index);
-      if (tt)
-       temp = (*tt && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-                 ? quote_string (tt)
-                 : quote_escapes (tt);
-      else
-        temp = (char *)NULL;
-      FREE (tt);
-    }
-  else if (var_is_special)      /* ${@} */
-    {
-      int sindex;
-      tt = (char *)xmalloc (2 + strlen (name));
-      tt[sindex = 0] = '$';
-      strcpy (tt + 1, name);
-
-      ret = param_expand (tt, &sindex, quoted, (int *)NULL, (int *)NULL,
-                         (int *)NULL, (int *)NULL, pflags);
-      free (tt);
-    }
-#if defined (ARRAY_VARS)
-  else if (valid_array_reference (name))
-    {
-      temp = array_value (name, quoted, &atype);
-      if (atype == 0 && temp)
-       temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-                 ? quote_string (temp)
-                 : quote_escapes (temp);
-      else if (atype == 1 && temp && QUOTED_NULL (temp) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-       rflags |= W_HASQUOTEDNULL;
-    }
-#endif
-  else if (var = find_variable (name))
-    {
-      if (var_isset (var) && invisible_p (var) == 0)
-       {
-#if defined (ARRAY_VARS)
-         if (assoc_p (var))
-           temp = assoc_reference (assoc_cell (var), "0");
-         else if (array_p (var))
-           temp = array_reference (array_cell (var), 0);
-         else
-           temp = value_cell (var);
-#else
-         temp = value_cell (var);
-#endif
-
-         if (temp)
-           temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-                     ? quote_string (temp)
-                     : quote_escapes (temp);
-       }
-      else
-       temp = (char *)NULL;
-    }
-  else
-    temp = (char *)NULL;
-
-  if (ret == 0)
-    {
-      ret = alloc_word_desc ();
-      ret->word = temp;
-      ret->flags |= rflags;
-    }
-  return ret;
-}
-
-/* Expand an indirect reference to a variable: ${!NAME} expands to the
-   value of the variable whose name is the value of NAME. */
-static WORD_DESC *
-parameter_brace_expand_indir (name, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at)
-     char *name;
-     int var_is_special, quoted;
-     int *quoted_dollar_atp, *contains_dollar_at;
-{
-  char *temp, *t;
-  WORD_DESC *w;
-
-  w = parameter_brace_expand_word (name, var_is_special, quoted, PF_IGNUNBOUND);
-  t = w->word;
-  /* Have to dequote here if necessary */
-  if (t)
-    {
-      temp = (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
-               ? dequote_string (t)
-               : dequote_escapes (t);
-      free (t);
-      t = temp;
-    }
-  dispose_word_desc (w);
-
-  chk_atstar (t, quoted, quoted_dollar_atp, contains_dollar_at);
-  if (t == 0)
-    return (WORD_DESC *)NULL;
-
-  w = parameter_brace_expand_word (t, SPECIAL_VAR(t, 0), quoted, 0);
-  free (t);
-
-  return w;
-}
-
-/* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
-   depending on the value of C, the separating character.  C can be one of
-   "-", "+", or "=".  QUOTED is true if the entire brace expression occurs
-   between double quotes. */
-static WORD_DESC *
-parameter_brace_expand_rhs (name, value, c, quoted, qdollaratp, hasdollarat)
-     char *name, *value;
-     int c, quoted, *qdollaratp, *hasdollarat;
-{
-  WORD_DESC *w;
-  WORD_LIST *l;
-  char *t, *t1, *temp;
-  int hasdol;
-
-  /* If the entire expression is between double quotes, we want to treat
-     the value as a double-quoted string, with the exception that we strip
-     embedded unescaped double quotes (for sh backwards compatibility). */
-  if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *value)
-    {
-      hasdol = 0;
-      temp = string_extract_double_quoted (value, &hasdol, 1);
-    }
-  else
-    temp = value;
-
-  w = alloc_word_desc ();
-  hasdol = 0;
-  /* XXX was 0 not quoted */
-  l = *temp ? expand_string_for_rhs (temp, quoted, &hasdol, (int *)NULL)
-           : (WORD_LIST *)0;
-  if (hasdollarat)
-    *hasdollarat = hasdol || (l && l->next);
-  if (temp != value)
-    free (temp);
-  if (l)
-    {
-      /* The expansion of TEMP returned something.  We need to treat things
-         slightly differently if HASDOL is non-zero.  If we have "$@", the
-         individual words have already been quoted.  We need to turn them
-         into a string with the words separated by the first character of
-         $IFS without any additional quoting, so string_list_dollar_at won't
-         do the right thing.  We use string_list_dollar_star instead. */
-      temp = (hasdol || l->next) ? string_list_dollar_star (l) : string_list (l);
-
-      /* If l->next is not null, we know that TEMP contained "$@", since that
-        is the only expansion that creates more than one word. */
-      if (qdollaratp && ((hasdol && quoted) || l->next))
-       *qdollaratp = 1;
-      dispose_words (l);
-    }
-  else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && hasdol)
-    {
-      /* The brace expansion occurred between double quotes and there was
-        a $@ in TEMP.  It does not matter if the $@ is quoted, as long as
-        it does not expand to anything.  In this case, we want to return
-        a quoted empty string. */
-      temp = make_quoted_char ('\0');
-      w->flags |= W_HASQUOTEDNULL;
-    }
-  else
-    temp = (char *)NULL;
-
-  if (c == '-' || c == '+')
-    {
-      w->word = temp;
-      return w;
-    }
-
-  /* c == '=' */
-  t = temp ? savestring (temp) : savestring ("");
-  t1 = dequote_string (t);
-  free (t);
-#if defined (ARRAY_VARS)
-  if (valid_array_reference (name))
-    assign_array_element (name, t1, 0);
-  else
-#endif /* ARRAY_VARS */
-  bind_variable (name, t1, 0);
-  free (t1);
-
-  w->word = temp;
-  return w;
-}
-
-/* Deal with the right hand side of a ${name:?value} expansion in the case
-   that NAME is null or not set.  If VALUE is non-null it is expanded and
-   used as the error message to print, otherwise a standard message is
-   printed. */
-static void
-parameter_brace_expand_error (name, value)
-     char *name, *value;
-{
-  WORD_LIST *l;
-  char *temp;
-
-  if (value && *value)
-    {
-      l = expand_string (value, 0);
-      temp =  string_list (l);
-      report_error ("%s: %s", name, temp ? temp : ""); /* XXX was value not "" */
-      FREE (temp);
-      dispose_words (l);
-    }
-  else
-    report_error (_("%s: parameter null or not set"), name);
-
-  /* Free the data we have allocated during this expansion, since we
-     are about to longjmp out. */
-  free (name);
-  FREE (value);
-}
-
-/* Return 1 if NAME is something for which parameter_brace_expand_length is
-   OK to do. */
-static int
-valid_length_expression (name)
-     char *name;
-{
-  return (name[1] == '\0' ||                                   /* ${#} */
-         ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0') ||  /* special param */
-         (DIGIT (name[1]) && all_digits (name + 1)) || /* ${#11} */
-#if defined (ARRAY_VARS)
-         valid_array_reference (name + 1) ||                   /* ${#a[7]} */
-#endif
-         legal_identifier (name + 1));                         /* ${#PS1} */
-}
-
-#if defined (HANDLE_MULTIBYTE)
-size_t
-mbstrlen (s)
-     const char *s;
-{
-  size_t clen, nc;
-  mbstate_t mbs, mbsbak;
-
-  nc = 0;
-  memset (&mbs, 0, sizeof (mbs));
-  mbsbak = mbs;
-  while ((clen = mbrlen(s, MB_CUR_MAX, &mbs)) != 0)
-    {
-      if (MB_INVALIDCH(clen))
-        {
-         clen = 1;     /* assume single byte */
-         mbs = mbsbak;
-        }
-
-      s += clen;
-      nc++;
-      mbsbak = mbs;
-    }
-  return nc;
-}
-#endif
-      
-
-/* Handle the parameter brace expansion that requires us to return the
-   length of a parameter. */
-static intmax_t
-parameter_brace_expand_length (name)
-     char *name;
-{
-  char *t, *newname;
-  intmax_t number, arg_index;
-  WORD_LIST *list;
-#if defined (ARRAY_VARS)
-  SHELL_VAR *var;
-#endif
-
-  if (name[1] == '\0')                 /* ${#} */
-    number = number_of_args ();
-  else if ((name[1] == '@' || name[1] == '*') && name[2] == '\0')      /* ${#@}, ${#*} */
-    number = number_of_args ();
-  else if ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0')
-    {
-      /* Take the lengths of some of the shell's special parameters. */
-      switch (name[1])
-       {
-       case '-':
-         t = which_set_flags ();
-         break;
-       case '?':
-         t = itos (last_command_exit_value);
-         break;
-       case '$':
-         t = itos (dollar_dollar_pid);
-         break;
-       case '!':
-         if (last_asynchronous_pid == NO_PID)
-           t = (char *)NULL;
-         else
-           t = itos (last_asynchronous_pid);
-         break;
-       case '#':
-         t = itos (number_of_args ());
-         break;
-       }
-      number = STRLEN (t);
-      FREE (t);
-    }
-#if defined (ARRAY_VARS)
-  else if (valid_array_reference (name + 1))
-    number = array_length_reference (name + 1);
-#endif /* ARRAY_VARS */
-  else
-    {
-      number = 0;
-
-      if (legal_number (name + 1, &arg_index))         /* ${#1} */
-       {
-         t = get_dollar_var_value (arg_index);
-         number = MB_STRLEN (t);
-         FREE (t);
-       }
-#if defined (ARRAY_VARS)
-      else if ((var = find_variable (name + 1)) && (invisible_p (var) == 0) && (array_p (var) || assoc_p (var)))
-       {
-         if (assoc_p (var))
-           t = assoc_reference (assoc_cell (var), "0");
-         else
-           t = array_reference (array_cell (var), 0);
-         number = MB_STRLEN (t);
-       }
-#endif
-      else                             /* ${#PS1} */
-       {
-         newname = savestring (name);
-         newname[0] = '$';
-         list = expand_string (newname, Q_DOUBLE_QUOTES);
-         t = list ? string_list (list) : (char *)NULL;
-         free (newname);
-         if (list)
-           dispose_words (list);
-
-         number = MB_STRLEN (t);
-         FREE (t);
-       }
-    }
-
-  return (number);
-}
-
-/* Skip characters in SUBSTR until DELIM.  SUBSTR is an arithmetic expression,
-   so we do some ad-hoc parsing of an arithmetic expression to find
-   the first DELIM, instead of using strchr(3).  Two rules:
-       1.  If the substring contains a `(', read until closing `)'.
-       2.  If the substring contains a `?', read past one `:' for each `?'.
-*/
-
-static char *
-skiparith (substr, delim)
-     char *substr;
-     int delim;
-{
-  size_t sublen;
-  int skipcol, pcount, i;
-  DECLARE_MBSTATE;
-
-  sublen = strlen (substr);
-  i = skipcol = pcount = 0;
-  while (substr[i])
-    {
-      /* Balance parens */
-      if (substr[i] == LPAREN)
-       {
-         pcount++;
-         i++;
-         continue;
-       }
-      if (substr[i] == RPAREN && pcount)
-       {
-         pcount--;
-         i++;
-         continue;
-       }
-      if (pcount)
-       {
-         ADVANCE_CHAR (substr, sublen, i);
-         continue;
-       }
-
-      /* Skip one `:' for each `?' */
-      if (substr[i] == ':' && skipcol)
-       {
-         skipcol--;
-         i++;
-         continue;
-       }
-      if (substr[i] == delim)
-       break;
-      if (substr[i] == '?')
-       {
-         skipcol++;
-         i++;
-         continue;
-       }
-      ADVANCE_CHAR (substr, sublen, i);
-    }
-
-  return (substr + i);
-}
-
-/* Verify and limit the start and end of the desired substring.  If
-   VTYPE == 0, a regular shell variable is being used; if it is 1,
-   then the positional parameters are being used; if it is 2, then
-   VALUE is really a pointer to an array variable that should be used.
-   Return value is 1 if both values were OK, 0 if there was a problem
-   with an invalid expression, or -1 if the values were out of range. */
-static int
-verify_substring_values (v, value, substr, vtype, e1p, e2p)
-     SHELL_VAR *v;
-     char *value, *substr;
-     int vtype;
-     intmax_t *e1p, *e2p;
-{
-  char *t, *temp1, *temp2;
-  arrayind_t len;
-  int expok;
-#if defined (ARRAY_VARS)
- ARRAY *a;
- HASH_TABLE *h;
-#endif
-
-  /* duplicate behavior of strchr(3) */
-  t = skiparith (substr, ':');
-  if (*t && *t == ':')
-    *t = '\0';
-  else
-    t = (char *)0;
-
-  temp1 = expand_arith_string (substr, Q_DOUBLE_QUOTES);
-  *e1p = evalexp (temp1, &expok);
-  free (temp1);
-  if (expok == 0)
-    return (0);
-
-  len = -1;    /* paranoia */
-  switch (vtype)
-    {
-    case VT_VARIABLE:
-    case VT_ARRAYMEMBER:
-      len = MB_STRLEN (value);
-      break;
-    case VT_POSPARMS:
-      len = number_of_args () + 1;
-      if (*e1p == 0)
-       len++;          /* add one arg if counting from $0 */
-      break;
-#if defined (ARRAY_VARS)
-    case VT_ARRAYVAR:
-      /* For arrays, the first value deals with array indices.  Negative
-        offsets count from one past the array's maximum index.  Associative
-        arrays treat the number of elements as the maximum index. */
-      if (assoc_p (v))
-       {
-         h = assoc_cell (v);
-         len = assoc_num_elements (h) + (*e1p < 0);
-       }
-      else
-       {
-         a = (ARRAY *)value;
-         len = array_max_index (a) + (*e1p < 0);       /* arrays index from 0 to n - 1 */
-       }
-      break;
-#endif
-    }
-
-  if (len == -1)       /* paranoia */
-    return -1;
-
-  if (*e1p < 0)                /* negative offsets count from end */
-    *e1p += len;
-
-  if (*e1p > len || *e1p < 0)
-    return (-1);
-
-#if defined (ARRAY_VARS)
-  /* For arrays, the second offset deals with the number of elements. */
-  if (vtype == VT_ARRAYVAR)
-    len = assoc_p (v) ? assoc_num_elements (h) : array_num_elements (a);
-#endif
-
-  if (t)
-    {
-      t++;
-      temp2 = savestring (t);
-      temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES);
-      free (temp2);
-      t[-1] = ':';
-      *e2p = evalexp (temp1, &expok);
-      free (temp1);
-      if (expok == 0)
-       return (0);
-      if (*e2p < 0)
-       {
-         internal_error (_("%s: substring expression < 0"), t);
-         return (0);
-       }
-#if defined (ARRAY_VARS)
-      /* In order to deal with sparse arrays, push the intelligence about how
-        to deal with the number of elements desired down to the array-
-        specific functions.  */
-      if (vtype != VT_ARRAYVAR)
-#endif
-       {
-         *e2p += *e1p;         /* want E2 chars starting at E1 */
-         if (*e2p > len)
-           *e2p = len;
-       }
-    }
-  else
-    *e2p = len;
-
-  return (1);
-}
-
-/* Return the type of variable specified by VARNAME (simple variable,
-   positional param, or array variable).  Also return the value specified
-   by VARNAME (value of a variable or a reference to an array element).
-   If this returns VT_VARIABLE, the caller assumes that CTLESC and CTLNUL
-   characters in the value are quoted with CTLESC and takes appropriate
-   steps.  For convenience, *VALP is set to the dequoted VALUE. */
-static int
-get_var_and_type (varname, value, quoted, varp, valp)
-     char *varname, *value;
-     int quoted;
-     SHELL_VAR **varp;
-     char **valp;
-{
-  int vtype;
-  char *temp;
-#if defined (ARRAY_VARS)
-  SHELL_VAR *v;
-#endif
-
-  /* This sets vtype to VT_VARIABLE or VT_POSPARMS */
-  vtype = (varname[0] == '@' || varname[0] == '*') && varname[1] == '\0';
-  if (vtype == VT_POSPARMS && varname[0] == '*')
-    vtype |= VT_STARSUB;
-  *varp = (SHELL_VAR *)NULL;
-
-#if defined (ARRAY_VARS)
-  if (valid_array_reference (varname))
-    {
-      v = array_variable_part (varname, &temp, (int *)0);
-      if (v && (array_p (v) || assoc_p (v)))
-       { /* [ */
-         if (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']')
-           {
-             /* Callers have to differentiate betwen indexed and associative */
-             vtype = VT_ARRAYVAR;
-             if (temp[0] == '*')
-               vtype |= VT_STARSUB;
-             *valp = array_p (v) ? (char *)array_cell (v) : (char *)assoc_cell (v);
-           }
-         else
-           {
-             vtype = VT_ARRAYMEMBER;
-             *valp = array_value (varname, 1, (int *)NULL);
-           }
-         *varp = v;
-       }
-      else if (v && (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']'))
-       {
-         vtype = VT_VARIABLE;
-         *varp = v;
-         if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
-           *valp = dequote_string (value);
-         else
-           *valp = dequote_escapes (value);
-       }
-      else
-       {
-         vtype = VT_ARRAYMEMBER;
-         *varp = v;
-         *valp = array_value (varname, 1, (int *)NULL);
-       }
-    }
-  else if ((v = find_variable (varname)) && (invisible_p (v) == 0) && (assoc_p (v) || array_p (v)))
-    {
-      vtype = VT_ARRAYMEMBER;
-      *varp = v;
-      *valp = assoc_p (v) ? assoc_reference (assoc_cell (v), "0") : array_reference (array_cell (v), 0);
-    }
-  else
-#endif
-    {
-      if (value && vtype == VT_VARIABLE)
-       {
-         if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
-           *valp = dequote_string (value);
-         else
-           *valp = dequote_escapes (value);
-       }
-      else
-       *valp = value;
-    }
-
-  return vtype;
-}
-
-/******************************************************/
-/*                                                   */
-/* Functions to extract substrings of variable values */
-/*                                                   */
-/******************************************************/
-
-#if defined (HANDLE_MULTIBYTE)
-/* Character-oriented rather than strictly byte-oriented substrings.  S and
-   E, rather being strict indices into STRING, indicate character (possibly
-   multibyte character) positions that require calculation.
-   Used by the ${param:offset[:length]} expansion. */
-static char *
-mb_substring (string, s, e)
-     char *string;
-     int s, e;
-{
-  char *tt;
-  int start, stop, i, slen;
-  DECLARE_MBSTATE;
-
-  start = 0;
-  /* Don't need string length in ADVANCE_CHAR unless multibyte chars possible. */
-  slen = (MB_CUR_MAX > 1) ? STRLEN (string) : 0;
-
-  i = s;
-  while (string[start] && i--)
-    ADVANCE_CHAR (string, slen, start);
-  stop = start;
-  i = e - s;
-  while (string[stop] && i--)
-    ADVANCE_CHAR (string, slen, stop);
-  tt = substring (string, start, stop);
-  return tt;
-}
-#endif
-  
-/* Process a variable substring expansion: ${name:e1[:e2]}.  If VARNAME
-   is `@', use the positional parameters; otherwise, use the value of
-   VARNAME.  If VARNAME is an array variable, use the array elements. */
-
-static char *
-parameter_brace_substring (varname, value, substr, quoted)
-     char *varname, *value, *substr;
-     int quoted;
-{
-  intmax_t e1, e2;
-  int vtype, r, starsub;
-  char *temp, *val, *tt, *oname;
-  SHELL_VAR *v;
-
-  if (value == 0)
-    return ((char *)NULL);
-
-  oname = this_command_name;
-  this_command_name = varname;
-
-  vtype = get_var_and_type (varname, value, quoted, &v, &val);
-  if (vtype == -1)
-    {
-      this_command_name = oname;
-      return ((char *)NULL);
-    }
-
-  starsub = vtype & VT_STARSUB;
-  vtype &= ~VT_STARSUB;
-
-  r = verify_substring_values (v, val, substr, vtype, &e1, &e2);
-  this_command_name = oname;
-  if (r <= 0)
-    return ((r == 0) ? &expand_param_error : (char *)NULL);
-
-  switch (vtype)
-    {
-    case VT_VARIABLE:
-    case VT_ARRAYMEMBER:
-#if defined (HANDLE_MULTIBYTE)
-      if (MB_CUR_MAX > 1)
-       tt = mb_substring (val, e1, e2);
-      else
-#endif
-      tt = substring (val, e1, e2);
-
-      if (vtype == VT_VARIABLE)
-       FREE (val);
-      if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
-       temp = quote_string (tt);
-      else
-       temp = tt ? quote_escapes (tt) : (char *)NULL;
-      FREE (tt);
-      break;
-    case VT_POSPARMS:
-      tt = pos_params (varname, e1, e2, quoted);
-      if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
-       {
-         temp = tt ? quote_escapes (tt) : (char *)NULL;
-         FREE (tt);
-       }
-      else
-       temp = tt;
-      break;
-#if defined (ARRAY_VARS)
-    case VT_ARRAYVAR:
-      if (assoc_p (v))
-       /* we convert to list and take first e2 elements starting at e1th
-          element -- officially undefined for now */   
-       temp = assoc_subrange (assoc_cell (v), e1, e2, starsub, quoted);
-      else
-      /* We want E2 to be the number of elements desired (arrays can be sparse,
-        so verify_substring_values just returns the numbers specified and we
-        rely on array_subrange to understand how to deal with them). */
-       temp = array_subrange (array_cell (v), e1, e2, starsub, quoted);
-      /* array_subrange now calls array_quote_escapes as appropriate, so the
-        caller no longer needs to. */
-      break;
-#endif
-    default:
-      temp = (char *)NULL;
-    }
-
-  return temp;
-}
-
-/****************************************************************/
-/*                                                             */
-/* Functions to perform pattern substitution on variable values */
-/*                                                             */
-/****************************************************************/
-
-char *
-pat_subst (string, pat, rep, mflags)
-     char *string, *pat, *rep;
-     int mflags;
-{
-  char *ret, *s, *e, *str;
-  int rsize, rptr, l, replen, mtype;
-
-  mtype = mflags & MATCH_TYPEMASK;
-
-  /* Special cases:
-   *   1.  A null pattern with mtype == MATCH_BEG means to prefix STRING
-   *       with REP and return the result.
-   *   2.  A null pattern with mtype == MATCH_END means to append REP to
-   *       STRING and return the result.
-   */
-  if ((pat == 0 || *pat == 0) && (mtype == MATCH_BEG || mtype == MATCH_END))
-    {
-      replen = STRLEN (rep);
-      l = strlen (string);
-      ret = (char *)xmalloc (replen + l + 2);
-      if (replen == 0)
-       strcpy (ret, string);
-      else if (mtype == MATCH_BEG)
-       {
-         strcpy (ret, rep);
-         strcpy (ret + replen, string);
-       }
-      else
-       {
-         strcpy (ret, string);
-         strcpy (ret + l, rep);
-       }
-      return (ret);
-    }
-
-  ret = (char *)xmalloc (rsize = 64);
-  ret[0] = '\0';
-
-  for (replen = STRLEN (rep), rptr = 0, str = string;;)
-    {
-      if (match_pattern (str, pat, mtype, &s, &e) == 0)
-       break;
-      l = s - str;
-      RESIZE_MALLOCED_BUFFER (ret, rptr, (l + replen), rsize, 64);
-
-      /* OK, now copy the leading unmatched portion of the string (from
-        str to s) to ret starting at rptr (the current offset).  Then copy
-        the replacement string at ret + rptr + (s - str).  Increment
-        rptr (if necessary) and str and go on. */
-      if (l)
-       {
-         strncpy (ret + rptr, str, l);
-         rptr += l;
-       }
-      if (replen)
-       {
-         strncpy (ret + rptr, rep, replen);
-         rptr += replen;
-       }
-      str = e;         /* e == end of match */
-
-      if (((mflags & MATCH_GLOBREP) == 0) || mtype != MATCH_ANY)
-       break;
-
-      if (s == e)
-       {
-         /* On a zero-length match, make sure we copy one character, since
-            we increment one character to avoid infinite recursion. */
-         RESIZE_MALLOCED_BUFFER (ret, rptr, 1, rsize, 64);
-         ret[rptr++] = *str++;
-         e++;          /* avoid infinite recursion on zero-length match */
-       }
-    }
-
-  /* Now copy the unmatched portion of the input string */
-  if (*str)
-    {
-      RESIZE_MALLOCED_BUFFER (ret, rptr, STRLEN(str) + 1, rsize, 64);
-      strcpy (ret + rptr, str);
-    }
-  else
-    ret[rptr] = '\0';
-
-  return ret;
-}
-
-/* Do pattern match and replacement on the positional parameters. */
-static char *
-pos_params_pat_subst (string, pat, rep, mflags)
-     char *string, *pat, *rep;
-     int mflags;
-{
-  WORD_LIST *save, *params;
-  WORD_DESC *w;
-  char *ret;
-  int pchar, qflags;
-
-  save = params = list_rest_of_args ();
-  if (save == 0)
-    return ((char *)NULL);
-
-  for ( ; params; params = params->next)
-    {
-      ret = pat_subst (params->word->word, pat, rep, mflags);
-      w = alloc_word_desc ();
-      w->word = ret ? ret : savestring ("");
-      dispose_word (params->word);
-      params->word = w;
-    }
-
-  pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@';
-  qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0;
-
-#if 0
-  if ((mflags & (MATCH_QUOTED|MATCH_STARSUB)) == (MATCH_QUOTED|MATCH_STARSUB))
-    ret = string_list_dollar_star (quote_list (save));
-  else if ((mflags & MATCH_STARSUB) == MATCH_STARSUB)
-    ret = string_list_dollar_star (save);
-  else if ((mflags & MATCH_QUOTED) == MATCH_QUOTED)
-    ret = string_list_dollar_at (save, qflags);
-  else
-    ret = string_list_dollar_star (save);
-#else
-  ret = string_list_pos_params (pchar, save, qflags);
-#endif
-
-  dispose_words (save);
-
-  return (ret);
-}
-
-/* Perform pattern substitution on VALUE, which is the expansion of
-   VARNAME.  PATSUB is an expression supplying the pattern to match
-   and the string to substitute.  QUOTED is a flags word containing
-   the type of quoting currently in effect. */
-static char *
-parameter_brace_patsub (varname, value, patsub, quoted)
-     char *varname, *value, *patsub;
-     int quoted;
-{
-  int vtype, mflags, starsub, delim;
-  char *val, *temp, *pat, *rep, *p, *lpatsub, *tt;
-  SHELL_VAR *v;
-
-  if (value == 0)
-    return ((char *)NULL);
-
-  this_command_name = varname;
-
-  vtype = get_var_and_type (varname, value, quoted, &v, &val);
-  if (vtype == -1)
-    return ((char *)NULL);
-
-  starsub = vtype & VT_STARSUB;
-  vtype &= ~VT_STARSUB;
-
-  mflags = 0;
-  if (patsub && *patsub == '/')
-    {
-      mflags |= MATCH_GLOBREP;
-      patsub++;
-    }
-
-  /* Malloc this because expand_string_if_necessary or one of the expansion
-     functions in its call chain may free it on a substitution error. */
-  lpatsub = savestring (patsub);
-
-  if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-    mflags |= MATCH_QUOTED;
-
-  if (starsub)
-    mflags |= MATCH_STARSUB;
-
-  /* If the pattern starts with a `/', make sure we skip over it when looking
-     for the replacement delimiter. */
-#if 0
-  if (rep = quoted_strchr ((*patsub == '/') ? lpatsub+1 : lpatsub, '/', ST_BACKSL))
-    *rep++ = '\0';
-  else
-    rep = (char *)NULL;
-#else
-  delim = skip_to_delim (lpatsub, ((*patsub == '/') ? 1 : 0), "/", 0);
-  if (lpatsub[delim] == '/')
-    {
-      lpatsub[delim] = 0;
-      rep = lpatsub + delim + 1;
-    }
-  else
-    rep = (char *)NULL;
-#endif
-
-  if (rep && *rep == '\0')
-    rep = (char *)NULL;
-
-  /* Perform the same expansions on the pattern as performed by the
-     pattern removal expansions. */
-  pat = getpattern (lpatsub, quoted, 1);
-
-  if (rep)
-    {
-      if ((mflags & MATCH_QUOTED) == 0)
-       rep = expand_string_if_necessary (rep, quoted, expand_string_unsplit);
-      else
-       rep = expand_string_to_string_internal (rep, quoted, expand_string_unsplit);
-    }
-
-  /* ksh93 doesn't allow the match specifier to be a part of the expanded
-     pattern.  This is an extension.  Make sure we don't anchor the pattern
-     at the beginning or end of the string if we're doing global replacement,
-     though. */
-  p = pat;
-  if (mflags & MATCH_GLOBREP)
-    mflags |= MATCH_ANY;
-  else if (pat && pat[0] == '#')
-    {
-      mflags |= MATCH_BEG;
-      p++;
-    }
-  else if (pat && pat[0] == '%')
-    {
-      mflags |= MATCH_END;
-      p++;
-    }
-  else
-    mflags |= MATCH_ANY;
-
-  /* OK, we now want to substitute REP for PAT in VAL.  If
-     flags & MATCH_GLOBREP is non-zero, the substitution is done
-     everywhere, otherwise only the first occurrence of PAT is
-     replaced.  The pattern matching code doesn't understand
-     CTLESC quoting CTLESC and CTLNUL so we use the dequoted variable
-     values passed in (VT_VARIABLE) so the pattern substitution
-     code works right.  We need to requote special chars after
-     we're done for VT_VARIABLE and VT_ARRAYMEMBER, and for the
-     other cases if QUOTED == 0, since the posparams and arrays
-     indexed by * or @ do special things when QUOTED != 0. */
-
-  switch (vtype)
-    {
-    case VT_VARIABLE:
-    case VT_ARRAYMEMBER:
-      temp = pat_subst (val, p, rep, mflags);
-      if (vtype == VT_VARIABLE)
-       FREE (val);
-      if (temp)
-       {
-         tt = (mflags & MATCH_QUOTED) ? quote_string (temp) : quote_escapes (temp);
-         free (temp);
-         temp = tt;
-       }
-      break;
-    case VT_POSPARMS:
-      temp = pos_params_pat_subst (val, p, rep, mflags);
-      if (temp && (mflags & MATCH_QUOTED) == 0)
-       {
-         tt = quote_escapes (temp);
-         free (temp);
-         temp = tt;
-       }
-      break;
-#if defined (ARRAY_VARS)
-    case VT_ARRAYVAR:
-      temp = assoc_p (v) ? assoc_patsub (assoc_cell (v), p, rep, mflags)
-                        : array_patsub (array_cell (v), p, rep, mflags);
-      /* Don't call quote_escapes anymore; array_patsub calls
-        array_quote_escapes as appropriate before adding the
-        space separators; ditto for assoc_patsub. */
-      break;
-#endif
-    }
-
-  FREE (pat);
-  FREE (rep);
-  free (lpatsub);
-
-  return temp;
-}
-
-/****************************************************************/
-/*                                                             */
-/*   Functions to perform case modification on variable values  */
-/*                                                             */
-/****************************************************************/
-
-/* Do case modification on the positional parameters. */
-
-static char *
-pos_params_modcase (string, pat, modop, mflags)
-     char *string, *pat;
-     int modop;
-     int mflags;
-{
-  WORD_LIST *save, *params;
-  WORD_DESC *w;
-  char *ret;
-  int pchar, qflags;
-
-  save = params = list_rest_of_args ();
-  if (save == 0)
-    return ((char *)NULL);
-
-  for ( ; params; params = params->next)
-    {
-      ret = sh_modcase (params->word->word, pat, modop);
-      w = alloc_word_desc ();
-      w->word = ret ? ret : savestring ("");
-      dispose_word (params->word);
-      params->word = w;
-    }
-
-  pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@';
-  qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0;
-
-  ret = string_list_pos_params (pchar, save, qflags);
-  dispose_words (save);
-
-  return (ret);
-}
-
-/* Perform case modification on VALUE, which is the expansion of
-   VARNAME.  MODSPEC is an expression supplying the type of modification
-   to perform.  QUOTED is a flags word containing the type of quoting
-   currently in effect. */
-static char *
-parameter_brace_casemod (varname, value, modspec, patspec, quoted)
-     char *varname, *value;
-     int modspec;
-     char *patspec;
-     int quoted;
-{
-  int vtype, starsub, modop, mflags, x;
-  char *val, *temp, *pat, *p, *lpat, *tt;
-  SHELL_VAR *v;
-
-  if (value == 0)
-    return ((char *)NULL);
-
-  this_command_name = varname;
-
-  vtype = get_var_and_type (varname, value, quoted, &v, &val);
-  if (vtype == -1)
-    return ((char *)NULL);
-
-  starsub = vtype & VT_STARSUB;
-  vtype &= ~VT_STARSUB;
-
-  modop = 0;
-  mflags = 0;
-  if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-    mflags |= MATCH_QUOTED;
-  if (starsub)
-    mflags |= MATCH_STARSUB;
-  
-  p = patspec;
-  if (modspec == '^')
-    {
-      x = p && p[0] == modspec;
-      modop = x ? CASE_UPPER : CASE_UPFIRST;
-      p += x;
-    }
-  else if (modspec == ',')
-    {
-      x = p && p[0] == modspec;
-      modop = x ? CASE_LOWER : CASE_LOWFIRST;
-      p += x;
-    }
-  else if (modspec == '~')
-    {
-      x = p && p[0] == modspec;
-      modop = x ? CASE_TOGGLEALL : CASE_TOGGLE;
-      p += x;
-    }
-    
-  lpat = p ? savestring (p) : 0;
-  /* Perform the same expansions on the pattern as performed by the
-     pattern removal expansions.  FOR LATER */
-  pat = lpat ? getpattern (lpat, quoted, 1) : 0;
-
-  /* OK, now we do the case modification. */
-  switch (vtype)
-    {
-    case VT_VARIABLE:
-    case VT_ARRAYMEMBER:
-      temp = sh_modcase (val, pat, modop);
-      if (vtype == VT_VARIABLE)
-       FREE (val);
-      if (temp)
-       {
-         tt = (mflags & MATCH_QUOTED) ? quote_string (temp) : quote_escapes (temp);
-         free (temp);
-         temp = tt;
-       }
-      break;
-
-    case VT_POSPARMS:
-      temp = pos_params_modcase (val, pat, modop, mflags);
-      if (temp && (mflags & MATCH_QUOTED)  == 0)
-       {
-         tt = quote_escapes (temp);
-         free (temp);
-         temp = tt;
-       }
-      break;
-
-#if defined (ARRAY_VARS)
-    case VT_ARRAYVAR:
-      temp = assoc_p (v) ? assoc_modcase (assoc_cell (v), pat, modop, mflags)
-                        : array_modcase (array_cell (v), pat, modop, mflags);
-      /* Don't call quote_escapes; array_modcase calls array_quote_escapes
-        as appropriate before adding the space separators; ditto for
-        assoc_modcase. */
-      break;
-#endif
-    }
-
-  FREE (pat);
-  free (lpat);
-
-  return temp;
-}
-
-/* Check for unbalanced parens in S, which is the contents of $(( ... )).  If
-   any occur, this must be a nested command substitution, so return 0.
-   Otherwise, return 1.  A valid arithmetic expression must always have a
-   ( before a matching ), so any cases where there are more right parens
-   means that this must not be an arithmetic expression, though the parser
-   will not accept it without a balanced total number of parens. */
-static int
-chk_arithsub (s, len)
-     const char *s;
-     int len;
-{
-  int i, count;
-  DECLARE_MBSTATE;
-
-  i = count = 0;
-  while (i < len)
-    {
-      if (s[i] == LPAREN)
-       count++;
-      else if (s[i] == RPAREN)
-       {
-         count--;
-         if (count < 0)
-           return 0;
-       }
-
-      switch (s[i])
-       {
-       default:
-         ADVANCE_CHAR (s, len, i);
-         break;
-
-       case '\\':
-         i++;
-         if (s[i])
-           ADVANCE_CHAR (s, len, i);
-         break;
-
-       case '\'':
-         i = skip_single_quoted (s, len, ++i);
-         break;
-
-       case '"':
-         i = skip_double_quoted ((char *)s, len, ++i);
-         break;
-       }
-    }
-
-  return (count == 0);
-}
-
-/****************************************************************/
-/*                                                             */
-/*     Functions to perform parameter expansion on a string    */
-/*                                                             */
-/****************************************************************/
-
-/* ${[#][!]name[[:][^[^]][,[,]]#[#]%[%]-=?+[word][:e1[:e2]]]} */
-static WORD_DESC *
-parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, contains_dollar_at)
-     char *string;
-     int *indexp, quoted, *quoted_dollar_atp, *contains_dollar_at, pflags;
-{
-  int check_nullness, var_is_set, var_is_null, var_is_special;
-  int want_substring, want_indir, want_patsub, want_casemod;
-  char *name, *value, *temp, *temp1;
-  WORD_DESC *tdesc, *ret;
-  int t_index, sindex, c, tflag, modspec;
-  intmax_t number;
-
-  temp = temp1 = value = (char *)NULL;
-  var_is_set = var_is_null = var_is_special = check_nullness = 0;
-  want_substring = want_indir = want_patsub = want_casemod = 0;
-
-  sindex = *indexp;
-  t_index = ++sindex;
-  /* ${#var} doesn't have any of the other parameter expansions on it. */
-  if (string[t_index] == '#' && legal_variable_starter (string[t_index+1]))            /* {{ */
-    name = string_extract (string, &t_index, "}", SX_VARNAME);
-  else
-#if defined (CASEMOD_EXPANSIONS)
-    /* To enable case-toggling expansions using the `~' operator character
-       change the 1 to 0. */
-#  if defined (CASEMOD_CAPCASE)
-    name = string_extract (string, &t_index, "#%^,~:-=?+/}", SX_VARNAME);
-#  else
-    name = string_extract (string, &t_index, "#%^,:-=?+/}", SX_VARNAME);
-#  endif /* CASEMOD_CAPCASE */
-#else
-    name = string_extract (string, &t_index, "#%:-=?+/}", SX_VARNAME);
-#endif /* CASEMOD_EXPANSIONS */
-
-  ret = 0;
-  tflag = 0;
-
-  /* If the name really consists of a special variable, then make sure
-     that we have the entire name.  We don't allow indirect references
-     to special variables except `#', `?', `@' and `*'. */
-  if ((sindex == t_index &&
-       (string[t_index] == '-' ||
-        string[t_index] == '?' ||
-        string[t_index] == '#')) ||
-      (sindex == t_index - 1 && string[sindex] == '!' &&
-       (string[t_index] == '#' ||
-        string[t_index] == '?' ||
-        string[t_index] == '@' ||
-        string[t_index] == '*')))
-    {
-      t_index++;
-      free (name);
-      temp1 = string_extract (string, &t_index, "#%:-=?+/}", 0);
-      name = (char *)xmalloc (3 + (strlen (temp1)));
-      *name = string[sindex];
-      if (string[sindex] == '!')
-       {
-         /* indirect reference of $#, $?, $@, or $* */
-         name[1] = string[sindex + 1];
-         strcpy (name + 2, temp1);
-       }
-      else     
-       strcpy (name + 1, temp1);
-      free (temp1);
-    }
-  sindex = t_index;
-
-  /* Find out what character ended the variable name.  Then
-     do the appropriate thing. */
-  if (c = string[sindex])
-    sindex++;
-
-  /* If c is followed by one of the valid parameter expansion
-     characters, move past it as normal.  If not, assume that
-     a substring specification is being given, and do not move
-     past it. */
-  if (c == ':' && VALID_PARAM_EXPAND_CHAR (string[sindex]))
-    {
-      check_nullness++;
-      if (c = string[sindex])
-       sindex++;
-    }
-  else if (c == ':' && string[sindex] != RBRACE)
-    want_substring = 1;
-  else if (c == '/' && string[sindex] != RBRACE)
-    want_patsub = 1;
-#if defined (CASEMOD_EXPANSIONS)
-  else if (c == '^' || c == ',' || c == '~')
-    {
-      modspec = c;
-      want_casemod = 1;
-    }
-#endif
-
-  /* Catch the valid and invalid brace expressions that made it through the
-     tests above. */
-  /* ${#-} is a valid expansion and means to take the length of $-.
-     Similarly for ${#?} and ${##}... */
-  if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
-       VALID_SPECIAL_LENGTH_PARAM (c) && string[sindex] == RBRACE)
-    {
-      name = (char *)xrealloc (name, 3);
-      name[1] = c;
-      name[2] = '\0';
-      c = string[sindex++];
-    }
-
-  /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */
-  if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
-       member (c, "%:=+/") && string[sindex] == RBRACE)
-    {
-      temp = (char *)NULL;
-      goto bad_substitution;
-    }
-
-  /* Indirect expansion begins with a `!'.  A valid indirect expansion is
-     either a variable name, one of the positional parameters or a special
-     variable that expands to one of the positional parameters. */
-  want_indir = *name == '!' &&
-    (legal_variable_starter ((unsigned char)name[1]) || DIGIT (name[1])
-                                       || VALID_INDIR_PARAM (name[1]));
-
-  /* Determine the value of this variable. */
-
-  /* Check for special variables, directly referenced. */
-  if (SPECIAL_VAR (name, want_indir))
-    var_is_special++;
-
-  /* Check for special expansion things, like the length of a parameter */
-  if (*name == '#' && name[1])
-    {
-      /* If we are not pointing at the character just after the
-        closing brace, then we haven't gotten all of the name.
-        Since it begins with a special character, this is a bad
-        substitution.  Also check NAME for validity before trying
-        to go on. */
-      if (string[sindex - 1] != RBRACE || (valid_length_expression (name) == 0))
-       {
-         temp = (char *)NULL;
-         goto bad_substitution;
-       }
-
-      number = parameter_brace_expand_length (name);
-      free (name);
-
-      *indexp = sindex;
-      if (number < 0)
-        return (&expand_wdesc_error);
-      else
-       {
-         ret = alloc_word_desc ();
-         ret->word = itos (number);
-         return ret;
-       }
-    }
-
-  /* ${@} is identical to $@. */
-  if (name[0] == '@' && name[1] == '\0')
-    {
-      if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-       *quoted_dollar_atp = 1;
-
-      if (contains_dollar_at)
-       *contains_dollar_at = 1;
-    }
-
-  /* Process ${!PREFIX*} expansion. */
-  if (want_indir && string[sindex - 1] == RBRACE &&
-      (string[sindex - 2] == '*' || string[sindex - 2] == '@') &&
-      legal_variable_starter ((unsigned char) name[1]))
-    {
-      char **x;
-      WORD_LIST *xlist;
-
-      temp1 = savestring (name + 1);
-      number = strlen (temp1);
-      temp1[number - 1] = '\0';
-      x = all_variables_matching_prefix (temp1);
-      xlist = strvec_to_word_list (x, 0, 0);
-      if (string[sindex - 2] == '*')
-       temp = string_list_dollar_star (xlist);
-      else
-       {
-         temp = string_list_dollar_at (xlist, quoted);
-         if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-           *quoted_dollar_atp = 1;
-         if (contains_dollar_at)
-           *contains_dollar_at = 1;
-       }
-      free (x);
-      dispose_words (xlist);
-      free (temp1);
-      *indexp = sindex;
-
-      ret = alloc_word_desc ();
-      ret->word = temp;
-      return ret;
-    }
-
-#if defined (ARRAY_VARS)      
-  /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */ /* [ */
-  if (want_indir && string[sindex - 1] == RBRACE &&
-      string[sindex - 2] == ']' && valid_array_reference (name+1))
-    {
-      char *x, *x1;
-
-      temp1 = savestring (name + 1);
-      x = array_variable_name (temp1, &x1, (int *)0);  /* [ */
-      FREE (x);
-      if (ALL_ELEMENT_SUB (x1[0]) && x1[1] == ']')
-       {
-         temp = array_keys (temp1, quoted);    /* handles assoc vars too */
-         if (x1[0] == '@')
-           {
-             if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-               *quoted_dollar_atp = 1;
-             if (contains_dollar_at)
-               *contains_dollar_at = 1;
-           }       
-
-         free (temp1);
-         *indexp = sindex;
-
-         ret = alloc_word_desc ();
-         ret->word = temp;
-         return ret;
-       }
-
-      free (temp1);
-    }
-#endif /* ARRAY_VARS */
-      
-  /* Make sure that NAME is valid before trying to go on. */
-  if (valid_brace_expansion_word (want_indir ? name + 1 : name,
-                                       var_is_special) == 0)
-    {
-      temp = (char *)NULL;
-      goto bad_substitution;
-    }
-
-  if (want_indir)
-    tdesc = parameter_brace_expand_indir (name + 1, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at);
-  else
-    tdesc = parameter_brace_expand_word (name, var_is_special, quoted, PF_IGNUNBOUND|(pflags&PF_NOSPLIT2));
-
-  if (tdesc)
-    {
-      temp = tdesc->word;
-      tflag = tdesc->flags;
-      dispose_word_desc (tdesc);
-    }
-  else
-    temp = (char  *)0;
-
-#if defined (ARRAY_VARS)
-  if (valid_array_reference (name))
-    chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at);
-#endif
-
-  var_is_set = temp != (char *)0;
-  var_is_null = check_nullness && (var_is_set == 0 || *temp == 0);
-
-  /* Get the rest of the stuff inside the braces. */
-  if (c && c != RBRACE)
-    {
-      /* Extract the contents of the ${ ... } expansion
-        according to the Posix.2 rules. */
-      value = extract_dollar_brace_string (string, &sindex, quoted, 0);
-      if (string[sindex] == RBRACE)
-       sindex++;
-      else
-       goto bad_substitution;
-    }
-  else
-    value = (char *)NULL;
-
-  *indexp = sindex;
-
-  /* If this is a substring spec, process it and add the result. */
-  if (want_substring)
-    {
-      temp1 = parameter_brace_substring (name, temp, value, quoted);
-      FREE (name);
-      FREE (value);
-      FREE (temp);
-
-      if (temp1 == &expand_param_error)
-       return (&expand_wdesc_error);
-      else if (temp1 == &expand_param_fatal)
-       return (&expand_wdesc_fatal);
-
-      ret = alloc_word_desc ();
-      ret->word = temp1;
-      if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-       ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
-      return ret;
-    }
-  else if (want_patsub)
-    {
-      temp1 = parameter_brace_patsub (name, temp, value, quoted);
-      FREE (name);
-      FREE (value);
-      FREE (temp);
-
-      if (temp1 == &expand_param_error)
-       return (&expand_wdesc_error);
-      else if (temp1 == &expand_param_fatal)
-       return (&expand_wdesc_fatal);
-
-      ret = alloc_word_desc ();
-      ret->word = temp1;
-      ret = alloc_word_desc ();
-      ret->word = temp1;
-      if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-       ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
-      return ret;
-    }
-#if defined (CASEMOD_EXPANSIONS)
-  else if (want_casemod)
-    {
-      temp1 = parameter_brace_casemod (name, temp, modspec, value, quoted);
-      FREE (name);
-      FREE (value);
-      FREE (temp);
-
-      if (temp1 == &expand_param_error)
-       return (&expand_wdesc_error);
-      else if (temp1 == &expand_param_fatal)
-       return (&expand_wdesc_fatal);
-
-      ret = alloc_word_desc ();
-      ret->word = temp1;
-      if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-       ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
-      return ret;
-    }
-#endif
-
-  /* Do the right thing based on which character ended the variable name. */
-  switch (c)
-    {
-    default:
-    case '\0':
-    bad_substitution:
-      report_error (_("%s: bad substitution"), string ? string : "??");
-      FREE (value);
-      FREE (temp);
-      free (name);
-      return &expand_wdesc_error;
-
-    case RBRACE:
-      if (var_is_set == 0 && unbound_vars_is_error && ((name[0] != '@' && name[0] != '*') || name[1]))
-       {
-         last_command_exit_value = EXECUTION_FAILURE;
-         err_unboundvar (name);
-         FREE (value);
-         FREE (temp);
-         free (name);
-         return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
-       }
-      break;
-
-    case '#':  /* ${param#[#]pattern} */
-    case '%':  /* ${param%[%]pattern} */
-      if (value == 0 || *value == '\0' || temp == 0 || *temp == '\0')
-       {
-         FREE (value);
-         break;
-       }
-      temp1 = parameter_brace_remove_pattern (name, temp, value, c, quoted);
-      free (temp);
-      free (value);
-
-      ret = alloc_word_desc ();
-      ret->word = temp1;
-      if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-       ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
-      return ret;
-
-    case '-':
-    case '=':
-    case '?':
-    case '+':
-      if (var_is_set && var_is_null == 0)
-       {
-         /* If the operator is `+', we don't want the value of the named
-            variable for anything, just the value of the right hand side. */
-
-         if (c == '+')
-           {
-             /* XXX -- if we're double-quoted and the named variable is "$@",
-                       we want to turn off any special handling of "$@" --
-                       we're not using it, so whatever is on the rhs applies. */
-             if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-               *quoted_dollar_atp = 0;
-             if (contains_dollar_at)
-               *contains_dollar_at = 0;
-
-             FREE (temp);
-             if (value)
-               {
-                 ret = parameter_brace_expand_rhs (name, value, c,
-                                                   quoted,
-                                                   quoted_dollar_atp,
-                                                   contains_dollar_at);
-                 /* XXX - fix up later, esp. noting presence of
-                          W_HASQUOTEDNULL in ret->flags */
-                 free (value);
-               }
-             else
-               temp = (char *)NULL;
-           }
-         else
-           {
-             FREE (value);
-           }
-         /* Otherwise do nothing; just use the value in TEMP. */
-       }
-      else     /* VAR not set or VAR is NULL. */
-       {
-         FREE (temp);
-         temp = (char *)NULL;
-         if (c == '=' && var_is_special)
-           {
-             report_error (_("$%s: cannot assign in this way"), name);
-             free (name);
-             free (value);
-             return &expand_wdesc_error;
-           }
-         else if (c == '?')
-           {
-             parameter_brace_expand_error (name, value);
-             return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
-           }
-         else if (c != '+')
-           {
-             /* XXX -- if we're double-quoted and the named variable is "$@",
-                       we want to turn off any special handling of "$@" --
-                       we're not using it, so whatever is on the rhs applies. */
-             if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
-               *quoted_dollar_atp = 0;
-             if (contains_dollar_at)
-               *contains_dollar_at = 0;
-
-             ret = parameter_brace_expand_rhs (name, value, c, quoted,
-                                               quoted_dollar_atp,
-                                               contains_dollar_at);
-             /* XXX - fix up later, esp. noting presence of
-                      W_HASQUOTEDNULL in tdesc->flags */
-           }
-         free (value);
-       }
-
-      break;
-    }
-  free (name);
-
-  if (ret == 0)
-    {
-      ret = alloc_word_desc ();
-      ret->flags = tflag;
-      ret->word = temp;
-    }
-  return (ret);
-}
-
-/* Expand a single ${xxx} expansion.  The braces are optional.  When
-   the braces are used, parameter_brace_expand() does the work,
-   possibly calling param_expand recursively. */
-static WORD_DESC *
-param_expand (string, sindex, quoted, expanded_something,
-             contains_dollar_at, quoted_dollar_at_p, had_quoted_null_p,
-             pflags)
-     char *string;
-     int *sindex, quoted, *expanded_something, *contains_dollar_at;
-     int *quoted_dollar_at_p, *had_quoted_null_p, pflags;
-{
-  char *temp, *temp1, uerror[3];
-  int zindex, t_index, expok;
-  unsigned char c;
-  intmax_t number;
-  SHELL_VAR *var;
-  WORD_LIST *list;
-  WORD_DESC *tdesc, *ret;
-  int tflag;
-
-  zindex = *sindex;
-  c = string[++zindex];
-
-  temp = (char *)NULL;
-  ret = tdesc = (WORD_DESC *)NULL;
-  tflag = 0;
-
-  /* Do simple cases first. Switch on what follows '$'. */
-  switch (c)
-    {
-    /* $0 .. $9? */
-    case '0':
-    case '1':
-    case '2':
-    case '3':
-    case '4':
-    case '5':
-    case '6':
-    case '7':
-    case '8':
-    case '9':
-      temp1 = dollar_vars[TODIGIT (c)];
-      if (unbound_vars_is_error && temp1 == (char *)NULL)
-       {
-         uerror[0] = '$';
-         uerror[1] = c;
-         uerror[2] = '\0';
-         last_command_exit_value = EXECUTION_FAILURE;
-         err_unboundvar (uerror);
-         return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
-       }
-      if (temp1)
-       temp = (*temp1 && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-                 ? quote_string (temp1)
-                 : quote_escapes (temp1);
-      else
-       temp = (char *)NULL;
-
-      break;
-
-    /* $$ -- pid of the invoking shell. */
-    case '$':
-      temp = itos (dollar_dollar_pid);
-      break;
-
-    /* $# -- number of positional parameters. */
-    case '#':
-      temp = itos (number_of_args ());
-      break;
-
-    /* $? -- return value of the last synchronous command. */
-    case '?':
-      temp = itos (last_command_exit_value);
-      break;
-
-    /* $- -- flags supplied to the shell on invocation or by `set'. */
-    case '-':
-      temp = which_set_flags ();
-      break;
-
-      /* $! -- Pid of the last asynchronous command. */
-    case '!':
-      /* If no asynchronous pids have been created, expand to nothing.
-        If `set -u' has been executed, and no async processes have
-        been created, this is an expansion error. */
-      if (last_asynchronous_pid == NO_PID)
-       {
-         if (expanded_something)
-           *expanded_something = 0;
-         temp = (char *)NULL;
-         if (unbound_vars_is_error)
-           {
-             uerror[0] = '$';
-             uerror[1] = c;
-             uerror[2] = '\0';
-             last_command_exit_value = EXECUTION_FAILURE;
-             err_unboundvar (uerror);
-             return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
-           }
-       }
-      else
-       temp = itos (last_asynchronous_pid);
-      break;
-
-    /* The only difference between this and $@ is when the arg is quoted. */
-    case '*':          /* `$*' */
-      list = list_rest_of_args ();
-
-#if 0
-      /* According to austin-group posix proposal by Geoff Clare in
-        <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
-
-       "The shell shall write a message to standard error and
-        immediately exit when it tries to expand an unset parameter
-        other than the '@' and '*' special parameters."
-      */
-
-      if (list == 0 && unbound_vars_is_error && (pflags & PF_IGNUNBOUND) == 0)
-       {
-         uerror[0] = '$';
-         uerror[1] = '*';
-         uerror[2] = '\0';
-         last_command_exit_value = EXECUTION_FAILURE;
-         err_unboundvar (uerror);
-         return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
-       }
-#endif
-
-      /* If there are no command-line arguments, this should just
-        disappear if there are other characters in the expansion,
-        even if it's quoted. */
-      if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && list == 0)
-       temp = (char *)NULL;
-      else if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES|Q_PATQUOTE))
-       {
-         /* If we have "$*" we want to make a string of the positional
-            parameters, separated by the first character of $IFS, and
-            quote the whole string, including the separators.  If IFS
-            is unset, the parameters are separated by ' '; if $IFS is
-            null, the parameters are concatenated. */
-         temp = (quoted & (Q_DOUBLE_QUOTES|Q_PATQUOTE)) ? string_list_dollar_star (list) : string_list (list);
-         temp1 = quote_string (temp);
-         if (*temp == 0)
-           tflag |= W_HASQUOTEDNULL;
-         free (temp);
-         temp = temp1;
-       }
-      else
-       {
-         /* We check whether or not we're eventually going to split $* here,
-            for example when IFS is empty and we are processing the rhs of
-            an assignment statement.  In that case, we don't separate the
-            arguments at all.  Otherwise, if the $* is not quoted it is
-            identical to $@ */
-#if 1
-#  if defined (HANDLE_MULTIBYTE)
-         if (expand_no_split_dollar_star && ifs_firstc[0] == 0)
-#  else
-         if (expand_no_split_dollar_star && ifs_firstc == 0)
-#  endif
-           temp = string_list_dollar_star (list);
-         else
-           temp = string_list_dollar_at (list, quoted);
-#else
-         temp = string_list_dollar_at (list, quoted);
-#endif
-         if (expand_no_split_dollar_star == 0 && contains_dollar_at)
-           *contains_dollar_at = 1;
-       }
-
-      dispose_words (list);
-      break;
-
-    /* When we have "$@" what we want is "$1" "$2" "$3" ... This
-       means that we have to turn quoting off after we split into
-       the individually quoted arguments so that the final split
-       on the first character of $IFS is still done.  */
-    case '@':          /* `$@' */
-      list = list_rest_of_args ();
-
-#if 0
-      /* According to austin-group posix proposal by Geoff Clare in
-        <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
-
-       "The shell shall write a message to standard error and
-        immediately exit when it tries to expand an unset parameter
-        other than the '@' and '*' special parameters."
-      */
-
-      if (list == 0 && unbound_vars_is_error && (pflags & PF_IGNUNBOUND) == 0)
-       {
-         uerror[0] = '$';
-         uerror[1] = '@';
-         uerror[2] = '\0';
-         last_command_exit_value = EXECUTION_FAILURE;
-         err_unboundvar (uerror);
-         return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
-       }
-#endif
-
-      /* We want to flag the fact that we saw this.  We can't turn
-        off quoting entirely, because other characters in the
-        string might need it (consider "\"$@\""), but we need some
-        way to signal that the final split on the first character
-        of $IFS should be done, even though QUOTED is 1. */
-      /* XXX - should this test include Q_PATQUOTE? */
-      if (quoted_dollar_at_p && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-       *quoted_dollar_at_p = 1;
-      if (contains_dollar_at)
-       *contains_dollar_at = 1;
-
-#if 0
-      if (pflags & PF_NOSPLIT2)
-       temp = string_list_internal (quoted ? quote_list (list) : list, " ");
-      else
-#endif
-      /* We want to separate the positional parameters with the first
-        character of $IFS in case $IFS is something other than a space.
-        We also want to make sure that splitting is done no matter what --
-        according to POSIX.2, this expands to a list of the positional
-        parameters no matter what IFS is set to. */
-      temp = string_list_dollar_at (list, quoted);
-
-      dispose_words (list);
-      break;
-
-    case LBRACE:
-      tdesc = parameter_brace_expand (string, &zindex, quoted, pflags,
-                                     quoted_dollar_at_p,
-                                     contains_dollar_at);
-
-      if (tdesc == &expand_wdesc_error || tdesc == &expand_wdesc_fatal)
-       return (tdesc);
-      temp = tdesc ? tdesc->word : (char *)0;
-
-      /* XXX */
-      /* Quoted nulls should be removed if there is anything else
-        in the string. */
-      /* Note that we saw the quoted null so we can add one back at
-        the end of this function if there are no other characters
-        in the string, discard TEMP, and go on.  The exception to
-        this is when we have "${@}" and $1 is '', since $@ needs
-        special handling. */
-      if (tdesc && tdesc->word && (tdesc->flags & W_HASQUOTEDNULL) && QUOTED_NULL (temp))
-       {
-         if (had_quoted_null_p)
-           *had_quoted_null_p = 1;
-         if (*quoted_dollar_at_p == 0)
-           {
-             free (temp);
-             tdesc->word = temp = (char *)NULL;
-           }
-           
-       }
-
-      ret = tdesc;
-      goto return0;
-
-    /* Do command or arithmetic substitution. */
-    case LPAREN:
-      /* We have to extract the contents of this paren substitution. */
-      t_index = zindex + 1;
-      temp = extract_command_subst (string, &t_index, 0);
-      zindex = t_index;
-
-      /* For Posix.2-style `$(( ))' arithmetic substitution,
-        extract the expression and pass it to the evaluator. */
-      if (temp && *temp == LPAREN)
-       {
-         char *temp2;
-         temp1 = temp + 1;
-         temp2 = savestring (temp1);
-         t_index = strlen (temp2) - 1;
-
-         if (temp2[t_index] != RPAREN)
-           {
-             free (temp2);
-             goto comsub;
-           }
-
-         /* Cut off ending `)' */
-         temp2[t_index] = '\0';
-
-         if (chk_arithsub (temp2, t_index) == 0)
-           {
-             free (temp2);
-             internal_warning (_("future versions of the shell will force evaluation as an arithmetic substitution"));
-             goto comsub;
-           }
-
-         /* Expand variables found inside the expression. */
-         temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES);
-         free (temp2);
-
-arithsub:
-         /* No error messages. */
-         this_command_name = (char *)NULL;
-         number = evalexp (temp1, &expok);
-         free (temp);
-         free (temp1);
-         if (expok == 0)
-           {
-             if (interactive_shell == 0 && posixly_correct)
-               {
-                 last_command_exit_value = EXECUTION_FAILURE;
-                 return (&expand_wdesc_fatal);
-               }
-             else
-               return (&expand_wdesc_error);
-           }
-         temp = itos (number);
-         break;
-       }
-
-comsub:
-      if (pflags & PF_NOCOMSUB)
-       /* we need zindex+1 because string[zindex] == RPAREN */
-       temp1 = substring (string, *sindex, zindex+1);
-      else
-       {
-         tdesc = command_substitute (temp, quoted);
-         temp1 = tdesc ? tdesc->word : (char *)NULL;
-         if (tdesc)
-           dispose_word_desc (tdesc);
-       }
-      FREE (temp);
-      temp = temp1;
-      break;
-
-    /* Do POSIX.2d9-style arithmetic substitution.  This will probably go
-       away in a future bash release. */
-    case '[':
-      /* Extract the contents of this arithmetic substitution. */
-      t_index = zindex + 1;
-      temp = extract_arithmetic_subst (string, &t_index);
-      zindex = t_index;
-      if (temp == 0)
-       {
-         temp = savestring (string);
-         if (expanded_something)
-           *expanded_something = 0;
-         goto return0;
-       }         
-
-       /* Do initial variable expansion. */
-      temp1 = expand_arith_string (temp, Q_DOUBLE_QUOTES);
-
-      goto arithsub;
-
-    default:
-      /* Find the variable in VARIABLE_LIST. */
-      temp = (char *)NULL;
-
-      for (t_index = zindex; (c = string[zindex]) && legal_variable_char (c); zindex++)
-       ;
-      temp1 = (zindex > t_index) ? substring (string, t_index, zindex) : (char *)NULL;
-
-      /* If this isn't a variable name, then just output the `$'. */
-      if (temp1 == 0 || *temp1 == '\0')
-       {
-         FREE (temp1);
-         temp = (char *)xmalloc (2);
-         temp[0] = '$';
-         temp[1] = '\0';
-         if (expanded_something)
-           *expanded_something = 0;
-         goto return0;
-       }
-
-      /* If the variable exists, return its value cell. */
-      var = find_variable (temp1);
-
-      if (var && invisible_p (var) == 0 && var_isset (var))
-       {
-#if defined (ARRAY_VARS)
-         if (assoc_p (var) || array_p (var))
-           {
-             temp = array_p (var) ? array_reference (array_cell (var), 0)
-                                  : assoc_reference (assoc_cell (var), "0");
-             if (temp)
-               temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-                         ? quote_string (temp)
-                         : quote_escapes (temp);
-             else if (unbound_vars_is_error)
-               goto unbound_variable;
-           }
-         else
-#endif
-           {
-             temp = value_cell (var);
-
-             temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-                       ? quote_string (temp)
-                       : quote_escapes (temp);
-           }
-
-         free (temp1);
-
-         goto return0;
-       }
-
-      temp = (char *)NULL;
-
-unbound_variable:
-      if (unbound_vars_is_error)
-       {
-         last_command_exit_value = EXECUTION_FAILURE;
-         err_unboundvar (temp1);
-       }
-      else
-       {
-         free (temp1);
-         goto return0;
-       }
-
-      free (temp1);
-      last_command_exit_value = EXECUTION_FAILURE;
-      return ((unbound_vars_is_error && interactive_shell == 0)
-               ? &expand_wdesc_fatal
-               : &expand_wdesc_error);
-    }
-
-  if (string[zindex])
-    zindex++;
-
-return0:
-  *sindex = zindex;
-
-  if (ret == 0)
-    {
-      ret = alloc_word_desc ();
-      ret->flags = tflag;      /* XXX */
-      ret->word = temp;
-    }
-  return ret;
-}
-
-/* Make a word list which is the result of parameter and variable
-   expansion, command substitution, arithmetic substitution, and
-   quote removal of WORD.  Return a pointer to a WORD_LIST which is
-   the result of the expansion.  If WORD contains a null word, the
-   word list returned is also null.
-
-   QUOTED contains flag values defined in shell.h.
-
-   ISEXP is used to tell expand_word_internal that the word should be
-   treated as the result of an expansion.  This has implications for
-   how IFS characters in the word are treated.
-
-   CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
-   they point to an integer value which receives information about expansion.
-   CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
-   EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
-   else zero.
-
-   This only does word splitting in the case of $@ expansion.  In that
-   case, we split on ' '. */
-
-/* Values for the local variable quoted_state. */
-#define UNQUOTED        0
-#define PARTIALLY_QUOTED 1
-#define WHOLLY_QUOTED    2
-
-static WORD_LIST *
-expand_word_internal (word, quoted, isexp, contains_dollar_at, expanded_something)
-     WORD_DESC *word;
-     int quoted, isexp;
-     int *contains_dollar_at;
-     int *expanded_something;
-{
-  WORD_LIST *list;
-  WORD_DESC *tword;
-
-  /* The intermediate string that we build while expanding. */
-  char *istring;
-
-  /* The current size of the above object. */
-  int istring_size;
-
-  /* Index into ISTRING. */
-  int istring_index;
-
-  /* Temporary string storage. */
-  char *temp, *temp1;
-
-  /* The text of WORD. */
-  register char *string;
-
-  /* The size of STRING. */
-  size_t string_size;
-
-  /* The index into STRING. */
-  int sindex;
-
-  /* This gets 1 if we see a $@ while quoted. */
-  int quoted_dollar_at;
-
-  /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
-     whether WORD contains no quoting characters, a partially quoted
-     string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
-  int quoted_state;
-
-  /* State flags */
-  int had_quoted_null;
-  int has_dollar_at;
-  int tflag;
-  int pflags;                  /* flags passed to param_expand */
-
-  int assignoff;               /* If assignment, offset of `=' */
-
-  register unsigned char c;    /* Current character. */
-  int t_index;                 /* For calls to string_extract_xxx. */
-
-  char twochars[2];
-
-  DECLARE_MBSTATE;
-
-  istring = (char *)xmalloc (istring_size = DEFAULT_INITIAL_ARRAY_SIZE);
-  istring[istring_index = 0] = '\0';
-  quoted_dollar_at = had_quoted_null = has_dollar_at = 0;
-  quoted_state = UNQUOTED;
-
-  string = word->word;
-  if (string == 0)
-    goto finished_with_string;
-  /* Don't need the string length for the SADD... and COPY_ macros unless
-     multibyte characters are possible. */
-  string_size = (MB_CUR_MAX > 1) ? strlen (string) : 1;
-
-  if (contains_dollar_at)
-    *contains_dollar_at = 0;
-
-  assignoff = -1;
-
-  /* Begin the expansion. */
-
-  for (sindex = 0; ;)
-    {
-      c = string[sindex];
-
-      /* Case on toplevel character. */
-      switch (c)
-       {
-       case '\0':
-         goto finished_with_string;
-
-       case CTLESC:
-         sindex++;
-#if HANDLE_MULTIBYTE
-         if (MB_CUR_MAX > 1 && string[sindex])
-           {
-             SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
-           }
-         else
-#endif
-           {
-             temp = (char *)xmalloc (3);
-             temp[0] = CTLESC;
-             temp[1] = c = string[sindex];
-             temp[2] = '\0';
-           }
-
-dollar_add_string:
-         if (string[sindex])
-           sindex++;
-
-add_string:
-         if (temp)
-           {
-             istring = sub_append_string (temp, istring, &istring_index, &istring_size);
-             temp = (char *)0;
-           }
-
-         break;
-
-#if defined (PROCESS_SUBSTITUTION)
-         /* Process substitution. */
-       case '<':
-       case '>':
-         {
-           if (string[++sindex] != LPAREN || (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (word->flags & (W_DQUOTE|W_NOPROCSUB)) || posixly_correct)
-             {
-               sindex--;       /* add_character: label increments sindex */
-               goto add_character;
-             }
-           else
-             t_index = sindex + 1; /* skip past both '<' and LPAREN */
-
-           temp1 = extract_process_subst (string, (c == '<') ? "<(" : ">(", &t_index); /*))*/
-           sindex = t_index;
-
-           /* If the process substitution specification is `<()', we want to
-              open the pipe for writing in the child and produce output; if
-              it is `>()', we want to open the pipe for reading in the child
-              and consume input. */
-           temp = temp1 ? process_substitute (temp1, (c == '>')) : (char *)0;
-
-           FREE (temp1);
-
-           goto dollar_add_string;
-         }
-#endif /* PROCESS_SUBSTITUTION */
-
-       case '=':
-         /* Posix.2 section 3.6.1 says that tildes following `=' in words
-            which are not assignment statements are not expanded.  If the
-            shell isn't in posix mode, though, we perform tilde expansion
-            on `likely candidate' unquoted assignment statements (flags
-            include W_ASSIGNMENT but not W_QUOTED).  A likely candidate
-            contains an unquoted :~ or =~.  Something to think about: we
-            now have a flag that says  to perform tilde expansion on arguments
-            to `assignment builtins' like declare and export that look like
-            assignment statements.  We now do tilde expansion on such words
-            even in POSIX mode. */     
-         if (word->flags & (W_ASSIGNRHS|W_NOTILDE))
-           {
-             if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c))
-               goto add_ifs_character;
-             else
-               goto add_character;
-           }
-         /* If we're not in posix mode or forcing assignment-statement tilde
-            expansion, note where the `=' appears in the word and prepare to
-            do tilde expansion following the first `='. */
-         if ((word->flags & W_ASSIGNMENT) &&
-             (posixly_correct == 0 || (word->flags & W_TILDEEXP)) &&
-             assignoff == -1 && sindex > 0)
-           assignoff = sindex;
-         if (sindex == assignoff && string[sindex+1] == '~')   /* XXX */
-           word->flags |= W_ITILDE;
-#if 0
-         else if ((word->flags & W_ASSIGNMENT) &&
-                  (posixly_correct == 0 || (word->flags & W_TILDEEXP)) &&
-                  string[sindex+1] == '~')
-           word->flags |= W_ITILDE;
-#endif
-         if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c))
-           goto add_ifs_character;
-         else
-           goto add_character;
-
-       case ':':
-         if (word->flags & W_NOTILDE)
-           {
-             if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c))
-               goto add_ifs_character;
-             else
-               goto add_character;
-           }
-
-         if ((word->flags & (W_ASSIGNMENT|W_ASSIGNRHS|W_TILDEEXP)) &&
-             string[sindex+1] == '~')
-           word->flags |= W_ITILDE;
-
-         if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c))
-           goto add_ifs_character;
-         else
-           goto add_character;
-
-       case '~':
-         /* If the word isn't supposed to be tilde expanded, or we're not
-            at the start of a word or after an unquoted : or = in an
-            assignment statement, we don't do tilde expansion. */
-         if ((word->flags & (W_NOTILDE|W_DQUOTE)) ||
-             (sindex > 0 && ((word->flags & W_ITILDE) == 0)) ||
-             (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-           {
-             word->flags &= ~W_ITILDE;
-             if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
-               goto add_ifs_character;
-             else
-               goto add_character;
-           }
-
-         if (word->flags & W_ASSIGNRHS)
-           tflag = 2;
-         else if (word->flags & (W_ASSIGNMENT|W_TILDEEXP))
-           tflag = 1;
-         else
-           tflag = 0;
-
-         temp = bash_tilde_find_word (string + sindex, tflag, &t_index);
-           
-         word->flags &= ~W_ITILDE;
-
-         if (temp && *temp && t_index > 0)
-           {
-             temp1 = bash_tilde_expand (temp, tflag);
-             if  (temp1 && *temp1 == '~' && STREQ (temp, temp1))
-               {
-                 FREE (temp);
-                 FREE (temp1);
-                 goto add_character;           /* tilde expansion failed */
-               }
-             free (temp);
-             temp = temp1;
-             sindex += t_index;
-             goto add_quoted_string;           /* XXX was add_string */
-           }
-         else
-           {
-             FREE (temp);
-             goto add_character;
-           }
-       
-       case '$':
-         if (expanded_something)
-           *expanded_something = 1;
-
-         has_dollar_at = 0;
-         pflags = (word->flags & W_NOCOMSUB) ? PF_NOCOMSUB : 0;
-         if (word->flags & W_NOSPLIT2)
-           pflags |= PF_NOSPLIT2;
-         tword = param_expand (string, &sindex, quoted, expanded_something,
-                              &has_dollar_at, &quoted_dollar_at,
-                              &had_quoted_null, pflags);
-
-         if (tword == &expand_wdesc_error || tword == &expand_wdesc_fatal)
-           {
-             free (string);
-             free (istring);
-             return ((tword == &expand_wdesc_error) ? &expand_word_error
-                                                    : &expand_word_fatal);
-           }
-         if (contains_dollar_at && has_dollar_at)
-           *contains_dollar_at = 1;
-
-         if (tword && (tword->flags & W_HASQUOTEDNULL))
-           had_quoted_null = 1;
-
-         temp = tword->word;
-         dispose_word_desc (tword);
-
-         goto add_string;
-         break;
-
-       case '`':               /* Backquoted command substitution. */
-         {
-           t_index = sindex++;
-
-           temp = string_extract (string, &sindex, "`", SX_REQMATCH);
-           /* The test of sindex against t_index is to allow bare instances of
-              ` to pass through, for backwards compatibility. */
-           if (temp == &extract_string_error || temp == &extract_string_fatal)
-             {
-               if (sindex - 1 == t_index)
-                 {
-                   sindex = t_index;
-                   goto add_character;
-                 }
-               report_error (_("bad substitution: no closing \"`\" in %s") , string+t_index);
-               free (string);
-               free (istring);
-               return ((temp == &extract_string_error) ? &expand_word_error
-                                                       : &expand_word_fatal);
-             }
-               
-           if (expanded_something)
-             *expanded_something = 1;
-
-           if (word->flags & W_NOCOMSUB)
-             /* sindex + 1 because string[sindex] == '`' */
-             temp1 = substring (string, t_index, sindex + 1);
-           else
-             {
-               de_backslash (temp);
-               tword = command_substitute (temp, quoted);
-               temp1 = tword ? tword->word : (char *)NULL;
-               if (tword)
-                 dispose_word_desc (tword);
-             }
-           FREE (temp);
-           temp = temp1;
-           goto dollar_add_string;
-         }
-
-       case '\\':
-         if (string[sindex + 1] == '\n')
-           {
-             sindex += 2;
-             continue;
-           }
-
-         c = string[++sindex];
-
-         if (quoted & Q_HERE_DOCUMENT)
-           tflag = CBSHDOC;
-         else if (quoted & Q_DOUBLE_QUOTES)
-           tflag = CBSDQUOTE;
-         else
-           tflag = 0;
-
-         if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && ((sh_syntaxtab[c] & tflag) == 0))
-           {
-             SCOPY_CHAR_I (twochars, '\\', c, string, sindex, string_size);
-           }
-         else if (c == 0)
-           {
-             c = CTLNUL;
-             sindex--;         /* add_character: label increments sindex */
-             goto add_character;
-           }
-         else
-           {
-             SCOPY_CHAR_I (twochars, CTLESC, c, string, sindex, string_size);
-           }
-
-         sindex++;
-add_twochars:
-         /* BEFORE jumping here, we need to increment sindex if appropriate */
-         RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size,
-                                 DEFAULT_ARRAY_SIZE);
-         istring[istring_index++] = twochars[0];
-         istring[istring_index++] = twochars[1];
-         istring[istring_index] = '\0';
-
-         break;
-
-       case '"':
-#if 0
-         if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (word->flags & W_DQUOTE))
-#else
-         if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-#endif
-           goto add_character;
-
-         t_index = ++sindex;
-         temp = string_extract_double_quoted (string, &sindex, 0);
-
-         /* If the quotes surrounded the entire string, then the
-            whole word was quoted. */
-         quoted_state = (t_index == 1 && string[sindex] == '\0')
-                           ? WHOLLY_QUOTED
-                           : PARTIALLY_QUOTED;
-
-         if (temp && *temp)
-           {
-             tword = alloc_word_desc ();
-             tword->word = temp;
-
-             temp = (char *)NULL;
-
-             has_dollar_at = 0;
-             /* Need to get W_HASQUOTEDNULL flag through this function. */
-             list = expand_word_internal (tword, Q_DOUBLE_QUOTES, 0, &has_dollar_at, (int *)NULL);
-
-             if (list == &expand_word_error || list == &expand_word_fatal)
-               {
-                 free (istring);
-                 free (string);
-                 /* expand_word_internal has already freed temp_word->word
-                    for us because of the way it prints error messages. */
-                 tword->word = (char *)NULL;
-                 dispose_word (tword);
-                 return list;
-               }
-
-             dispose_word (tword);
-
-             /* "$@" (a double-quoted dollar-at) expands into nothing,
-                not even a NULL word, when there are no positional
-                parameters. */
-             if (list == 0 && has_dollar_at)
-               {
-                 quoted_dollar_at++;
-                 break;
-               }
-
-             /* If we get "$@", we know we have expanded something, so we
-                need to remember it for the final split on $IFS.  This is
-                a special case; it's the only case where a quoted string
-                can expand into more than one word.  It's going to come back
-                from the above call to expand_word_internal as a list with
-                a single word, in which all characters are quoted and
-                separated by blanks.  What we want to do is to turn it back
-                into a list for the next piece of code. */
-             if (list)
-               dequote_list (list);
-
-             if (list && list->word && (list->word->flags & W_HASQUOTEDNULL))
-               had_quoted_null = 1;
-
-             if (has_dollar_at)
-               {
-                 quoted_dollar_at++;
-                 if (contains_dollar_at)
-                   *contains_dollar_at = 1;
-                 if (expanded_something)
-                   *expanded_something = 1;
-               }
-           }
-         else
-           {
-             /* What we have is "".  This is a minor optimization. */
-             FREE (temp);
-             list = (WORD_LIST *)NULL;
-           }
-
-         /* The code above *might* return a list (consider the case of "$@",
-            where it returns "$1", "$2", etc.).  We can't throw away the
-            rest of the list, and we have to make sure each word gets added
-            as quoted.  We test on tresult->next:  if it is non-NULL, we
-            quote the whole list, save it to a string with string_list, and
-            add that string. We don't need to quote the results of this
-            (and it would be wrong, since that would quote the separators
-            as well), so we go directly to add_string. */
-         if (list)
-           {
-             if (list->next)
-               {
-#if 0
-                 if (quoted_dollar_at && word->flags & W_NOSPLIT2)
-                   temp = string_list_internal (quote_list (list), " ");
-                 else
-#endif
-                 /* Testing quoted_dollar_at makes sure that "$@" is
-                    split correctly when $IFS does not contain a space. */
-                 temp = quoted_dollar_at
-                               ? string_list_dollar_at (list, Q_DOUBLE_QUOTES)
-                               : string_list (quote_list (list));
-                 dispose_words (list);
-                 goto add_string;
-               }
-             else
-               {
-                 temp = savestring (list->word->word);
-                 tflag = list->word->flags;
-                 dispose_words (list);
-
-                 /* If the string is not a quoted null string, we want
-                    to remove any embedded unquoted CTLNUL characters.
-                    We do not want to turn quoted null strings back into
-                    the empty string, though.  We do this because we
-                    want to remove any quoted nulls from expansions that
-                    contain other characters.  For example, if we have
-                    x"$*"y or "x$*y" and there are no positional parameters,
-                    the $* should expand into nothing. */
-                 /* We use the W_HASQUOTEDNULL flag to differentiate the
-                    cases:  a quoted null character as above and when
-                    CTLNUL is contained in the (non-null) expansion
-                    of some variable.  We use the had_quoted_null flag to
-                    pass the value through this function to its caller. */
-                 if ((tflag & W_HASQUOTEDNULL) && QUOTED_NULL (temp) == 0)
-                   remove_quoted_nulls (temp); /* XXX */
-               }
-           }
-         else
-           temp = (char *)NULL;
-
-         /* We do not want to add quoted nulls to strings that are only
-            partially quoted; we can throw them away. */
-         if (temp == 0 && quoted_state == PARTIALLY_QUOTED)
-           continue;
-
-       add_quoted_string:
-
-         if (temp)
-           {
-             temp1 = temp;
-             temp = quote_string (temp);
-             free (temp1);
-             goto add_string;
-           }
-         else
-           {
-             /* Add NULL arg. */
-             c = CTLNUL;
-             sindex--;         /* add_character: label increments sindex */
-             goto add_character;
-           }
-
-         /* break; */
-
-       case '\'':
-#if 0
-         if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (word->flags & W_DQUOTE))
-#else
-         if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-#endif
-           goto add_character;
-
-         t_index = ++sindex;
-         temp = string_extract_single_quoted (string, &sindex);
-
-         /* If the entire STRING was surrounded by single quotes,
-            then the string is wholly quoted. */
-         quoted_state = (t_index == 1 && string[sindex] == '\0')
-                           ? WHOLLY_QUOTED
-                           : PARTIALLY_QUOTED;
-
-         /* If all we had was '', it is a null expansion. */
-         if (*temp == '\0')
-           {
-             free (temp);
-             temp = (char *)NULL;
-           }
-         else
-           remove_quoted_escapes (temp);       /* ??? */
-
-         /* We do not want to add quoted nulls to strings that are only
-            partially quoted; such nulls are discarded. */
-         if (temp == 0 && (quoted_state == PARTIALLY_QUOTED))
-           continue;
-
-         /* If we have a quoted null expansion, add a quoted NULL to istring. */
-         if (temp == 0)
-           {
-             c = CTLNUL;
-             sindex--;         /* add_character: label increments sindex */
-             goto add_character;
-           }
-         else
-           goto add_quoted_string;
-
-         /* break; */
-
-       default:
-         /* This is the fix for " $@ " */
-       add_ifs_character:
-         if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (isexp == 0 && isifs (c)))
-           {
-             if (string[sindex])       /* from old goto dollar_add_string */
-               sindex++;
-             if (c == 0)
-               {
-                 c = CTLNUL;
-                 goto add_character;
-               }
-             else
-               {
-#if HANDLE_MULTIBYTE
-                 if (MB_CUR_MAX > 1)
-                   sindex--;
-
-                 if (MB_CUR_MAX > 1)
-                   {
-                     SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
-                   }
-                 else
-#endif
-                   {
-                     twochars[0] = CTLESC;
-                     twochars[1] = c;
-                     goto add_twochars;
-                   }
-               }
-           }
-
-         SADD_MBCHAR (temp, string, sindex, string_size);
-
-       add_character:
-         RESIZE_MALLOCED_BUFFER (istring, istring_index, 1, istring_size,
-                                 DEFAULT_ARRAY_SIZE);
-         istring[istring_index++] = c;
-         istring[istring_index] = '\0';
-
-         /* Next character. */
-         sindex++;
-       }
-    }
-
-finished_with_string:
-  /* OK, we're ready to return.  If we have a quoted string, and
-     quoted_dollar_at is not set, we do no splitting at all; otherwise
-     we split on ' '.  The routines that call this will handle what to
-     do if nothing has been expanded. */
-
-  /* Partially and wholly quoted strings which expand to the empty
-     string are retained as an empty arguments.  Unquoted strings
-     which expand to the empty string are discarded.  The single
-     exception is the case of expanding "$@" when there are no
-     positional parameters.  In that case, we discard the expansion. */
-
-  /* Because of how the code that handles "" and '' in partially
-     quoted strings works, we need to make ISTRING into a QUOTED_NULL
-     if we saw quoting characters, but the expansion was empty.
-     "" and '' are tossed away before we get to this point when
-     processing partially quoted strings.  This makes "" and $xxx""
-     equivalent when xxx is unset.  We also look to see whether we
-     saw a quoted null from a ${} expansion and add one back if we
-     need to. */
-
-  /* If we expand to nothing and there were no single or double quotes
-     in the word, we throw it away.  Otherwise, we return a NULL word.
-     The single exception is for $@ surrounded by double quotes when
-     there are no positional parameters.  In that case, we also throw
-     the word away. */
-
-  if (*istring == '\0')
-    {
-      if (quoted_dollar_at == 0 && (had_quoted_null || quoted_state == PARTIALLY_QUOTED))
-       {
-         istring[0] = CTLNUL;
-         istring[1] = '\0';
-         tword = make_bare_word (istring);
-         tword->flags |= W_HASQUOTEDNULL;              /* XXX */
-         list = make_word_list (tword, (WORD_LIST *)NULL);
-         if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-           tword->flags |= W_QUOTED;
-       }
-      /* According to sh, ksh, and Posix.2, if a word expands into nothing
-        and a double-quoted "$@" appears anywhere in it, then the entire
-        word is removed. */
-      else  if (quoted_state == UNQUOTED || quoted_dollar_at)
-       list = (WORD_LIST *)NULL;
-#if 0
-      else
-       {
-         tword = make_bare_word (istring);
-         if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-           tword->flags |= W_QUOTED;
-         list = make_word_list (tword, (WORD_LIST *)NULL);
-       }
-#else
-      else
-       list = (WORD_LIST *)NULL;
-#endif
-    }
-  else if (word->flags & W_NOSPLIT)
-    {
-      tword = make_bare_word (istring);
-      if (word->flags & W_ASSIGNMENT)
-       tword->flags |= W_ASSIGNMENT;   /* XXX */
-      if (word->flags & W_COMPASSIGN)
-       tword->flags |= W_COMPASSIGN;   /* XXX */
-      if (word->flags & W_NOGLOB)
-       tword->flags |= W_NOGLOB;       /* XXX */
-      if (word->flags & W_NOEXPAND)
-       tword->flags |= W_NOEXPAND;     /* XXX */
-      if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
-       tword->flags |= W_QUOTED;
-      if (had_quoted_null)
-       tword->flags |= W_HASQUOTEDNULL;
-      list = make_word_list (tword, (WORD_LIST *)NULL);
-    }
-  else
-    {
-      char *ifs_chars;
-
-      ifs_chars = (quoted_dollar_at || has_dollar_at) ? ifs_value : (char *)NULL;
-
-      /* If we have $@, we need to split the results no matter what.  If
-        IFS is unset or NULL, string_list_dollar_at has separated the
-        positional parameters with a space, so we split on space (we have
-        set ifs_chars to " \t\n" above if ifs is unset).  If IFS is set,
-        string_list_dollar_at has separated the positional parameters
-        with the first character of $IFS, so we split on $IFS. */
-      if (has_dollar_at && ifs_chars)
-       list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
-      else
-       {
-         tword = make_bare_word (istring);
-         if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED))
-           tword->flags |= W_QUOTED;
-         if (word->flags & W_ASSIGNMENT)
-           tword->flags |= W_ASSIGNMENT;
-         if (word->flags & W_COMPASSIGN)
-           tword->flags |= W_COMPASSIGN;
-         if (word->flags & W_NOGLOB)
-           tword->flags |= W_NOGLOB;
-         if (word->flags & W_NOEXPAND)
-           tword->flags |= W_NOEXPAND;
-         if (had_quoted_null)
-           tword->flags |= W_HASQUOTEDNULL;    /* XXX */
-         list = make_word_list (tword, (WORD_LIST *)NULL);
-       }
-    }
-
-  free (istring);
-  return (list);
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*                Functions for Quote Removal                      */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Perform quote removal on STRING.  If QUOTED > 0, assume we are obeying the
-   backslash quoting rules for within double quotes or a here document. */
-char *
-string_quote_removal (string, quoted)
-     char *string;
-     int quoted;
-{
-  size_t slen;
-  char *r, *result_string, *temp, *send;
-  int sindex, tindex, dquote;
-  unsigned char c;
-  DECLARE_MBSTATE;
-
-  /* The result can be no longer than the original string. */
-  slen = strlen (string);
-  send = string + slen;
-
-  r = result_string = (char *)xmalloc (slen + 1);
-
-  for (dquote = sindex = 0; c = string[sindex];)
-    {
-      switch (c)
-       {
-       case '\\':
-         c = string[++sindex];
-         if (c == 0)
-           {
-             *r++ = '\\';
-             break;
-           }
-         if (((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote) && (sh_syntaxtab[c] & CBSDQUOTE) == 0)
-           *r++ = '\\';
-         /* FALLTHROUGH */
-
-       default:
-         SCOPY_CHAR_M (r, string, send, sindex);
-         break;
-
-       case '\'':
-         if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote)
-           {
-             *r++ = c;
-             sindex++;
-             break;
-           }
-         tindex = sindex + 1;
-         temp = string_extract_single_quoted (string, &tindex);
-         if (temp)
-           {
-             strcpy (r, temp);
-             r += strlen (r);
-             free (temp);
-           }
-         sindex = tindex;
-         break;
-
-       case '"':
-         dquote = 1 - dquote;
-         sindex++;
-         break;
-       }
-    }
-    *r = '\0';
-    return (result_string);
-}
-
-#if 0
-/* UNUSED */
-/* Perform quote removal on word WORD.  This allocates and returns a new
-   WORD_DESC *. */
-WORD_DESC *
-word_quote_removal (word, quoted)
-     WORD_DESC *word;
-     int quoted;
-{
-  WORD_DESC *w;
-  char *t;
-
-  t = string_quote_removal (word->word, quoted);
-  w = alloc_word_desc ();
-  w->word = t ? t : savestring ("");
-  return (w);
-}
-
-/* Perform quote removal on all words in LIST.  If QUOTED is non-zero,
-   the members of the list are treated as if they are surrounded by
-   double quotes.  Return a new list, or NULL if LIST is NULL. */
-WORD_LIST *
-word_list_quote_removal (list, quoted)
-     WORD_LIST *list;
-     int quoted;
-{
-  WORD_LIST *result, *t, *tresult, *e;
-
-  for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
-    {
-      tresult = make_word_list (word_quote_removal (t->word, quoted), (WORD_LIST *)NULL);
-#if 0
-      result = (WORD_LIST *) list_append (result, tresult);
-#else
-      if (result == 0)
-       result = e = tresult;
-      else
-       {
-         e->next = tresult;
-         while (e->next)
-           e = e->next;
-       }
-#endif
-    }
-  return (result);
-}
-#endif
-
-/*******************************************
- *                                        *
- *    Functions to perform word splitting  *
- *                                        *
- *******************************************/
-
-void
-setifs (v)
-     SHELL_VAR *v;
-{
-  char *t;
-  unsigned char uc;
-
-  ifs_var = v;
-  ifs_value = (v && value_cell (v)) ? value_cell (v) : " \t\n";
-
-  /* Should really merge ifs_cmap with sh_syntaxtab.  XXX - doesn't yet
-     handle multibyte chars in IFS */
-  memset (ifs_cmap, '\0', sizeof (ifs_cmap));
-  for (t = ifs_value ; t && *t; t++)
-    {
-      uc = *t;
-      ifs_cmap[uc] = 1;
-    }
-
-#if defined (HANDLE_MULTIBYTE)
-  if (ifs_value == 0)
-    {
-      ifs_firstc[0] = '\0';
-      ifs_firstc_len = 1;
-    }
-  else
-    {
-      size_t ifs_len;
-      ifs_len = strnlen (ifs_value, MB_CUR_MAX);
-      ifs_firstc_len = MBLEN (ifs_value, ifs_len);
-      if (ifs_firstc_len == 1 || ifs_firstc_len == 0 || MB_INVALIDCH (ifs_firstc_len))
-       {
-         ifs_firstc[0] = ifs_value[0];
-         ifs_firstc[1] = '\0';
-         ifs_firstc_len = 1;
-       }
-      else
-       memcpy (ifs_firstc, ifs_value, ifs_firstc_len);
-    }
-#else
-  ifs_firstc = ifs_value ? *ifs_value : 0;
-#endif
-}
-
-char *
-getifs ()
-{
-  return ifs_value;
-}
-
-/* This splits a single word into a WORD LIST on $IFS, but only if the word
-   is not quoted.  list_string () performs quote removal for us, even if we
-   don't do any splitting. */
-WORD_LIST *
-word_split (w, ifs_chars)
-     WORD_DESC *w;
-     char *ifs_chars;
-{
-  WORD_LIST *result;
-
-  if (w)
-    {
-      char *xifs;
-
-      xifs = ((w->flags & W_QUOTED) || ifs_chars == 0) ? "" : ifs_chars;
-      result = list_string (w->word, xifs, w->flags & W_QUOTED);
-    }
-  else
-    result = (WORD_LIST *)NULL;
-
-  return (result);
-}
-
-/* Perform word splitting on LIST and return the RESULT.  It is possible
-   to return (WORD_LIST *)NULL. */
-static WORD_LIST *
-word_list_split (list)
-     WORD_LIST *list;
-{
-  WORD_LIST *result, *t, *tresult, *e;
-
-  for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
-    {
-      tresult = word_split (t->word, ifs_value);
-      if (result == 0)
-        result = e = tresult;
-      else
-       {
-         e->next = tresult;
-         while (e->next)
-           e = e->next;
-       }
-    }
-  return (result);
-}
-
-/**************************************************
- *                                               *
- *    Functions to expand an entire WORD_LIST    *
- *                                               *
- **************************************************/
-
-/* Do any word-expansion-specific cleanup and jump to top_level */
-static void
-exp_jump_to_top_level (v)
-     int v;
-{
-  set_pipestatus_from_exit (last_command_exit_value);
-
-  /* Cleanup code goes here. */
-  expand_no_split_dollar_star = 0;     /* XXX */
-  expanding_redir = 0;
-  assigning_in_environment = 0;
-
-  if (parse_and_execute_level == 0)
-    top_level_cleanup ();                      /* from sig.c */
-
-  jump_to_top_level (v);
-}
-
-/* Put NLIST (which is a WORD_LIST * of only one element) at the front of
-   ELIST, and set ELIST to the new list. */
-#define PREPEND_LIST(nlist, elist) \
-       do { nlist->next = elist; elist = nlist; } while (0)
-
-/* Separate out any initial variable assignments from TLIST.  If set -k has
-   been executed, remove all assignment statements from TLIST.  Initial
-   variable assignments and other environment assignments are placed
-   on SUBST_ASSIGN_VARLIST. */
-static WORD_LIST *
-separate_out_assignments (tlist)
-     WORD_LIST *tlist;
-{
-  register WORD_LIST *vp, *lp;
-
-  if (tlist == 0)
-    return ((WORD_LIST *)NULL);
-
-  if (subst_assign_varlist)
-    dispose_words (subst_assign_varlist);      /* Clean up after previous error */
-
-  subst_assign_varlist = (WORD_LIST *)NULL;
-  vp = lp = tlist;
-
-  /* Separate out variable assignments at the start of the command.
-     Loop invariant: vp->next == lp
-     Loop postcondition:
-       lp = list of words left after assignment statements skipped
-       tlist = original list of words
-  */
-  while (lp && (lp->word->flags & W_ASSIGNMENT))
-    {
-      vp = lp;
-      lp = lp->next;
-    }
-
-  /* If lp != tlist, we have some initial assignment statements.
-     We make SUBST_ASSIGN_VARLIST point to the list of assignment
-     words and TLIST point to the remaining words.  */
-  if (lp != tlist)
-    {
-      subst_assign_varlist = tlist;
-      /* ASSERT(vp->next == lp); */
-      vp->next = (WORD_LIST *)NULL;    /* terminate variable list */
-      tlist = lp;                      /* remainder of word list */
-    }
-
-  /* vp == end of variable list */
-  /* tlist == remainder of original word list without variable assignments */
-  if (!tlist)
-    /* All the words in tlist were assignment statements */
-    return ((WORD_LIST *)NULL);
-
-  /* ASSERT(tlist != NULL); */
-  /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
-
-  /* If the -k option is in effect, we need to go through the remaining
-     words, separate out the assignment words, and place them on
-     SUBST_ASSIGN_VARLIST. */
-  if (place_keywords_in_env)
-    {
-      WORD_LIST *tp;   /* tp == running pointer into tlist */
-
-      tp = tlist;
-      lp = tlist->next;
-
-      /* Loop Invariant: tp->next == lp */
-      /* Loop postcondition: tlist == word list without assignment statements */
-      while (lp)
-       {
-         if (lp->word->flags & W_ASSIGNMENT)
-           {
-             /* Found an assignment statement, add this word to end of
-                subst_assign_varlist (vp). */
-             if (!subst_assign_varlist)
-               subst_assign_varlist = vp = lp;
-             else
-               {
-                 vp->next = lp;
-                 vp = lp;
-               }
-
-             /* Remove the word pointed to by LP from TLIST. */
-             tp->next = lp->next;
-             /* ASSERT(vp == lp); */
-             lp->next = (WORD_LIST *)NULL;
-             lp = tp->next;
-           }
-         else
-           {
-             tp = lp;
-             lp = lp->next;
-           }
-       }
-    }
-  return (tlist);
-}
-
-#define WEXP_VARASSIGN 0x001
-#define WEXP_BRACEEXP  0x002
-#define WEXP_TILDEEXP  0x004
-#define WEXP_PARAMEXP  0x008
-#define WEXP_PATHEXP   0x010
-
-/* All of the expansions, including variable assignments at the start of
-   the list. */
-#define WEXP_ALL       (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
-
-/* All of the expansions except variable assignments at the start of
-   the list. */
-#define WEXP_NOVARS    (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
-
-/* All of the `shell expansions': brace expansion, tilde expansion, parameter
-   expansion, command substitution, arithmetic expansion, word splitting, and
-   quote removal. */
-#define WEXP_SHELLEXP  (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
-
-/* Take the list of words in LIST and do the various substitutions.  Return
-   a new list of words which is the expanded list, and without things like
-   variable assignments. */
-
-WORD_LIST *
-expand_words (list)
-     WORD_LIST *list;
-{
-  return (expand_word_list_internal (list, WEXP_ALL));
-}
-
-/* Same as expand_words (), but doesn't hack variable or environment
-   variables. */
-WORD_LIST *
-expand_words_no_vars (list)
-     WORD_LIST *list;
-{
-  return (expand_word_list_internal (list, WEXP_NOVARS));
-}
-
-WORD_LIST *
-expand_words_shellexp (list)
-     WORD_LIST *list;
-{
-  return (expand_word_list_internal (list, WEXP_SHELLEXP));
-}
-
-static WORD_LIST *
-glob_expand_word_list (tlist, eflags)
-     WORD_LIST *tlist;
-     int eflags;
-{
-  char **glob_array, *temp_string;
-  register int glob_index;
-  WORD_LIST *glob_list, *output_list, *disposables, *next;
-  WORD_DESC *tword;
-
-  output_list = disposables = (WORD_LIST *)NULL;
-  glob_array = (char **)NULL;
-  while (tlist)
-    {
-      /* For each word, either globbing is attempted or the word is
-        added to orig_list.  If globbing succeeds, the results are
-        added to orig_list and the word (tlist) is added to the list
-        of disposable words.  If globbing fails and failed glob
-        expansions are left unchanged (the shell default), the
-        original word is added to orig_list.  If globbing fails and
-        failed glob expansions are removed, the original word is
-        added to the list of disposable words.  orig_list ends up
-        in reverse order and requires a call to REVERSE_LIST to
-        be set right.  After all words are examined, the disposable
-        words are freed. */
-      next = tlist->next;
-
-      /* If the word isn't an assignment and contains an unquoted
-        pattern matching character, then glob it. */
-      if ((tlist->word->flags & W_NOGLOB) == 0 &&
-         unquoted_glob_pattern_p (tlist->word->word))
-       {
-         glob_array = shell_glob_filename (tlist->word->word);
-
-         /* Handle error cases.
-            I don't think we should report errors like "No such file
-            or directory".  However, I would like to report errors
-            like "Read failed". */
-
-         if (glob_array == 0 || GLOB_FAILED (glob_array))
-           {
-             glob_array = (char **)xmalloc (sizeof (char *));
-             glob_array[0] = (char *)NULL;
-           }
-
-         /* Dequote the current word in case we have to use it. */
-         if (glob_array[0] == NULL)
-           {
-             temp_string = dequote_string (tlist->word->word);
-             free (tlist->word->word);
-             tlist->word->word = temp_string;
-           }
-
-         /* Make the array into a word list. */
-         glob_list = (WORD_LIST *)NULL;
-         for (glob_index = 0; glob_array[glob_index]; glob_index++)
-           {
-             tword = make_bare_word (glob_array[glob_index]);
-             tword->flags |= W_GLOBEXP;        /* XXX */
-             glob_list = make_word_list (tword, glob_list);
-           }
-
-         if (glob_list)
-           {
-             output_list = (WORD_LIST *)list_append (glob_list, output_list);
-             PREPEND_LIST (tlist, disposables);
-           }
-         else if (fail_glob_expansion != 0)
-           {
-             report_error (_("no match: %s"), tlist->word->word);
-             exp_jump_to_top_level (DISCARD);
-           }
-         else if (allow_null_glob_expansion == 0)
-           {
-             /* Failed glob expressions are left unchanged. */
-             PREPEND_LIST (tlist, output_list);
-           }
-         else
-           {
-             /* Failed glob expressions are removed. */
-             PREPEND_LIST (tlist, disposables);
-           }
-       }
-      else
-       {
-         /* Dequote the string. */
-         temp_string = dequote_string (tlist->word->word);
-         free (tlist->word->word);
-         tlist->word->word = temp_string;
-         PREPEND_LIST (tlist, output_list);
-       }
-
-      strvec_dispose (glob_array);
-      glob_array = (char **)NULL;
-
-      tlist = next;
-    }
-
-  if (disposables)
-    dispose_words (disposables);
-
-  if (output_list)
-    output_list = REVERSE_LIST (output_list, WORD_LIST *);
-
-  return (output_list);
-}
-
-#if defined (BRACE_EXPANSION)
-static WORD_LIST *
-brace_expand_word_list (tlist, eflags)
-     WORD_LIST *tlist;
-     int eflags;
-{
-  register char **expansions;
-  char *temp_string;
-  WORD_LIST *disposables, *output_list, *next;
-  WORD_DESC *w;
-  int eindex;
-
-  for (disposables = output_list = (WORD_LIST *)NULL; tlist; tlist = next)
-    {
-      next = tlist->next;
-
-      if ((tlist->word->flags & (W_COMPASSIGN|W_ASSIGNARG)) == (W_COMPASSIGN|W_ASSIGNARG))
-        {
-/*itrace("brace_expand_word_list: %s: W_COMPASSIGN|W_ASSIGNARG", tlist->word->word);*/
-         PREPEND_LIST (tlist, output_list);
-         continue;
-        }
-          
-      /* Only do brace expansion if the word has a brace character.  If
-        not, just add the word list element to BRACES and continue.  In
-        the common case, at least when running shell scripts, this will
-        degenerate to a bunch of calls to `mbschr', and then what is
-        basically a reversal of TLIST into BRACES, which is corrected
-        by a call to REVERSE_LIST () on BRACES when the end of TLIST
-        is reached. */
-      if (mbschr (tlist->word->word, LBRACE))
-       {
-         expansions = brace_expand (tlist->word->word);
-
-         for (eindex = 0; temp_string = expansions[eindex]; eindex++)
-           {
-             w = make_word (temp_string);
-             /* If brace expansion didn't change the word, preserve
-                the flags.  We may want to preserve the flags
-                unconditionally someday -- XXX */
-             if (STREQ (temp_string, tlist->word->word))
-               w->flags = tlist->word->flags;
-             output_list = make_word_list (w, output_list);
-             free (expansions[eindex]);
-           }
-         free (expansions);
-
-         /* Add TLIST to the list of words to be freed after brace
-            expansion has been performed. */
-         PREPEND_LIST (tlist, disposables);
-       }
-      else
-       PREPEND_LIST (tlist, output_list);
-    }
-
-  if (disposables)
-    dispose_words (disposables);
-
-  if (output_list)
-    output_list = REVERSE_LIST (output_list, WORD_LIST *);
-
-  return (output_list);
-}
-#endif
-
-#if defined (ARRAY_VARS)
-/* Take WORD, a compound associative array assignment, and internally run
-   'declare -A w', where W is the variable name portion of WORD. */
-static int
-make_internal_declare (word, option)
-     char *word;
-     char *option;
-{
-  int t;
-  WORD_LIST *wl;
-  WORD_DESC *w;
-
-  w = make_word (word);
-
-  t = assignment (w->word, 0);
-  w->word[t] = '\0';
-
-  wl = make_word_list (w, (WORD_LIST *)NULL);
-  wl = make_word_list (make_word (option), wl);
-
-  return (declare_builtin (wl));  
-}  
-#endif
-
-static WORD_LIST *
-shell_expand_word_list (tlist, eflags)
-     WORD_LIST *tlist;
-     int eflags;
-{
-  WORD_LIST *expanded, *orig_list, *new_list, *next, *temp_list;
-  int expanded_something, has_dollar_at;
-  char *temp_string;
-
-  /* We do tilde expansion all the time.  This is what 1003.2 says. */
-  new_list = (WORD_LIST *)NULL;
-  for (orig_list = tlist; tlist; tlist = next)
-    {
-      temp_string = tlist->word->word;
-
-      next = tlist->next;
-
-#if defined (ARRAY_VARS)
-      /* If this is a compound array assignment to a builtin that accepts
-         such assignments (e.g., `declare'), take the assignment and perform
-         it separately, handling the semantics of declarations inside shell
-         functions.  This avoids the double-evaluation of such arguments,
-         because `declare' does some evaluation of compound assignments on
-         its own. */
-      if ((tlist->word->flags & (W_COMPASSIGN|W_ASSIGNARG)) == (W_COMPASSIGN|W_ASSIGNARG))
-       {
-         int t;
-
-         if (tlist->word->flags & W_ASSIGNASSOC)
-           make_internal_declare (tlist->word->word, "-A");
-
-         t = do_word_assignment (tlist->word);
-         if (t == 0)
-           {
-             last_command_exit_value = EXECUTION_FAILURE;
-             exp_jump_to_top_level (DISCARD);
-           }
-
-         /* Now transform the word as ksh93 appears to do and go on */
-         t = assignment (tlist->word->word, 0);
-         tlist->word->word[t] = '\0';
-         tlist->word->flags &= ~(W_ASSIGNMENT|W_NOSPLIT|W_COMPASSIGN|W_ASSIGNARG|W_ASSIGNASSOC);
-       }
-#endif
-
-      expanded_something = 0;
-      expanded = expand_word_internal
-       (tlist->word, 0, 0, &has_dollar_at, &expanded_something);
-
-      if (expanded == &expand_word_error || expanded == &expand_word_fatal)
-       {
-         /* By convention, each time this error is returned,
-            tlist->word->word has already been freed. */
-         tlist->word->word = (char *)NULL;
-
-         /* Dispose our copy of the original list. */
-         dispose_words (orig_list);
-         /* Dispose the new list we're building. */
-         dispose_words (new_list);
-
-         last_command_exit_value = EXECUTION_FAILURE;
-         if (expanded == &expand_word_error)
-           exp_jump_to_top_level (DISCARD);
-         else
-           exp_jump_to_top_level (FORCE_EOF);
-       }
-
-      /* Don't split words marked W_NOSPLIT. */
-      if (expanded_something && (tlist->word->flags & W_NOSPLIT) == 0)
-       {
-         temp_list = word_list_split (expanded);
-         dispose_words (expanded);
-       }
-      else
-       {
-         /* If no parameter expansion, command substitution, process
-            substitution, or arithmetic substitution took place, then
-            do not do word splitting.  We still have to remove quoted
-            null characters from the result. */
-         word_list_remove_quoted_nulls (expanded);
-         temp_list = expanded;
-       }
-
-      expanded = REVERSE_LIST (temp_list, WORD_LIST *);
-      new_list = (WORD_LIST *)list_append (expanded, new_list);
-    }
-
-  if (orig_list)  
-    dispose_words (orig_list);
-
-  if (new_list)
-    new_list = REVERSE_LIST (new_list, WORD_LIST *);
-
-  return (new_list);
-}
-
-/* The workhorse for expand_words () and expand_words_no_vars ().
-   First arg is LIST, a WORD_LIST of words.
-   Second arg EFLAGS is a flags word controlling which expansions are
-   performed.
-
-   This does all of the substitutions: brace expansion, tilde expansion,
-   parameter expansion, command substitution, arithmetic expansion,
-   process substitution, word splitting, and pathname expansion, according
-   to the bits set in EFLAGS.  Words with the W_QUOTED or W_NOSPLIT bits
-   set, or for which no expansion is done, do not undergo word splitting.
-   Words with the W_NOGLOB bit set do not undergo pathname expansion. */
-static WORD_LIST *
-expand_word_list_internal (list, eflags)
-     WORD_LIST *list;
-     int eflags;
-{
-  WORD_LIST *new_list, *temp_list;
-  int tint;
-
-  if (list == 0)
-    return ((WORD_LIST *)NULL);
-
-  garglist = new_list = copy_word_list (list);
-  if (eflags & WEXP_VARASSIGN)
-    {
-      garglist = new_list = separate_out_assignments (new_list);
-      if (new_list == 0)
-       {
-         if (subst_assign_varlist)
-           {
-             /* All the words were variable assignments, so they are placed
-                into the shell's environment. */
-             for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
-               {
-                 this_command_name = (char *)NULL;     /* no arithmetic errors */
-                 tint = do_word_assignment (temp_list->word);
-                 /* Variable assignment errors in non-interactive shells
-                    running in Posix.2 mode cause the shell to exit. */
-                 if (tint == 0)
-                   {
-                     last_command_exit_value = EXECUTION_FAILURE;
-                     if (interactive_shell == 0 && posixly_correct)
-                       exp_jump_to_top_level (FORCE_EOF);
-                     else
-                       exp_jump_to_top_level (DISCARD);
-                   }
-               }
-             dispose_words (subst_assign_varlist);
-             subst_assign_varlist = (WORD_LIST *)NULL;
-           }
-         return ((WORD_LIST *)NULL);
-       }
-    }
-
-  /* Begin expanding the words that remain.  The expansions take place on
-     things that aren't really variable assignments. */
-
-#if defined (BRACE_EXPANSION)
-  /* Do brace expansion on this word if there are any brace characters
-     in the string. */
-  if ((eflags & WEXP_BRACEEXP) && brace_expansion && new_list)
-    new_list = brace_expand_word_list (new_list, eflags);
-#endif /* BRACE_EXPANSION */
-
-  /* Perform the `normal' shell expansions: tilde expansion, parameter and
-     variable substitution, command substitution, arithmetic expansion,
-     and word splitting. */
-  new_list = shell_expand_word_list (new_list, eflags);
-
-  /* Okay, we're almost done.  Now let's just do some filename
-     globbing. */
-  if (new_list)
-    {
-      if ((eflags & WEXP_PATHEXP) && disallow_filename_globbing == 0)
-       /* Glob expand the word list unless globbing has been disabled. */
-       new_list = glob_expand_word_list (new_list, eflags);
-      else
-       /* Dequote the words, because we're not performing globbing. */
-       new_list = dequote_list (new_list);
-    }
-
-  if ((eflags & WEXP_VARASSIGN) && subst_assign_varlist)
-    {
-      sh_wassign_func_t *assign_func;
-
-      /* If the remainder of the words expand to nothing, Posix.2 requires
-        that the variable and environment assignments affect the shell's
-        environment. */
-      assign_func = new_list ? assign_in_env : do_word_assignment;
-      tempenv_assign_error = 0;
-
-      for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
-       {
-         this_command_name = (char *)NULL;
-         assigning_in_environment = (assign_func == assign_in_env);
-         tint = (*assign_func) (temp_list->word);
-         assigning_in_environment = 0;
-         /* Variable assignment errors in non-interactive shells running
-            in Posix.2 mode cause the shell to exit. */
-         if (tint == 0)
-           {
-             if (assign_func == do_word_assignment)
-               {
-                 last_command_exit_value = EXECUTION_FAILURE;
-                 if (interactive_shell == 0 && posixly_correct)
-                   exp_jump_to_top_level (FORCE_EOF);
-                 else
-                   exp_jump_to_top_level (DISCARD);
-               }
-             else
-               tempenv_assign_error++;
-           }
-       }
-
-      dispose_words (subst_assign_varlist);
-      subst_assign_varlist = (WORD_LIST *)NULL;
-    }
-
-#if 0
-  tint = list_length (new_list) + 1;
-  RESIZE_MALLOCED_BUFFER (glob_argv_flags, 0, tint, glob_argv_flags_size, 16);
-  for (tint = 0, temp_list = new_list; temp_list; temp_list = temp_list->next)
-    glob_argv_flags[tint++] = (temp_list->word->flags & W_GLOBEXP) ? '1' : '0';
-  glob_argv_flags[tint] = '\0';
-#endif
-
-  return (new_list);
-}
diff --git a/subst.h~ b/subst.h~
deleted file mode 100644 (file)
index c9f5f45..0000000
--- a/subst.h~
+++ /dev/null
@@ -1,302 +0,0 @@
-/* subst.h -- Names of externally visible functions in subst.c. */
-
-/* Copyright (C) 1993-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 (_SUBST_H_)
-#define _SUBST_H_
-
-#include "stdc.h"
-
-/* Constants which specify how to handle backslashes and quoting in
-   expand_word_internal ().  Q_DOUBLE_QUOTES means to use the function
-   slashify_in_quotes () to decide whether the backslash should be
-   retained.  Q_HERE_DOCUMENT means slashify_in_here_document () to
-   decide whether to retain the backslash.  Q_KEEP_BACKSLASH means
-   to unconditionally retain the backslash.  Q_PATQUOTE means that we're
-   expanding a pattern ${var%#[#%]pattern} in an expansion surrounded
-   by double quotes. */
-#define Q_DOUBLE_QUOTES  0x01
-#define Q_HERE_DOCUMENT  0x02
-#define Q_KEEP_BACKSLASH 0x04
-#define Q_PATQUOTE      0x08
-#define Q_QUOTED        0x10
-#define Q_ADDEDQUOTES   0x20
-#define Q_QUOTEDNULL    0x40
-
-/* Flag values controlling how assignment statements are treated. */
-#define ASS_APPEND     0x01
-#define ASS_MKLOCAL    0x02
-#define ASS_MKASSOC    0x04
-
-/* Flags for the string extraction functions. */
-#define SX_NOALLOC     0x01    /* just skip; don't return substring */
-#define SX_VARNAME     0x02    /* variable name; for string_extract () */
-#define SX_REQMATCH    0x04    /* closing/matching delimiter required */
-#define SX_COMMAND     0x08    /* extracting a shell script/command */
-#define SX_NOCTLESC    0x10    /* don't honor CTLESC quoting */
-#define SX_NOESCCTLNUL 0x20    /* don't let CTLESC quote CTLNUL */
-#define SX_NOLONGJMP   0x40    /* don't longjmp on fatal error */
-#define SX_ARITHSUB    0x80    /* extracting $(( ... )) */
-
-/* Remove backslashes which are quoting backquotes from STRING.  Modifies
-   STRING, and returns a pointer to it. */
-extern char * de_backslash __P((char *));
-
-/* Replace instances of \! in a string with !. */
-extern void unquote_bang __P((char *));
-
-/* Extract the $( construct in STRING, and return a new string.
-   Start extracting at (SINDEX) as if we had just seen "$(".
-   Make (SINDEX) get the position just after the matching ")".
-   XFLAGS is additional flags to pass to other extraction functions, */
-extern char *extract_command_subst __P((char *, int *, int));
-
-/* Extract the $[ construct in STRING, and return a new string.
-   Start extracting at (SINDEX) as if we had just seen "$[".
-   Make (SINDEX) get the position just after the matching "]". */
-extern char *extract_arithmetic_subst __P((char *, int *));
-
-#if defined (PROCESS_SUBSTITUTION)
-/* Extract the <( or >( construct in STRING, and return a new string.
-   Start extracting at (SINDEX) as if we had just seen "<(".
-   Make (SINDEX) get the position just after the matching ")". */
-extern char *extract_process_subst __P((char *, char *, int *));
-#endif /* PROCESS_SUBSTITUTION */
-
-/* Extract the name of the variable to bind to from the assignment string. */
-extern char *assignment_name __P((char *));
-
-/* Return a single string of all the words present in LIST, separating
-   each word with SEP. */
-extern char *string_list_internal __P((WORD_LIST *, char *));
-
-/* Return a single string of all the words present in LIST, separating
-   each word with a space. */
-extern char *string_list __P((WORD_LIST *));
-
-/* Turn $* into a single string, obeying POSIX rules. */
-extern char *string_list_dollar_star __P((WORD_LIST *));
-
-/* Expand $@ into a single string, obeying POSIX rules. */
-extern char *string_list_dollar_at __P((WORD_LIST *, int));
-
-/* Turn the positional paramters into a string, understanding quoting and
-   the various subtleties of using the first character of $IFS as the
-   separator.  Calls string_list_dollar_at, string_list_dollar_star, and
-   string_list as appropriate. */
-extern char *string_list_pos_params __P((int, WORD_LIST *, int));
-
-/* Perform quoted null character removal on each element of LIST.
-   This modifies LIST. */
-extern void word_list_remove_quoted_nulls __P((WORD_LIST *));
-
-/* This performs word splitting and quoted null character removal on
-   STRING. */
-extern WORD_LIST *list_string __P((char *, char *, int));
-
-extern char *ifs_firstchar  __P((int *));
-extern char *get_word_from_string __P((char **, char *, char **));
-extern char *strip_trailing_ifs_whitespace __P((char *, char *, int));
-
-/* Given STRING, an assignment string, get the value of the right side
-   of the `=', and bind it to the left side.  If EXPAND is true, then
-   perform tilde expansion, parameter expansion, command substitution,
-   and arithmetic expansion on the right-hand side.  Do not perform word
-   splitting on the result of expansion. */
-extern int do_assignment __P((char *));
-extern int do_assignment_no_expand __P((char *));
-extern int do_word_assignment __P((WORD_DESC *));
-
-/* Append SOURCE to TARGET at INDEX.  SIZE is the current amount
-   of space allocated to TARGET.  SOURCE can be NULL, in which
-   case nothing happens.  Gets rid of SOURCE by free ()ing it.
-   Returns TARGET in case the location has changed. */
-extern char *sub_append_string __P((char *, char *, int *, int *));
-
-/* Append the textual representation of NUMBER to TARGET.
-   INDEX and SIZE are as in SUB_APPEND_STRING. */
-extern char *sub_append_number __P((intmax_t, char *, int *, int *));
-
-/* Return the word list that corresponds to `$*'. */
-extern WORD_LIST *list_rest_of_args __P((void));
-
-/* Make a single large string out of the dollar digit variables,
-   and the rest_of_args.  If DOLLAR_STAR is 1, then obey the special
-   case of "$*" with respect to IFS. */
-extern char *string_rest_of_args __P((int));
-
-extern int number_of_args __P((void));
-
-/* Expand STRING by performing parameter expansion, command substitution,
-   and arithmetic expansion.  Dequote the resulting WORD_LIST before
-   returning it, but do not perform word splitting.  The call to
-   remove_quoted_nulls () is made here because word splitting normally
-   takes care of quote removal. */
-extern WORD_LIST *expand_string_unsplit __P((char *, int));
-
-/* Expand the rhs of an assignment statement. */
-extern WORD_LIST *expand_string_assignment __P((char *, int));
-
-/* Expand a prompt string. */
-extern WORD_LIST *expand_prompt_string __P((char *, int, int));
-
-/* Expand STRING just as if you were expanding a word.  This also returns
-   a list of words.  Note that filename globbing is *NOT* done for word
-   or string expansion, just when the shell is expanding a command.  This
-   does parameter expansion, command substitution, arithmetic expansion,
-   and word splitting.  Dequote the resultant WORD_LIST before returning. */
-extern WORD_LIST *expand_string __P((char *, int));
-
-/* Convenience functions that expand strings to strings, taking care of
-   converting the WORD_LIST * returned by the expand_string* functions
-   to a string and deallocating the WORD_LIST *. */
-extern char *expand_string_to_string __P((char *, int));
-extern char *expand_string_unsplit_to_string __P((char *, int));
-extern char *expand_assignment_string_to_string __P((char *, int));
-
-/* Expand an arithmetic expression string */
-extern char *expand_arith_string __P((char *, int));
-
-/* De-quote quoted characters in STRING. */
-extern char *dequote_string __P((char *));
-
-/* De-quote CTLESC-escaped CTLESC or CTLNUL characters in STRING. */
-extern char *dequote_escapes __P((char *));
-
-/* De-quote quoted characters in each word in LIST. */
-extern WORD_LIST *dequote_list __P((WORD_LIST *));
-
-/* Expand WORD, performing word splitting on the result.  This does
-   parameter expansion, command substitution, arithmetic expansion,
-   word splitting, and quote removal. */
-extern WORD_LIST *expand_word __P((WORD_DESC *, int));
-
-/* Expand WORD, but do not perform word splitting on the result.  This
-   does parameter expansion, command substitution, arithmetic expansion,
-   and quote removal. */
-extern WORD_LIST *expand_word_unsplit __P((WORD_DESC *, int));
-extern WORD_LIST *expand_word_leave_quoted __P((WORD_DESC *, int));
-
-/* Return the value of a positional parameter.  This handles values > 10. */
-extern char *get_dollar_var_value __P((intmax_t));
-
-/* Quote a string to protect it from word splitting. */
-extern char *quote_string __P((char *));
-
-/* Quote escape characters (characters special to interals of expansion)
-   in a string. */
-extern char *quote_escapes __P((char *));
-
-/* And remove such quoted special characters. */
-extern char *remove_quoted_escapes __P((char *));
-
-/* Remove CTLNUL characters from STRING unless they are quoted with CTLESC. */
-extern char *remove_quoted_nulls __P((char *));
-
-/* Perform quote removal on STRING.  If QUOTED > 0, assume we are obeying the
-   backslash quoting rules for within double quotes. */
-extern char *string_quote_removal __P((char *, int));
-
-/* Perform quote removal on word WORD.  This allocates and returns a new
-   WORD_DESC *. */
-extern WORD_DESC *word_quote_removal __P((WORD_DESC *, int));
-
-/* Perform quote removal on all words in LIST.  If QUOTED is non-zero,
-   the members of the list are treated as if they are surrounded by
-   double quotes.  Return a new list, or NULL if LIST is NULL. */
-extern WORD_LIST *word_list_quote_removal __P((WORD_LIST *, int));
-
-/* Called when IFS is changed to maintain some private variables. */
-extern void setifs __P((SHELL_VAR *));
-
-/* Return the value of $IFS, or " \t\n" if IFS is unset. */
-extern char *getifs __P((void));
-
-/* This splits a single word into a WORD LIST on $IFS, but only if the word
-   is not quoted.  list_string () performs quote removal for us, even if we
-   don't do any splitting. */
-extern WORD_LIST *word_split __P((WORD_DESC *, char *));
-
-/* Take the list of words in LIST and do the various substitutions.  Return
-   a new list of words which is the expanded list, and without things like
-   variable assignments. */
-extern WORD_LIST *expand_words __P((WORD_LIST *));
-
-/* Same as expand_words (), but doesn't hack variable or environment
-   variables. */
-extern WORD_LIST *expand_words_no_vars __P((WORD_LIST *));
-
-/* Perform the `normal shell expansions' on a WORD_LIST.  These are
-   brace expansion, tilde expansion, parameter and variable substitution,
-   command substitution, arithmetic expansion, and word splitting. */
-extern WORD_LIST *expand_words_shellexp __P((WORD_LIST *));
-
-extern WORD_DESC *command_substitute __P((char *, int));
-extern char *pat_subst __P((char *, char *, char *, int));
-
-extern int fifos_pending __P((void));
-extern void unlink_fifo_list __P((void));
-
-extern WORD_LIST *list_string_with_quotes __P((char *));
-
-#if defined (ARRAY_VARS)
-extern char *extract_array_assignment_list __P((char *, int *));
-#endif
-
-#if defined (COND_COMMAND)
-extern char *remove_backslashes __P((char *));
-extern char *cond_expand_word __P((WORD_DESC *, int));
-#endif
-
-/* Flags for skip_to_delim */
-#define SD_NOJMP       0x01    /* don't longjmp on fatal error. */
-#define SD_INVERT      0x02    /* look for chars NOT in passed set */
-#define SD_NOQUOTEDELIM        0x04    /* don't let single or double quotes act as delimiters */
-#define SD_NOSKIPCMD   0x08    /* don't skip over $(, <(, or >( command/process substitution */
-
-extern int skip_to_delim __P((char *, int, char *, int));
-
-#if defined (READLINE)
-extern int char_is_quoted __P((char *, int));
-extern int unclosed_pair __P((char *, int, char *));
-extern WORD_LIST *split_at_delims __P((char *, int, char *, int, int, int *, int *));
-#endif
-
-/* Variables used to keep track of the characters in IFS. */
-extern SHELL_VAR *ifs_var;
-extern char *ifs_value;
-extern unsigned char ifs_cmap[];
-
-#if defined (HANDLE_MULTIBYTE)
-extern unsigned char ifs_firstc[];
-extern size_t ifs_firstc_len;
-#else
-extern unsigned char ifs_firstc;
-#endif
-
-/* Evaluates to 1 if C is a character in $IFS. */
-#define isifs(c)       (ifs_cmap[(unsigned char)(c)] != 0)
-
-/* How to determine the quoted state of the character C. */
-#define QUOTED_CHAR(c)  ((c) == CTLESC)
-
-/* Is the first character of STRING a quoted NULL character? */
-#define QUOTED_NULL(string) ((string)[0] == CTLNUL && (string)[1] == '\0')
-
-#endif /* !_SUBST_H_ */
diff --git a/support/bashbug.sh~ b/support/bashbug.sh~
deleted file mode 100644 (file)
index b00a55b..0000000
+++ /dev/null
@@ -1,271 +0,0 @@
-#!/bin/sh -
-#
-# bashbug - create a bug report and mail it to the bug address
-#
-# The bug address depends on the release status of the shell.  Versions
-# with status `devel', `alpha', `beta', or `rc' mail bug reports to
-# chet@cwru.edu and, optionally, to bash-testers@cwru.edu.
-# Other versions send mail to bug-bash@gnu.org.
-#
-# Copyright (C) 1996-2004 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
-
-#
-# configuration section:
-#      these variables are filled in by the make target in Makefile
-#
-MACHINE="!MACHINE!"
-OS="!OS!"
-CC="!CC!"
-CFLAGS="!CFLAGS!"
-RELEASE="!RELEASE!"
-PATCHLEVEL="!PATCHLEVEL!"
-RELSTATUS="!RELSTATUS!"
-MACHTYPE="!MACHTYPE!"
-
-PATH=/bin:/usr/bin:/usr/local/bin:$PATH
-export PATH
-
-# Check if TMPDIR is set, default to /tmp
-: ${TMPDIR:=/tmp}
-
-#Securely create a temporary directory for the temporary files
-TEMPDIR=$TMPDIR/bbug.$$
-(umask 077 && mkdir $TEMPDIR) || {
-       echo "$0: could not create temporary directory" >&2
-       exit 1
-}
-
-TEMPFILE1=$TEMPDIR/bbug1
-TEMPFILE2=$TEMPDIR/bbug2
-        
-USAGE="Usage: $0 [--help] [--version] [bug-report-email-address]"
-VERSTR="GNU bashbug, version ${RELEASE}.${PATCHLEVEL}-${RELSTATUS}"
-
-do_help= do_version=
-
-while [ $# -gt 0 ]; do
-       case "$1" in
-       --help)         shift ; do_help=y ;;
-       --version)      shift ; do_version=y ;;
-       --)             shift ; break ;;
-       -*)             echo "bashbug: ${1}: invalid option" >&2
-                       echo "$USAGE" >& 2
-                       exit 2 ;;
-       *)              break ;;
-       esac
-done
-
-if [ -n "$do_version" ]; then
-       echo "${VERSTR}"
-       exit 0
-fi
-
-if [ -n "$do_help" ]; then
-       echo "${VERSTR}"
-       echo "${USAGE}"
-       echo
-       cat << HERE_EOF
-Bashbug is used to send mail to the Bash maintainers
-for when Bash doesn't behave like you'd like, or expect.
-
-Bashbug will start up your editor (as defined by the shell's
-EDITOR environment variable) with a preformatted bug report
-template for you to fill in. The report will be mailed to the
-bash maintainers by default. See the manual for details.
-
-If you invoke bashbug by accident, just quit your editor without
-saving any changes to the template, and no bug report will be sent.
-HERE_EOF
-       exit 0
-fi
-
-# Figure out how to echo a string without a trailing newline
-N=`echo 'hi there\c'`
-case "$N" in
-*c)    n=-n c= ;;
-*)     n= c='\c' ;;
-esac
-
-BASHTESTERS="bash-testers@cwru.edu"
-
-case "$RELSTATUS" in
-alpha*|beta*|devel*|rc*)       BUGBASH=chet@cwru.edu ;;
-*)                             BUGBASH=bug-bash@gnu.org ;;
-esac
-
-case "$RELSTATUS" in
-alpha*|beta*|devel*|rc*)
-               echo "$0: This is a testing release.  Would you like your bug report"
-               echo "$0: to be sent to the bash-testers mailing list?"
-               echo $n "$0: Send to bash-testers? $c"
-               read ans
-               case "$ans" in
-               y*|Y*)  BUGBASH="${BUGBASH},${BASHTESTERS}" ;;
-               esac ;;
-esac
-
-BUGADDR="${1-$BUGBASH}"
-
-if [ -z "$DEFEDITOR" ] && [ -z "$EDITOR" ]; then
-       if [ -x /usr/bin/editor ]; then
-               DEFEDITOR=editor
-       elif [ -x /usr/local/bin/ce ]; then
-               DEFEDITOR=ce
-       elif [ -x /usr/local/bin/emacs ]; then
-               DEFEDITOR=emacs
-       elif [ -x /usr/contrib/bin/emacs ]; then
-               DEFEDITOR=emacs
-       elif [ -x /usr/bin/emacs ]; then
-               DEFEDITOR=emacs
-       elif [ -x /usr/bin/xemacs ]; then
-               DEFEDITOR=xemacs
-       elif [ -x /usr/contrib/bin/jove ]; then
-               DEFEDITOR=jove
-       elif [ -x /usr/local/bin/jove ]; then
-               DEFEDITOR=jove
-       elif [ -x /usr/bin/vi ]; then
-               DEFEDITOR=vi
-       else
-               echo "$0: No default editor found: attempting to use vi" >&2
-               DEFEDITOR=vi
-       fi
-fi
-
-
-: ${EDITOR=$DEFEDITOR}
-
-: ${USER=${LOGNAME-`whoami`}}
-
-trap 'rm -rf "$TEMPDIR"; exit 1' 1 2 3 13 15
-trap 'rm -rf "$TEMPDIR"' 0
-
-UN=
-if (uname) >/dev/null 2>&1; then
-       UN=`uname -a`
-fi
-
-if [ -f /usr/lib/sendmail ] ; then
-       RMAIL="/usr/lib/sendmail"
-       SMARGS="-i -t"
-elif [ -f /usr/sbin/sendmail ] ; then
-       RMAIL="/usr/sbin/sendmail"
-       SMARGS="-i -t"
-else
-       RMAIL=rmail
-       SMARGS="$BUGADDR"
-fi
-
-INITIAL_SUBJECT='[50 character or so descriptive subject here (for reference)]'
-
-cat > "$TEMPFILE1" <<EOF
-From: ${USER}
-To: ${BUGADDR}
-Subject: ${INITIAL_SUBJECT}
-
-Configuration Information [Automatically generated, do not change]:
-Machine: $MACHINE
-OS: $OS
-Compiler: $CC
-Compilation CFLAGS: $CFLAGS
-uname output: $UN
-Machine Type: $MACHTYPE
-
-Bash Version: $RELEASE
-Patch Level: $PATCHLEVEL
-Release Status: $RELSTATUS
-
-Description:
-       [Detailed description of the problem, suggestion, or complaint.]
-
-Repeat-By:
-       [Describe the sequence of events that causes the problem
-       to occur.]
-
-Fix:
-       [Description of how to fix the problem.  If you don't know a
-       fix for the problem, don't include this section.]
-EOF
-
-cp "$TEMPFILE1" "$TEMPFILE2"
-chmod u+w "$TEMPFILE1"
-
-trap '' 2              # ignore interrupts while in editor
-
-edstat=1
-while [ $edstat -ne 0 ]; do
-       $EDITOR "$TEMPFILE1"
-       edstat=$?
-
-       if [ $edstat -ne 0 ]; then
-               echo "$0: editor \`$EDITOR' exited with nonzero status."
-               echo "$0: Perhaps it was interrupted."
-               echo "$0: Type \`y' to give up, and lose your bug report;"
-               echo "$0: type \`n' to re-enter the editor."
-               echo $n "$0: Do you want to give up? $c"
-
-               read ans
-               case "$ans" in
-               [Yy]*) exit 1 ;;
-               esac
-
-               continue
-       fi
-
-       # find the subject from the temp file and see if it's been changed
-       CURR_SUB=`grep '^Subject: ' "$TEMPFILE1" | sed 's|^Subject:[    ]*||' | sed 1q`
-
-       case "$CURR_SUB" in
-       "${INITIAL_SUBJECT}")
-               echo
-               echo "$0: You have not changed the subject from the default."
-               echo "$0: Please use a more descriptive subject header."
-               echo "$0: Type \`y' to give up, and lose your bug report;"
-               echo "$0: type \`n' to re-enter the editor."
-               echo $n "$0: Do you want to give up? $c"
-
-               read ans
-               case "$ans" in
-               [Yy]*) exit 1 ;;
-               esac
-
-               echo "$0:  The editor will be restarted in five seconds."
-               sleep 5
-               edstat=1
-               ;;
-       esac
-
-done
-
-trap 'rm -rf "$TEMPDIR"; exit 1' 2     # restore trap on SIGINT
-
-if cmp -s "$TEMPFILE1" "$TEMPFILE2"
-then
-       echo "File not changed, no bug report submitted."
-       exit
-fi
-
-echo $n "Send bug report? [y/n] $c"
-read ans
-case "$ans" in
-[Nn]*) exit 0 ;;
-esac
-
-${RMAIL} $SMARGS < "$TEMPFILE1" || {
-       cat "$TEMPFILE1" >> $HOME/dead.bashbug
-       echo "$0: mail failed: report saved in $HOME/dead.bashbug" >&2
-}
-
-exit 0
diff --git a/support/config.sub~ b/support/config.sub~
deleted file mode 100644 (file)
index 8659ca3..0000000
+++ /dev/null
@@ -1,1662 +0,0 @@
-#! /bin/sh
-# Configuration validation subroutine script.
-#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 20098
-#   Free Software Foundation, Inc.
-
-timestamp='2008-03-26'
-
-# This file is (in principle) common to ALL GNU software.
-# The presence of a machine in this file suggests that SOME GNU software
-# can handle that machine.  It does not imply ALL GNU software can.
-#
-# This file 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 of the License, 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., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-
-# Please send patches to <config-patches@gnu.org>.  Submit a context
-# diff and a properly formatted ChangeLog entry.
-#
-# Configuration subroutine to validate and canonicalize a configuration type.
-# Supply the specified configuration type as an argument.
-# If it is invalid, we print an error message on stderr and exit with code 1.
-# Otherwise, we print the canonical config type on stdout and succeed.
-
-# This file is supposed to be the same for all GNU packages
-# and recognize all the CPU types, system types and aliases
-# that are meaningful with *any* GNU software.
-# Each package is responsible for reporting which valid configurations
-# it does not support.  The user should be able to distinguish
-# a failure to support a valid configuration from a meaningless
-# configuration.
-
-# The goal of this file is to map all the various variations of a given
-# machine specification into a single specification in the form:
-#      CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# or in some cases, the newer four-part form:
-#      CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
-# It is wrong to echo any other type of specification.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS
-       $0 [OPTION] ALIAS
-
-Canonicalize a configuration name.
-
-Operation modes:
-  -h, --help         print this help, then exit
-  -t, --time-stamp   print date of last modification, then exit
-  -v, --version      print version number, then exit
-
-Report bugs and patches to <config-patches@gnu.org>."
-
-version="\
-GNU config.sub ($timestamp)
-
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006, 2007, 2008,2009 Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions.  There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
-  case $1 in
-    --time-stamp | --time* | -t )
-       echo "$timestamp" ; exit ;;
-    --version | -v )
-       echo "$version" ; exit ;;
-    --help | --h* | -h )
-       echo "$usage"; exit ;;
-    -- )     # Stop option processing
-       shift; break ;;
-    - )        # Use stdin as input.
-       break ;;
-    -* )
-       echo "$me: invalid option $1$help"
-       exit 1 ;;
-
-    *local*)
-       # First pass through any local machine types.
-       echo $1
-       exit ;;
-
-    * )
-       break ;;
-  esac
-done
-
-case $# in
- 0) echo "$me: missing argument$help" >&2
-    exit 1;;
- 1) ;;
- *) echo "$me: too many arguments$help" >&2
-    exit 1;;
-esac
-
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
-  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
-  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
-  storm-chaos* | os2-emx* | rtmk-nova*)
-    os=-$maybe_os
-    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
-    ;;
-  *)
-    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
-    if [ $basic_machine != $1 ]
-    then os=`echo $1 | sed 's/.*-/-/'`
-    else os=; fi
-    ;;
-esac
-
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work.  We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
-       -sun*os*)
-               # Prevent following clause from handling this invalid input.
-               ;;
-       -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
-       -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
-       -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
-       -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-       -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-       -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-       -apple | -axis | -knuth | -cray)
-               os=
-               basic_machine=$1
-               ;;
-       -sim | -cisco | -oki | -wec | -winbond)
-               os=
-               basic_machine=$1
-               ;;
-       -scout)
-               ;;
-       -wrs)
-               os=-vxworks
-               basic_machine=$1
-               ;;
-       -chorusos*)
-               os=-chorusos
-               basic_machine=$1
-               ;;
-       -chorusrdb)
-               os=-chorusrdb
-               basic_machine=$1
-               ;;
-       -hiux*)
-               os=-hiuxwe2
-               ;;
-       -sco6)
-               os=-sco5v6
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco5)
-               os=-sco3.2v5
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco4)
-               os=-sco3.2v4
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco3.2.[4-9]*)
-               os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco3.2v[4-9]*)
-               # Don't forget version if it is 3.2v4 or newer.
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco5v6*)
-               # Don't forget version if it is 3.2v4 or newer.
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco*)
-               os=-sco3.2v2
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -udk*)
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -isc)
-               os=-isc2.2
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -clix*)
-               basic_machine=clipper-intergraph
-               ;;
-       -isc*)
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -lynx*)
-               os=-lynxos
-               ;;
-       -ptx*)
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
-               ;;
-       -windowsnt*)
-               os=`echo $os | sed -e 's/windowsnt/winnt/'`
-               ;;
-       -psos*)
-               os=-psos
-               ;;
-       -mint | -mint[0-9]*)
-               basic_machine=m68k-atari
-               os=-mint
-               ;;
-esac
-
-# Decode aliases for certain CPU-COMPANY combinations.
-case $basic_machine in
-       # Recognize the basic CPU types without company name.
-       # Some are omitted here because they have special meanings below.
-       1750a | 580 \
-       | a29k \
-       | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
-       | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
-       | am33_2.0 \
-       | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
-       | bfin \
-       | c4x | clipper \
-       | d10v | d30v | dlx | dsp16xx \
-       | fido | fr30 | frv \
-       | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
-       | i370 | i860 | i960 | ia64 \
-       | ip2k | iq2000 \
-       | m32c | m32r | m32rle | m68000 | m68k | m88k \
-       | maxq | mb | microblaze | mcore | mep | metag \
-       | mips | mipsbe | mipseb | mipsel | mipsle \
-       | mips16 \
-       | mips64 | mips64el \
-       | mips64octeon | mips64octeonel \
-       | mips64orion | mips64orionel \
-       | mips64r5900 | mips64r5900el \
-       | mips64vr | mips64vrel \
-       | mips64vr4100 | mips64vr4100el \
-       | mips64vr4300 | mips64vr4300el \
-       | mips64vr5000 | mips64vr5000el \
-       | mips64vr5900 | mips64vr5900el \
-       | mipsisa32 | mipsisa32el \
-       | mipsisa32r2 | mipsisa32r2el \
-       | mipsisa64 | mipsisa64el \
-       | mipsisa64r2 | mipsisa64r2el \
-       | mipsisa64sb1 | mipsisa64sb1el \
-       | mipsisa64sr71k | mipsisa64sr71kel \
-       | mipstx39 | mipstx39el \
-       | mn10200 | mn10300 \
-       | mt \
-       | msp430 \
-       | nios | nios2 \
-       | ns16k | ns32k \
-       | or32 \
-       | pdp10 | pdp11 | pj | pjl \
-       | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
-       | pyramid \
-       | score \
-       | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
-       | sh64 | sh64le \
-       | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
-       | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
-       | spu | strongarm \
-       | tahoe | thumb | tic4x | tic80 | tron \
-       | v850 | v850e \
-       | we32k \
-       | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
-       | z8k)
-               basic_machine=$basic_machine-unknown
-               ;;
-       m6811 | m68hc11 | m6812 | m68hc12)
-               # Motorola 68HC11/12.
-               basic_machine=$basic_machine-unknown
-               os=-none
-               ;;
-       m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
-               ;;
-       ms1)
-               basic_machine=mt-unknown
-               ;;
-
-       # We use `pc' rather than `unknown'
-       # because (1) that's what they normally are, and
-       # (2) the word "unknown" tends to confuse beginning users.
-       i*86 | x86_64)
-         basic_machine=$basic_machine-pc
-         ;;
-       # Object if more than one company name word.
-       *-*-*)
-               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
-               exit 1
-               ;;
-       # Recognize the basic CPU types with company name.
-       580-* \
-       | a29k-* \
-       | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
-       | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
-       | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
-       | arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
-       | avr-* | avr32-* \
-       | bfin-* | bs2000-* \
-       | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
-       | clipper-* | craynv-* | cydra-* \
-       | d10v-* | d30v-* | dlx-* \
-       | elxsi-* \
-       | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
-       | h8300-* | h8500-* \
-       | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
-       | i*86-* | i860-* | i960-* | ia64-* \
-       | ip2k-* | iq2000-* \
-       | m32c-* | m32r-* | m32rle-* \
-       | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
-       | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
-       | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
-       | mips16-* \
-       | mips64-* | mips64el-* \
-       | mips64octeon-* | mips64octeonel-* \
-       | mips64orion-* | mips64orionel-* \
-       | mips64r5900-* | mips64r5900el-* \
-       | mips64vr-* | mips64vrel-* \
-       | mips64vr4100-* | mips64vr4100el-* \
-       | mips64vr4300-* | mips64vr4300el-* \
-       | mips64vr5000-* | mips64vr5000el-* \
-       | mips64vr5900-* | mips64vr5900el-* \
-       | mipsisa32-* | mipsisa32el-* \
-       | mipsisa32r2-* | mipsisa32r2el-* \
-       | mipsisa64-* | mipsisa64el-* \
-       | mipsisa64r2-* | mipsisa64r2el-* \
-       | mipsisa64sb1-* | mipsisa64sb1el-* \
-       | mipsisa64sr71k-* | mipsisa64sr71kel-* \
-       | mipstx39-* | mipstx39el-* \
-       | mmix-* \
-       | mt-* \
-       | msp430-* \
-       | nios-* | nios2-* \
-       | none-* | np1-* | ns16k-* | ns32k-* \
-       | orion-* \
-       | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
-       | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
-       | pyramid-* \
-       | romp-* | rs6000-* \
-       | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
-       | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
-       | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
-       | sparclite-* \
-       | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
-       | tahoe-* | thumb-* \
-       | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
-       | tron-* \
-       | v850-* | v850e-* | vax-* \
-       | we32k-* \
-       | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
-       | xstormy16-* | xtensa*-* \
-       | ymp-* \
-       | z8k-*)
-               ;;
-       # Recognize the basic CPU types without company name, with glob match.
-       xtensa*)
-               basic_machine=$basic_machine-unknown
-               ;;
-       # Recognize the various machine names and aliases which stand
-       # for a CPU type and a company and sometimes even an OS.
-       386bsd)
-               basic_machine=i386-unknown
-               os=-bsd
-               ;;
-       3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
-               basic_machine=m68000-att
-               ;;
-       3b*)
-               basic_machine=we32k-att
-               ;;
-       a29khif)
-               basic_machine=a29k-amd
-               os=-udi
-               ;;
-       abacus)
-               basic_machine=abacus-unknown
-               ;;
-       adobe68k)
-               basic_machine=m68010-adobe
-               os=-scout
-               ;;
-       alliant | fx80)
-               basic_machine=fx80-alliant
-               ;;
-       altos | altos3068)
-               basic_machine=m68k-altos
-               ;;
-       am29k)
-               basic_machine=a29k-none
-               os=-bsd
-               ;;
-       amd64)
-               basic_machine=x86_64-pc
-               ;;
-       amd64-*)
-               basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       amdahl)
-               basic_machine=580-amdahl
-               os=-sysv
-               ;;
-       amiga | amiga-*)
-               basic_machine=m68k-unknown
-               ;;
-       amigaos | amigados)
-               basic_machine=m68k-unknown
-               os=-amigaos
-               ;;
-       amigaunix | amix)
-               basic_machine=m68k-unknown
-               os=-sysv4
-               ;;
-       apollo68)
-               basic_machine=m68k-apollo
-               os=-sysv
-               ;;
-       apollo68bsd)
-               basic_machine=m68k-apollo
-               os=-bsd
-               ;;
-       aux)
-               basic_machine=m68k-apple
-               os=-aux
-               ;;
-       balance)
-               basic_machine=ns32k-sequent
-               os=-dynix
-               ;;
-       blackfin)
-               basic_machine=bfin-unknown
-               os=-linux
-               ;;
-       blackfin-*)
-               basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
-               os=-linux
-               ;;
-       c90)
-               basic_machine=c90-cray
-               os=-unicos
-               ;;
-       convex-c1)
-               basic_machine=c1-convex
-               os=-bsd
-               ;;
-       convex-c2)
-               basic_machine=c2-convex
-               os=-bsd
-               ;;
-       convex-c32)
-               basic_machine=c32-convex
-               os=-bsd
-               ;;
-       convex-c34)
-               basic_machine=c34-convex
-               os=-bsd
-               ;;
-       convex-c38)
-               basic_machine=c38-convex
-               os=-bsd
-               ;;
-       cray | j90)
-               basic_machine=j90-cray
-               os=-unicos
-               ;;
-       craynv)
-               basic_machine=craynv-cray
-               os=-unicosmp
-               ;;
-       cr16)
-               basic_machine=cr16-unknown
-               os=-elf
-               ;;
-       crds | unos)
-               basic_machine=m68k-crds
-               ;;
-       crisv32 | crisv32-* | etraxfs*)
-               basic_machine=crisv32-axis
-               ;;
-       cris | cris-* | etrax*)
-               basic_machine=cris-axis
-               ;;
-       crx)
-               basic_machine=crx-unknown
-               os=-elf
-               ;;
-       da30 | da30-*)
-               basic_machine=m68k-da30
-               ;;
-       decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
-               basic_machine=mips-dec
-               ;;
-       decsystem10* | dec10*)
-               basic_machine=pdp10-dec
-               os=-tops10
-               ;;
-       decsystem20* | dec20*)
-               basic_machine=pdp10-dec
-               os=-tops20
-               ;;
-       delta | 3300 | motorola-3300 | motorola-delta \
-             | 3300-motorola | delta-motorola)
-               basic_machine=m68k-motorola
-               ;;
-       delta88)
-               basic_machine=m88k-motorola
-               os=-sysv3
-               ;;
-       djgpp)
-               basic_machine=i586-pc
-               os=-msdosdjgpp
-               ;;
-       dpx20 | dpx20-*)
-               basic_machine=rs6000-bull
-               os=-bosx
-               ;;
-       dpx2* | dpx2*-bull)
-               basic_machine=m68k-bull
-               os=-sysv3
-               ;;
-       ebmon29k)
-               basic_machine=a29k-amd
-               os=-ebmon
-               ;;
-       elxsi)
-               basic_machine=elxsi-elxsi
-               os=-bsd
-               ;;
-       encore | umax | mmax)
-               basic_machine=ns32k-encore
-               ;;
-       es1800 | OSE68k | ose68k | ose | OSE)
-               basic_machine=m68k-ericsson
-               os=-ose
-               ;;
-       fx2800)
-               basic_machine=i860-alliant
-               ;;
-       genix)
-               basic_machine=ns32k-ns
-               ;;
-       gmicro)
-               basic_machine=tron-gmicro
-               os=-sysv
-               ;;
-       go32)
-               basic_machine=i386-pc
-               os=-go32
-               ;;
-       h3050r* | hiux*)
-               basic_machine=hppa1.1-hitachi
-               os=-hiuxwe2
-               ;;
-       h8300hms)
-               basic_machine=h8300-hitachi
-               os=-hms
-               ;;
-       h8300xray)
-               basic_machine=h8300-hitachi
-               os=-xray
-               ;;
-       h8500hms)
-               basic_machine=h8500-hitachi
-               os=-hms
-               ;;
-       harris)
-               basic_machine=m88k-harris
-               os=-sysv3
-               ;;
-       hp300-*)
-               basic_machine=m68k-hp
-               ;;
-       hp300bsd)
-               basic_machine=m68k-hp
-               os=-bsd
-               ;;
-       hp300hpux)
-               basic_machine=m68k-hp
-               os=-hpux
-               ;;
-       hp3k9[0-9][0-9] | hp9[0-9][0-9])
-               basic_machine=hppa1.0-hp
-               ;;
-       hp9k2[0-9][0-9] | hp9k31[0-9])
-               basic_machine=m68000-hp
-               ;;
-       hp9k3[2-9][0-9])
-               basic_machine=m68k-hp
-               ;;
-       hp9k6[0-9][0-9] | hp6[0-9][0-9])
-               basic_machine=hppa1.0-hp
-               ;;
-       hp9k7[0-79][0-9] | hp7[0-79][0-9])
-               basic_machine=hppa1.1-hp
-               ;;
-       hp9k78[0-9] | hp78[0-9])
-               # FIXME: really hppa2.0-hp
-               basic_machine=hppa1.1-hp
-               ;;
-       hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
-               # FIXME: really hppa2.0-hp
-               basic_machine=hppa1.1-hp
-               ;;
-       hp9k8[0-9][13679] | hp8[0-9][13679])
-               basic_machine=hppa1.1-hp
-               ;;
-       hp9k8[0-9][0-9] | hp8[0-9][0-9])
-               basic_machine=hppa1.0-hp
-               ;;
-       hppa-next)
-               os=-nextstep3
-               ;;
-       hppaosf)
-               basic_machine=hppa1.1-hp
-               os=-osf
-               ;;
-       hppro)
-               basic_machine=hppa1.1-hp
-               os=-proelf
-               ;;
-       i370-ibm* | ibm*)
-               basic_machine=i370-ibm
-               ;;
-# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
-       i*86v32)
-               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
-               os=-sysv32
-               ;;
-       i*86v4*)
-               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
-               os=-sysv4
-               ;;
-       i*86v)
-               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
-               os=-sysv
-               ;;
-       i*86sol2)
-               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
-               os=-solaris2
-               ;;
-       i386mach)
-               basic_machine=i386-mach
-               os=-mach
-               ;;
-       i386-vsta | vsta)
-               basic_machine=i386-unknown
-               os=-vsta
-               ;;
-       iris | iris4d)
-               basic_machine=mips-sgi
-               case $os in
-                   -irix*)
-                       ;;
-                   *)
-                       os=-irix4
-                       ;;
-               esac
-               ;;
-       isi68 | isi)
-               basic_machine=m68k-isi
-               os=-sysv
-               ;;
-       m68knommu)
-               basic_machine=m68k-unknown
-               os=-linux
-               ;;
-       m68knommu-*)
-               basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
-               os=-linux
-               ;;
-       m88k-omron*)
-               basic_machine=m88k-omron
-               ;;
-       magnum | m3230)
-               basic_machine=mips-mips
-               os=-sysv
-               ;;
-       merlin)
-               basic_machine=ns32k-utek
-               os=-sysv
-               ;;
-       mingw32)
-               basic_machine=i386-pc
-               os=-mingw32
-               ;;
-       mingw32ce)
-               basic_machine=arm-unknown
-               os=-mingw32ce
-               ;;
-       miniframe)
-               basic_machine=m68000-convergent
-               ;;
-       *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
-               basic_machine=m68k-atari
-               os=-mint
-               ;;
-       mips3*-*)
-               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
-               ;;
-       mips3*)
-               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
-               ;;
-       monitor)
-               basic_machine=m68k-rom68k
-               os=-coff
-               ;;
-       morphos)
-               basic_machine=powerpc-unknown
-               os=-morphos
-               ;;
-       msdos)
-               basic_machine=i386-pc
-               os=-msdos
-               ;;
-       ms1-*)
-               basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
-               ;;
-       mvs)
-               basic_machine=i370-ibm
-               os=-mvs
-               ;;
-       ncr3000)
-               basic_machine=i486-ncr
-               os=-sysv4
-               ;;
-       netbsd386)
-               basic_machine=i386-unknown
-               os=-netbsd
-               ;;
-       netwinder)
-               basic_machine=armv4l-rebel
-               os=-linux
-               ;;
-       news | news700 | news800 | news900)
-               basic_machine=m68k-sony
-               os=-newsos
-               ;;
-       news1000)
-               basic_machine=m68030-sony
-               os=-newsos
-               ;;
-       news-3600 | risc-news)
-               basic_machine=mips-sony
-               os=-newsos
-               ;;
-       necv70)
-               basic_machine=v70-nec
-               os=-sysv
-               ;;
-       next | m*-next )
-               basic_machine=m68k-next
-               case $os in
-                   -nextstep* )
-                       ;;
-                   -ns2*)
-                     os=-nextstep2
-                       ;;
-                   *)
-                     os=-nextstep3
-                       ;;
-               esac
-               ;;
-       nh3000)
-               basic_machine=m68k-harris
-               os=-cxux
-               ;;
-       nh[45]000)
-               basic_machine=m88k-harris
-               os=-cxux
-               ;;
-       nindy960)
-               basic_machine=i960-intel
-               os=-nindy
-               ;;
-       mon960)
-               basic_machine=i960-intel
-               os=-mon960
-               ;;
-       nonstopux)
-               basic_machine=mips-compaq
-               os=-nonstopux
-               ;;
-       np1)
-               basic_machine=np1-gould
-               ;;
-       nsr-tandem)
-               basic_machine=nsr-tandem
-               ;;
-       op50n-* | op60c-*)
-               basic_machine=hppa1.1-oki
-               os=-proelf
-               ;;
-       openrisc | openrisc-*)
-               basic_machine=or32-unknown
-               ;;
-       os400)
-               basic_machine=powerpc-ibm
-               os=-os400
-               ;;
-       OSE68000 | ose68000)
-               basic_machine=m68000-ericsson
-               os=-ose
-               ;;
-       os68k)
-               basic_machine=m68k-none
-               os=-os68k
-               ;;
-       pa-hitachi)
-               basic_machine=hppa1.1-hitachi
-               os=-hiuxwe2
-               ;;
-       paragon)
-               basic_machine=i860-intel
-               os=-osf
-               ;;
-       parisc)
-               basic_machine=hppa-unknown
-               os=-linux
-               ;;
-       parisc-*)
-               basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
-               os=-linux
-               ;;
-       pbd)
-               basic_machine=sparc-tti
-               ;;
-       pbb)
-               basic_machine=m68k-tti
-               ;;
-       pc532 | pc532-*)
-               basic_machine=ns32k-pc532
-               ;;
-       pc98)
-               basic_machine=i386-pc
-               ;;
-       pc98-*)
-               basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       pentium | p5 | k5 | k6 | nexgen | viac3)
-               basic_machine=i586-pc
-               ;;
-       pentiumpro | p6 | 6x86 | athlon | athlon_*)
-               basic_machine=i686-pc
-               ;;
-       pentiumii | pentium2 | pentiumiii | pentium3)
-               basic_machine=i686-pc
-               ;;
-       pentium4)
-               basic_machine=i786-pc
-               ;;
-       pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
-               basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       pentiumpro-* | p6-* | 6x86-* | athlon-*)
-               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
-               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       pentium4-*)
-               basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       pn)
-               basic_machine=pn-gould
-               ;;
-       power)  basic_machine=power-ibm
-               ;;
-       ppc)    basic_machine=powerpc-unknown
-               ;;
-       ppc-*)  basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       ppcle | powerpclittle | ppc-le | powerpc-little)
-               basic_machine=powerpcle-unknown
-               ;;
-       ppcle-* | powerpclittle-*)
-               basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       ppc64)  basic_machine=powerpc64-unknown
-               ;;
-       ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       ppc64le | powerpc64little | ppc64-le | powerpc64-little)
-               basic_machine=powerpc64le-unknown
-               ;;
-       ppc64le-* | powerpc64little-*)
-               basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       ps2)
-               basic_machine=i386-ibm
-               ;;
-       pw32)
-               basic_machine=i586-unknown
-               os=-pw32
-               ;;
-       rdos)
-               basic_machine=i386-pc
-               os=-rdos
-               ;;
-       rom68k)
-               basic_machine=m68k-rom68k
-               os=-coff
-               ;;
-       rm[46]00)
-               basic_machine=mips-siemens
-               ;;
-       rtpc | rtpc-*)
-               basic_machine=romp-ibm
-               ;;
-       s390 | s390-*)
-               basic_machine=s390-ibm
-               ;;
-       s390x | s390x-*)
-               basic_machine=s390x-ibm
-               ;;
-       sa29200)
-               basic_machine=a29k-amd
-               os=-udi
-               ;;
-       sb1)
-               basic_machine=mipsisa64sb1-unknown
-               ;;
-       sb1el)
-               basic_machine=mipsisa64sb1el-unknown
-               ;;
-       sde)
-               basic_machine=mipsisa32-sde
-               os=-elf
-               ;;
-       sei)
-               basic_machine=mips-sei
-               os=-seiux
-               ;;
-       sequent)
-               basic_machine=i386-sequent
-               ;;
-       sh)
-               basic_machine=sh-hitachi
-               os=-hms
-               ;;
-       sh5el)
-               basic_machine=sh5le-unknown
-               ;;
-       sh64)
-               basic_machine=sh64-unknown
-               ;;
-       sparclite-wrs | simso-wrs)
-               basic_machine=sparclite-wrs
-               os=-vxworks
-               ;;
-       sps7)
-               basic_machine=m68k-bull
-               os=-sysv2
-               ;;
-       spur)
-               basic_machine=spur-unknown
-               ;;
-       st2000)
-               basic_machine=m68k-tandem
-               ;;
-       stratus)
-               basic_machine=i860-stratus
-               os=-sysv4
-               ;;
-       sun2)
-               basic_machine=m68000-sun
-               ;;
-       sun2os3)
-               basic_machine=m68000-sun
-               os=-sunos3
-               ;;
-       sun2os4)
-               basic_machine=m68000-sun
-               os=-sunos4
-               ;;
-       sun3os3)
-               basic_machine=m68k-sun
-               os=-sunos3
-               ;;
-       sun3os4)
-               basic_machine=m68k-sun
-               os=-sunos4
-               ;;
-       sun4os3)
-               basic_machine=sparc-sun
-               os=-sunos3
-               ;;
-       sun4os4)
-               basic_machine=sparc-sun
-               os=-sunos4
-               ;;
-       sun4sol2)
-               basic_machine=sparc-sun
-               os=-solaris2
-               ;;
-       sun3 | sun3-*)
-               basic_machine=m68k-sun
-               ;;
-       sun4)
-               basic_machine=sparc-sun
-               ;;
-       sun386 | sun386i | roadrunner)
-               basic_machine=i386-sun
-               ;;
-       sv1)
-               basic_machine=sv1-cray
-               os=-unicos
-               ;;
-       symmetry)
-               basic_machine=i386-sequent
-               os=-dynix
-               ;;
-       t3e)
-               basic_machine=alphaev5-cray
-               os=-unicos
-               ;;
-       t90)
-               basic_machine=t90-cray
-               os=-unicos
-               ;;
-       tic54x | c54x*)
-               basic_machine=tic54x-unknown
-               os=-coff
-               ;;
-       tic55x | c55x*)
-               basic_machine=tic55x-unknown
-               os=-coff
-               ;;
-       tic6x | c6x*)
-               basic_machine=tic6x-unknown
-               os=-coff
-               ;;
-       tile*)
-               basic_machine=tile-unknown
-               os=-linux-gnu
-               ;;
-       tx39)
-               basic_machine=mipstx39-unknown
-               ;;
-       tx39el)
-               basic_machine=mipstx39el-unknown
-               ;;
-       toad1)
-               basic_machine=pdp10-xkl
-               os=-tops20
-               ;;
-       tower | tower-32)
-               basic_machine=m68k-ncr
-               ;;
-       tpf)
-               basic_machine=s390x-ibm
-               os=-tpf
-               ;;
-       udi29k)
-               basic_machine=a29k-amd
-               os=-udi
-               ;;
-       ultra3)
-               basic_machine=a29k-nyu
-               os=-sym1
-               ;;
-       v810 | necv810)
-               basic_machine=v810-nec
-               os=-none
-               ;;
-       vaxv)
-               basic_machine=vax-dec
-               os=-sysv
-               ;;
-       vms)
-               basic_machine=vax-dec
-               os=-vms
-               ;;
-       vpp*|vx|vx-*)
-               basic_machine=f301-fujitsu
-               ;;
-       vxworks960)
-               basic_machine=i960-wrs
-               os=-vxworks
-               ;;
-       vxworks68)
-               basic_machine=m68k-wrs
-               os=-vxworks
-               ;;
-       vxworks29k)
-               basic_machine=a29k-wrs
-               os=-vxworks
-               ;;
-       w65*)
-               basic_machine=w65-wdc
-               os=-none
-               ;;
-       w89k-*)
-               basic_machine=hppa1.1-winbond
-               os=-proelf
-               ;;
-       xbox)
-               basic_machine=i686-pc
-               os=-mingw32
-               ;;
-       xps | xps100)
-               basic_machine=xps100-honeywell
-               ;;
-       ymp)
-               basic_machine=ymp-cray
-               os=-unicos
-               ;;
-       z8k-*-coff)
-               basic_machine=z8k-unknown
-               os=-sim
-               ;;
-       none)
-               basic_machine=none-none
-               os=-none
-               ;;
-
-# Here we handle the default manufacturer of certain CPU types.  It is in
-# some cases the only manufacturer, in others, it is the most popular.
-       w89k)
-               basic_machine=hppa1.1-winbond
-               ;;
-       op50n)
-               basic_machine=hppa1.1-oki
-               ;;
-       op60c)
-               basic_machine=hppa1.1-oki
-               ;;
-       romp)
-               basic_machine=romp-ibm
-               ;;
-       mmix)
-               basic_machine=mmix-knuth
-               ;;
-       rs6000)
-               basic_machine=rs6000-ibm
-               ;;
-       vax)
-               basic_machine=vax-dec
-               ;;
-       pdp10)
-               # there are many clones, so DEC is not a safe bet
-               basic_machine=pdp10-unknown
-               ;;
-       pdp11)
-               basic_machine=pdp11-dec
-               ;;
-       we32k)
-               basic_machine=we32k-att
-               ;;
-       sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
-               basic_machine=sh-unknown
-               ;;
-       sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
-               basic_machine=sparc-sun
-               ;;
-       cydra)
-               basic_machine=cydra-cydrome
-               ;;
-       orion)
-               basic_machine=orion-highlevel
-               ;;
-       orion105)
-               basic_machine=clipper-highlevel
-               ;;
-       mac | mpw | mac-mpw)
-               basic_machine=m68k-apple
-               ;;
-       pmac | pmac-mpw)
-               basic_machine=powerpc-apple
-               ;;
-       *-unknown)
-               # Make sure to match an already-canonicalized machine name.
-               ;;
-       *)
-               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
-               exit 1
-               ;;
-esac
-
-# Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
-       *-digital*)
-               basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
-               ;;
-       *-commodore*)
-               basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
-               ;;
-       *)
-               ;;
-esac
-
-# Decode manufacturer-specific aliases for certain operating systems.
-
-if [ x"$os" != x"" ]
-then
-case $os in
-        # First match some system type aliases
-        # that might get confused with valid system types.
-       # -solaris* is a basic system type, with this one exception.
-       -solaris1 | -solaris1.*)
-               os=`echo $os | sed -e 's|solaris1|sunos4|'`
-               ;;
-       -solaris)
-               os=-solaris2
-               ;;
-       -svr4*)
-               os=-sysv4
-               ;;
-       -unixware*)
-               os=-sysv4.2uw
-               ;;
-       -gnu/linux*)
-               os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
-               ;;
-       # First accept the basic system types.
-       # The portable systems comes first.
-       # Each alternative MUST END IN A *, to match a version number.
-       # -sysv* is not here because it comes later, after sysvr4.
-       -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
-             | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
-             | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
-             | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
-             | -aos* \
-             | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
-             | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
-             | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
-             | -openbsd* | -solidbsd* \
-             | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
-             | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
-             | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
-             | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
-             | -chorusos* | -chorusrdb* \
-             | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-             | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
-             | -uxpv* | -beos* | -mpeix* | -udk* \
-             | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
-             | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
-             | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
-             | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
-             | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
-             | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-             | -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
-       # Remember, each alternative MUST END IN *, to match a version number.
-               ;;
-       -qnx*)
-               case $basic_machine in
-                   x86-* | i*86-*)
-                       ;;
-                   *)
-                       os=-nto$os
-                       ;;
-               esac
-               ;;
-       -nto-qnx*)
-               ;;
-       -nto*)
-               os=`echo $os | sed -e 's|nto|nto-qnx|'`
-               ;;
-       -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
-             | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
-             | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
-               ;;
-       -mac*)
-               os=`echo $os | sed -e 's|mac|macos|'`
-               ;;
-       -linux-dietlibc)
-               os=-linux-dietlibc
-               ;;
-       -linux*)
-               os=`echo $os | sed -e 's|linux|linux-gnu|'`
-               ;;
-       -sunos5*)
-               os=`echo $os | sed -e 's|sunos5|solaris2|'`
-               ;;
-       -sunos6*)
-               os=`echo $os | sed -e 's|sunos6|solaris3|'`
-               ;;
-       -opened*)
-               os=-openedition
-               ;;
-        -os400*)
-               os=-os400
-               ;;
-       -wince*)
-               os=-wince
-               ;;
-       -osfrose*)
-               os=-osfrose
-               ;;
-       -osf*)
-               os=-osf
-               ;;
-       -utek*)
-               os=-bsd
-               ;;
-       -dynix*)
-               os=-bsd
-               ;;
-       -acis*)
-               os=-aos
-               ;;
-       -atheos*)
-               os=-atheos
-               ;;
-       -syllable*)
-               os=-syllable
-               ;;
-       -386bsd)
-               os=-bsd
-               ;;
-       -ctix* | -uts*)
-               os=-sysv
-               ;;
-       -nova*)
-               os=-rtmk-nova
-               ;;
-       -ns2 )
-               os=-nextstep2
-               ;;
-       -nsk*)
-               os=-nsk
-               ;;
-       # Preserve the version number of sinix5.
-       -sinix5.*)
-               os=`echo $os | sed -e 's|sinix|sysv|'`
-               ;;
-       -sinix*)
-               os=-sysv4
-               ;;
-        -tpf*)
-               os=-tpf
-               ;;
-       -triton*)
-               os=-sysv3
-               ;;
-       -oss*)
-               os=-sysv3
-               ;;
-       -svr4)
-               os=-sysv4
-               ;;
-       -svr3)
-               os=-sysv3
-               ;;
-       -sysvr4)
-               os=-sysv4
-               ;;
-       # This must come after -sysvr4.
-       -sysv*)
-               ;;
-       -ose*)
-               os=-ose
-               ;;
-       -es1800*)
-               os=-ose
-               ;;
-       -xenix)
-               os=-xenix
-               ;;
-       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
-               os=-mint
-               ;;
-       -aros*)
-               os=-aros
-               ;;
-       -kaos*)
-               os=-kaos
-               ;;
-       -zvmoe)
-               os=-zvmoe
-               ;;
-       -none)
-               ;;
-       *)
-               # Get rid of the `-' at the beginning of $os.
-               os=`echo $os | sed 's/[^-]*-//'`
-               echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
-               exit 1
-               ;;
-esac
-else
-
-# Here we handle the default operating systems that come with various machines.
-# The value should be what the vendor currently ships out the door with their
-# machine or put another way, the most popular os provided with the machine.
-
-# Note that if you're going to try to match "-MANUFACTURER" here (say,
-# "-sun"), then you have to tell the case statement up towards the top
-# that MANUFACTURER isn't an operating system.  Otherwise, code above
-# will signal an error saying that MANUFACTURER isn't an operating
-# system, and we'll never get to this point.
-
-case $basic_machine in
-        score-*)
-               os=-elf
-               ;;
-        spu-*)
-               os=-elf
-               ;;
-       *-acorn)
-               os=-riscix1.2
-               ;;
-       arm*-rebel)
-               os=-linux
-               ;;
-       arm*-semi)
-               os=-aout
-               ;;
-        c4x-* | tic4x-*)
-               os=-coff
-               ;;
-       # This must come before the *-dec entry.
-       pdp10-*)
-               os=-tops20
-               ;;
-       pdp11-*)
-               os=-none
-               ;;
-       *-dec | vax-*)
-               os=-ultrix4.2
-               ;;
-       m68*-apollo)
-               os=-domain
-               ;;
-       i386-sun)
-               os=-sunos4.0.2
-               ;;
-       m68000-sun)
-               os=-sunos3
-               # This also exists in the configure program, but was not the
-               # default.
-               # os=-sunos4
-               ;;
-       m68*-cisco)
-               os=-aout
-               ;;
-        mep-*)
-               os=-elf
-               ;;
-       mips*-cisco)
-               os=-elf
-               ;;
-       mips*-*)
-               os=-elf
-               ;;
-       or32-*)
-               os=-coff
-               ;;
-       *-tti)  # must be before sparc entry or we get the wrong os.
-               os=-sysv3
-               ;;
-       sparc-* | *-sun)
-               os=-sunos4.1.1
-               ;;
-       *-be)
-               os=-beos
-               ;;
-       *-haiku)
-               os=-haiku
-               ;;
-       *-ibm)
-               os=-aix
-               ;;
-       *-knuth)
-               os=-mmixware
-               ;;
-       *-wec)
-               os=-proelf
-               ;;
-       *-winbond)
-               os=-proelf
-               ;;
-       *-oki)
-               os=-proelf
-               ;;
-       *-hp)
-               os=-hpux
-               ;;
-       *-hitachi)
-               os=-hiux
-               ;;
-       i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
-               os=-sysv
-               ;;
-       *-cbm)
-               os=-amigaos
-               ;;
-       *-dg)
-               os=-dgux
-               ;;
-       *-dolphin)
-               os=-sysv3
-               ;;
-       m68k-ccur)
-               os=-rtu
-               ;;
-       m88k-omron*)
-               os=-luna
-               ;;
-       *-next )
-               os=-nextstep
-               ;;
-       *-sequent)
-               os=-ptx
-               ;;
-       *-crds)
-               os=-unos
-               ;;
-       *-ns)
-               os=-genix
-               ;;
-       i370-*)
-               os=-mvs
-               ;;
-       *-next)
-               os=-nextstep3
-               ;;
-       *-gould)
-               os=-sysv
-               ;;
-       *-highlevel)
-               os=-bsd
-               ;;
-       *-encore)
-               os=-bsd
-               ;;
-       *-sgi)
-               os=-irix
-               ;;
-       *-siemens)
-               os=-sysv4
-               ;;
-       *-masscomp)
-               os=-rtu
-               ;;
-       f30[01]-fujitsu | f700-fujitsu)
-               os=-uxpv
-               ;;
-       *-rom68k)
-               os=-coff
-               ;;
-       *-*bug)
-               os=-coff
-               ;;
-       *-apple)
-               os=-macos
-               ;;
-       *-atari*)
-               os=-mint
-               ;;
-       *)
-               os=-none
-               ;;
-esac
-fi
-
-# Here we handle the case where we know the os, and the CPU type, but not the
-# manufacturer.  We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
-       *-unknown)
-               case $os in
-                       -riscix*)
-                               vendor=acorn
-                               ;;
-                       -sunos*)
-                               vendor=sun
-                               ;;
-                       -aix*)
-                               vendor=ibm
-                               ;;
-                       -beos*)
-                               vendor=be
-                               ;;
-                       -hpux*)
-                               vendor=hp
-                               ;;
-                       -mpeix*)
-                               vendor=hp
-                               ;;
-                       -hiux*)
-                               vendor=hitachi
-                               ;;
-                       -unos*)
-                               vendor=crds
-                               ;;
-                       -dgux*)
-                               vendor=dg
-                               ;;
-                       -luna*)
-                               vendor=omron
-                               ;;
-                       -genix*)
-                               vendor=ns
-                               ;;
-                       -mvs* | -opened*)
-                               vendor=ibm
-                               ;;
-                       -os400*)
-                               vendor=ibm
-                               ;;
-                       -ptx*)
-                               vendor=sequent
-                               ;;
-                       -tpf*)
-                               vendor=ibm
-                               ;;
-                       -vxsim* | -vxworks* | -windiss*)
-                               vendor=wrs
-                               ;;
-                       -aux*)
-                               vendor=apple
-                               ;;
-                       -hms*)
-                               vendor=hitachi
-                               ;;
-                       -mpw* | -macos*)
-                               vendor=apple
-                               ;;
-                       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
-                               vendor=atari
-                               ;;
-                       -vos*)
-                               vendor=stratus
-                               ;;
-               esac
-               basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
-               ;;
-esac
-
-echo $basic_machine$os
-exit
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/test.c~ b/test.c~
deleted file mode 100644 (file)
index ad634f9..0000000
--- a/test.c~
+++ /dev/null
@@ -1,825 +0,0 @@
-/* test.c - GNU test program (ksb and mjb) */
-
-/* Modified to run with the GNU shell Apr 25, 1988 by bfox. */
-
-/* Copyright (C) 1987-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/>.
-*/
-
-/* Define PATTERN_MATCHING to get the csh-like =~ and !~ pattern-matching
-   binary operators. */
-/* #define PATTERN_MATCHING */
-
-#if defined (HAVE_CONFIG_H)
-#  include <config.h>
-#endif
-
-#include <stdio.h>
-
-#include "bashtypes.h"
-
-#if !defined (HAVE_LIMITS_H)
-#  include <sys/param.h>
-#endif
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include <errno.h>
-#if !defined (errno)
-extern int errno;
-#endif /* !errno */
-
-#if !defined (_POSIX_VERSION) && defined (HAVE_SYS_FILE_H)
-#  include <sys/file.h>
-#endif /* !_POSIX_VERSION */
-#include "posixstat.h"
-#include "filecntl.h"
-
-#include "bashintl.h"
-
-#include "shell.h"
-#include "pathexp.h"
-#include "test.h"
-#include "builtins/common.h"
-
-#include <glob/strmatch.h>
-
-#if !defined (STRLEN)
-#  define STRLEN(s) ((s)[0] ? ((s)[1] ? ((s)[2] ? strlen(s) : 2) : 1) : 0)
-#endif
-
-#if !defined (STREQ)
-#  define STREQ(a, b) ((a)[0] == (b)[0] && strcmp (a, b) == 0)
-#endif /* !STREQ */
-
-#if !defined (R_OK)
-#define R_OK 4
-#define W_OK 2
-#define X_OK 1
-#define F_OK 0
-#endif /* R_OK */
-
-#define EQ     0
-#define NE     1
-#define LT     2
-#define GT     3
-#define LE     4
-#define GE     5
-
-#define NT     0
-#define OT     1
-#define EF     2
-
-/* The following few defines control the truth and false output of each stage.
-   TRUE and FALSE are what we use to compute the final output value.
-   SHELL_BOOLEAN is the form which returns truth or falseness in shell terms.
-   Default is TRUE = 1, FALSE = 0, SHELL_BOOLEAN = (!value). */
-#define TRUE 1
-#define FALSE 0
-#define SHELL_BOOLEAN(value) (!(value))
-
-#define TEST_ERREXIT_STATUS    2
-
-static procenv_t test_exit_buf;
-static int test_error_return;
-#define test_exit(val) \
-       do { test_error_return = val; longjmp (test_exit_buf, 1); } while (0)
-
-extern int sh_stat __P((const char *, struct stat *));
-
-static int pos;                /* The offset of the current argument in ARGV. */
-static int argc;       /* The number of arguments present in ARGV. */
-static char **argv;    /* The argument list. */
-static int noeval;
-
-static void test_syntax_error __P((char *, char *)) __attribute__((__noreturn__));
-static void beyond __P((void)) __attribute__((__noreturn__));
-static void integer_expected_error __P((char *)) __attribute__((__noreturn__));
-
-static int unary_operator __P((void));
-static int binary_operator __P((void));
-static int two_arguments __P((void));
-static int three_arguments __P((void));
-static int posixtest __P((void));
-
-static int expr __P((void));
-static int term __P((void));
-static int and __P((void));
-static int or __P((void));
-
-static int filecomp __P((char *, char *, int));
-static int arithcomp __P((char *, char *, int, int));
-static int patcomp __P((char *, char *, int));
-
-static void
-test_syntax_error (format, arg)
-     char *format, *arg;
-{
-  builtin_error (format, arg);
-  test_exit (TEST_ERREXIT_STATUS);
-}
-
-/*
- * beyond - call when we're beyond the end of the argument list (an
- *     error condition)
- */
-static void
-beyond ()
-{
-  test_syntax_error (_("argument expected"), (char *)NULL);
-}
-
-/* Syntax error for when an integer argument was expected, but
-   something else was found. */
-static void
-integer_expected_error (pch)
-     char *pch;
-{
-  test_syntax_error (_("%s: integer expression expected"), pch);
-}
-
-/* Increment our position in the argument list.  Check that we're not
-   past the end of the argument list.  This check is supressed if the
-   argument is FALSE.  Made a macro for efficiency. */
-#define advance(f) do { ++pos; if (f && pos >= argc) beyond (); } while (0)
-#define unary_advance() do { advance (1); ++pos; } while (0)
-
-/*
- * expr:
- *     or
- */
-static int
-expr ()
-{
-  if (pos >= argc)
-    beyond ();
-
-  return (FALSE ^ or ());              /* Same with this. */
-}
-
-/*
- * or:
- *     and
- *     and '-o' or
- */
-static int
-or ()
-{
-  int value, v2;
-
-  value = and ();
-  if (pos < argc && argv[pos][0] == '-' && argv[pos][1] == 'o' && !argv[pos][2])
-    {
-      advance (0);
-      v2 = or ();
-      return (value || v2);
-    }
-
-  return (value);
-}
-
-/*
- * and:
- *     term
- *     term '-a' and
- */
-static int
-and ()
-{
-  int value, v2;
-
-  value = term ();
-  if (pos < argc && argv[pos][0] == '-' && argv[pos][1] == 'a' && !argv[pos][2])
-    {
-      advance (0);
-      v2 = and ();
-      return (value && v2);
-    }
-  return (value);
-}
-
-/*
- * term - parse a term and return 1 or 0 depending on whether the term
- *     evaluates to true or false, respectively.
- *
- * term ::=
- *     '-'('a'|'b'|'c'|'d'|'e'|'f'|'g'|'h'|'k'|'p'|'r'|'s'|'u'|'w'|'x') filename
- *     '-'('G'|'L'|'O'|'S'|'N') filename
- *     '-t' [int]
- *     '-'('z'|'n') string
- *     '-o' option
- *     string
- *     string ('!='|'='|'==') string
- *     <int> '-'(eq|ne|le|lt|ge|gt) <int>
- *     file '-'(nt|ot|ef) file
- *     '(' <expr> ')'
- * int ::=
- *     positive and negative integers
- */
-static int
-term ()
-{
-  int value;
-
-  if (pos >= argc)
-    beyond ();
-
-  /* Deal with leading `not's. */
-  if (argv[pos][0] == '!' && argv[pos][1] == '\0')
-    {
-      value = 0;
-      while (pos < argc && argv[pos][0] == '!' && argv[pos][1] == '\0')
-       {
-         advance (1);
-         value = 1 - value;
-       }
-
-      return (value ? !term() : term());
-    }
-
-  /* A paren-bracketed argument. */
-  if (argv[pos][0] == '(' && argv[pos][1] == '\0') /* ) */
-    {
-      advance (1);
-      value = expr ();
-      if (argv[pos] == 0) /* ( */
-       test_syntax_error (_("`)' expected"), (char *)NULL);
-      else if (argv[pos][0] != ')' || argv[pos][1]) /* ( */
-       test_syntax_error (_("`)' expected, found %s"), argv[pos]);
-      advance (0);
-      return (value);
-    }
-
-  /* are there enough arguments left that this could be dyadic? */
-  if ((pos + 3 <= argc) && test_binop (argv[pos + 1]))
-    value = binary_operator ();
-
-  /* Might be a switch type argument */
-  else if (argv[pos][0] == '-' && argv[pos][2] == '\0')
-    {
-      if (test_unop (argv[pos]))
-       value = unary_operator ();
-      else
-       test_syntax_error (_("%s: unary operator expected"), argv[pos]);
-    }
-  else
-    {
-      value = argv[pos][0] != '\0';
-      advance (0);
-    }
-
-  return (value);
-}
-
-static int
-filecomp (s, t, op)
-     char *s, *t;
-     int op;
-{
-  struct stat st1, st2;
-  int r1, r2;
-
-  if ((r1 = sh_stat (s, &st1)) < 0)
-    {
-      if (op == EF)
-       return (FALSE);
-    }
-  if ((r2 = sh_stat (t, &st2)) < 0)
-    {
-      if (op == EF)
-       return (FALSE);
-    }
-  
-  switch (op)
-    {
-    case OT: return (r1 < r2 || (r2 == 0 && st1.st_mtime < st2.st_mtime));
-    case NT: return (r1 > r2 || (r1 == 0 && st1.st_mtime > st2.st_mtime));
-    case EF: return (same_file (s, t, &st1, &st2));
-    }
-  return (FALSE);
-}
-
-static int
-arithcomp (s, t, op, flags)
-     char *s, *t;
-     int op, flags;
-{
-  intmax_t l, r;
-  int expok;
-
-  if (flags & TEST_ARITHEXP)
-    {
-      l = evalexp (s, &expok);
-      if (expok == 0)
-       return (FALSE);         /* should probably longjmp here */
-      r = evalexp (t, &expok);
-      if (expok == 0)
-       return (FALSE);         /* ditto */
-    }
-  else
-    {
-      if (legal_number (s, &l) == 0)
-       integer_expected_error (s);
-      if (legal_number (t, &r) == 0)
-       integer_expected_error (t);
-    }
-
-  switch (op)
-    {
-    case EQ: return (l == r);
-    case NE: return (l != r);
-    case LT: return (l < r);
-    case GT: return (l > r);
-    case LE: return (l <= r);
-    case GE: return (l >= r);
-    }
-
-  return (FALSE);
-}
-
-static int
-patcomp (string, pat, op)
-     char *string, *pat;
-     int op;
-{
-  int m;
-
-  m = strmatch (pat, string, FNMATCH_EXTFLAG|FNMATCH_IGNCASE);
-  return ((op == EQ) ? (m == 0) : (m != 0));
-}
-
-int
-binary_test (op, arg1, arg2, flags)
-     char *op, *arg1, *arg2;
-     int flags;
-{
-  int patmatch;
-
-  patmatch = (flags & TEST_PATMATCH);
-
-  if (op[0] == '=' && (op[1] == '\0' || (op[1] == '=' && op[2] == '\0')))
-    return (patmatch ? patcomp (arg1, arg2, EQ) : STREQ (arg1, arg2));
-
-  else if ((op[0] == '>' || op[0] == '<') && op[1] == '\0')
-    return ((op[0] == '>') ? (strcmp (arg1, arg2) > 0) : (strcmp (arg1, arg2) < 0));
-
-  else if (op[0] == '!' && op[1] == '=' && op[2] == '\0')
-    return (patmatch ? patcomp (arg1, arg2, NE) : (STREQ (arg1, arg2) == 0));
-
-  else if (op[2] == 't')
-    {
-      switch (op[1])
-       {
-       case 'n': return (filecomp (arg1, arg2, NT));           /* -nt */
-       case 'o': return (filecomp (arg1, arg2, OT));           /* -ot */
-       case 'l': return (arithcomp (arg1, arg2, LT, flags));   /* -lt */
-       case 'g': return (arithcomp (arg1, arg2, GT, flags));   /* -gt */
-       }
-    }
-  else if (op[1] == 'e')
-    {
-      switch (op[2])
-       {
-       case 'f': return (filecomp (arg1, arg2, EF));           /* -ef */
-       case 'q': return (arithcomp (arg1, arg2, EQ, flags));   /* -eq */
-       }
-    }
-  else if (op[2] == 'e')
-    {
-      switch (op[1])
-       {
-       case 'n': return (arithcomp (arg1, arg2, NE, flags));   /* -ne */
-       case 'g': return (arithcomp (arg1, arg2, GE, flags));   /* -ge */
-       case 'l': return (arithcomp (arg1, arg2, LE, flags));   /* -le */
-       }
-    }
-
-  return (FALSE);      /* should never get here */
-}
-
-
-static int
-binary_operator ()
-{
-  int value;
-  char *w;
-
-  w = argv[pos + 1];
-  if ((w[0] == '=' && (w[1] == '\0' || (w[1] == '=' && w[2] == '\0'))) || /* =, == */
-      ((w[0] == '>' || w[0] == '<') && w[1] == '\0') ||                /* <, > */
-      (w[0] == '!' && w[1] == '=' && w[2] == '\0'))            /* != */
-    {
-      value = binary_test (w, argv[pos], argv[pos + 2], 0);
-      pos += 3;
-      return (value);
-    }
-
-#if defined (PATTERN_MATCHING)
-  if ((w[0] == '=' || w[0] == '!') && w[1] == '~' && w[2] == '\0')
-    {
-      value = patcomp (argv[pos], argv[pos + 2], w[0] == '=' ? EQ : NE);
-      pos += 3;
-      return (value);
-    }
-#endif
-
-  if ((w[0] != '-' || w[3] != '\0') || test_binop (w) == 0)
-    {
-      test_syntax_error (_("%s: binary operator expected"), w);
-      /* NOTREACHED */
-      return (FALSE);
-    }
-
-  value = binary_test (w, argv[pos], argv[pos + 2], 0);
-  pos += 3;
-  return value;
-}
-
-static int
-unary_operator ()
-{
-  char *op;
-  intmax_t r;
-
-  op = argv[pos];
-  if (test_unop (op) == 0)
-    return (FALSE);
-
-  /* the only tricky case is `-t', which may or may not take an argument. */
-  if (op[1] == 't')
-    {
-      advance (0);
-      if (pos < argc)
-       {
-         if (legal_number (argv[pos], &r))
-           {
-             advance (0);
-             return (unary_test (op, argv[pos - 1]));
-           }
-         else
-           return (FALSE);
-       }
-      else
-       return (unary_test (op, "1"));
-    }
-
-  /* All of the unary operators take an argument, so we first call
-     unary_advance (), which checks to make sure that there is an
-     argument, and then advances pos right past it.  This means that
-     pos - 1 is the location of the argument. */
-  unary_advance ();
-  return (unary_test (op, argv[pos - 1]));
-}
-
-int
-unary_test (op, arg)
-     char *op, *arg;
-{
-  intmax_t r;
-  struct stat stat_buf;
-     
-  switch (op[1])
-    {
-    case 'a':                  /* file exists in the file system? */
-    case 'e':
-      return (sh_stat (arg, &stat_buf) == 0);
-
-    case 'r':                  /* file is readable? */
-      return (sh_eaccess (arg, R_OK) == 0);
-
-    case 'w':                  /* File is writeable? */
-      return (sh_eaccess (arg, W_OK) == 0);
-
-    case 'x':                  /* File is executable? */
-      return (sh_eaccess (arg, X_OK) == 0);
-
-    case 'O':                  /* File is owned by you? */
-      return (sh_stat (arg, &stat_buf) == 0 &&
-             (uid_t) current_user.euid == (uid_t) stat_buf.st_uid);
-
-    case 'G':                  /* File is owned by your group? */
-      return (sh_stat (arg, &stat_buf) == 0 &&
-             (gid_t) current_user.egid == (gid_t) stat_buf.st_gid);
-
-    case 'N':
-      return (sh_stat (arg, &stat_buf) == 0 &&
-             stat_buf.st_atime <= stat_buf.st_mtime);
-
-    case 'f':                  /* File is a file? */
-      if (sh_stat (arg, &stat_buf) < 0)
-       return (FALSE);
-
-      /* -f is true if the given file exists and is a regular file. */
-#if defined (S_IFMT)
-      return (S_ISREG (stat_buf.st_mode) || (stat_buf.st_mode & S_IFMT) == 0);
-#else
-      return (S_ISREG (stat_buf.st_mode));
-#endif /* !S_IFMT */
-
-    case 'd':                  /* File is a directory? */
-      return (sh_stat (arg, &stat_buf) == 0 && (S_ISDIR (stat_buf.st_mode)));
-
-    case 's':                  /* File has something in it? */
-      return (sh_stat (arg, &stat_buf) == 0 && stat_buf.st_size > (off_t) 0);
-
-    case 'S':                  /* File is a socket? */
-#if !defined (S_ISSOCK)
-      return (FALSE);
-#else
-      return (sh_stat (arg, &stat_buf) == 0 && S_ISSOCK (stat_buf.st_mode));
-#endif /* S_ISSOCK */
-
-    case 'c':                  /* File is character special? */
-      return (sh_stat (arg, &stat_buf) == 0 && S_ISCHR (stat_buf.st_mode));
-
-    case 'b':                  /* File is block special? */
-      return (sh_stat (arg, &stat_buf) == 0 && S_ISBLK (stat_buf.st_mode));
-
-    case 'p':                  /* File is a named pipe? */
-#ifndef S_ISFIFO
-      return (FALSE);
-#else
-      return (sh_stat (arg, &stat_buf) == 0 && S_ISFIFO (stat_buf.st_mode));
-#endif /* S_ISFIFO */
-
-    case 'L':                  /* Same as -h  */
-    case 'h':                  /* File is a symbolic link? */
-#if !defined (S_ISLNK) || !defined (HAVE_LSTAT)
-      return (FALSE);
-#else
-      return ((arg[0] != '\0') &&
-             (lstat (arg, &stat_buf) == 0) && S_ISLNK (stat_buf.st_mode));
-#endif /* S_IFLNK && HAVE_LSTAT */
-
-    case 'u':                  /* File is setuid? */
-      return (sh_stat (arg, &stat_buf) == 0 && (stat_buf.st_mode & S_ISUID) != 0);
-
-    case 'g':                  /* File is setgid? */
-      return (sh_stat (arg, &stat_buf) == 0 && (stat_buf.st_mode & S_ISGID) != 0);
-
-    case 'k':                  /* File has sticky bit set? */
-#if !defined (S_ISVTX)
-      /* This is not Posix, and is not defined on some Posix systems. */
-      return (FALSE);
-#else
-      return (sh_stat (arg, &stat_buf) == 0 && (stat_buf.st_mode & S_ISVTX) != 0);
-#endif
-
-    case 't':  /* File fd is a terminal? */
-      if (legal_number (arg, &r) == 0)
-       return (FALSE);
-      return ((r == (int)r) && isatty ((int)r));
-
-    case 'n':                  /* True if arg has some length. */
-      return (arg[0] != '\0');
-
-    case 'z':                  /* True if arg has no length. */
-      return (arg[0] == '\0');
-
-    case 'o':                  /* True if option `arg' is set. */
-      return (minus_o_option_value (arg) == 1);
-    }
-
-  /* We can't actually get here, but this shuts up gcc. */
-  return (FALSE);
-}
-
-/* Return TRUE if OP is one of the test command's binary operators. */
-int
-test_binop (op)
-     char *op;
-{
-  if (op[0] == '=' && op[1] == '\0')
-    return (1);                /* '=' */
-  else if ((op[0] == '<' || op[0] == '>') && op[1] == '\0')  /* string <, > */
-    return (1);
-  else if ((op[0] == '=' || op[0] == '!') && op[1] == '=' && op[2] == '\0')
-    return (1);                /* `==' and `!=' */
-#if defined (PATTERN_MATCHING)
-  else if (op[2] == '\0' && op[1] == '~' && (op[0] == '=' || op[0] == '!'))
-    return (1);
-#endif
-  else if (op[0] != '-' || op[2] == '\0' || op[3] != '\0')
-    return (0);
-  else
-    {
-      if (op[2] == 't')
-       switch (op[1])
-         {
-         case 'n':             /* -nt */
-         case 'o':             /* -ot */
-         case 'l':             /* -lt */
-         case 'g':             /* -gt */
-           return (1);
-         default:
-           return (0);
-         }
-      else if (op[1] == 'e')
-       switch (op[2])
-         {
-         case 'q':             /* -eq */
-         case 'f':             /* -ef */
-           return (1);
-         default:
-           return (0);
-         }
-      else if (op[2] == 'e')
-       switch (op[1])
-         {
-         case 'n':             /* -ne */
-         case 'g':             /* -ge */
-         case 'l':             /* -le */
-           return (1);
-         default:
-           return (0);
-         }
-      else
-       return (0);
-    }
-}
-
-/* Return non-zero if OP is one of the test command's unary operators. */
-int
-test_unop (op)
-     char *op;
-{
-  if (op[0] != '-' || op[2] != 0)
-    return (0);
-
-  switch (op[1])
-    {
-    case 'a': case 'b': case 'c': case 'd': case 'e':
-    case 'f': case 'g': case 'h': case 'k': case 'n':
-    case 'o': case 'p': case 'r': case 's': case 't':
-    case 'u': case 'w': case 'x': case 'z':
-    case 'G': case 'L': case 'O': case 'S': case 'N':
-      return (1);
-    }
-
-  return (0);
-}
-
-static int
-two_arguments ()
-{
-  if (argv[pos][0] == '!' && argv[pos][1] == '\0')
-    return (argv[pos + 1][0] == '\0');
-  else if (argv[pos][0] == '-' && argv[pos][2] == '\0')
-    {
-      if (test_unop (argv[pos]))
-       return (unary_operator ());
-      else
-       test_syntax_error (_("%s: unary operator expected"), argv[pos]);
-    }
-  else
-    test_syntax_error (_("%s: unary operator expected"), argv[pos]);
-
-  return (0);
-}
-
-#define ANDOR(s)  (s[0] == '-' && !s[2] && (s[1] == 'a' || s[1] == 'o'))
-
-/* This could be augmented to handle `-t' as equivalent to `-t 1', but
-   POSIX requires that `-t' be given an argument. */
-#define ONE_ARG_TEST(s)                ((s)[0] != '\0')
-
-static int
-three_arguments ()
-{
-  int value;
-
-  if (test_binop (argv[pos+1]))
-    {
-      value = binary_operator ();
-      pos = argc;
-    }
-  else if (ANDOR (argv[pos+1]))
-    {
-      if (argv[pos+1][1] == 'a')
-       value = ONE_ARG_TEST(argv[pos]) && ONE_ARG_TEST(argv[pos+2]);
-      else
-       value = ONE_ARG_TEST(argv[pos]) || ONE_ARG_TEST(argv[pos+2]);
-      pos = argc;
-    }
-  else if (argv[pos][0] == '!' && argv[pos][1] == '\0')
-    {
-      advance (1);
-      value = !two_arguments ();
-    }
-  else if (argv[pos][0] == '(' && argv[pos+2][0] == ')')
-    {
-      value = ONE_ARG_TEST(argv[pos+1]);
-      pos = argc;
-    }
-  else
-    test_syntax_error (_("%s: binary operator expected"), argv[pos+1]);
-
-  return (value);
-}
-
-/* This is an implementation of a Posix.2 proposal by David Korn. */
-static int
-posixtest ()
-{
-  int value;
-
-  switch (argc - 1)    /* one extra passed in */
-    {
-      case 0:
-       value = FALSE;
-       pos = argc;
-       break;
-
-      case 1:
-       value = ONE_ARG_TEST(argv[1]);
-       pos = argc;
-       break;
-
-      case 2:
-       value = two_arguments ();
-       pos = argc;
-       break;
-
-      case 3:
-       value = three_arguments ();
-       break;
-
-      case 4:
-       if (argv[pos][0] == '!' && argv[pos][1] == '\0')
-         {
-           advance (1);
-           value = !three_arguments ();
-           break;
-         }
-       /* FALLTHROUGH */
-      default:
-       value = expr ();
-    }
-
-  return (value);
-}
-
-/*
- * [:
- *     '[' expr ']'
- * test:
- *     test expr
- */
-int
-test_command (margc, margv)
-     int margc;
-     char **margv;
-{
-  int value;
-  int code;
-
-  USE_VAR(margc);
-
-  code = setjmp (test_exit_buf);
-
-  if (code)
-    return (test_error_return);
-
-  argv = margv;
-
-  if (margv[0] && margv[0][0] == '[' && margv[0][1] == '\0')
-    {
-      --margc;
-
-      if (margv[margc] && (margv[margc][0] != ']' || margv[margc][1]))
-       test_syntax_error (_("missing `]'"), (char *)NULL);
-
-      if (margc < 2)
-       test_exit (SHELL_BOOLEAN (FALSE));
-    }
-
-  argc = margc;
-  pos = 1;
-
-  if (pos >= argc)
-    test_exit (SHELL_BOOLEAN (FALSE));
-
-  noeval = 0;
-  value = posixtest ();
-
-  if (pos != argc)
-    test_syntax_error (_("too many arguments"), (char *)NULL);
-
-  test_exit (SHELL_BOOLEAN (value));
-}
diff --git a/test.h~ b/test.h~
deleted file mode 100644 (file)
index 9188b5b..0000000
--- a/test.h~
+++ /dev/null
@@ -1,38 +0,0 @@
-/* test.h -- external interface to the conditional command code. */
-
-/* Copyright (C) 1997-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/>.
-*/
-
-#ifndef _TEST_H_
-#define _TEST_H_
-
-#include "stdc.h"
-
-/* Values for the flags argument to binary_test */
-#define TEST_PATMATCH  0x01
-#define TEST_ARITHEXP  0x02
-
-extern int test_unop __P((char *));
-extern int test_binop __P((char *));
-
-extern int unary_test __P((char *, char *));
-extern int binary_test __P((char *, char *, char *, int));
-
-extern int test_command __P((int, char **));
-
-#endif /* _TEST_H_ */
diff --git a/tests/RUN-ONE-TEST~ b/tests/RUN-ONE-TEST~
deleted file mode 100755 (executable)
index 3efcf32..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-BUILD_DIR=/usr/local/build/chet/bash/bash-current
-THIS_SH=$BUILD_DIR/bash
-PATH=$PATH:$BUILD_DIR
-
-export THIS_SH PATH
-
-rm -f /tmp/xx
-
-/bin/sh "$@"
diff --git a/tests/comsub.tests~ b/tests/comsub.tests~
deleted file mode 100644 (file)
index d481dc3..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-# command substution parsing tests
-
-TABSIZE=`grep -v '^[ #]' $CAPS </dev/null | grep -v "^$" | grep -v "^capalias"| grep -v "^infoalias" | wc -l`
-
-recho `echo ab cd #efg
-hijkl`
-
-recho ab$(echo mn; echo op)yz
-
-a=`echo 'a b c' | sed 's/ /\\
-/g' | grep 'b'`
-recho $a
-
-recho `echo 'a\' b`
-
-recho `echo '\$' bab`
-
-recho `echo '\`' ab`
-
-recho `echo '\\' ab`
-
-# old-style command substitution parsing compatibility tests -- post bash-3.1
-recho 'foo \\
-bar'
-
-recho 'foo \
-bar'
-
-echo `recho sed -e 's/[        :]/\\
-/g'`
-
-echo `recho sed -e 's/[        :]/\
-/g'`
-
-echo `recho 'foo\\
-bar'`
-
-echo `recho 'foo\
-bar'`  
-
-echo $(recho 'foo\
-bar')
diff --git a/tests/comsub1.sub~ b/tests/comsub1.sub~
deleted file mode 100644 (file)
index 66a6b37..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-: $(echo \;)
-
-: $(case a in a) echo ;;# comment
-esac)
-
-: $(case a in a) echo ;; # comment
-esac)
-
-: $(: \;# not a comment )
-
-: $(: \ # not a comment)
-
-echo $(case a in a) echo \#esac ;;
-esac)
-
-: $(case a in a) : ;#esac ;;
-esac)
-
-: $(case a in a) : ;#esac comment )
-esac)
-
-: $(case a in a) : ;
-esac)
-
-echo $(#comment )
-echo a)
diff --git a/tests/dollar-at-star~ b/tests/dollar-at-star~
deleted file mode 100755 (executable)
index 79e4a5b..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-# first, let's start with the basics
-
-recho "$@"
-recho "$*"
-
-recho $@
-recho $*
-
-set a b
-
-recho "$*"
-
-# If IFS is null, the parameters are joined without separators
-IFS=''
-recho "$*"
-
-# If IFS is unset, the parameters are separated by spaces
-unset IFS
-recho "${*}"
-
-recho "$@"
-recho $@
-
-IFS='/'
-set bob 'tom dick harry' joe
-set $*
-recho $#
-recho $1
-recho $2
-recho $3
-
-set bob 'tom dick harry' joe
-set ${*}
-recho $#
-recho $1
-recho $2
-recho $3
-
-set bob 'tom dick harry' joe
-set $@
-recho $#
-recho $1
-recho $2
-recho $3
-
-set bob 'tom dick harry' joe
-set ${@}
-recho $#
-recho $1
-recho $2
-recho $3
-
-# according to POSIX.2, unquoted $* should expand to multiple words if
-# $IFS is null, just like unquoted $@
-IFS=''
-set bob 'tom dick harry' joe
-set $*
-recho $#
-recho $1
-recho $2
-recho $3
-
-set bob 'tom dick harry' joe
-set $@
-recho $#
-recho $1
-recho $2
-recho $3
-
-# if IFS is unset, the individual positional parameters are split on
-# " \t\n" if $* or $@ are unquoted
-unset IFS
-set bob 'tom dick harry' joe
-set $*
-recho $#
-recho $1
-recho $2
-recho $3
-
-set bob 'tom dick harry' joe
-set $@  
-recho $#                                              
-recho $1
-recho $2
-recho $3
-
-# but not for "$@" or "$*"
-set bob 'tom dick harry' joe
-set "$*"
-recho $#
-recho $1
-recho $2
-recho $3
-
-set bob 'tom dick harry' joe
-set "$@"
-recho $#
-recho $1
-recho $2
-recho $3
-
-# POSIX.2 says these should both expand the positional parameters
-# to multiple words
-set a b c d e
-IFS=""
-recho $@
-recho "$@"
-
-# this example is straight from the POSIX.2 rationale
-set foo bar bam
-
-recho "$@"
-recho "$*"
-
-unset IFS
-
-recho "$@"
-recho $@
-recho "$*"
-
-IFS=:
-
-# special variables
-set -- 1 2 3 4 5 6 7 8 9 10
-
-bar=${*}
-foo=$*
-echo foo = "$foo"
-echo bar = "$bar"
-
-foo1=$@
-bar1=${@}
-
-echo foo1 = "$foo1"
-echo bar1 = "$bar1"
-
-foo2="$*"
-bar2="${*}"
-
-echo foo2 = "$foo2"
-echo bar2 = "$bar2"
-
-eval foo3='$*' bar3='${*}'
-echo foo3 = "$foo3"
-echo bar3 = "$bar3"
-
-case $* in
-*\:*)  echo ok 1;;
-*)     echo bad 1;;
-esac
-
-case $@ in
-*\:*)  echo bad 2;;
-*)     echo ok 2;;
-esac
-
-case "$*" in
-*\:*)  echo ok 3;;
-*)     echo bad 3;;
-esac
-
-case "$@" in
-*\:*)  echo bad 4;;
-*)     echo ok 4;;
-esac
-
-IFS=$' \t\n'
-
-bar=${*}
-foo=$*
-echo foo = "$foo"
-echo bar = "$bar"
-
-foo1=$@
-bar1=${@}
-
-echo foo1 = "$foo1"
-echo bar1 = "$bar1"
-
-foo2="$*"
-bar2="${*}"
-
-echo foo2 = "$foo2"
-echo bar2 = "$bar2"
-
-eval foo3='$*' bar3='${*}'
-echo foo3 = "$foo3"
-echo bar3 = "$bar3"
-
-case $* in
-*\ *)  echo ok 1;;
-*)     echo bad 1;;
-esac
-
-case $@ in
-*\ *)  echo ok 2;;
-*)     echo bad 2;;
-esac
-
-case "$*" in
-*\ *)  echo ok 3;;
-*)     echo bad 3;;
-esac
-
-case "$@" in
-*\ *)  echo ok 4;;
-*)     echo bad 4;;
-esac
-
-# tests for special expansion of "$*" and "${array[*]}" when used with other
-# expansions -- bugs through bash-2.05b
-${THIS_SH} ./dollar-star1.sub
-
-# tests for expansion of "$@" on rhs of things like ${param:+word}.  Bugs
-# though bash-2.05b
-${THIS_SH} ./dollar-at1.sub
-
-# tests for expansion of other variables in double-quoted strings containing
-# $@.  Bugs through bash-2.05b
-${THIS_SH} ./dollar-at2.sub
-
-# tests for various expansions of $* in different contexts -- word split,
-# no splitting, etc. when $IFS is NUL
-${THIS_SH} ./dollar-star2.sub
-
-# tests for expansions of "${array[*]}" and "${array[@]}" when $IFS is not the
-# default and the array contains null elements
-${THIS_SH} ./dollar-star3.sub
-
-# test for set -u and expansions of $@ when there are no positional parameters
-${THIS_SH} ./dollar-at3.sub
-# test for set -u and expansions of $* when there are no positional parameters
-${THIS_SH} ./dollar-star4.sub
-
-exit 0
diff --git a/tests/dollar.right~ b/tests/dollar.right~
deleted file mode 100644 (file)
index 65e0bb6..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-argv[1] = <>
-argv[1] = <a b>
-argv[1] = <ab>
-argv[1] = <a b>
-argv[1] = <a>
-argv[2] = <b>
-argv[1] = <a>
-argv[2] = <b>
-argv[1] = <3>
-argv[1] = <bob>
-argv[1] = <tom dick harry>
-argv[1] = <joe>
-argv[1] = <3>
-argv[1] = <bob>
-argv[1] = <tom dick harry>
-argv[1] = <joe>
-argv[1] = <3>
-argv[1] = <bob>
-argv[1] = <tom dick harry>
-argv[1] = <joe>
-argv[1] = <3>
-argv[1] = <bob>
-argv[1] = <tom dick harry>
-argv[1] = <joe>
-argv[1] = <3>
-argv[1] = <bob>
-argv[1] = <tom dick harry>
-argv[1] = <joe>
-argv[1] = <3>
-argv[1] = <bob>
-argv[1] = <tom dick harry>
-argv[1] = <joe>
-argv[1] = <5>
-argv[1] = <bob>
-argv[1] = <tom>
-argv[1] = <dick>
-argv[1] = <5>
-argv[1] = <bob>
-argv[1] = <tom>
-argv[1] = <dick>
-argv[1] = <1>
-argv[1] = <bob>
-argv[2] = <tom>
-argv[3] = <dick>
-argv[4] = <harry>
-argv[5] = <joe>
-argv[1] = <3>
-argv[1] = <bob>
-argv[1] = <tom>
-argv[2] = <dick>
-argv[3] = <harry>
-argv[1] = <joe>
-argv[1] = <a>
-argv[2] = <b>
-argv[3] = <c>
-argv[4] = <d>
-argv[5] = <e>
-argv[1] = <a>
-argv[2] = <b>
-argv[3] = <c>
-argv[4] = <d>
-argv[5] = <e>
-argv[1] = <foo>
-argv[2] = <bar>
-argv[3] = <bam>
-argv[1] = <foobarbam>
-argv[1] = <foo>
-argv[2] = <bar>
-argv[3] = <bam>
-argv[1] = <foo>
-argv[2] = <bar>
-argv[3] = <bam>
-argv[1] = <foo bar bam>
-foo = 1:2:3:4:5:6:7:8:9:10
-bar = 1:2:3:4:5:6:7:8:9:10
-foo1 = 1 2 3 4 5 6 7 8 9 10
-bar1 = 1 2 3 4 5 6 7 8 9 10
-foo2 = 1:2:3:4:5:6:7:8:9:10
-bar2 = 1:2:3:4:5:6:7:8:9:10
-foo3 = 1:2:3:4:5:6:7:8:9:10
-bar3 = 1:2:3:4:5:6:7:8:9:10
-ok 1
-ok 2
-ok 3
-ok 4
-foo = 1 2 3 4 5 6 7 8 9 10
-bar = 1 2 3 4 5 6 7 8 9 10
-foo1 = 1 2 3 4 5 6 7 8 9 10
-bar1 = 1 2 3 4 5 6 7 8 9 10
-foo2 = 1 2 3 4 5 6 7 8 9 10
-bar2 = 1 2 3 4 5 6 7 8 9 10
-foo3 = 1 2 3 4 5 6 7 8 9 10
-bar3 = 1 2 3 4 5 6 7 8 9 10
-ok 1
-ok 2
-ok 3
-ok 4
-xa|xb|xc
-xa|xb|xc
-a|b|c
-a|b|c
-a b c
-a b c
-xa xb xc
-xa xb xc
-a|b
-b|c
-a b
-b c
-a|b|c
-a|b|c
-xa|xb|xc
-xa|xb|xc
-3
-3
-3
-3
-3
-3
-3
-3
-argv[1] = <echo 1 ; echo 1>
-argv[1] = <echo 1 2 ; echo 1>
-argv[2] = <2>
-argv[1] = <echo 1 ; echo 1>
-argv[1] = <echo 1 2 ; echo 1>
-argv[2] = <2>
-argv[1] = <AB>
-argv[1] = <AB>
-argv[1] = <A BC D>
-argv[1] = <A BC D>
-argv[1] = <A BC D>
-argv[1] = <A B>
-argv[2] = <C D>
-argv[1] = <A BC D>
-argv[1] = <A BC D>
-argv[1] = <fooq//barq/>
-argv[1] = <fooq>
-argv[2] = <>
-argv[3] = <barq>
-argv[4] = <>
-argv[1] = <foo!//bar!/>
-argv[1] = <foo!>
-argv[2] = <>
-argv[3] = <bar!>
-argv[4] = <>
-argv[1] = <ooq//arq/>
-argv[1] = <ooq>
-argv[2] = <>
-argv[3] = <arq>
-argv[4] = <>
-0
-bar
-./dollar-at3.sub: line 6: $@: unbound variable
-0
-bar
-./dollar-star4.sub: line 6: *: unbound variable
diff --git a/tests/exp.tests~ b/tests/exp.tests~
deleted file mode 100644 (file)
index 42fbf72..0000000
+++ /dev/null
@@ -1,384 +0,0 @@
-#
-# A suite of tests for bash word expansions
-#
-# This tests parameter and variable expansion, with an empahsis on
-# proper quoting behavior.
-#
-# Chet Ramey
-
-#
-# If you comment out the body of this function, you can do a diff against
-# `expansion-tests.right' to see if the shell is behaving correctly
-#
-expect()
-{
-       echo expect "$@"
-}
-
-# Test the substitution quoting characters (CTLESC and CTLNUL) in different
-# combinations
-
-expect "<^A>"
-recho `echo '\ 1'`
-expect "<^A>"
-recho `echo "\ 1"`
-expect "<^B>"
-recho `echo '\ 2'`
-expect "<^B>"
-recho `echo "\ 2"`
-expect "<^A>"
-recho `echo \ 1`
-expect "<^B>"
-recho `echo \ 2`
-
-# Test null strings without variable expansion
-expect "<abcdefgh>"
-recho abcd""efgh
-expect "<abcdefgh>"
-recho abcd''efgh
-expect "<abcdefgh>"
-recho ""abcdefgh
-expect "<abcdefgh>"
-recho ''abcdefgh
-expect "<abcd>"
-recho abcd""
-expect "<abcd>"
-recho abcd''
-
-# Test the quirky behavior of $@ in ""
-expect nothing
-recho "$@"
-expect "< >"
-recho " $@"
-expect "<-->"
-recho "-${@}-"
-
-# Test null strings with variable expansion that fails
-expect '<>'
-recho $xxx""
-expect '<>'
-recho ""$xxx
-expect '<>'
-recho $xxx''
-expect '<>'
-recho ''$xxx
-expect '<>'
-recho $xxx""$yyy
-expect '<>'
-recho $xxx''$yyy
-
-# Test null strings with variable expansion that succeeds
-xxx=abc
-yyy=def
-
-expect '<abc>'
-recho $xxx""
-expect '<abc>'
-recho ""$xxx
-expect '<abc>'
-recho $xxx''
-expect '<abc>'
-recho ''$xxx
-expect '<abcdef>'
-recho $xxx""$yyy
-expect '<abcdef>'
-recho $xxx''$yyy
-
-unset xxx yyy
-
-# Test the unquoted special quoting characters
-expect "<^A>"
-recho \ 1
-expect "<^B>"
-recho \ 2
-expect "<^A>"
-recho "\ 1"
-expect "<^B>"
-recho "\ 2"
-expect "<^A>"
-recho '\ 1'
-expect "<^B>"
-recho '\ 2'
-
-# Test expansion of a variable that is unset
-expect nothing
-recho $xxx
-expect '<>'
-recho "$xxx"
-
-expect nothing
-recho "$xxx${@}"
-
-# Test empty string expansion
-expect '<>'
-recho ""
-expect '<>'
-recho ''
-
-# Test command substitution with (disabled) history substitution
-expect '<Hello World!>'
-# set +H
-recho "`echo \"Hello world!\"`"
-
-# Test some shell special characters
-expect '<`>'
-recho "\`"
-expect '<">'
-recho "\""
-expect '<\^A>'
-recho "\\ 1"
-
-expect '<\$>'
-recho "\\$"
-
-expect '<\\>'
-recho "\\\\"
-
-# This should give argv[1] = a argv[2] = b
-expect '<a> <b>'
-FOO=`echo 'a b' | tr ' ' '\012'`
-recho $FOO
-
-# This should give argv[1] = ^A argv[2] = ^B
-expect '<^A> <^B>'
-FOO=`echo '\ 1 \ 2' | tr ' ' '\012'`
-recho $FOO
-
-# Test quoted and unquoted globbing characters
-expect '<**>'
-recho "*"*
-
-expect '<\.\./*/>'
-recho "\.\./*/"
-
-# Test patterns that come up when the shell quotes funny character
-# combinations
-expect '<^A^B^A^B>'
-recho '\ 1\ 2\ 1\ 2'
-expect '<^A^A>'
-recho '\ 1\ 1'
-expect '<^A^B>'
-recho '\ 1\ 2'
-expect '<^A^A^B>'
-recho '\ 1\ 1\ 2'
-
-# More tests of "$@"
-set abc def ghi jkl
-expect '<  abc> <def> <ghi> <jkl  >'
-recho "  $@  "
-expect '<  abc> <def> <ghi> <jkl  >'
-recho "${1+  $@  }"
-
-set abc def ghi jkl
-expect '<--abc> <def> <ghi> <jkl-->'
-recho "--$@--"
-
-set "a b" cd ef gh
-expect '<a b> <cd> <ef> <gh>'
-recho ${1+"$@"}
-expect '<a b> <cd> <ef> <gh>'
-recho ${foo:-"$@"}
-expect '<a b> <cd> <ef> <gh>'
-recho "${@}"
-
-expect '<  >'
-recho "  "
-expect '< - >'
-recho " - "
-
-# Test combinations of different types of quoting in a fully-quoted string
-# (so the WHOLLY_QUOTED tests fail and it doesn't get set)
-expect '</^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/>'
-recho "/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*"'$'"/\1/"
-
-# Test the various Posix parameter expansions
-
-expect '<foo bar>'
-recho "${x:-$(echo "foo bar")}"
-expect '<foo> <bar>'
-recho ${x:-$(echo "foo bar")}
-
-unset X
-expect '<abc>'
-recho ${X:=abc}
-expect '<abc>'
-recho $X
-
-set a b c
-expect '<posix>'
-recho ${3:+posix}
-
-POSIX=/usr/posix
-expect '<10>'
-recho ${#POSIX}
-
-# remove shortest trailing match
-x=file.c
-expect '<file.o>'
-recho ${x%.c}.o
-
-# remove longest trailing match
-x=posix/src/std
-expect '<posix>'
-recho ${x%%/*}
-
-# remove shortest leading pattern
-x=$HOME/src/cmd
-expect '</src/cmd>'
-recho ${x#$HOME}
-
-# remove longest leading pattern
-x=/one/two/three
-expect '<three>'
-recho ${x##*/}
-
-# pattern removal of patterns that don't match
-z=abcdef
-
-expect '<abcdef>'
-recho ${z#xyz}
-expect '<abcdef>'
-recho ${z##xyz}
-
-expect '<abcdef>'
-recho ${z%xyz}
-expect '<abcdef>'
-recho ${z%%xyz}
-
-# Command substitution and the quirky differences between `` and $()
-
-expect '<\$x>'
-recho '\$x'
-
-expect '<$x>'
-recho `echo '\$x'`
-
-expect '<\$x>'
-recho $(echo '\$x')
-
-# The difference between $* "$*" and "$@"
-
-set "abc" "def ghi" "jkl"
-
-expect '<abc> <def> <ghi> <jkl>'
-recho $*
-
-expect '<abc def ghi jkl>'
-recho "$*"
-
-OIFS="$IFS"
-IFS=":$IFS"
-
-# The special behavior of "$*", using the first character of $IFS as separator
-expect '<abc:def ghi:jkl>'
-recho "$*"
-
-IFS="$OIFS"
-
-expect '<abc> <def ghi> <jkl>'
-recho "$@"
-
-expect '<xxabc> <def ghi> <jklyy>'
-recho "xx$@yy"
-
-expect '<abc> <def ghi> <jklabc> <def ghi> <jkl>'
-recho "$@$@"
-
-foo=abc
-bar=def
-
-expect '<abcdef>'
-recho "$foo""$bar"
-
-unset foo
-set $foo bar '' xyz "$foo" abc
-
-expect '<bar> <> <xyz> <> <abc>'
-recho "$@"
-
-# More tests of quoting and deferred evaluation
-
-foo=10 x=foo
-y='$'$x
-expect '<$foo>'
-recho $y
-eval y='$'$x
-expect '<10>'
-recho $y
-
-# case statements
-
-NL='
-'
-x='ab
-cd'
-
-expect '<newline expected>'
-case "$x" in
-*$NL*) recho "newline expected" ;;
-esac
-
-expect '<got it>'
-case \? in
-*"?"*) recho "got it" ;;
-esac
-
-expect '<got it>'
-case \? in
-*\?*) recho "got it" ;;
-esac
-
-set one two three four five
-expect '<one> <three> <five>'
-recho $1 $3 ${5} $8 ${9}
-
-# length tests on positional parameters and some special parameters
-
-expect '<5> <5>'
-recho $# ${#}
-expect '<3>'
-recho ${#1}
-expect '<1>'
-recho ${##}
-expect '<1>'
-recho ${#?}
-expect '<5>'
-recho ${#@}
-expect '<5>'
-recho ${#*}
-expect '<5>'
-recho "${#@}"
-expect '<5>'
-recho "${#*}"
-
-expect '<42>'
-recho $((28 + 14))
-expect '<26>'
-recho $[ 13 * 2 ]
-
-expect '<\>'
-recho `echo \\\\`
-
-expect '<~>'
-recho '~'
-
-expect nothing
-recho $!
-expect nothing
-recho ${!}
-
-# test word splitting of assignment statements not preceding a command
-a="a b c d e"
-declare b=$a
-expect '<a> <b> <c> <d> <e>'
-recho $b
-
-a="a?b?c"
-
-echo ${a//\\?/ }
-
-echo ${a//\?/ }
-
-${THIS_SH} ./exp1.sub
-
-${THIS_SH} ./exp2.sub
diff --git a/tests/extglob.tests~ b/tests/extglob.tests~
deleted file mode 100644 (file)
index eb26d55..0000000
+++ /dev/null
@@ -1,370 +0,0 @@
-# test the ksh-like extended globbing features: [!@*?+](patlist)
-
-shopt -s extglob
-
-expect()
-{
-       echo expect "$@"
-}
-
-case "/dev/udp/129.22.8.102/45" in
-/dev/@(tcp|udp)/*/*)   echo ok 1;;
-*)             echo bad 1;;
-esac
-
-# valid numbers
-case 12 in
-0|[1-9]*([0-9]))       echo ok 2;;
-*)                     echo bad 2;;
-esac
-
-case 12abc in
-0|[1-9]*([0-9]))       echo bad 3;;
-*)                     echo ok 3;;
-esac
-
-case 1 in
-0|[1-9]*([0-9]))       echo ok 4;;
-*)                     echo bad 4;;
-esac
-
-# octal numbers
-case 07 in
-+([0-7]))              echo ok 5;;
-*)                     echo bad 5;;
-esac
-
-case 0377 in
-+([0-7]))              echo ok 6;;
-*)                     echo bad 6;;
-esac
-
-case 09 in
-+([0-7]))              echo bad 7;;
-*)                     echo ok 7;;
-esac
-
-# stuff from korn's book
-case paragraph in
-para@(chute|graph))    echo ok 8;;
-*)                     echo bad 8;;
-esac
-
-case paramour in
-para@(chute|graph))    echo bad 9;;
-*)                     echo ok 9;;
-esac
-
-case para991 in
-para?([345]|99)1)      echo ok 10;;
-*)                     echo bad 10;;
-esac
-
-case para381 in
-para?([345]|99)1)      echo bad 11;;
-*)                     echo ok 11;;
-esac
-
-case paragraph in
-para*([0-9]))          echo bad 12;;
-*)                     echo ok 12;;
-esac
-
-case para in
-para*([0-9]))          echo ok 13;;
-*)                     echo bad 13;;
-esac
-
-case para13829383746592 in
-para*([0-9]))          echo ok 14;;
-*)                     echo bad 14;;
-esac
-
-case paragraph in
-para*([0-9]))          echo bad 15;;
-*)                     echo ok 15;;
-esac
-
-case para in
-para+([0-9]))          echo bad 16;;
-*)                     echo ok 16;;
-esac
-
-case para987346523 in
-para+([0-9]))          echo ok 17;;
-*)                     echo bad 17;;
-esac
-
-case paragraph in
-para!(*.[0-9]))                echo ok 18;;
-*)                     echo bad 18;;
-esac
-
-case para.38 in
-para!(*.[0-9]))                echo ok 19;;
-*)                     echo bad 19;;
-esac
-
-case para.graph in
-para!(*.[0-9]))                echo ok 20;;
-*)                     echo bad 20;;
-esac
-
-case para39 in
-para!(*.[0-9]))                echo ok 21;;
-*)                     echo bad 21;;
-esac
-
-# tests derived from those in rosenblatt's korn shell book
-
-case "" in
-*(0|1|3|5|7|9))                echo ok 22;;
-*)                     echo bad 22;
-esac
-
-case 137577991 in
-*(0|1|3|5|7|9))                echo ok 23;;
-*)                     echo bad 23;
-esac
-
-case 2468 in
-*(0|1|3|5|7|9))                echo bad 24;;
-*)                     echo ok 24;
-esac
-
-case file.c in
-*.c?(c))               echo ok 25;;
-*)                     echo bad 25;;
-esac
-
-case file.C in
-*.c?(c))               echo bad 26;;
-*)                     echo ok 26;;
-esac
-
-case file.cc in
-*.c?(c))               echo ok 27;;
-*)                     echo bad 27;;
-esac
-
-case file.ccc in
-*.c?(c))               echo bad 28;;
-*)                     echo ok 28;;
-esac
-
-case parse.y in
-!(*.c|*.h|Makefile.in|config*|README)) echo ok 29;;
-*)                     echo bad 29;;
-esac
-
-case shell.c in
-!(*.c|*.h|Makefile.in|config*|README)) echo bad 30;;
-*)                     echo ok 30;;
-esac
-
-case Makefile in
-!(*.c|*.h|Makefile.in|config*|README)) echo ok 31;;
-*)                     echo bad 31;;
-esac
-
-case "VMS.FILE;1" in
-*\;[1-9]*([0-9]))      echo ok 32;;
-*)                     echo bad 32;;
-esac
-
-case "VMS.FILE;0" in
-*\;[1-9]*([0-9]))      echo bad 33;;
-*)                     echo ok 33;;
-esac
-case "VMS.FILE;" in
-*\;[1-9]*([0-9]))      echo bad 34;;
-*)                     echo ok 34;;
-esac
-case "VMS.FILE;139" in
-*\;[1-9]*([0-9]))      echo ok 35;;
-*)                     echo bad 35;;
-esac
-case "VMS.FILE;1N" in
-*\;[1-9]*([0-9]))      echo bad 36;;
-*)                     echo ok 36;;
-esac
-
-# tests derived from the pd-ksh test suite
-
-MYDIR=$PWD      # save where we are
-
-TESTDIR=/tmp/eglob-test-$$
-mkdir $TESTDIR
-builtin cd $TESTDIR || { echo $0: cannot cd to $TESTDIR >&2 ; exit 1; }
-rm -rf *
-
-touch abcx abcz bbc
-expect '!([*)*'
-echo !([*)*
-
-expect '+(a|b[)*'
-echo +(a|b[)*
-
-expect '[a*(]*z'
-echo [a*(]*)z
-
-rm -f abcx abcz bbc
-
-touch abc
-
-expect '+()c'
-echo +()c
-expect '+()x'
-echo +()x
-expect abc
-echo +(*)c
-expect '+(*)x'
-echo +(*)x
-
-# extended globbing should not be performed on the output of substitutions
-x='@(*)'
-expect '@(*)'
-echo $x
-
-expect 'no-file+(a|b)stuff'
-echo no-file+(a|b)stuff
-expect 'no-file+(a*(c)|b)stuff'
-echo no-file+(a*(c)|b)stuff
-
-touch abd acd
-
-expect 'abd acd'
-echo a+(b|c)d
-
-expect 'acd'
-echo a!(@(b|B))d
-
-expect 'abd'
-echo a[b*(foo|bar)]d
-
-# simple kleene star tests
-expect no
-case foo in *(a|b[)) echo yes;; *) echo no;; esac
-
-expect yes
-case foo in *(a|b[)|f*) echo yes;; *) echo no;; esac
-
-# this doesn't work right yet; it is an incorrectly formed pattern
-expect yes
-case '*(a|b[)' in *(a|b[)) echo yes;; *) echo no;; esac
-
-# check extended globbing in pattern removal -- these don't work right yet
-x=abcdef
-
-expect '1: bcdef'
-echo 1: ${x#+(a|abc)}
-expect '2: def'
-echo 2: ${x##+(a|abc)}
-expect '3: abcde'
-echo 3: ${x%+(def|f)}
-expect '4: abc'
-echo 4: ${x%%+(f|def)}
-
-# these work ok
-
-expect '5: ef'
-echo 5: ${x#*(a|b)cd}
-expect '6: ef'
-echo 6: "${x#*(a|b)cd}"
-expect '7: abcdef'
-echo 7: ${x#"*(a|b)cd"}
-
-# More tests derived from a bug report concerning extended glob patterns
-# following a *
-builtin cd $TESTDIR || { echo $0: cannot cd to $TESTDIR >&2 ; exit 1; }
-rm -rf *
-
-touch ab abcdef abef abcfef
-
-expect 'ab abef'
-echo ab*(e|f)
-
-expect 'abcfef abef'
-echo ab?*(e|f)
-
-expect abcdef
-echo ab*d+(e|f)
-
-expect 'ab abcdef abcfef abef'
-echo ab**(e|f)
-
-expect 'abcdef abcfef abef'
-echo ab*+(e|f)
-
-case 'abcfefg' in
-ab**(e|f))     echo ok 37;;
-*)             echo bad 37;;
-esac
-
-case 'abcfefg' in
-ab**(e|f)g)    echo ok 38;;
-*a)            echo bad 38;;
-esac
-
-case ab in
-ab*+(e|f))     echo bad 39;;
-*)             echo ok 39;;
-esac
-
-case abef in
-ab***ef)       echo ok 40;;
-*)             echo bad 40;;
-esac
-
-case abef in
-ab**)          echo ok 41;;
-*)             echo bad 41;;
-esac
-
-# bug in all versions up to and including bash-2.05b
-case "123abc" in
-*?(a)bc)       echo ok 42;;
-*)             echo bad 42;;
-esac
-
-# clean up and do the next one
-
-builtin cd /
-rm -rf $TESTDIR
-
-mkdir $TESTDIR
-builtin cd $TESTDIR
-
-LC_COLLATE=C # have to set this; it affects the sorting 
-touch a.b a,b a:b a-b a\;b a\ b a_b
-
-echo a[^[:alnum:]]b
-echo a[-.,:\;\ _]b
-
-echo a@([^[:alnum:]])b
-echo a@([-.,:; _])b
-echo a@([.])b
-echo a@([^.])b
-echo a@([^x])b
-echo a+([^[:alnum:]])b
-
-echo a@(.|[^[:alnum:]])b
-
-builtin cd /
-rm -rf $TESTDIR
-
-x=abcdef
-recho "${x#*(a|b)cd}"
-
-TEST='a , b'
-shopt -s globstar
-echo ${TEST//*([[:space:]]),*([[:space:]])/,}
-shopt -u globstar
-
-# this is for the benefit of pure coverage, so it writes the pcv file
-# in the right place
-builtin cd "$MYDIR"
-
-${THIS_SH} ./extglob1.sub
-
-exit 0
diff --git a/tests/globstar.tests~ b/tests/globstar.tests~
deleted file mode 100644 (file)
index 51856c3..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-: ${TMPDIR:=/var/tmp}
-dir=$PWD
-
-shopt -s globstar
-
-export LANG=C LC_ALL=C LC_COLLATE=C
-
-GDIR=$TMPDIR/globstar-$$
-
-mkdir $GDIR || exit 1
-cd $GDIR || exit 1
-
-mkdir lib builtins
-mkdir lib/glob lib/readline lib/sh
-
-touch builtins/history.o builtins/jobs.o builtins/kill.o builtins/let.o builtins/mapfile.o
-touch lib/glob/glob.o lib/glob/smatch.o lib/glob/strmatch.o
-touch lib/readline/bind.o lib/readline/callback.o lib/readline/compat.o lib/readline/complete.o lib/readline/display.o
-
-touch lib/sh/casemod.o lib/sh/clktck.o lib/sh/clock.o lib/sh/eaccess.o
-touch lib/sh/fdprintf.o lib/sh/fmtullong.o lib/sh/fmtulong.o lib/sh/fmtumax.o
-touch lib/sh/fpurge.o lib/sh/getenv.o lib/sh/input_avail.o lib/sh/itos.o
-
-touch alias.o
-touch pcomplib.o print_cmd.o redir.o shell.o sig.o stringlib.o subst.o syntax.o
-touch test.o trap.o unwind_prot.o variables.o version.o xmalloc.o y.tab.o
-
-ls lib/**
-
-ls lib/**/*.o
-
-echo **/*.o
-
-ls **
-
-echo **
-
-cd $dir
-rm -rf $GDIR
diff --git a/tests/history.tests~ b/tests/history.tests~
deleted file mode 100644 (file)
index 7ca7558..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-trap 'rm /tmp/newhistory' 0
-
-# bad options
-history -x
-# cannot use -r and -w at the same time
-history -r -w /dev/null
-
-# bad option
-fc -v
-
-unset HISTFILESIZE
-
-# all of these should result in an empty history list
-history -c
-history -r /dev/null
-history -n /dev/null
-history -c
-
-HISTFILE=history.list
-HISTCONTROL=ignoreboth
-HISTIGNORE='&:history*:fc*'
-HISTSIZE=32
-
-shopt -s cmdhist
-set -o history
-
-history
-
-fc -l
-fc -nl
-
-fc -lr
-fc -nlr
-
-history -s "echo line for history"
-history
-
-history -p '!!'
-
-fc -nl
-
-HISTFILE=/tmp/newhistory
-history -a
-echo displaying \$HISTFILE after history -a
-cat $HISTFILE
-
-history
-history -w
-cat $HISTFILE
-
-history -s "echo line 2 for history"
-history
-history -p '!e'
-history -p '!!'
-
-# this should show up as one history entry
-for x in one two three
-do
-       :
-done
-history
-
-# just a basic test.  a full test suite for history expansion should be
-# created
-set -H
-!!
-!e
-
-unset HISTSIZE
-unset HISTFILE
-
-fc -l 4
-fc -l 4 8
-
-fc -l one=two three=four 502
-
-history 4
-
-shopt -so history
-shopt -s expand_aliases
-
-alias r="fc -s"
-
-echo aa ab ac
-
-r a=x
-r x=4 b=8
-
-# this had better fail with `no command found'
-r cc
-
-unalias -a
-alias
-
-# these two blocks had better both result in the same output
-echo aa
-echo bb
-echo cc
-fc -e cat
-
-echo aa
-echo bb
-echo cc
-fc -e cat -1
-
-set +o history
-
-shopt -q -o history
-echo $?
-
-${THIS_SH} ./history1.sub
diff --git a/tests/jobs.tests~ b/tests/jobs.tests~
deleted file mode 100644 (file)
index 8ed5822..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-# test out %+, jobs -p, and $! agreement in a subshell first
-${THIS_SH} ./jobs1.sub
-
-# test out fg/bg failure in a subshell
-${THIS_SH} ./jobs2.sub
-
-# test out behavior of waiting for background pids -- bug in versions
-# before 2.03
-${THIS_SH} ./jobs3.sub
-
-# test out behavior of using job control notation when job control is not
-# active
-${THIS_SH} ./jobs4.sub
-
-jobs
-echo $?
-
-# a no-such-job error, since we can use job control notation without job control
-wait %1
-
-# make sure we can't fg a job started when job control was not active
-sleep 30 &
-pid=$!
-fg %1
-# make sure the killed processes don't cause a message
-exec 5>&2
-exec 2>/dev/null
-kill -n 9 $pid
-wait    # make sure we reap the processes while stderr is still redirected
-exec 2>&5
-
-echo wait-for-pid
-sleep 10 &
-wait $!
-
-echo wait-errors
-wait 1-1
-wait -- -4
-
-echo wait-for-background-pids
-sleep 5 &
-sleep 8 &
-wait
-
-echo async list wait-for-background-pids
-sleep 5 & sleep 8 &
-wait
-
-echo async list wait for child
-sleep 5 & echo forked
-wait
-
-echo wait-when-no-children
-wait
-
-set -m
-
-echo wait-for-job
-sleep 5 &
-wait %2                # this should be a no-such-job error
-echo $?
-wait %1
-
-echo async list wait-for-job
-sleep 5 & echo forked
-wait %1
-
-echo fg-bg 1
-sleep 5 &
-%1
-
-echo fg-bg 2
-sleep 5 &
-fg %%
-
-echo fg-bg 3
-sleep 5 &
-fg %s
-
-echo fg-bg 4
-sleep 5 &
-fg %?ee
-
-# these next two are error cases
-echo fg-bg 5
-sleep 15 &
-fg %2          # this should be a no-such-job error
-bg %1          # this should be a `bg background job?' error
-wait
-
-# these may someday mean to start the jobs, but not print the line
-# describing the status, but for now they are errors
-echo fg-bg 6
-sleep 5 &
-fg -s %1
-bg -s %1
-wait
-
-# someday this may mean to disown all stopped jobs, but for now it is
-# an error
-disown -s
-
-# this is an error -- the job with the pid that is the value of $! is
-# retained only until a `wait' is performed
-disown %1
-
-# this, however, is an error
-disown %2
-
-echo wait-for-non-child
-wait 1
-echo $?
-
-exit 1 | exit 2 | exit 3
-echo $? -- ${PIPESTATUS[@]} -- ${PIPESTATUS[0]} - ${PIPESTATUS[1]} - ${PIPESTATUS[2]}
-
-sleep 300 &
-sleep300pid=$!
-echo sleep300pid = $sleep300pid
-sleep 350 &
-sleep 400 &
-
-jobs
-
-echo running jobs:
-jobs -r
-
-# should be an error
-kill -n 1 %4
-# should be an error
-jobs %4
-echo current job:
-jobs %+
-echo previous job:
-jobs %-
-
-kill -STOP %2
-sleep 5        # give time for the shell to get the stop notification
-echo after kill -STOP
-echo running jobs:
-jobs -r
-echo stopped jobs:
-jobs -s
-
-disown %1
-
-echo after disown
-jobs
-echo running jobs:
-jobs -r
-echo stopped jobs:
-jobs -s
-
-kill -s CONT %2
-echo after kill -s CONT
-echo running jobs:
-jobs -r
-echo stopped jobs:
-jobs -s
-
-kill -STOP %3
-sleep 5        # give time for the shell to get the stop notification
-echo after kill -STOP, backgrounding %3:
-bg %3
-
-disown -h %2
-
-# make sure the killed processes don't cause a message
-exec 5>&2
-exec 2>/dev/null
-
-echo killing...
-kill -n 9 %2 %3
-wait   # make sure we reap the processes while stderr is still redirected
-echo done
-
-exec 2>&5
-
-sleep 10 &
-kill -STOP %1
-sleep 5        # give time for the shell to get the stop notification
-echo after KILL -STOP, foregrounding %1
-fg %1
-
-echo done
diff --git a/tests/misc/regress/log.orig b/tests/misc/regress/log.orig
deleted file mode 100644 (file)
index c1f1e19..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-:; ./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
deleted file mode 100644 (file)
index 4b3bf2b..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#! /bin/sh
-for cmd in sh bash ash ksh zsh
-do
-       echo
-       echo $cmd:
-       for demo in shx?
-       do
-               $cmd $demo
-       done
-done
diff --git a/tests/run-glob-test~ b/tests/run-glob-test~
deleted file mode 100644 (file)
index 659112a..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-PATH=$PATH:`pwd`
-export PATH
-${THIS_SH} ./glob-test 2>&1 | grep -v '^expect' > /tmp/xx
-diff /tmp/xx glob.right && rm -f /tmp/xx
diff --git a/tests/run-globstar~ b/tests/run-globstar~
deleted file mode 100644 (file)
index 1ea0814..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-PATH=$PATH:`pwd`
-export PATH
-${THIS_SH} ./globstar.test  > /tmp/xx 2>&1
-diff /tmp/xx globstar.right && rm -f /tmp/xx
diff --git a/tests/run-trap~ b/tests/run-trap~
deleted file mode 100644 (file)
index b448443..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-echo "warning: UNIX versions number signals differently.  If output differing" >&2
-echo "warning: only in line numbers is produced, please do not consider this" >&2
-echo "warning: a test failure." >&2
-
-${THIS_SH} ./trap.tests > /tmp/xx 2>&1
-diff /tmp/xx trap.right && rm -f /tmp/xx
diff --git a/tests/trap.tests~ b/tests/trap.tests~
deleted file mode 100644 (file)
index 83497a3..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-# test the trap code
-
-trap 'echo exiting' 0
-trap 'echo aborting' 1 2 3 6 15
-
-# make sure a user-specified subshell runs the exit trap, but does not
-# inherit the exit trap from a parent shell
-( trap 'echo subshell exit' 0; exit 0 )
-( exit 0 )
-
-trap
-
-func()
-{
-       trap 'echo ${FUNCNAME:-$0}[$LINENO] funcdebug' DEBUG
-       echo funcdebug line
-}
-
-trap 'echo [$LINENO] debug' DEBUG
-echo debug line
-
-trap
-
-func
-
-trap
-
-trap 'echo ${FUNCNAME:-$0}[$LINENO] debug' DEBUG
-func2()
-{
-       echo func2debug line
-}
-declare -ft func2
-func2
-
-unset -f func2
-
-trap '' DEBUG
-
-trap
-
-trap - debug
-
-trap
-
-trap - HUP
-trap hup
-trap '' INT
-trap '' int
-
-trap
-
-# exit 0 in exit trap should set exit status
-(
-set -e
-trap 'exit 0' EXIT
-false   
-echo bad
-)
-echo $?
-
-# hmmm...should this set the handling to SIG_IGN for children, too?
-trap '' USR2
-./trap1.sub
-
-# test ERR trap
-./trap2.sub
-
-#
-# show that setting a trap on SIGCHLD is not disastrous.
-#
-set -o monitor
-
-trap 'echo caught a child death' SIGCHLD
-
-sleep 7 & sleep 6 & sleep 5 &
-
-# this will only catch the first, since there's a trap on SIGCHLD
-wait
-
-trap -p SIGCHLD
-
-# Now reset some of the signals the shell handles specially back to
-# their default values (with or without the SIG prefix)
-trap - SIGINT QUIT TERM
-
-trap
-
-trap - SIGCHLD
-wait
diff --git a/tests/trap3.sub~ b/tests/trap3.sub~
deleted file mode 100644 (file)
index fb4df8c..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-PS4='+[$LINENO] '
-trap 'echo trap: $LINENO' ERR
-
-echo 1
-echo 2
-echo 3 | cat | false
-echo 4
diff --git a/tests/vredir2.sub~ b/tests/vredir2.sub~
deleted file mode 100644 (file)
index e1a380d..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-: ${TMPDIR:=/var/tmp}
-SHELLSFILE=$TMPDIR/shells-$$
-
-cat > $TMPDIR/shells-$$ <<EOF
-/bin/bash
-/bin/csh
-/bin/ksh
-/bin/sh
-/bin/tcsh
-/bin/zsh
-EOF
-
-oclosev()
-{
-exec {v}>&-
-}
-
-iclosev()
-{
-exec {v}<&-
-}
-
-exec {v}>&1
-echo $v
-
-echo foo 1 >&$v
-echo foo 2 >&$v
-echo foo 3 >&$v
-
-oclosev
-
-exec {v}<$SHELLSFILE
-echo $v
-
-while read line <&$v
-do
-       echo $line
-done
-
-iclosev
-
-type oclosev
-type iclosev
-
-while read -r -u ${fd}
-do
-       echo $REPLY
-done {fd}<$SHELLSFILE
-
-rm -f $SHELLSFILE
-
-exit 0
diff --git a/trap.c.save1 b/trap.c.save1
deleted file mode 100644 (file)
index b41304e..0000000
+++ /dev/null
@@ -1,1042 +0,0 @@
-/* trap.c -- Not the trap command, but useful functions for manipulating
-   those objects.  The trap command is in builtins/trap.def. */
-
-/* Copyright (C) 1987-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/>.
-*/
-
-#include "config.h"
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include "bashtypes.h"
-#include "bashansi.h"
-
-#include <stdio.h>
-#include <errno.h>
-
-#include "bashintl.h"
-
-#include "trap.h"
-
-#include "shell.h"
-#include "flags.h"
-#include "input.h"     /* for save_token_state, restore_token_state */
-#include "jobs.h"
-#include "signames.h"
-#include "builtins.h"
-#include "builtins/common.h"
-#include "builtins/builtext.h"
-
-#ifndef errno
-extern int errno;
-#endif
-
-/* Flags which describe the current handling state of a signal. */
-#define SIG_INHERITED   0x0    /* Value inherited from parent. */
-#define SIG_TRAPPED     0x1    /* Currently trapped. */
-#define SIG_HARD_IGNORE 0x2    /* Signal was ignored on shell entry. */
-#define SIG_SPECIAL     0x4    /* Treat this signal specially. */
-#define SIG_NO_TRAP     0x8    /* Signal cannot be trapped. */
-#define SIG_INPROGRESS 0x10    /* Signal handler currently executing. */
-#define SIG_CHANGED    0x20    /* Trap value changed in trap handler. */
-#define SIG_IGNORED    0x40    /* The signal is currently being ignored. */
-
-#define SPECIAL_TRAP(s)        ((s) == EXIT_TRAP || (s) == DEBUG_TRAP || (s) == ERROR_TRAP || (s) == RETURN_TRAP)
-
-/* An array of such flags, one for each signal, describing what the
-   shell will do with a signal.  DEBUG_TRAP == NSIG; some code below
-   assumes this. */
-static int sigmodes[BASH_NSIG];
-
-static void free_trap_command __P((int));
-static void change_signal __P((int, char *));
-
-static void get_original_signal __P((int));
-
-static int _run_trap_internal __P((int, char *));
-
-static void reset_signal __P((int));
-static void restore_signal __P((int));
-static void reset_or_restore_signal_handlers __P((sh_resetsig_func_t *));
-
-/* Variables used here but defined in other files. */
-extern int last_command_exit_value;
-extern int line_number;
-
-extern char *this_command_name;
-extern sh_builtin_func_t *this_shell_builtin;
-extern procenv_t wait_intr_buf;
-extern int return_catch_flag, return_catch_value;
-extern int subshell_level;
-
-/* The list of things to do originally, before we started trapping. */
-SigHandler *original_signals[NSIG];
-
-/* For each signal, a slot for a string, which is a command to be
-   executed when that signal is recieved.  The slot can also contain
-   DEFAULT_SIG, which means do whatever you were going to do before
-   you were so rudely interrupted, or IGNORE_SIG, which says ignore
-   this signal. */
-char *trap_list[BASH_NSIG];
-
-/* A bitmap of signals received for which we have trap handlers. */
-int pending_traps[NSIG];
-
-/* Set to the number of the signal we're running the trap for + 1.
-   Used in execute_cmd.c and builtins/common.c to clean up when
-   parse_and_execute does not return normally after executing the
-   trap command (e.g., when `return' is executed in the trap command). */
-int running_trap;
-
-/* Set to last_command_exit_value before running a trap. */
-int trap_saved_exit_value;
-
-/* The (trapped) signal received while executing in the `wait' builtin */
-int wait_signal_received;
-
-/* A value which can never be the target of a trap handler. */
-#define IMPOSSIBLE_TRAP_HANDLER (SigHandler *)initialize_traps
-
-#define GETORIGSIG(sig) \
-  do { \
-    original_signals[sig] = (SigHandler *)set_signal_handler (sig, SIG_DFL); \
-    set_signal_handler (sig, original_signals[sig]); \
-    if (original_signals[sig] == SIG_IGN) \
-      sigmodes[sig] |= SIG_HARD_IGNORE; \
-  } while (0)
-
-#define GET_ORIGINAL_SIGNAL(sig) \
-  if (sig && sig < NSIG && original_signals[sig] == IMPOSSIBLE_TRAP_HANDLER) \
-    GETORIGSIG(sig)
-
-void
-initialize_traps ()
-{
-  register int i;
-
-  initialize_signames();
-
-  trap_list[EXIT_TRAP] = trap_list[DEBUG_TRAP] = trap_list[ERROR_TRAP] = trap_list[RETURN_TRAP] = (char *)NULL;
-  sigmodes[EXIT_TRAP] = sigmodes[DEBUG_TRAP] = sigmodes[ERROR_TRAP] = sigmodes[RETURN_TRAP] = SIG_INHERITED;
-  original_signals[EXIT_TRAP] = IMPOSSIBLE_TRAP_HANDLER;
-
-  for (i = 1; i < NSIG; i++)
-    {
-      pending_traps[i] = 0;
-      trap_list[i] = (char *)DEFAULT_SIG;
-      sigmodes[i] = SIG_INHERITED;
-      original_signals[i] = IMPOSSIBLE_TRAP_HANDLER;
-    }
-
-  /* Show which signals are treated specially by the shell. */
-#if defined (SIGCHLD)
-  GETORIGSIG (SIGCHLD);
-  sigmodes[SIGCHLD] |= (SIG_SPECIAL | SIG_NO_TRAP);
-#endif /* SIGCHLD */
-
-  GETORIGSIG (SIGINT);
-  sigmodes[SIGINT] |= SIG_SPECIAL;
-
-#if defined (__BEOS__)
-  /* BeOS sets SIGINT to SIG_IGN! */
-  original_signals[SIGINT] = SIG_DFL;
-  sigmodes[SIGINT] &= ~SIG_HARD_IGNORE;
-#endif
-
-  GETORIGSIG (SIGQUIT);
-  sigmodes[SIGQUIT] |= SIG_SPECIAL;
-
-  if (interactive)
-    {
-      GETORIGSIG (SIGTERM);
-      sigmodes[SIGTERM] |= SIG_SPECIAL;
-    }
-}
-
-#ifdef INCLUDE_UNUSED
-/* Return a printable representation of the trap handler for SIG. */
-static char *
-trap_handler_string (sig)
-     int sig;
-{
-  if (trap_list[sig] == (char *)DEFAULT_SIG)
-    return "DEFAULT_SIG";
-  else if (trap_list[sig] == (char *)IGNORE_SIG)
-    return "IGNORE_SIG";
-  else if (trap_list[sig] == (char *)IMPOSSIBLE_TRAP_HANDLER)
-    return "IMPOSSIBLE_TRAP_HANDLER";
-  else if (trap_list[sig])
-    return trap_list[sig];
-  else
-    return "NULL";
-}
-#endif
-
-/* Return the print name of this signal. */
-char *
-signal_name (sig)
-     int sig;
-{
-  char *ret;
-
-  /* on cygwin32, signal_names[sig] could be null */
-  ret = (sig >= BASH_NSIG || sig < 0 || signal_names[sig] == NULL)
-       ? _("invalid signal number")
-       : signal_names[sig];
-
-  return ret;
-}
-
-/* Turn a string into a signal number, or a number into
-   a signal number.  If STRING is "2", "SIGINT", or "INT",
-   then (int)2 is returned.  Return NO_SIG if STRING doesn't
-   contain a valid signal descriptor. */
-int
-decode_signal (string, flags)
-     char *string;
-     int flags;
-{
-  intmax_t sig;
-  char *name;
-
-  if (legal_number (string, &sig))
-    return ((sig >= 0 && sig < NSIG) ? (int)sig : NO_SIG);
-
-  /* A leading `SIG' may be omitted. */
-  for (sig = 0; sig < BASH_NSIG; sig++)
-    {
-      name = signal_names[sig];
-      if (name == 0 || name[0] == '\0')
-       continue;
-
-      /* Check name without the SIG prefix first case sensitivly or
-        insensitively depending on whether flags includes DSIG_NOCASE */
-      if (STREQN (name, "SIG", 3))
-       {
-         name += 3;
-
-         if ((flags & DSIG_NOCASE) && strcasecmp (string, name) == 0)
-           return ((int)sig);
-         else if ((flags & DSIG_NOCASE) == 0 && strcmp (string, name) == 0)
-           return ((int)sig);
-         /* If we can't use the `SIG' prefix to match, punt on this
-            name now. */
-         else if ((flags & DSIG_SIGPREFIX) == 0)
-           continue;
-       }
-
-      /* Check name with SIG prefix case sensitively or insensitively
-        depending on whether flags includes DSIG_NOCASE */
-      name = signal_names[sig];
-      if ((flags & DSIG_NOCASE) && strcasecmp (string, name) == 0)
-       return ((int)sig);
-      else if ((flags & DSIG_NOCASE) == 0 && strcmp (string, name) == 0)
-       return ((int)sig);
-    }
-
-  return (NO_SIG);
-}
-
-/* Non-zero when we catch a trapped signal. */
-static int catch_flag;
-
-void
-run_pending_traps ()
-{
-  register int sig;
-  int old_exit_value, *token_state;
-
-  if (catch_flag == 0)         /* simple optimization */
-    return;
-
-  catch_flag = 0;
-
-  /* Preserve $? when running trap. */
-  old_exit_value = last_command_exit_value;
-
-  for (sig = 1; sig < NSIG; sig++)
-    {
-      /* XXX this could be made into a counter by using
-        while (pending_traps[sig]--) instead of the if statement. */
-      if (pending_traps[sig])
-       {
-#if defined (HAVE_POSIX_SIGNALS)
-         sigset_t set, oset;
-
-         sigemptyset (&set);
-         sigemptyset (&oset);
-
-         sigaddset (&set, sig);
-         sigprocmask (SIG_BLOCK, &set, &oset);
-#else
-#  if defined (HAVE_BSD_SIGNALS)
-         int oldmask = sigblock (sigmask (sig));
-#  endif
-#endif /* HAVE_POSIX_SIGNALS */
-
-         if (sig == SIGINT)
-           {
-             run_interrupt_trap ();
-             CLRINTERRUPT;
-           }
-#if defined (JOB_CONTROL) && defined (SIGCHLD)
-         else if (sig == SIGCHLD &&
-                  trap_list[SIGCHLD] != (char *)IMPOSSIBLE_TRAP_HANDLER &&
-                  (sigmodes[SIGCHLD] & SIG_INPROGRESS) == 0)
-           {
-             run_sigchld_trap (pending_traps[sig]);    /* use as counter */
-           }
-#endif
-         else if (trap_list[sig] == (char *)DEFAULT_SIG ||
-                  trap_list[sig] == (char *)IGNORE_SIG ||
-                  trap_list[sig] == (char *)IMPOSSIBLE_TRAP_HANDLER)
-           {
-             /* This is possible due to a race condition.  Say a bash
-                process has SIGTERM trapped.  A subshell is spawned
-                using { list; } & and the parent does something and kills
-                the subshell with SIGTERM.  It's possible for the subshell
-                to set pending_traps[SIGTERM] to 1 before the code in
-                execute_cmd.c eventually calls restore_original_signals
-                to reset the SIGTERM signal handler in the subshell.  The
-                next time run_pending_traps is called, pending_traps[SIGTERM]
-                will be 1, but the trap handler in trap_list[SIGTERM] will
-                be invalid (probably DEFAULT_SIG, but it could be IGNORE_SIG).
-                Unless we catch this, the subshell will dump core when
-                trap_list[SIGTERM] == DEFAULT_SIG, because DEFAULT_SIG is
-                usually 0x0. */
-             internal_warning (_("run_pending_traps: bad value in trap_list[%d]: %p"),
-                               sig, trap_list[sig]);
-             if (trap_list[sig] == (char *)DEFAULT_SIG)
-               {
-                 internal_warning (_("run_pending_traps: signal handler is SIG_DFL, resending %d (%s) to myself"), sig, signal_name (sig));
-                 kill (getpid (), sig);
-               }
-           }
-         else
-           {
-             token_state = save_token_state ();
-             parse_and_execute (savestring (trap_list[sig]), "trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE);
-             restore_token_state (token_state);
-             free (token_state);
-           }
-
-         pending_traps[sig] = 0;
-
-#if defined (HAVE_POSIX_SIGNALS)
-         sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
-#else
-#  if defined (HAVE_BSD_SIGNALS)
-         sigsetmask (oldmask);
-#  endif
-#endif /* POSIX_VERSION */
-       }
-    }
-
-  last_command_exit_value = old_exit_value;
-}
-
-sighandler
-trap_handler (sig)
-     int sig;
-{
-  int oerrno;
-
-  if ((sigmodes[sig] & SIG_TRAPPED) == 0)
-    {
-#if defined (DEBUG)
-      internal_warning ("trap_handler: signal %d: signal not trapped", sig);
-#endif
-      SIGRETURN (0);
-    }
-
-  if ((sig >= NSIG) ||
-      (trap_list[sig] == (char *)DEFAULT_SIG) ||
-      (trap_list[sig] == (char *)IGNORE_SIG))
-    programming_error (_("trap_handler: bad signal %d"), sig);
-  else
-    {
-      oerrno = errno;
-#if defined (MUST_REINSTALL_SIGHANDLERS)
-#  if defined (JOB_CONTROL) && defined (SIGCHLD)
-      if (sig != SIGCHLD)
-#  endif /* JOB_CONTROL && SIGCHLD */
-      set_signal_handler (sig, trap_handler);
-#endif /* MUST_REINSTALL_SIGHANDLERS */
-
-      catch_flag = 1;
-      pending_traps[sig]++;
-
-      if (interrupt_immediately && this_shell_builtin && (this_shell_builtin == wait_builtin))
-       {
-         wait_signal_received = sig;
-         longjmp (wait_intr_buf, 1);
-       }
-
-      if (interrupt_immediately)
-       run_pending_traps ();
-
-      errno = oerrno;
-    }
-
-  SIGRETURN (0);
-}
-
-#if defined (JOB_CONTROL) && defined (SIGCHLD)
-
-#ifdef INCLUDE_UNUSED
-/* Make COMMAND_STRING be executed when SIGCHLD is caught. */
-void
-set_sigchld_trap (command_string)
-     char *command_string;
-{
-  set_signal (SIGCHLD, command_string);
-}
-#endif
-
-/* Make COMMAND_STRING be executed when SIGCHLD is caught iff SIGCHLD
-   is not already trapped.  IMPOSSIBLE_TRAP_HANDLER is used as a sentinel
-   to make sure that a SIGCHLD trap handler run via run_sigchld_trap can
-   reset the disposition to the default and not have the original signal
-   accidentally restored, undoing the user's command. */
-void
-maybe_set_sigchld_trap (command_string)
-     char *command_string;
-{
-  if ((sigmodes[SIGCHLD] & SIG_TRAPPED) == 0 && trap_list[SIGCHLD] == (char *)IMPOSSIBLE_TRAP_HANDLER)
-    set_signal (SIGCHLD, command_string);
-}
-
-/* Temporarily set the SIGCHLD trap string to IMPOSSIBLE_TRAP_HANDLER.  Used
-   as a sentinel in run_sigchld_trap and maybe_set_sigchld_trap to see whether
-   or not a SIGCHLD trap handler reset SIGCHLD disposition to the default. */
-void
-set_impossible_sigchld_trap ()
-{
-  restore_default_signal (SIGCHLD);
-  change_signal (SIGCHLD, (char *)IMPOSSIBLE_TRAP_HANDLER);
-  sigmodes[SIGCHLD] &= ~SIG_TRAPPED;   /* maybe_set_sigchld_trap checks this */
-}
-#endif /* JOB_CONTROL && SIGCHLD */
-
-void
-set_debug_trap (command)
-     char *command;
-{
-  set_signal (DEBUG_TRAP, command);
-}
-
-void
-set_error_trap (command)
-     char *command;
-{
-  set_signal (ERROR_TRAP, command);
-}
-
-void
-set_return_trap (command)
-     char *command;
-{
-  set_signal (RETURN_TRAP, command);
-}
-
-#ifdef INCLUDE_UNUSED
-void
-set_sigint_trap (command)
-     char *command;
-{
-  set_signal (SIGINT, command);
-}
-#endif
-
-/* Reset the SIGINT handler so that subshells that are doing `shellsy'
-   things, like waiting for command substitution or executing commands
-   in explicit subshells ( ( cmd ) ), can catch interrupts properly. */
-SigHandler *
-set_sigint_handler ()
-{
-  if (sigmodes[SIGINT] & SIG_HARD_IGNORE)
-    return ((SigHandler *)SIG_IGN);
-
-  else if (sigmodes[SIGINT] & SIG_IGNORED)
-    return ((SigHandler *)set_signal_handler (SIGINT, SIG_IGN)); /* XXX */
-
-  else if (sigmodes[SIGINT] & SIG_TRAPPED)
-    return ((SigHandler *)set_signal_handler (SIGINT, trap_handler));
-
-  /* The signal is not trapped, so set the handler to the shell's special
-     interrupt handler. */
-  else if (interactive)        /* XXX - was interactive_shell */
-    return (set_signal_handler (SIGINT, sigint_sighandler));
-  else
-    return (set_signal_handler (SIGINT, termsig_sighandler));
-}
-
-/* Return the correct handler for signal SIG according to the values in
-   sigmodes[SIG]. */
-SigHandler *
-trap_to_sighandler (sig)
-     int sig;
-{
-  if (sigmodes[sig] & (SIG_IGNORED|SIG_HARD_IGNORE))
-    return (SIG_IGN);
-  else if (sigmodes[sig] & SIG_TRAPPED)
-    return (trap_handler);
-  else
-    return (SIG_DFL);
-}
-
-/* Set SIG to call STRING as a command. */
-void
-set_signal (sig, string)
-     int sig;
-     char *string;
-{
-  if (SPECIAL_TRAP (sig))
-    {
-      change_signal (sig, savestring (string));
-      if (sig == EXIT_TRAP && interactive == 0)
-       initialize_terminating_signals ();
-      return;
-    }
-
-  /* A signal ignored on entry to the shell cannot be trapped or reset, but
-     no error is reported when attempting to do so.  -- Posix.2 */
-  if (sigmodes[sig] & SIG_HARD_IGNORE)
-    return;
-
-  /* Make sure we have original_signals[sig] if the signal has not yet
-     been trapped. */
-  if ((sigmodes[sig] & SIG_TRAPPED) == 0)
-    {
-      /* If we aren't sure of the original value, check it. */
-      if (original_signals[sig] == IMPOSSIBLE_TRAP_HANDLER)
-        GETORIGSIG (sig);
-      if (original_signals[sig] == SIG_IGN)
-       return;
-    }
-
-  /* Only change the system signal handler if SIG_NO_TRAP is not set.
-     The trap command string is changed in either case.  The shell signal
-     handlers for SIGINT and SIGCHLD run the user specified traps in an
-     environment in which it is safe to do so. */
-  if ((sigmodes[sig] & SIG_NO_TRAP) == 0)
-    {
-      set_signal_handler (sig, SIG_IGN);
-      change_signal (sig, savestring (string));
-      set_signal_handler (sig, trap_handler);
-    }
-  else
-    change_signal (sig, savestring (string));
-}
-
-static void
-free_trap_command (sig)
-     int sig;
-{
-  if ((sigmodes[sig] & SIG_TRAPPED) && trap_list[sig] &&
-      (trap_list[sig] != (char *)IGNORE_SIG) &&
-      (trap_list[sig] != (char *)DEFAULT_SIG) &&
-      (trap_list[sig] != (char *)IMPOSSIBLE_TRAP_HANDLER))
-    free (trap_list[sig]);
-}
-
-/* If SIG has a string assigned to it, get rid of it.  Then give it
-   VALUE. */
-static void
-change_signal (sig, value)
-     int sig;
-     char *value;
-{
-  if ((sigmodes[sig] & SIG_INPROGRESS) == 0)
-    free_trap_command (sig);
-  trap_list[sig] = value;
-
-  sigmodes[sig] |= SIG_TRAPPED;
-  if (value == (char *)IGNORE_SIG)
-    sigmodes[sig] |= SIG_IGNORED;
-  else
-    sigmodes[sig] &= ~SIG_IGNORED;
-  if (sigmodes[sig] & SIG_INPROGRESS)
-    sigmodes[sig] |= SIG_CHANGED;
-}
-
-static void
-get_original_signal (sig)
-     int sig;
-{
-  /* If we aren't sure the of the original value, then get it. */
-  if (original_signals[sig] == (SigHandler *)IMPOSSIBLE_TRAP_HANDLER)
-    GETORIGSIG (sig);
-}
-
-/* Restore the default action for SIG; i.e., the action the shell
-   would have taken before you used the trap command.  This is called
-   from trap_builtin (), which takes care to restore the handlers for
-   the signals the shell treats specially. */
-void
-restore_default_signal (sig)
-     int sig;
-{
-  if (SPECIAL_TRAP (sig))
-    {
-      if ((sig != DEBUG_TRAP && sig != ERROR_TRAP && sig != RETURN_TRAP) ||
-         (sigmodes[sig] & SIG_INPROGRESS) == 0)
-       free_trap_command (sig);
-      trap_list[sig] = (char *)NULL;
-      sigmodes[sig] &= ~SIG_TRAPPED;
-      if (sigmodes[sig] & SIG_INPROGRESS)
-       sigmodes[sig] |= SIG_CHANGED;
-      return;
-    }
-
-  GET_ORIGINAL_SIGNAL (sig);
-
-  /* A signal ignored on entry to the shell cannot be trapped or reset, but
-     no error is reported when attempting to do so.  Thanks Posix.2. */
-  if (sigmodes[sig] & SIG_HARD_IGNORE)
-    return;
-
-  /* If we aren't trapping this signal, don't bother doing anything else. */
-  if ((sigmodes[sig] & SIG_TRAPPED) == 0)
-    return;
-
-  /* Only change the signal handler for SIG if it allows it. */
-  if ((sigmodes[sig] & SIG_NO_TRAP) == 0)
-    set_signal_handler (sig, original_signals[sig]);
-
-  /* Change the trap command in either case. */
-  change_signal (sig, (char *)DEFAULT_SIG);
-
-  /* Mark the signal as no longer trapped. */
-  sigmodes[sig] &= ~SIG_TRAPPED;
-}
-
-/* Make this signal be ignored. */
-void
-ignore_signal (sig)
-     int sig;
-{
-  if (SPECIAL_TRAP (sig) && ((sigmodes[sig] & SIG_IGNORED) == 0))
-    {
-      change_signal (sig, (char *)IGNORE_SIG);
-      return;
-    }
-
-  GET_ORIGINAL_SIGNAL (sig);
-
-  /* A signal ignored on entry to the shell cannot be trapped or reset.
-     No error is reported when the user attempts to do so. */
-  if (sigmodes[sig] & SIG_HARD_IGNORE)
-    return;
-
-  /* If already trapped and ignored, no change necessary. */
-  if (sigmodes[sig] & SIG_IGNORED)
-    return;
-
-  /* Only change the signal handler for SIG if it allows it. */
-  if ((sigmodes[sig] & SIG_NO_TRAP) == 0)
-    set_signal_handler (sig, SIG_IGN);
-
-  /* Change the trap command in either case. */
-  change_signal (sig, (char *)IGNORE_SIG);
-}
-
-/* Handle the calling of "trap 0".  The only sticky situation is when
-   the command to be executed includes an "exit".  This is why we have
-   to provide our own place for top_level to jump to. */
-int
-run_exit_trap ()
-{
-  char *trap_command;
-  int code, function_code, retval;
-
-  trap_saved_exit_value = last_command_exit_value;
-  function_code = 0;
-
-  /* Run the trap only if signal 0 is trapped and not ignored, and we are not
-     currently running in the trap handler (call to exit in the list of
-     commands given to trap 0). */
-  if ((sigmodes[EXIT_TRAP] & SIG_TRAPPED) &&
-      (sigmodes[EXIT_TRAP] & (SIG_IGNORED|SIG_INPROGRESS)) == 0)
-    {
-      trap_command = savestring (trap_list[EXIT_TRAP]);
-      sigmodes[EXIT_TRAP] &= ~SIG_TRAPPED;
-      sigmodes[EXIT_TRAP] |= SIG_INPROGRESS;
-
-      retval = trap_saved_exit_value;
-      running_trap = 1;
-
-      code = setjmp (top_level);
-
-      /* If we're in a function, make sure return longjmps come here, too. */
-      if (return_catch_flag)
-       function_code = setjmp (return_catch);
-
-      if (code == 0 && function_code == 0)
-       {
-         reset_parser ();
-         parse_and_execute (trap_command, "exit trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE);
-       }
-      else if (code == ERREXIT)
-       retval = last_command_exit_value;
-      else if (code == EXITPROG)
-       retval = last_command_exit_value;
-      else if (function_code != 0)
-        retval = return_catch_value;
-      else
-       retval = trap_saved_exit_value;
-
-      running_trap = 0;
-      return retval;
-    }
-
-  return (trap_saved_exit_value);
-}
-
-void
-run_trap_cleanup (sig)
-     int sig;
-{
-  sigmodes[sig] &= ~(SIG_INPROGRESS|SIG_CHANGED);
-}
-
-/* Run a trap command for SIG.  SIG is one of the signals the shell treats
-   specially.  Returns the exit status of the executed trap command list. */
-static int
-_run_trap_internal (sig, tag)
-     int sig;
-     char *tag;
-{
-  char *trap_command, *old_trap;
-  int trap_exit_value, *token_state;
-  int save_return_catch_flag, function_code, flags;
-  procenv_t save_return_catch;
-
-  trap_exit_value = function_code = 0;
-  /* Run the trap only if SIG is trapped and not ignored, and we are not
-     currently executing in the trap handler. */
-  if ((sigmodes[sig] & SIG_TRAPPED) && ((sigmodes[sig] & SIG_IGNORED) == 0) &&
-      (trap_list[sig] != (char *)IMPOSSIBLE_TRAP_HANDLER) &&
-      ((sigmodes[sig] & SIG_INPROGRESS) == 0))
-    {
-      old_trap = trap_list[sig];
-      sigmodes[sig] |= SIG_INPROGRESS;
-      sigmodes[sig] &= ~SIG_CHANGED;           /* just to be sure */
-      trap_command =  savestring (old_trap);
-
-      running_trap = sig + 1;
-      trap_saved_exit_value = last_command_exit_value;
-
-      token_state = save_token_state ();
-
-      /* If we're in a function, make sure return longjmps come here, too. */
-      save_return_catch_flag = return_catch_flag;
-      if (return_catch_flag)
-       {
-         COPY_PROCENV (return_catch, save_return_catch);
-         function_code = setjmp (return_catch);
-       }
-
-      flags = SEVAL_NONINT|SEVAL_NOHIST;
-      if (sig != DEBUG_TRAP && sig != RETURN_TRAP && sig != ERROR_TRAP)
-       flags |= SEVAL_RESETLINE;
-      if (function_code == 0)
-       parse_and_execute (trap_command, tag, flags);
-
-      restore_token_state (token_state);
-      free (token_state);
-
-      trap_exit_value = last_command_exit_value;
-      last_command_exit_value = trap_saved_exit_value;
-      running_trap = 0;
-
-      sigmodes[sig] &= ~SIG_INPROGRESS;
-
-      if (sigmodes[sig] & SIG_CHANGED)
-       {
-#if 0
-         /* Special traps like EXIT, DEBUG, RETURN are handled explicitly in
-            the places where they can be changed using unwind-protects.  For
-            example, look at execute_cmd.c:execute_function(). */
-         if (SPECIAL_TRAP (sig) == 0)
-#endif
-           free (old_trap);
-         sigmodes[sig] &= ~SIG_CHANGED;
-       }
-
-      if (save_return_catch_flag)
-       {
-         return_catch_flag = save_return_catch_flag;
-         return_catch_value = trap_exit_value;
-         COPY_PROCENV (save_return_catch, return_catch);
-         if (function_code)
-           longjmp (return_catch, 1);
-       }
-    }
-
-  return trap_exit_value;
-}
-
-int
-run_debug_trap ()
-{
-  int trap_exit_value;
-  pid_t save_pgrp;
-
-  /* XXX - question:  should the DEBUG trap inherit the RETURN trap? */
-  trap_exit_value = 0;
-  if ((sigmodes[DEBUG_TRAP] & SIG_TRAPPED) && ((sigmodes[DEBUG_TRAP] & SIG_IGNORED) == 0) && ((sigmodes[DEBUG_TRAP] & SIG_INPROGRESS) == 0))
-    {
-#if defined (JOB_CONTROL)
-      save_pgrp = pipeline_pgrp;
-itrace("run_debug_trap: save_pgrp = %d pipeline_pgrp -> 0", save_pgrp);
-      pipeline_pgrp = 0;
-      save_pipeline (1);
-      stop_making_children ();
-#  if defined (PGRP_PIPE)
-      close_pgrp_pipe ();
-#  endif
-#endif
-      trap_exit_value = _run_trap_internal (DEBUG_TRAP, "debug trap");
-#if defined (JOB_CONTROL)
-      pipeline_pgrp = save_pgrp;
-      restore_pipeline (1);
-itrace("run_debug_trap: after restore_pipeline");
-if (pipeline_pgrp > 0)
-  {
-itrace("run_debug_trap: pipeline_pgrp = %d give_terminal_to (%d, 1)", pipeline_pgrp, pipeline_pgrp);
-      give_terminal_to (pipeline_pgrp, 1);
-  }
-      notify_and_cleanup ();
-#endif
-      
-#if defined (DEBUGGER)
-      /* If we're in the debugger and the DEBUG trap returns 2 while we're in
-        a function or sourced script, we force a `return'. */
-      if (debugging_mode && trap_exit_value == 2 && return_catch_flag)
-       {
-         return_catch_value = trap_exit_value;
-         longjmp (return_catch, 1);
-       }
-#endif
-    }
-  return trap_exit_value;
-}
-
-void
-run_error_trap ()
-{
-  if ((sigmodes[ERROR_TRAP] & SIG_TRAPPED) && ((sigmodes[ERROR_TRAP] & SIG_IGNORED) == 0) && (sigmodes[ERROR_TRAP] & SIG_INPROGRESS) == 0)
-    _run_trap_internal (ERROR_TRAP, "error trap");
-}
-
-void
-run_return_trap ()
-{
-  int old_exit_value;
-
-#if 0
-  if ((sigmodes[DEBUG_TRAP] & SIG_TRAPPED) && (sigmodes[DEBUG_TRAP] & SIG_INPROGRESS))
-    return;
-#endif
-
-  if ((sigmodes[RETURN_TRAP] & SIG_TRAPPED) && ((sigmodes[RETURN_TRAP] & SIG_IGNORED) == 0) && (sigmodes[RETURN_TRAP] & SIG_INPROGRESS) == 0)
-    {
-      old_exit_value = last_command_exit_value;
-      _run_trap_internal (RETURN_TRAP, "return trap");
-      last_command_exit_value = old_exit_value;
-    }
-}
-
-/* Run a trap set on SIGINT.  This is called from throw_to_top_level (), and
-   declared here to localize the trap functions. */
-void
-run_interrupt_trap ()
-{
-  _run_trap_internal (SIGINT, "interrupt trap");
-}
-
-#ifdef INCLUDE_UNUSED
-/* Free all the allocated strings in the list of traps and reset the trap
-   values to the default. */
-void
-free_trap_strings ()
-{
-  register int i;
-
-  for (i = 0; i < BASH_NSIG; i++)
-    {
-      free_trap_command (i);
-      trap_list[i] = (char *)DEFAULT_SIG;
-      sigmodes[i] &= ~SIG_TRAPPED;
-    }
-  trap_list[DEBUG_TRAP] = trap_list[EXIT_TRAP] = trap_list[ERROR_TRAP] = trap_list[RETURN_TRAP] = (char *)NULL;
-}
-#endif
-
-/* Reset the handler for SIG to the original value. */
-static void
-reset_signal (sig)
-     int sig;
-{
-  set_signal_handler (sig, original_signals[sig]);
-  sigmodes[sig] &= ~SIG_TRAPPED;
-}
-
-/* Set the handler signal SIG to the original and free any trap
-   command associated with it. */
-static void
-restore_signal (sig)
-     int sig;
-{
-  set_signal_handler (sig, original_signals[sig]);
-  change_signal (sig, (char *)DEFAULT_SIG);
-  sigmodes[sig] &= ~SIG_TRAPPED;
-}
-
-static void
-reset_or_restore_signal_handlers (reset)
-     sh_resetsig_func_t *reset;
-{
-  register int i;
-
-  /* Take care of the exit trap first */
-  if (sigmodes[EXIT_TRAP] & SIG_TRAPPED)
-    {
-      sigmodes[EXIT_TRAP] &= ~SIG_TRAPPED;
-      if (reset != reset_signal)
-       {
-         free_trap_command (EXIT_TRAP);
-         trap_list[EXIT_TRAP] = (char *)NULL;
-       }
-    }
-
-  for (i = 1; i < NSIG; i++)
-    {
-      if (sigmodes[i] & SIG_TRAPPED)
-       {
-         if (trap_list[i] == (char *)IGNORE_SIG)
-           set_signal_handler (i, SIG_IGN);
-         else
-           (*reset) (i);
-       }
-      else if (sigmodes[i] & SIG_SPECIAL)
-       (*reset) (i);
-    }
-
-  /* Command substitution and other child processes don't inherit the
-     debug, error, or return traps.  If we're in the debugger, and the
-     `functrace' or `errtrace' options have been set, then let command
-     substitutions inherit them.  Let command substitution inherit the
-     RETURN trap if we're in the debugger and tracing functions. */
-  if (function_trace_mode == 0)
-    {
-      sigmodes[DEBUG_TRAP] &= ~SIG_TRAPPED;
-      sigmodes[RETURN_TRAP] &= ~SIG_TRAPPED;
-    }
-  if (error_trace_mode == 0)
-    sigmodes[ERROR_TRAP] &= ~SIG_TRAPPED;
-}
-
-/* Reset trapped signals to their original values, but don't free the
-   trap strings.  Called by the command substitution code. */
-void
-reset_signal_handlers ()
-{
-  reset_or_restore_signal_handlers (reset_signal);
-}
-
-/* Reset all trapped signals to their original values.  Signals set to be
-   ignored with trap '' SIGNAL should be ignored, so we make sure that they
-   are.  Called by child processes after they are forked. */
-void
-restore_original_signals ()
-{
-  reset_or_restore_signal_handlers (restore_signal);
-}
-
-/* If a trap handler exists for signal SIG, then call it; otherwise just
-   return failure. */
-int
-maybe_call_trap_handler (sig)
-     int sig;
-{
-  /* Call the trap handler for SIG if the signal is trapped and not ignored. */
-  if ((sigmodes[sig] & SIG_TRAPPED) && ((sigmodes[sig] & SIG_IGNORED) == 0))
-    {
-      switch (sig)
-       {
-       case SIGINT:
-         run_interrupt_trap ();
-         break;
-       case EXIT_TRAP:
-         run_exit_trap ();
-         break;
-       case DEBUG_TRAP:
-         run_debug_trap ();
-         break;
-       case ERROR_TRAP:
-         run_error_trap ();
-         break;
-       default:
-         trap_handler (sig);
-         break;
-       }
-      return (1);
-    }
-  else
-    return (0);
-}
-
-int
-signal_is_trapped (sig)
-     int sig;
-{
-  return (sigmodes[sig] & SIG_TRAPPED);
-}
-
-int
-signal_is_special (sig)
-     int sig;
-{
-  return (sigmodes[sig] & SIG_SPECIAL);
-}
-
-int
-signal_is_ignored (sig)
-     int sig;
-{
-  return (sigmodes[sig] & SIG_IGNORED);
-}
-
-void
-set_signal_ignored (sig)
-     int sig;
-{
-  sigmodes[sig] |= SIG_HARD_IGNORE;
-  original_signals[sig] = SIG_IGN;
-}
-
-int
-signal_in_progress (sig)
-     int sig;
-{
-  return (sigmodes[sig] & SIG_INPROGRESS);
-}
diff --git a/trap.c~ b/trap.c~
deleted file mode 100644 (file)
index ef938d5..0000000
--- a/trap.c~
+++ /dev/null
@@ -1,1063 +0,0 @@
-/* trap.c -- Not the trap command, but useful functions for manipulating
-   those objects.  The trap command is in builtins/trap.def. */
-
-/* Copyright (C) 1987-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/>.
-*/
-
-#include "config.h"
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include "bashtypes.h"
-#include "bashansi.h"
-
-#include <stdio.h>
-#include <errno.h>
-
-#include "bashintl.h"
-
-#include "trap.h"
-
-#include "shell.h"
-#include "flags.h"
-#include "input.h"     /* for save_token_state, restore_token_state */
-#include "jobs.h"
-#include "signames.h"
-#include "builtins.h"
-#include "builtins/common.h"
-#include "builtins/builtext.h"
-
-#ifndef errno
-extern int errno;
-#endif
-
-/* Flags which describe the current handling state of a signal. */
-#define SIG_INHERITED   0x0    /* Value inherited from parent. */
-#define SIG_TRAPPED     0x1    /* Currently trapped. */
-#define SIG_HARD_IGNORE 0x2    /* Signal was ignored on shell entry. */
-#define SIG_SPECIAL     0x4    /* Treat this signal specially. */
-#define SIG_NO_TRAP     0x8    /* Signal cannot be trapped. */
-#define SIG_INPROGRESS 0x10    /* Signal handler currently executing. */
-#define SIG_CHANGED    0x20    /* Trap value changed in trap handler. */
-#define SIG_IGNORED    0x40    /* The signal is currently being ignored. */
-
-#define SPECIAL_TRAP(s)        ((s) == EXIT_TRAP || (s) == DEBUG_TRAP || (s) == ERROR_TRAP || (s) == RETURN_TRAP)
-
-/* An array of such flags, one for each signal, describing what the
-   shell will do with a signal.  DEBUG_TRAP == NSIG; some code below
-   assumes this. */
-static int sigmodes[BASH_NSIG];
-
-static void free_trap_command __P((int));
-static void change_signal __P((int, char *));
-
-static void get_original_signal __P((int));
-
-static int _run_trap_internal __P((int, char *));
-
-static void free_trap_string __P((int));
-static void reset_signal __P((int));
-static void restore_signal __P((int));
-static void reset_or_restore_signal_handlers __P((sh_resetsig_func_t *));
-
-/* Variables used here but defined in other files. */
-extern int last_command_exit_value;
-extern int line_number;
-
-extern char *this_command_name;
-extern sh_builtin_func_t *this_shell_builtin;
-extern procenv_t wait_intr_buf;
-extern int return_catch_flag, return_catch_value;
-extern int subshell_level;
-extern WORD_LIST *subst_assign_varlist;
-
-/* The list of things to do originally, before we started trapping. */
-SigHandler *original_signals[NSIG];
-
-/* For each signal, a slot for a string, which is a command to be
-   executed when that signal is recieved.  The slot can also contain
-   DEFAULT_SIG, which means do whatever you were going to do before
-   you were so rudely interrupted, or IGNORE_SIG, which says ignore
-   this signal. */
-char *trap_list[BASH_NSIG];
-
-/* A bitmap of signals received for which we have trap handlers. */
-int pending_traps[NSIG];
-
-/* Set to the number of the signal we're running the trap for + 1.
-   Used in execute_cmd.c and builtins/common.c to clean up when
-   parse_and_execute does not return normally after executing the
-   trap command (e.g., when `return' is executed in the trap command). */
-int running_trap;
-
-/* Set to last_command_exit_value before running a trap. */
-int trap_saved_exit_value;
-
-/* The (trapped) signal received while executing in the `wait' builtin */
-int wait_signal_received;
-
-/* A value which can never be the target of a trap handler. */
-#define IMPOSSIBLE_TRAP_HANDLER (SigHandler *)initialize_traps
-
-#define GETORIGSIG(sig) \
-  do { \
-    original_signals[sig] = (SigHandler *)set_signal_handler (sig, SIG_DFL); \
-    set_signal_handler (sig, original_signals[sig]); \
-    if (original_signals[sig] == SIG_IGN) \
-      sigmodes[sig] |= SIG_HARD_IGNORE; \
-  } while (0)
-
-#define GET_ORIGINAL_SIGNAL(sig) \
-  if (sig && sig < NSIG && original_signals[sig] == IMPOSSIBLE_TRAP_HANDLER) \
-    GETORIGSIG(sig)
-
-void
-initialize_traps ()
-{
-  register int i;
-
-  initialize_signames();
-
-  trap_list[EXIT_TRAP] = trap_list[DEBUG_TRAP] = trap_list[ERROR_TRAP] = trap_list[RETURN_TRAP] = (char *)NULL;
-  sigmodes[EXIT_TRAP] = sigmodes[DEBUG_TRAP] = sigmodes[ERROR_TRAP] = sigmodes[RETURN_TRAP] = SIG_INHERITED;
-  original_signals[EXIT_TRAP] = IMPOSSIBLE_TRAP_HANDLER;
-
-  for (i = 1; i < NSIG; i++)
-    {
-      pending_traps[i] = 0;
-      trap_list[i] = (char *)DEFAULT_SIG;
-      sigmodes[i] = SIG_INHERITED;
-      original_signals[i] = IMPOSSIBLE_TRAP_HANDLER;
-    }
-
-  /* Show which signals are treated specially by the shell. */
-#if defined (SIGCHLD)
-  GETORIGSIG (SIGCHLD);
-  sigmodes[SIGCHLD] |= (SIG_SPECIAL | SIG_NO_TRAP);
-#endif /* SIGCHLD */
-
-  GETORIGSIG (SIGINT);
-  sigmodes[SIGINT] |= SIG_SPECIAL;
-
-#if defined (__BEOS__)
-  /* BeOS sets SIGINT to SIG_IGN! */
-  original_signals[SIGINT] = SIG_DFL;
-  sigmodes[SIGINT] &= ~SIG_HARD_IGNORE;
-#endif
-
-  GETORIGSIG (SIGQUIT);
-  sigmodes[SIGQUIT] |= SIG_SPECIAL;
-
-  if (interactive)
-    {
-      GETORIGSIG (SIGTERM);
-      sigmodes[SIGTERM] |= SIG_SPECIAL;
-    }
-}
-
-#ifdef INCLUDE_UNUSED
-/* Return a printable representation of the trap handler for SIG. */
-static char *
-trap_handler_string (sig)
-     int sig;
-{
-  if (trap_list[sig] == (char *)DEFAULT_SIG)
-    return "DEFAULT_SIG";
-  else if (trap_list[sig] == (char *)IGNORE_SIG)
-    return "IGNORE_SIG";
-  else if (trap_list[sig] == (char *)IMPOSSIBLE_TRAP_HANDLER)
-    return "IMPOSSIBLE_TRAP_HANDLER";
-  else if (trap_list[sig])
-    return trap_list[sig];
-  else
-    return "NULL";
-}
-#endif
-
-/* Return the print name of this signal. */
-char *
-signal_name (sig)
-     int sig;
-{
-  char *ret;
-
-  /* on cygwin32, signal_names[sig] could be null */
-  ret = (sig >= BASH_NSIG || sig < 0 || signal_names[sig] == NULL)
-       ? _("invalid signal number")
-       : signal_names[sig];
-
-  return ret;
-}
-
-/* Turn a string into a signal number, or a number into
-   a signal number.  If STRING is "2", "SIGINT", or "INT",
-   then (int)2 is returned.  Return NO_SIG if STRING doesn't
-   contain a valid signal descriptor. */
-int
-decode_signal (string, flags)
-     char *string;
-     int flags;
-{
-  intmax_t sig;
-  char *name;
-
-  if (legal_number (string, &sig))
-    return ((sig >= 0 && sig < NSIG) ? (int)sig : NO_SIG);
-
-  /* A leading `SIG' may be omitted. */
-  for (sig = 0; sig < BASH_NSIG; sig++)
-    {
-      name = signal_names[sig];
-      if (name == 0 || name[0] == '\0')
-       continue;
-
-      /* Check name without the SIG prefix first case sensitivly or
-        insensitively depending on whether flags includes DSIG_NOCASE */
-      if (STREQN (name, "SIG", 3))
-       {
-         name += 3;
-
-         if ((flags & DSIG_NOCASE) && strcasecmp (string, name) == 0)
-           return ((int)sig);
-         else if ((flags & DSIG_NOCASE) == 0 && strcmp (string, name) == 0)
-           return ((int)sig);
-         /* If we can't use the `SIG' prefix to match, punt on this
-            name now. */
-         else if ((flags & DSIG_SIGPREFIX) == 0)
-           continue;
-       }
-
-      /* Check name with SIG prefix case sensitively or insensitively
-        depending on whether flags includes DSIG_NOCASE */
-      name = signal_names[sig];
-      if ((flags & DSIG_NOCASE) && strcasecmp (string, name) == 0)
-       return ((int)sig);
-      else if ((flags & DSIG_NOCASE) == 0 && strcmp (string, name) == 0)
-       return ((int)sig);
-    }
-
-  return (NO_SIG);
-}
-
-/* Non-zero when we catch a trapped signal. */
-static int catch_flag;
-
-void
-run_pending_traps ()
-{
-  register int sig;
-  int old_exit_value, *token_state;
-  WORD_LIST *save_subst_varlist;
-
-  if (catch_flag == 0)         /* simple optimization */
-    return;
-
-  catch_flag = 0;
-
-  /* Preserve $? when running trap. */
-  old_exit_value = last_command_exit_value;
-
-  for (sig = 1; sig < NSIG; sig++)
-    {
-      /* XXX this could be made into a counter by using
-        while (pending_traps[sig]--) instead of the if statement. */
-      if (pending_traps[sig])
-       {
-#if defined (HAVE_POSIX_SIGNALS)
-         sigset_t set, oset;
-
-         sigemptyset (&set);
-         sigemptyset (&oset);
-
-         sigaddset (&set, sig);
-         sigprocmask (SIG_BLOCK, &set, &oset);
-#else
-#  if defined (HAVE_BSD_SIGNALS)
-         int oldmask = sigblock (sigmask (sig));
-#  endif
-#endif /* HAVE_POSIX_SIGNALS */
-
-         if (sig == SIGINT)
-           {
-             run_interrupt_trap ();
-             CLRINTERRUPT;
-           }
-#if defined (JOB_CONTROL) && defined (SIGCHLD)
-         else if (sig == SIGCHLD &&
-                  trap_list[SIGCHLD] != (char *)IMPOSSIBLE_TRAP_HANDLER &&
-                  (sigmodes[SIGCHLD] & SIG_INPROGRESS) == 0)
-           {
-             run_sigchld_trap (pending_traps[sig]);    /* use as counter */
-           }
-#endif
-         else if (trap_list[sig] == (char *)DEFAULT_SIG ||
-                  trap_list[sig] == (char *)IGNORE_SIG ||
-                  trap_list[sig] == (char *)IMPOSSIBLE_TRAP_HANDLER)
-           {
-             /* This is possible due to a race condition.  Say a bash
-                process has SIGTERM trapped.  A subshell is spawned
-                using { list; } & and the parent does something and kills
-                the subshell with SIGTERM.  It's possible for the subshell
-                to set pending_traps[SIGTERM] to 1 before the code in
-                execute_cmd.c eventually calls restore_original_signals
-                to reset the SIGTERM signal handler in the subshell.  The
-                next time run_pending_traps is called, pending_traps[SIGTERM]
-                will be 1, but the trap handler in trap_list[SIGTERM] will
-                be invalid (probably DEFAULT_SIG, but it could be IGNORE_SIG).
-                Unless we catch this, the subshell will dump core when
-                trap_list[SIGTERM] == DEFAULT_SIG, because DEFAULT_SIG is
-                usually 0x0. */
-             internal_warning (_("run_pending_traps: bad value in trap_list[%d]: %p"),
-                               sig, trap_list[sig]);
-             if (trap_list[sig] == (char *)DEFAULT_SIG)
-               {
-                 internal_warning (_("run_pending_traps: signal handler is SIG_DFL, resending %d (%s) to myself"), sig, signal_name (sig));
-                 kill (getpid (), sig);
-               }
-           }
-         else
-           {
-             token_state = save_token_state ();
-             save_subst_varlist = subst_assign_varlist;
-             subst_assign_varlist = 0;
-
-             parse_and_execute (savestring (trap_list[sig]), "trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE);
-             restore_token_state (token_state);
-             free (token_state);
-
-             subst_assign_varlist = save_subst_varlist;
-           }
-
-         pending_traps[sig] = 0;
-
-#if defined (HAVE_POSIX_SIGNALS)
-         sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
-#else
-#  if defined (HAVE_BSD_SIGNALS)
-         sigsetmask (oldmask);
-#  endif
-#endif /* POSIX_VERSION */
-       }
-    }
-
-  last_command_exit_value = old_exit_value;
-}
-
-sighandler
-trap_handler (sig)
-     int sig;
-{
-  int oerrno;
-
-  if ((sigmodes[sig] & SIG_TRAPPED) == 0)
-    {
-#if defined (DEBUG)
-      internal_warning ("trap_handler: signal %d: signal not trapped", sig);
-#endif
-      SIGRETURN (0);
-    }
-
-  if ((sig >= NSIG) ||
-      (trap_list[sig] == (char *)DEFAULT_SIG) ||
-      (trap_list[sig] == (char *)IGNORE_SIG))
-    programming_error (_("trap_handler: bad signal %d"), sig);
-  else
-    {
-      oerrno = errno;
-#if defined (MUST_REINSTALL_SIGHANDLERS)
-#  if defined (JOB_CONTROL) && defined (SIGCHLD)
-      if (sig != SIGCHLD)
-#  endif /* JOB_CONTROL && SIGCHLD */
-      set_signal_handler (sig, trap_handler);
-#endif /* MUST_REINSTALL_SIGHANDLERS */
-
-      catch_flag = 1;
-      pending_traps[sig]++;
-
-      if (interrupt_immediately && this_shell_builtin && (this_shell_builtin == wait_builtin))
-       {
-         wait_signal_received = sig;
-         longjmp (wait_intr_buf, 1);
-       }
-
-      if (interrupt_immediately)
-       run_pending_traps ();
-
-      errno = oerrno;
-    }
-
-  SIGRETURN (0);
-}
-
-#if defined (JOB_CONTROL) && defined (SIGCHLD)
-
-#ifdef INCLUDE_UNUSED
-/* Make COMMAND_STRING be executed when SIGCHLD is caught. */
-void
-set_sigchld_trap (command_string)
-     char *command_string;
-{
-  set_signal (SIGCHLD, command_string);
-}
-#endif
-
-/* Make COMMAND_STRING be executed when SIGCHLD is caught iff SIGCHLD
-   is not already trapped.  IMPOSSIBLE_TRAP_HANDLER is used as a sentinel
-   to make sure that a SIGCHLD trap handler run via run_sigchld_trap can
-   reset the disposition to the default and not have the original signal
-   accidentally restored, undoing the user's command. */
-void
-maybe_set_sigchld_trap (command_string)
-     char *command_string;
-{
-  if ((sigmodes[SIGCHLD] & SIG_TRAPPED) == 0 && trap_list[SIGCHLD] == (char *)IMPOSSIBLE_TRAP_HANDLER)
-    set_signal (SIGCHLD, command_string);
-}
-
-/* Temporarily set the SIGCHLD trap string to IMPOSSIBLE_TRAP_HANDLER.  Used
-   as a sentinel in run_sigchld_trap and maybe_set_sigchld_trap to see whether
-   or not a SIGCHLD trap handler reset SIGCHLD disposition to the default. */
-void
-set_impossible_sigchld_trap ()
-{
-  restore_default_signal (SIGCHLD);
-  change_signal (SIGCHLD, (char *)IMPOSSIBLE_TRAP_HANDLER);
-  sigmodes[SIGCHLD] &= ~SIG_TRAPPED;   /* maybe_set_sigchld_trap checks this */
-}
-#endif /* JOB_CONTROL && SIGCHLD */
-
-void
-set_debug_trap (command)
-     char *command;
-{
-  set_signal (DEBUG_TRAP, command);
-}
-
-void
-set_error_trap (command)
-     char *command;
-{
-  set_signal (ERROR_TRAP, command);
-}
-
-void
-set_return_trap (command)
-     char *command;
-{
-  set_signal (RETURN_TRAP, command);
-}
-
-#ifdef INCLUDE_UNUSED
-void
-set_sigint_trap (command)
-     char *command;
-{
-  set_signal (SIGINT, command);
-}
-#endif
-
-/* Reset the SIGINT handler so that subshells that are doing `shellsy'
-   things, like waiting for command substitution or executing commands
-   in explicit subshells ( ( cmd ) ), can catch interrupts properly. */
-SigHandler *
-set_sigint_handler ()
-{
-  if (sigmodes[SIGINT] & SIG_HARD_IGNORE)
-    return ((SigHandler *)SIG_IGN);
-
-  else if (sigmodes[SIGINT] & SIG_IGNORED)
-    return ((SigHandler *)set_signal_handler (SIGINT, SIG_IGN)); /* XXX */
-
-  else if (sigmodes[SIGINT] & SIG_TRAPPED)
-    return ((SigHandler *)set_signal_handler (SIGINT, trap_handler));
-
-  /* The signal is not trapped, so set the handler to the shell's special
-     interrupt handler. */
-  else if (interactive)        /* XXX - was interactive_shell */
-    return (set_signal_handler (SIGINT, sigint_sighandler));
-  else
-    return (set_signal_handler (SIGINT, termsig_sighandler));
-}
-
-/* Return the correct handler for signal SIG according to the values in
-   sigmodes[SIG]. */
-SigHandler *
-trap_to_sighandler (sig)
-     int sig;
-{
-  if (sigmodes[sig] & (SIG_IGNORED|SIG_HARD_IGNORE))
-    return (SIG_IGN);
-  else if (sigmodes[sig] & SIG_TRAPPED)
-    return (trap_handler);
-  else
-    return (SIG_DFL);
-}
-
-/* Set SIG to call STRING as a command. */
-void
-set_signal (sig, string)
-     int sig;
-     char *string;
-{
-  if (SPECIAL_TRAP (sig))
-    {
-      change_signal (sig, savestring (string));
-      if (sig == EXIT_TRAP && interactive == 0)
-       initialize_terminating_signals ();
-      return;
-    }
-
-  /* A signal ignored on entry to the shell cannot be trapped or reset, but
-     no error is reported when attempting to do so.  -- Posix.2 */
-  if (sigmodes[sig] & SIG_HARD_IGNORE)
-    return;
-
-  /* Make sure we have original_signals[sig] if the signal has not yet
-     been trapped. */
-  if ((sigmodes[sig] & SIG_TRAPPED) == 0)
-    {
-      /* If we aren't sure of the original value, check it. */
-      if (original_signals[sig] == IMPOSSIBLE_TRAP_HANDLER)
-        GETORIGSIG (sig);
-      if (original_signals[sig] == SIG_IGN)
-       return;
-    }
-
-  /* Only change the system signal handler if SIG_NO_TRAP is not set.
-     The trap command string is changed in either case.  The shell signal
-     handlers for SIGINT and SIGCHLD run the user specified traps in an
-     environment in which it is safe to do so. */
-  if ((sigmodes[sig] & SIG_NO_TRAP) == 0)
-    {
-      set_signal_handler (sig, SIG_IGN);
-      change_signal (sig, savestring (string));
-      set_signal_handler (sig, trap_handler);
-    }
-  else
-    change_signal (sig, savestring (string));
-}
-
-static void
-free_trap_command (sig)
-     int sig;
-{
-  if ((sigmodes[sig] & SIG_TRAPPED) && trap_list[sig] &&
-      (trap_list[sig] != (char *)IGNORE_SIG) &&
-      (trap_list[sig] != (char *)DEFAULT_SIG) &&
-      (trap_list[sig] != (char *)IMPOSSIBLE_TRAP_HANDLER))
-    free (trap_list[sig]);
-}
-
-/* If SIG has a string assigned to it, get rid of it.  Then give it
-   VALUE. */
-static void
-change_signal (sig, value)
-     int sig;
-     char *value;
-{
-  if ((sigmodes[sig] & SIG_INPROGRESS) == 0)
-    free_trap_command (sig);
-  trap_list[sig] = value;
-
-  sigmodes[sig] |= SIG_TRAPPED;
-  if (value == (char *)IGNORE_SIG)
-    sigmodes[sig] |= SIG_IGNORED;
-  else
-    sigmodes[sig] &= ~SIG_IGNORED;
-  if (sigmodes[sig] & SIG_INPROGRESS)
-    sigmodes[sig] |= SIG_CHANGED;
-}
-
-static void
-get_original_signal (sig)
-     int sig;
-{
-  /* If we aren't sure the of the original value, then get it. */
-  if (sig > 0 && sig < NSIG && original_signals[sig] == (SigHandler *)IMPOSSIBLE_TRAP_HANDLER)
-    GETORIGSIG (sig);
-}
-
-/* Restore the default action for SIG; i.e., the action the shell
-   would have taken before you used the trap command.  This is called
-   from trap_builtin (), which takes care to restore the handlers for
-   the signals the shell treats specially. */
-void
-restore_default_signal (sig)
-     int sig;
-{
-  if (SPECIAL_TRAP (sig))
-    {
-      if ((sig != DEBUG_TRAP && sig != ERROR_TRAP && sig != RETURN_TRAP) ||
-         (sigmodes[sig] & SIG_INPROGRESS) == 0)
-       free_trap_command (sig);
-      trap_list[sig] = (char *)NULL;
-      sigmodes[sig] &= ~SIG_TRAPPED;
-      if (sigmodes[sig] & SIG_INPROGRESS)
-       sigmodes[sig] |= SIG_CHANGED;
-      return;
-    }
-
-  GET_ORIGINAL_SIGNAL (sig);
-
-  /* A signal ignored on entry to the shell cannot be trapped or reset, but
-     no error is reported when attempting to do so.  Thanks Posix.2. */
-  if (sigmodes[sig] & SIG_HARD_IGNORE)
-    return;
-
-  /* If we aren't trapping this signal, don't bother doing anything else. */
-  if ((sigmodes[sig] & SIG_TRAPPED) == 0)
-    return;
-
-  /* Only change the signal handler for SIG if it allows it. */
-  if ((sigmodes[sig] & SIG_NO_TRAP) == 0)
-    set_signal_handler (sig, original_signals[sig]);
-
-  /* Change the trap command in either case. */
-  change_signal (sig, (char *)DEFAULT_SIG);
-
-  /* Mark the signal as no longer trapped. */
-  sigmodes[sig] &= ~SIG_TRAPPED;
-}
-
-/* Make this signal be ignored. */
-void
-ignore_signal (sig)
-     int sig;
-{
-  if (SPECIAL_TRAP (sig) && ((sigmodes[sig] & SIG_IGNORED) == 0))
-    {
-      change_signal (sig, (char *)IGNORE_SIG);
-      return;
-    }
-
-  GET_ORIGINAL_SIGNAL (sig);
-
-  /* A signal ignored on entry to the shell cannot be trapped or reset.
-     No error is reported when the user attempts to do so. */
-  if (sigmodes[sig] & SIG_HARD_IGNORE)
-    return;
-
-  /* If already trapped and ignored, no change necessary. */
-  if (sigmodes[sig] & SIG_IGNORED)
-    return;
-
-  /* Only change the signal handler for SIG if it allows it. */
-  if ((sigmodes[sig] & SIG_NO_TRAP) == 0)
-    set_signal_handler (sig, SIG_IGN);
-
-  /* Change the trap command in either case. */
-  change_signal (sig, (char *)IGNORE_SIG);
-}
-
-/* Handle the calling of "trap 0".  The only sticky situation is when
-   the command to be executed includes an "exit".  This is why we have
-   to provide our own place for top_level to jump to. */
-int
-run_exit_trap ()
-{
-  char *trap_command;
-  int code, function_code, retval;
-
-  trap_saved_exit_value = last_command_exit_value;
-  function_code = 0;
-
-  /* Run the trap only if signal 0 is trapped and not ignored, and we are not
-     currently running in the trap handler (call to exit in the list of
-     commands given to trap 0). */
-  if ((sigmodes[EXIT_TRAP] & SIG_TRAPPED) &&
-      (sigmodes[EXIT_TRAP] & (SIG_IGNORED|SIG_INPROGRESS)) == 0)
-    {
-      trap_command = savestring (trap_list[EXIT_TRAP]);
-      sigmodes[EXIT_TRAP] &= ~SIG_TRAPPED;
-      sigmodes[EXIT_TRAP] |= SIG_INPROGRESS;
-
-      retval = trap_saved_exit_value;
-      running_trap = 1;
-
-      code = setjmp (top_level);
-
-      /* If we're in a function, make sure return longjmps come here, too. */
-      if (return_catch_flag)
-       function_code = setjmp (return_catch);
-
-      if (code == 0 && function_code == 0)
-       {
-         reset_parser ();
-         parse_and_execute (trap_command, "exit trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE);
-       }
-      else if (code == ERREXIT)
-       retval = last_command_exit_value;
-      else if (code == EXITPROG)
-       retval = last_command_exit_value;
-      else if (function_code != 0)
-        retval = return_catch_value;
-      else
-       retval = trap_saved_exit_value;
-
-      running_trap = 0;
-      return retval;
-    }
-
-  return (trap_saved_exit_value);
-}
-
-void
-run_trap_cleanup (sig)
-     int sig;
-{
-  sigmodes[sig] &= ~(SIG_INPROGRESS|SIG_CHANGED);
-}
-
-/* Run a trap command for SIG.  SIG is one of the signals the shell treats
-   specially.  Returns the exit status of the executed trap command list. */
-static int
-_run_trap_internal (sig, tag)
-     int sig;
-     char *tag;
-{
-  char *trap_command, *old_trap;
-  int trap_exit_value, *token_state;
-  int save_return_catch_flag, function_code, flags;
-  procenv_t save_return_catch;
-  WORD_LIST *save_subst_varlist;
-
-  trap_exit_value = function_code = 0;
-  /* Run the trap only if SIG is trapped and not ignored, and we are not
-     currently executing in the trap handler. */
-  if ((sigmodes[sig] & SIG_TRAPPED) && ((sigmodes[sig] & SIG_IGNORED) == 0) &&
-      (trap_list[sig] != (char *)IMPOSSIBLE_TRAP_HANDLER) &&
-      ((sigmodes[sig] & SIG_INPROGRESS) == 0))
-    {
-      old_trap = trap_list[sig];
-      sigmodes[sig] |= SIG_INPROGRESS;
-      sigmodes[sig] &= ~SIG_CHANGED;           /* just to be sure */
-      trap_command =  savestring (old_trap);
-
-      running_trap = sig + 1;
-      trap_saved_exit_value = last_command_exit_value;
-
-      token_state = save_token_state ();
-      save_subst_varlist = subst_assign_varlist;
-      subst_assign_varlist = 0;
-
-      /* If we're in a function, make sure return longjmps come here, too. */
-      save_return_catch_flag = return_catch_flag;
-      if (return_catch_flag)
-       {
-         COPY_PROCENV (return_catch, save_return_catch);
-         function_code = setjmp (return_catch);
-       }
-
-      flags = SEVAL_NONINT|SEVAL_NOHIST;
-      if (sig != DEBUG_TRAP && sig != RETURN_TRAP && sig != ERROR_TRAP)
-       flags |= SEVAL_RESETLINE;
-      if (function_code == 0)
-       parse_and_execute (trap_command, tag, flags);
-
-      restore_token_state (token_state);
-      free (token_state);
-
-      subst_assign_varlist = save_subst_varlist;
-
-      trap_exit_value = last_command_exit_value;
-      last_command_exit_value = trap_saved_exit_value;
-      running_trap = 0;
-
-      sigmodes[sig] &= ~SIG_INPROGRESS;
-
-      if (sigmodes[sig] & SIG_CHANGED)
-       {
-#if 0
-         /* Special traps like EXIT, DEBUG, RETURN are handled explicitly in
-            the places where they can be changed using unwind-protects.  For
-            example, look at execute_cmd.c:execute_function(). */
-         if (SPECIAL_TRAP (sig) == 0)
-#endif
-           free (old_trap);
-         sigmodes[sig] &= ~SIG_CHANGED;
-       }
-
-      if (save_return_catch_flag)
-       {
-         return_catch_flag = save_return_catch_flag;
-         return_catch_value = trap_exit_value;
-         COPY_PROCENV (save_return_catch, return_catch);
-         if (function_code)
-           longjmp (return_catch, 1);
-       }
-    }
-
-  return trap_exit_value;
-}
-
-int
-run_debug_trap ()
-{
-  int trap_exit_value;
-  pid_t save_pgrp;
-  int save_pipe[2];
-
-  /* XXX - question:  should the DEBUG trap inherit the RETURN trap? */
-  trap_exit_value = 0;
-  if ((sigmodes[DEBUG_TRAP] & SIG_TRAPPED) && ((sigmodes[DEBUG_TRAP] & SIG_IGNORED) == 0) && ((sigmodes[DEBUG_TRAP] & SIG_INPROGRESS) == 0))
-    {
-#if defined (JOB_CONTROL)
-      save_pgrp = pipeline_pgrp;
-      pipeline_pgrp = 0;
-      save_pipeline (1);
-#  if defined (PGRP_PIPE)
-      save_pgrp_pipe (save_pipe, 1);
-#  endif
-      stop_making_children ();
-#endif
-
-      trap_exit_value = _run_trap_internal (DEBUG_TRAP, "debug trap");
-
-#if defined (JOB_CONTROL)
-      pipeline_pgrp = save_pgrp;
-      restore_pipeline (1);
-#  if defined (PGRP_PIPE)
-      close_pgrp_pipe ();
-      restore_pgrp_pipe (save_pipe);
-#  endif
-      if (pipeline_pgrp > 0)
-       give_terminal_to (pipeline_pgrp, 1);
-      notify_and_cleanup ();
-#endif
-      
-#if defined (DEBUGGER)
-      /* If we're in the debugger and the DEBUG trap returns 2 while we're in
-        a function or sourced script, we force a `return'. */
-      if (debugging_mode && trap_exit_value == 2 && return_catch_flag)
-       {
-         return_catch_value = trap_exit_value;
-         longjmp (return_catch, 1);
-       }
-#endif
-    }
-  return trap_exit_value;
-}
-
-void
-run_error_trap ()
-{
-  if ((sigmodes[ERROR_TRAP] & SIG_TRAPPED) && ((sigmodes[ERROR_TRAP] & SIG_IGNORED) == 0) && (sigmodes[ERROR_TRAP] & SIG_INPROGRESS) == 0)
-    _run_trap_internal (ERROR_TRAP, "error trap");
-}
-
-void
-run_return_trap ()
-{
-  int old_exit_value;
-
-#if 0
-  if ((sigmodes[DEBUG_TRAP] & SIG_TRAPPED) && (sigmodes[DEBUG_TRAP] & SIG_INPROGRESS))
-    return;
-#endif
-
-  if ((sigmodes[RETURN_TRAP] & SIG_TRAPPED) && ((sigmodes[RETURN_TRAP] & SIG_IGNORED) == 0) && (sigmodes[RETURN_TRAP] & SIG_INPROGRESS) == 0)
-    {
-      old_exit_value = last_command_exit_value;
-      _run_trap_internal (RETURN_TRAP, "return trap");
-      last_command_exit_value = old_exit_value;
-    }
-}
-
-/* Run a trap set on SIGINT.  This is called from throw_to_top_level (), and
-   declared here to localize the trap functions. */
-void
-run_interrupt_trap ()
-{
-  _run_trap_internal (SIGINT, "interrupt trap");
-}
-
-#ifdef INCLUDE_UNUSED
-/* Free all the allocated strings in the list of traps and reset the trap
-   values to the default. */
-void
-free_trap_strings ()
-{
-  register int i;
-
-  for (i = 0; i < BASH_NSIG; i++)
-    free_trap_string (i);
-  trap_list[DEBUG_TRAP] = trap_list[EXIT_TRAP] = trap_list[ERROR_TRAP] = trap_list[RETURN_TRAP] = (char *)NULL;
-}
-
-/* Free a trap command string associated with SIG without changing signal
-   disposition. */
-static void
-free_trap_string (sig)
-     int sig;
-{
-  change_signal (sig, (char *)DEFAULT_SIG);
-  sigmodes[sig] &= ~SIG_TRAPPED;
-}
-#endif
-
-/* Reset the handler for SIG to the original value. */
-static void
-reset_signal (sig)
-     int sig;
-{
-  set_signal_handler (sig, original_signals[sig]);
-  sigmodes[sig] &= ~SIG_TRAPPED;
-}
-
-/* Set the handler signal SIG to the original and free any trap
-   command associated with it. */
-static void
-restore_signal (sig)
-     int sig;
-{
-  set_signal_handler (sig, original_signals[sig]);
-  change_signal (sig, (char *)DEFAULT_SIG);
-  sigmodes[sig] &= ~SIG_TRAPPED;
-}
-
-static void
-reset_or_restore_signal_handlers (reset)
-     sh_resetsig_func_t *reset;
-{
-  register int i;
-
-  /* Take care of the exit trap first */
-  if (sigmodes[EXIT_TRAP] & SIG_TRAPPED)
-    {
-      sigmodes[EXIT_TRAP] &= ~SIG_TRAPPED;
-      if (reset != reset_signal)
-       {
-         free_trap_command (EXIT_TRAP);
-         trap_list[EXIT_TRAP] = (char *)NULL;
-       }
-    }
-
-  for (i = 1; i < NSIG; i++)
-    {
-      if (sigmodes[i] & SIG_TRAPPED)
-       {
-         if (trap_list[i] == (char *)IGNORE_SIG)
-           set_signal_handler (i, SIG_IGN);
-         else
-           (*reset) (i);
-       }
-      else if (sigmodes[i] & SIG_SPECIAL)
-       (*reset) (i);
-    }
-
-  /* Command substitution and other child processes don't inherit the
-     debug, error, or return traps.  If we're in the debugger, and the
-     `functrace' or `errtrace' options have been set, then let command
-     substitutions inherit them.  Let command substitution inherit the
-     RETURN trap if we're in the debugger and tracing functions. */
-  if (function_trace_mode == 0)
-    {
-      sigmodes[DEBUG_TRAP] &= ~SIG_TRAPPED;
-      sigmodes[RETURN_TRAP] &= ~SIG_TRAPPED;
-    }
-  if (error_trace_mode == 0)
-    sigmodes[ERROR_TRAP] &= ~SIG_TRAPPED;
-}
-
-/* Reset trapped signals to their original values, but don't free the
-   trap strings.  Called by the command substitution code. */
-void
-reset_signal_handlers ()
-{
-  reset_or_restore_signal_handlers (reset_signal);
-}
-
-/* Reset all trapped signals to their original values.  Signals set to be
-   ignored with trap '' SIGNAL should be ignored, so we make sure that they
-   are.  Called by child processes after they are forked. */
-void
-restore_original_signals ()
-{
-  reset_or_restore_signal_handlers (restore_signal);
-}
-
-/* If a trap handler exists for signal SIG, then call it; otherwise just
-   return failure. */
-int
-maybe_call_trap_handler (sig)
-     int sig;
-{
-  /* Call the trap handler for SIG if the signal is trapped and not ignored. */
-  if ((sigmodes[sig] & SIG_TRAPPED) && ((sigmodes[sig] & SIG_IGNORED) == 0))
-    {
-      switch (sig)
-       {
-       case SIGINT:
-         run_interrupt_trap ();
-         break;
-       case EXIT_TRAP:
-         run_exit_trap ();
-         break;
-       case DEBUG_TRAP:
-         run_debug_trap ();
-         break;
-       case ERROR_TRAP:
-         run_error_trap ();
-         break;
-       default:
-         trap_handler (sig);
-         break;
-       }
-      return (1);
-    }
-  else
-    return (0);
-}
-
-int
-signal_is_trapped (sig)
-     int sig;
-{
-  return (sigmodes[sig] & SIG_TRAPPED);
-}
-
-int
-signal_is_special (sig)
-     int sig;
-{
-  return (sigmodes[sig] & SIG_SPECIAL);
-}
-
-int
-signal_is_ignored (sig)
-     int sig;
-{
-  return (sigmodes[sig] & SIG_IGNORED);
-}
-
-void
-set_signal_ignored (sig)
-     int sig;
-{
-  sigmodes[sig] |= SIG_HARD_IGNORE;
-  original_signals[sig] = SIG_IGN;
-}
-
-int
-signal_in_progress (sig)
-     int sig;
-{
-  return (sigmodes[sig] & SIG_INPROGRESS);
-}
diff --git a/variables.c~ b/variables.c~
deleted file mode 100644 (file)
index bdc27c7..0000000
+++ /dev/null
@@ -1,4675 +0,0 @@
-/* variables.c -- Functions for hacking shell variables. */
-
-/* Copyright (C) 1987-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/>.
-*/
-
-#include "config.h"
-
-#include "bashtypes.h"
-#include "posixstat.h"
-#include "posixtime.h"
-
-#if defined (__QNX__)
-#  if defined (__QNXNTO__)
-#    include <sys/netmgr.h>
-#  else
-#    include <sys/vc.h>
-#  endif /* !__QNXNTO__ */
-#endif /* __QNX__ */
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#include <stdio.h>
-#include "chartypes.h"
-#if defined (HAVE_PWD_H)
-#  include <pwd.h>
-#endif
-#include "bashansi.h"
-#include "bashintl.h"
-
-#define NEED_XTRACE_SET_DECL
-
-#include "shell.h"
-#include "flags.h"
-#include "execute_cmd.h"
-#include "findcmd.h"
-#include "mailcheck.h"
-#include "input.h"
-#include "hashcmd.h"
-#include "pathexp.h"
-#include "alias.h"
-
-#include "builtins/getopt.h"
-#include "builtins/common.h"
-
-#if defined (READLINE)
-#  include "bashline.h"
-#  include <readline/readline.h>
-#else
-#  include <tilde/tilde.h>
-#endif
-
-#if defined (HISTORY)
-#  include "bashhist.h"
-#  include <readline/history.h>
-#endif /* HISTORY */
-
-#if defined (PROGRAMMABLE_COMPLETION)
-#  include "pcomplete.h"
-#endif
-
-#define TEMPENV_HASH_BUCKETS   4       /* must be power of two */
-
-#define ifsname(s)     ((s)[0] == 'I' && (s)[1] == 'F' && (s)[2] == 'S' && (s)[3] == '\0')
-
-extern char **environ;
-
-/* Variables used here and defined in other files. */
-extern int posixly_correct;
-extern int line_number;
-extern int subshell_environment, indirection_level, subshell_level;
-extern int build_version, patch_level;
-extern int expanding_redir;
-extern char *dist_version, *release_status;
-extern char *shell_name;
-extern char *primary_prompt, *secondary_prompt;
-extern char *current_host_name;
-extern sh_builtin_func_t *this_shell_builtin;
-extern SHELL_VAR *this_shell_function;
-extern char *the_printed_command_except_trap;
-extern char *this_command_name;
-extern char *command_execution_string;
-extern time_t shell_start_time;
-extern int assigning_in_environment;
-extern int executing_builtin;
-
-#if defined (READLINE)
-extern int no_line_editing;
-extern int perform_hostname_completion;
-#endif
-
-/* The list of shell variables that the user has created at the global
-   scope, or that came from the environment. */
-VAR_CONTEXT *global_variables = (VAR_CONTEXT *)NULL;
-
-/* The current list of shell variables, including function scopes */
-VAR_CONTEXT *shell_variables = (VAR_CONTEXT *)NULL;
-
-/* The list of shell functions that the user has created, or that came from
-   the environment. */
-HASH_TABLE *shell_functions = (HASH_TABLE *)NULL;
-
-#if defined (DEBUGGER)
-/* The table of shell function definitions that the user defined or that
-   came from the environment. */
-HASH_TABLE *shell_function_defs = (HASH_TABLE *)NULL;
-#endif
-
-/* The current variable context.  This is really a count of how deep into
-   executing functions we are. */
-int variable_context = 0;
-
-/* The set of shell assignments which are made only in the environment
-   for a single command. */
-HASH_TABLE *temporary_env = (HASH_TABLE *)NULL;
-
-/* Set to non-zero if an assignment error occurs while putting variables
-   into the temporary environment. */
-int tempenv_assign_error;
-
-/* Some funky variables which are known about specially.  Here is where
-   "$*", "$1", and all the cruft is kept. */
-char *dollar_vars[10];
-WORD_LIST *rest_of_args = (WORD_LIST *)NULL;
-
-/* The value of $$. */
-pid_t dollar_dollar_pid;
-
-/* Non-zero means that we have to remake EXPORT_ENV. */
-int array_needs_making = 1;
-
-/* The number of times BASH has been executed.  This is set
-   by initialize_variables (). */
-int shell_level = 0;
-
-/* An array which is passed to commands as their environment.  It is
-   manufactured from the union of the initial environment and the
-   shell variables that are marked for export. */
-char **export_env = (char **)NULL;
-static int export_env_index;
-static int export_env_size;
-
-#if defined (READLINE)
-static int winsize_assignment;         /* currently assigning to LINES or COLUMNS */
-static int winsize_assigned;           /* assigned to LINES or COLUMNS */
-#endif
-
-/* Some forward declarations. */
-static void create_variable_tables __P((void));
-
-static void set_machine_vars __P((void));
-static void set_home_var __P((void));
-static void set_shell_var __P((void));
-static char *get_bash_name __P((void));
-static void initialize_shell_level __P((void));
-static void uidset __P((void));
-#if defined (ARRAY_VARS)
-static void make_vers_array __P((void));
-#endif
-
-static SHELL_VAR *null_assign __P((SHELL_VAR *, char *, arrayind_t, char *));
-#if defined (ARRAY_VARS)
-static SHELL_VAR *null_array_assign __P((SHELL_VAR *, char *, arrayind_t, char *));
-#endif
-static SHELL_VAR *get_self __P((SHELL_VAR *));
-
-#if defined (ARRAY_VARS)
-static SHELL_VAR *init_dynamic_array_var __P((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int));
-static SHELL_VAR *init_dynamic_assoc_var __P((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int));
-#endif
-
-static SHELL_VAR *assign_seconds __P((SHELL_VAR *, char *, arrayind_t, char *));
-static SHELL_VAR *get_seconds __P((SHELL_VAR *));
-static SHELL_VAR *init_seconds_var __P((void));
-
-static int brand __P((void));
-static void sbrand __P((unsigned long));               /* set bash random number generator. */
-static void seedrand __P((void));                      /* seed generator randomly */
-static SHELL_VAR *assign_random __P((SHELL_VAR *, char *, arrayind_t, char *));
-static SHELL_VAR *get_random __P((SHELL_VAR *));
-
-static SHELL_VAR *assign_lineno __P((SHELL_VAR *, char *, arrayind_t, char *));
-static SHELL_VAR *get_lineno __P((SHELL_VAR *));
-
-static SHELL_VAR *assign_subshell __P((SHELL_VAR *, char *, arrayind_t, char *));
-static SHELL_VAR *get_subshell __P((SHELL_VAR *));
-
-static SHELL_VAR *get_bashpid __P((SHELL_VAR *));
-
-#if defined (HISTORY)
-static SHELL_VAR *get_histcmd __P((SHELL_VAR *));
-#endif
-
-#if defined (READLINE)
-static SHELL_VAR *get_comp_wordbreaks __P((SHELL_VAR *));
-static SHELL_VAR *assign_comp_wordbreaks __P((SHELL_VAR *, char *, arrayind_t, char *));
-#endif
-
-#if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
-static SHELL_VAR *assign_dirstack __P((SHELL_VAR *, char *, arrayind_t, char *));
-static SHELL_VAR *get_dirstack __P((SHELL_VAR *));
-#endif
-
-#if defined (ARRAY_VARS)
-static SHELL_VAR *get_groupset __P((SHELL_VAR *));
-
-static SHELL_VAR *build_hashcmd __P((SHELL_VAR *));
-static SHELL_VAR *get_hashcmd __P((SHELL_VAR *));
-static SHELL_VAR *assign_hashcmd __P((SHELL_VAR *,  char *, arrayind_t, char *));
-#  if defined (ALIAS)
-static SHELL_VAR *build_aliasvar __P((SHELL_VAR *));
-static SHELL_VAR *get_aliasvar __P((SHELL_VAR *));
-static SHELL_VAR *assign_aliasvar __P((SHELL_VAR *,  char *, arrayind_t, char *));
-#  endif
-#endif
-
-static SHELL_VAR *get_funcname __P((SHELL_VAR *));
-static SHELL_VAR *init_funcname_var __P((void));
-
-static void initialize_dynamic_variables __P((void));
-
-static SHELL_VAR *hash_lookup __P((const char *, HASH_TABLE *));
-static SHELL_VAR *new_shell_variable __P((const char *));
-static SHELL_VAR *make_new_variable __P((const char *, HASH_TABLE *));
-static SHELL_VAR *bind_variable_internal __P((const char *, char *, HASH_TABLE *, int, int));
-
-static void dispose_variable_value __P((SHELL_VAR *));
-static void free_variable_hash_data __P((PTR_T));
-
-static VARLIST *vlist_alloc __P((int));
-static VARLIST *vlist_realloc __P((VARLIST *, int));
-static void vlist_add __P((VARLIST *, SHELL_VAR *, int));
-
-static void flatten __P((HASH_TABLE *, sh_var_map_func_t *, VARLIST *, int));
-
-static int qsort_var_comp __P((SHELL_VAR **, SHELL_VAR **));
-
-static SHELL_VAR **vapply __P((sh_var_map_func_t *));
-static SHELL_VAR **fapply __P((sh_var_map_func_t *));
-
-static int visible_var __P((SHELL_VAR *));
-static int visible_and_exported __P((SHELL_VAR *));
-static int export_environment_candidate __P((SHELL_VAR *));
-static int local_and_exported __P((SHELL_VAR *));
-static int variable_in_context __P((SHELL_VAR *));
-#if defined (ARRAY_VARS)
-static int visible_array_vars __P((SHELL_VAR *));
-#endif
-
-static SHELL_VAR *bind_tempenv_variable __P((const char *, char *));
-static void push_temp_var __P((PTR_T));
-static void propagate_temp_var __P((PTR_T));
-static void dispose_temporary_env __P((sh_free_func_t *));     
-
-static inline char *mk_env_string __P((const char *, const char *));
-static char **make_env_array_from_var_list __P((SHELL_VAR **));
-static char **make_var_export_array __P((VAR_CONTEXT *));
-static char **make_func_export_array __P((void));
-static void add_temp_array_to_env __P((char **, int, int));
-
-static int n_shell_variables __P((void));
-static int set_context __P((SHELL_VAR *));
-
-static void push_func_var __P((PTR_T));
-static void push_exported_var __P((PTR_T));
-
-static inline int find_special_var __P((const char *));
-
-static void
-create_variable_tables ()
-{
-  if (shell_variables == 0)
-    {
-      shell_variables = global_variables = new_var_context ((char *)NULL, 0);
-      shell_variables->scope = 0;
-      shell_variables->table = hash_create (0);
-    }
-
-  if (shell_functions == 0)
-    shell_functions = hash_create (0);
-
-#if defined (DEBUGGER)
-  if (shell_function_defs == 0)
-    shell_function_defs = hash_create (0);
-#endif
-}
-
-/* Initialize the shell variables from the current environment.
-   If PRIVMODE is nonzero, don't import functions from ENV or
-   parse $SHELLOPTS. */
-void
-initialize_shell_variables (env, privmode)
-     char **env;
-     int privmode;
-{
-  char *name, *string, *temp_string;
-  int c, char_index, string_index, string_length;
-  SHELL_VAR *temp_var;
-
-  create_variable_tables ();
-
-  for (string_index = 0; string = env[string_index++]; )
-    {
-      char_index = 0;
-      name = string;
-      while ((c = *string++) && c != '=')
-       ;
-      if (string[-1] == '=')
-       char_index = string - name - 1;
-
-      /* If there are weird things in the environment, like `=xxx' or a
-        string without an `=', just skip them. */
-      if (char_index == 0)
-       continue;
-
-      /* ASSERT(name[char_index] == '=') */
-      name[char_index] = '\0';
-      /* Now, name = env variable name, string = env variable value, and
-        char_index == strlen (name) */
-
-      temp_var = (SHELL_VAR *)NULL;
-
-      /* If exported function, define it now.  Don't import functions from
-        the environment in privileged mode. */
-      if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4))
-       {
-         string_length = strlen (string);
-         temp_string = (char *)xmalloc (3 + string_length + char_index);
-
-         strcpy (temp_string, name);
-         temp_string[char_index] = ' ';
-         strcpy (temp_string + char_index + 1, string);
-
-         parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST);
-
-         /* Ancient backwards compatibility.  Old versions of bash exported
-            functions like name()=() {...} */
-         if (name[char_index - 1] == ')' && name[char_index - 2] == '(')
-           name[char_index - 2] = '\0';
-
-         if (temp_var = find_function (name))
-           {
-             VSETATTR (temp_var, (att_exported|att_imported));
-             array_needs_making = 1;
-           }
-         else
-           report_error (_("error importing function definition for `%s'"), name);
-
-         /* ( */
-         if (name[char_index - 1] == ')' && name[char_index - 2] == '\0')
-           name[char_index - 2] = '(';         /* ) */
-       }
-#if defined (ARRAY_VARS)
-#  if 0
-      /* Array variables may not yet be exported. */
-      else if (*string == '(' && string[1] == '[' && string[strlen (string) - 1] == ')')
-       {
-         string_length = 1;
-         temp_string = extract_array_assignment_list (string, &string_length);
-         temp_var = assign_array_from_string (name, temp_string);
-         FREE (temp_string);
-         VSETATTR (temp_var, (att_exported | att_imported));
-         array_needs_making = 1;
-       }
-#  endif
-#endif
-#if 0
-      else if (legal_identifier (name))
-#else
-      else
-#endif
-       {
-         temp_var = bind_variable (name, string, 0);
-         if (legal_identifier (name))
-           VSETATTR (temp_var, (att_exported | att_imported));
-         else
-           VSETATTR (temp_var, (att_exported | att_imported | att_invisible));
-         array_needs_making = 1;
-       }
-
-      name[char_index] = '=';
-      /* temp_var can be NULL if it was an exported function with a syntax
-        error (a different bug, but it still shouldn't dump core). */
-      if (temp_var && function_p (temp_var) == 0)      /* XXX not yet */
-       {
-         CACHE_IMPORTSTR (temp_var, name);
-       }
-    }
-
-  set_pwd ();
-
-  /* Set up initial value of $_ */
-  temp_var = set_if_not ("_", dollar_vars[0]);
-
-  /* Remember this pid. */
-  dollar_dollar_pid = getpid ();
-
-  /* Now make our own defaults in case the vars that we think are
-     important are missing. */
-  temp_var = set_if_not ("PATH", DEFAULT_PATH_VALUE);
-#if 0
-  set_auto_export (temp_var);  /* XXX */
-#endif
-
-  temp_var = set_if_not ("TERM", "dumb");
-#if 0
-  set_auto_export (temp_var);  /* XXX */
-#endif
-
-#if defined (__QNX__)
-  /* set node id -- don't import it from the environment */
-  {
-    char node_name[22];
-#  if defined (__QNXNTO__)
-    netmgr_ndtostr(ND2S_LOCAL_STR, ND_LOCAL_NODE, node_name, sizeof(node_name));
-#  else
-    qnx_nidtostr (getnid (), node_name, sizeof (node_name));
-#  endif
-    temp_var = bind_variable ("NODE", node_name, 0);
-    set_auto_export (temp_var);
-  }
-#endif
-
-  /* set up the prompts. */
-  if (interactive_shell)
-    {
-#if defined (PROMPT_STRING_DECODE)
-      set_if_not ("PS1", primary_prompt);
-#else
-      if (current_user.uid == -1)
-       get_current_user_info ();
-      set_if_not ("PS1", current_user.euid == 0 ? "# " : primary_prompt);
-#endif
-      set_if_not ("PS2", secondary_prompt);
-    }
-  set_if_not ("PS4", "+ ");
-
-  /* Don't allow IFS to be imported from the environment. */
-  temp_var = bind_variable ("IFS", " \t\n", 0);
-  setifs (temp_var);
-
-  /* Magic machine types.  Pretty convenient. */
-  set_machine_vars ();
-
-  /* Default MAILCHECK for interactive shells.  Defer the creation of a
-     default MAILPATH until the startup files are read, because MAIL
-     names a mail file if MAILPATH is not set, and we should provide a
-     default only if neither is set. */
-  if (interactive_shell)
-    {
-      temp_var = set_if_not ("MAILCHECK", posixly_correct ? "600" : "60");
-      VSETATTR (temp_var, att_integer);
-    }
-
-  /* Do some things with shell level. */
-  initialize_shell_level ();
-
-  set_ppid ();
-
-  /* Initialize the `getopts' stuff. */
-  temp_var = bind_variable ("OPTIND", "1", 0);
-  VSETATTR (temp_var, att_integer);
-  getopts_reset (0);
-  bind_variable ("OPTERR", "1", 0);
-  sh_opterr = 1;
-
-  if (login_shell == 1 && posixly_correct == 0)
-    set_home_var ();
-
-  /* Get the full pathname to THIS shell, and set the BASH variable
-     to it. */
-  name = get_bash_name ();
-  temp_var = bind_variable ("BASH", name, 0);
-  free (name);
-
-  /* Make the exported environment variable SHELL be the user's login
-     shell.  Note that the `tset' command looks at this variable
-     to determine what style of commands to output; if it ends in "csh",
-     then C-shell commands are output, else Bourne shell commands. */
-  set_shell_var ();
-
-  /* Make a variable called BASH_VERSION which contains the version info. */
-  bind_variable ("BASH_VERSION", shell_version_string (), 0);
-#if defined (ARRAY_VARS)
-  make_vers_array ();
-#endif
-
-  if (command_execution_string)
-    bind_variable ("BASH_EXECUTION_STRING", command_execution_string, 0);
-
-  /* Find out if we're supposed to be in Posix.2 mode via an
-     environment variable. */
-  temp_var = find_variable ("POSIXLY_CORRECT");
-  if (!temp_var)
-    temp_var = find_variable ("POSIX_PEDANTIC");
-  if (temp_var && imported_p (temp_var))
-    sv_strict_posix (temp_var->name);
-
-#if defined (HISTORY)
-  /* Set history variables to defaults, and then do whatever we would
-     do if the variable had just been set.  Do this only in the case
-     that we are remembering commands on the history list. */
-  if (remember_on_history)
-    {
-      name = bash_tilde_expand (posixly_correct ? "~/.sh_history" : "~/.bash_history", 0);
-
-      set_if_not ("HISTFILE", name);
-      free (name);
-
-#if 0
-      set_if_not ("HISTSIZE", "500");
-      sv_histsize ("HISTSIZE");
-#endif
-    }
-#endif /* HISTORY */
-
-  /* Seed the random number generator. */
-  seedrand ();
-
-  /* Handle some "special" variables that we may have inherited from a
-     parent shell. */
-  if (interactive_shell)
-    {
-      temp_var = find_variable ("IGNOREEOF");
-      if (!temp_var)
-       temp_var = find_variable ("ignoreeof");
-      if (temp_var && imported_p (temp_var))
-       sv_ignoreeof (temp_var->name);
-    }
-
-#if defined (HISTORY)
-  if (interactive_shell && remember_on_history)
-    {
-      sv_history_control ("HISTCONTROL");
-      sv_histignore ("HISTIGNORE");
-      sv_histtimefmt ("HISTTIMEFORMAT");
-    }
-#endif /* HISTORY */
-
-#if defined (READLINE) && defined (STRICT_POSIX)
-  /* POSIXLY_CORRECT will only be 1 here if the shell was compiled
-     -DSTRICT_POSIX */
-  if (interactive_shell && posixly_correct && no_line_editing == 0)
-    rl_prefer_env_winsize = 1;
-#endif /* READLINE && STRICT_POSIX */
-
-     /*
-      * 24 October 2001
-      *
-      * I'm tired of the arguing and bug reports.  Bash now leaves SSH_CLIENT
-      * and SSH2_CLIENT alone.  I'm going to rely on the shell_level check in
-      * isnetconn() to avoid running the startup files more often than wanted.
-      * That will, of course, only work if the user's login shell is bash, so
-      * I've made that behavior conditional on SSH_SOURCE_BASHRC being defined
-      * in config-top.h.
-      */
-#if 0
-  temp_var = find_variable ("SSH_CLIENT");
-  if (temp_var && imported_p (temp_var))
-    {
-      VUNSETATTR (temp_var, att_exported);
-      array_needs_making = 1;
-    }
-  temp_var = find_variable ("SSH2_CLIENT");
-  if (temp_var && imported_p (temp_var))
-    {
-      VUNSETATTR (temp_var, att_exported);
-      array_needs_making = 1;
-    }
-#endif
-
-  /* Get the user's real and effective user ids. */
-  uidset ();
-
-  /* Initialize the dynamic variables, and seed their values. */
-  initialize_dynamic_variables ();
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*          Setting values for special shell variables             */
-/*                                                                 */
-/* **************************************************************** */
-
-static void
-set_machine_vars ()
-{
-  SHELL_VAR *temp_var;
-
-  temp_var = set_if_not ("HOSTTYPE", HOSTTYPE);
-  temp_var = set_if_not ("OSTYPE", OSTYPE);
-  temp_var = set_if_not ("MACHTYPE", MACHTYPE);
-
-  temp_var = set_if_not ("HOSTNAME", current_host_name);
-}
-
-/* Set $HOME to the information in the password file if we didn't get
-   it from the environment. */
-
-/* This function is not static so the tilde and readline libraries can
-   use it. */
-char *
-sh_get_home_dir ()
-{
-  if (current_user.home_dir == 0)
-    get_current_user_info ();
-  return current_user.home_dir;
-}
-
-static void
-set_home_var ()
-{
-  SHELL_VAR *temp_var;
-
-  temp_var = find_variable ("HOME");
-  if (temp_var == 0)
-    temp_var = bind_variable ("HOME", sh_get_home_dir (), 0);
-#if 0
-  VSETATTR (temp_var, att_exported);
-#endif
-}
-
-/* Set $SHELL to the user's login shell if it is not already set.  Call
-   get_current_user_info if we haven't already fetched the shell. */
-static void
-set_shell_var ()
-{
-  SHELL_VAR *temp_var;
-
-  temp_var = find_variable ("SHELL");
-  if (temp_var == 0)
-    {
-      if (current_user.shell == 0)
-       get_current_user_info ();
-      temp_var = bind_variable ("SHELL", current_user.shell, 0);
-    }
-#if 0
-  VSETATTR (temp_var, att_exported);
-#endif
-}
-
-static char *
-get_bash_name ()
-{
-  char *name;
-
-  if ((login_shell == 1) && RELPATH(shell_name))
-    {
-      if (current_user.shell == 0)
-       get_current_user_info ();
-      name = savestring (current_user.shell);
-    }
-  else if (ABSPATH(shell_name))
-    name = savestring (shell_name);
-  else if (shell_name[0] == '.' && shell_name[1] == '/')
-    {
-      /* Fast path for common case. */
-      char *cdir;
-      int len;
-
-      cdir = get_string_value ("PWD");
-      if (cdir)
-       {
-         len = strlen (cdir);
-         name = (char *)xmalloc (len + strlen (shell_name) + 1);
-         strcpy (name, cdir);
-         strcpy (name + len, shell_name + 1);
-       }
-      else
-       name = savestring (shell_name);
-    }
-  else
-    {
-      char *tname;
-      int s;
-
-      tname = find_user_command (shell_name);
-
-      if (tname == 0)
-       {
-         /* Try the current directory.  If there is not an executable
-            there, just punt and use the login shell. */
-         s = file_status (shell_name);
-         if (s & FS_EXECABLE)
-           {
-             tname = make_absolute (shell_name, get_string_value ("PWD"));
-             if (*shell_name == '.')
-               {
-                 name = sh_canonpath (tname, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
-                 if (name == 0)
-                   name = tname;
-                 else
-                   free (tname);
-               }
-            else
-               name = tname;
-           }
-         else
-           {
-             if (current_user.shell == 0)
-               get_current_user_info ();
-             name = savestring (current_user.shell);
-           }
-       }
-      else
-       {
-         name = full_pathname (tname);
-         free (tname);
-       }
-    }
-
-  return (name);
-}
-
-void
-adjust_shell_level (change)
-     int change;
-{
-  char new_level[5], *old_SHLVL;
-  intmax_t old_level;
-  SHELL_VAR *temp_var;
-
-  old_SHLVL = get_string_value ("SHLVL");
-  if (old_SHLVL == 0 || *old_SHLVL == '\0' || legal_number (old_SHLVL, &old_level) == 0)
-    old_level = 0;
-
-  shell_level = old_level + change;
-  if (shell_level < 0)
-    shell_level = 0;
-  else if (shell_level > 1000)
-    {
-      internal_warning (_("shell level (%d) too high, resetting to 1"), shell_level);
-      shell_level = 1;
-    }
-
-  /* We don't need the full generality of itos here. */
-  if (shell_level < 10)
-    {
-      new_level[0] = shell_level + '0';
-      new_level[1] = '\0';
-    }
-  else if (shell_level < 100)
-    {
-      new_level[0] = (shell_level / 10) + '0';
-      new_level[1] = (shell_level % 10) + '0';
-      new_level[2] = '\0';
-    }
-  else if (shell_level < 1000)
-    {
-      new_level[0] = (shell_level / 100) + '0';
-      old_level = shell_level % 100;
-      new_level[1] = (old_level / 10) + '0';
-      new_level[2] = (old_level % 10) + '0';
-      new_level[3] = '\0';
-    }
-
-  temp_var = bind_variable ("SHLVL", new_level, 0);
-  set_auto_export (temp_var);
-}
-
-static void
-initialize_shell_level ()
-{
-  adjust_shell_level (1);
-}
-
-/* If we got PWD from the environment, update our idea of the current
-   working directory.  In any case, make sure that PWD exists before
-   checking it.  It is possible for getcwd () to fail on shell startup,
-   and in that case, PWD would be undefined.  If this is an interactive
-   login shell, see if $HOME is the current working directory, and if
-   that's not the same string as $PWD, set PWD=$HOME. */
-
-void
-set_pwd ()
-{
-  SHELL_VAR *temp_var, *home_var;
-  char *temp_string, *home_string;
-
-  home_var = find_variable ("HOME");
-  home_string = home_var ? value_cell (home_var) : (char *)NULL;
-
-  temp_var = find_variable ("PWD");
-  if (temp_var && imported_p (temp_var) &&
-      (temp_string = value_cell (temp_var)) &&
-      same_file (temp_string, ".", (struct stat *)NULL, (struct stat *)NULL))
-    set_working_directory (temp_string);
-  else if (home_string && interactive_shell && login_shell &&
-          same_file (home_string, ".", (struct stat *)NULL, (struct stat *)NULL))
-    {
-      set_working_directory (home_string);
-      temp_var = bind_variable ("PWD", home_string, 0);
-      set_auto_export (temp_var);
-    }
-  else
-    {
-      temp_string = get_working_directory ("shell-init");
-      if (temp_string)
-       {
-         temp_var = bind_variable ("PWD", temp_string, 0);
-         set_auto_export (temp_var);
-         free (temp_string);
-       }
-    }
-
-  /* According to the Single Unix Specification, v2, $OLDPWD is an
-     `environment variable' and therefore should be auto-exported.
-     Make a dummy invisible variable for OLDPWD, and mark it as exported. */
-  temp_var = bind_variable ("OLDPWD", (char *)NULL, 0);
-  VSETATTR (temp_var, (att_exported | att_invisible));
-}
-
-/* Make a variable $PPID, which holds the pid of the shell's parent.  */
-void
-set_ppid ()
-{
-  char namebuf[INT_STRLEN_BOUND(pid_t) + 1], *name;
-  SHELL_VAR *temp_var;
-
-  name = inttostr (getppid (), namebuf, sizeof(namebuf));
-  temp_var = find_variable ("PPID");
-  if (temp_var)
-    VUNSETATTR (temp_var, (att_readonly | att_exported));
-  temp_var = bind_variable ("PPID", name, 0);
-  VSETATTR (temp_var, (att_readonly | att_integer));
-}
-
-static void
-uidset ()
-{
-  char buff[INT_STRLEN_BOUND(uid_t) + 1], *b;
-  register SHELL_VAR *v;
-
-  b = inttostr (current_user.uid, buff, sizeof (buff));
-  v = find_variable ("UID");
-  if (v == 0)
-    {
-      v = bind_variable ("UID", b, 0);
-      VSETATTR (v, (att_readonly | att_integer));
-    }
-
-  if (current_user.euid != current_user.uid)
-    b = inttostr (current_user.euid, buff, sizeof (buff));
-
-  v = find_variable ("EUID");
-  if (v == 0)
-    {
-      v = bind_variable ("EUID", b, 0);
-      VSETATTR (v, (att_readonly | att_integer));
-    }
-}
-
-#if defined (ARRAY_VARS)
-static void
-make_vers_array ()
-{
-  SHELL_VAR *vv;
-  ARRAY *av;
-  char *s, d[32], b[INT_STRLEN_BOUND(int) + 1];
-
-  unbind_variable ("BASH_VERSINFO");
-
-  vv = make_new_array_variable ("BASH_VERSINFO");
-  av = array_cell (vv);
-  strcpy (d, dist_version);
-  s = strchr (d, '.');
-  if (s)
-    *s++ = '\0';
-  array_insert (av, 0, d);
-  array_insert (av, 1, s);
-  s = inttostr (patch_level, b, sizeof (b));
-  array_insert (av, 2, s);
-  s = inttostr (build_version, b, sizeof (b));
-  array_insert (av, 3, s);
-  array_insert (av, 4, release_status);
-  array_insert (av, 5, MACHTYPE);
-
-  VSETATTR (vv, att_readonly);
-}
-#endif /* ARRAY_VARS */
-
-/* Set the environment variables $LINES and $COLUMNS in response to
-   a window size change. */
-void
-sh_set_lines_and_columns (lines, cols)
-     int lines, cols;
-{
-  char val[INT_STRLEN_BOUND(int) + 1], *v;
-
-#if defined (READLINE)
-  /* If we are currently assigning to LINES or COLUMNS, don't do anything. */
-  if (winsize_assignment)
-    return;
-#endif
-
-  v = inttostr (lines, val, sizeof (val));
-  bind_variable ("LINES", v, 0);
-
-  v = inttostr (cols, val, sizeof (val));
-  bind_variable ("COLUMNS", v, 0);
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*                Printing variables and values                    */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Print LIST (a list of shell variables) to stdout in such a way that
-   they can be read back in. */
-void
-print_var_list (list)
-     register SHELL_VAR **list;
-{
-  register int i;
-  register SHELL_VAR *var;
-
-  for (i = 0; list && (var = list[i]); i++)
-    if (invisible_p (var) == 0)
-      print_assignment (var);
-}
-
-/* Print LIST (a list of shell functions) to stdout in such a way that
-   they can be read back in. */
-void
-print_func_list (list)
-     register SHELL_VAR **list;
-{
-  register int i;
-  register SHELL_VAR *var;
-
-  for (i = 0; list && (var = list[i]); i++)
-    {
-      printf ("%s ", var->name);
-      print_var_function (var);
-      printf ("\n");
-    }
-}
-      
-/* Print the value of a single SHELL_VAR.  No newline is
-   output, but the variable is printed in such a way that
-   it can be read back in. */
-void
-print_assignment (var)
-     SHELL_VAR *var;
-{
-  if (var_isset (var) == 0)
-    return;
-
-  if (function_p (var))
-    {
-      printf ("%s", var->name);
-      print_var_function (var);
-      printf ("\n");
-    }
-#if defined (ARRAY_VARS)
-  else if (array_p (var))
-    print_array_assignment (var, 0);
-  else if (assoc_p (var))
-    print_assoc_assignment (var, 0);
-#endif /* ARRAY_VARS */
-  else
-    {
-      printf ("%s=", var->name);
-      print_var_value (var, 1);
-      printf ("\n");
-    }
-}
-
-/* Print the value cell of VAR, a shell variable.  Do not print
-   the name, nor leading/trailing newline.  If QUOTE is non-zero,
-   and the value contains shell metacharacters, quote the value
-   in such a way that it can be read back in. */
-void
-print_var_value (var, quote)
-     SHELL_VAR *var;
-     int quote;
-{
-  char *t;
-
-  if (var_isset (var) == 0)
-    return;
-
-  if (quote && posixly_correct == 0 && ansic_shouldquote (value_cell (var)))
-    {
-      t = ansic_quote (value_cell (var), 0, (int *)0);
-      printf ("%s", t);
-      free (t);
-    }
-  else if (quote && sh_contains_shell_metas (value_cell (var)))
-    {
-      t = sh_single_quote (value_cell (var));
-      printf ("%s", t);
-      free (t);
-    }
-  else
-    printf ("%s", value_cell (var));
-}
-
-/* Print the function cell of VAR, a shell variable.  Do not
-   print the name, nor leading/trailing newline. */
-void
-print_var_function (var)
-     SHELL_VAR *var;
-{
-  char *x;
-
-  if (function_p (var) && var_isset (var))
-    {
-      x = named_function_string ((char *)NULL, function_cell(var), FUNC_MULTILINE|FUNC_EXTERNAL);
-      printf ("%s", x);
-    }
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Dynamic Variables                           */
-/*                                                                 */
-/* **************************************************************** */
-
-/* DYNAMIC VARIABLES
-
-   These are variables whose values are generated anew each time they are
-   referenced.  These are implemented using a pair of function pointers
-   in the struct variable: assign_func, which is called from bind_variable
-   and, if arrays are compiled into the shell, some of the functions in
-   arrayfunc.c, and dynamic_value, which is called from find_variable.
-
-   assign_func is called from bind_variable_internal, if
-   bind_variable_internal discovers that the variable being assigned to
-   has such a function.  The function is called as
-       SHELL_VAR *temp = (*(entry->assign_func)) (entry, value, ind)
-   and the (SHELL_VAR *)temp is returned as the value of bind_variable.  It
-   is usually ENTRY (self).  IND is an index for an array variable, and
-   unused otherwise.
-
-   dynamic_value is called from find_variable_internal to return a `new'
-   value for the specified dynamic varible.  If this function is NULL,
-   the variable is treated as a `normal' shell variable.  If it is not,
-   however, then this function is called like this:
-       tempvar = (*(var->dynamic_value)) (var);
-
-   Sometimes `tempvar' will replace the value of `var'.  Other times, the
-   shell will simply use the string value.  Pretty object-oriented, huh?
-
-   Be warned, though: if you `unset' a special variable, it loses its
-   special meaning, even if you subsequently set it.
-
-   The special assignment code would probably have been better put in
-   subst.c: do_assignment_internal, in the same style as
-   stupidly_hack_special_variables, but I wanted the changes as
-   localized as possible.  */
-
-#define INIT_DYNAMIC_VAR(var, val, gfunc, afunc) \
-  do \
-    { \
-      v = bind_variable (var, (val), 0); \
-      v->dynamic_value = gfunc; \
-      v->assign_func = afunc; \
-    } \
-  while (0)
-
-#define INIT_DYNAMIC_ARRAY_VAR(var, gfunc, afunc) \
-  do \
-    { \
-      v = make_new_array_variable (var); \
-      v->dynamic_value = gfunc; \
-      v->assign_func = afunc; \
-    } \
-  while (0)
-
-#define INIT_DYNAMIC_ASSOC_VAR(var, gfunc, afunc) \
-  do \
-    { \
-      v = make_new_assoc_variable (var); \
-      v->dynamic_value = gfunc; \
-      v->assign_func = afunc; \
-    } \
-  while (0)
-
-static SHELL_VAR *
-null_assign (self, value, unused, key)
-     SHELL_VAR *self;
-     char *value;
-     arrayind_t unused;
-     char *key;
-{
-  return (self);
-}
-
-#if defined (ARRAY_VARS)
-static SHELL_VAR *
-null_array_assign (self, value, ind, key)
-     SHELL_VAR *self;
-     char *value;
-     arrayind_t ind;
-     char *key;
-{
-  return (self);
-}
-#endif
-
-/* Degenerate `dynamic_value' function; just returns what's passed without
-   manipulation. */
-static SHELL_VAR *
-get_self (self)
-     SHELL_VAR *self;
-{
-  return (self);
-}
-
-#if defined (ARRAY_VARS)
-/* A generic dynamic array variable initializer.  Intialize array variable
-   NAME with dynamic value function GETFUNC and assignment function SETFUNC. */
-static SHELL_VAR *
-init_dynamic_array_var (name, getfunc, setfunc, attrs)
-     char *name;
-     sh_var_value_func_t *getfunc;
-     sh_var_assign_func_t *setfunc;
-     int attrs;
-{
-  SHELL_VAR *v;
-
-  v = find_variable (name);
-  if (v)
-    return (v);
-  INIT_DYNAMIC_ARRAY_VAR (name, getfunc, setfunc);
-  if (attrs)
-    VSETATTR (v, attrs);
-  return v;
-}
-
-static SHELL_VAR *
-init_dynamic_assoc_var (name, getfunc, setfunc, attrs)
-     char *name;
-     sh_var_value_func_t *getfunc;
-     sh_var_assign_func_t *setfunc;
-     int attrs;
-{
-  SHELL_VAR *v;
-
-  v = find_variable (name);
-  if (v)
-    return (v);
-  INIT_DYNAMIC_ASSOC_VAR (name, getfunc, setfunc);
-  if (attrs)
-    VSETATTR (v, attrs);
-  return v;
-}
-#endif
-
-/* The value of $SECONDS.  This is the number of seconds since shell
-   invocation, or, the number of seconds since the last assignment + the
-   value of the last assignment. */
-static intmax_t seconds_value_assigned;
-
-static SHELL_VAR *
-assign_seconds (self, value, unused, key)
-     SHELL_VAR *self;
-     char *value;
-     arrayind_t unused;
-     char *key;
-{
-  if (legal_number (value, &seconds_value_assigned) == 0)
-    seconds_value_assigned = 0;
-  shell_start_time = NOW;
-  return (self);
-}
-
-static SHELL_VAR *
-get_seconds (var)
-     SHELL_VAR *var;
-{
-  time_t time_since_start;
-  char *p;
-
-  time_since_start = NOW - shell_start_time;
-  p = itos(seconds_value_assigned + time_since_start);
-
-  FREE (value_cell (var));
-
-  VSETATTR (var, att_integer);
-  var_setvalue (var, p);
-  return (var);
-}
-
-static SHELL_VAR *
-init_seconds_var ()
-{
-  SHELL_VAR *v;
-
-  v = find_variable ("SECONDS");
-  if (v)
-    {
-      if (legal_number (value_cell(v), &seconds_value_assigned) == 0)
-       seconds_value_assigned = 0;
-    }
-  INIT_DYNAMIC_VAR ("SECONDS", (v ? value_cell (v) : (char *)NULL), get_seconds, assign_seconds);
-  return v;      
-}
-     
-/* The random number seed.  You can change this by setting RANDOM. */
-static unsigned long rseed = 1;
-static int last_random_value;
-static int seeded_subshell = 0;
-
-/* A linear congruential random number generator based on the example
-   one in the ANSI C standard.  This one isn't very good, but a more
-   complicated one is overkill. */
-
-/* Returns a pseudo-random number between 0 and 32767. */
-static int
-brand ()
-{
-#if 0
-  rseed = rseed * 1103515245 + 12345;
-  return ((unsigned int)((rseed >> 16) & 32767));      /* was % 32768 */
-#else
-  /* From "Random number generators: good ones are hard to find",
-     Park and Miller, Communications of the ACM, vol. 31, no. 10,
-     October 1988, p. 1195. filtered through FreeBSD */
-  long h, l;
-
-  if (rseed == 0)
-    seedrand ();
-  h = rseed / 127773;
-  l = rseed % 127773;
-  rseed = 16807 * l - 2836 * h;
-#if 0
-  if (rseed < 0)
-    rseed += 0x7fffffff;
-#endif
-  return ((unsigned int)(rseed & 32767));      /* was % 32768 */
-#endif
-}
-
-/* Set the random number generator seed to SEED. */
-static void
-sbrand (seed)
-     unsigned long seed;
-{
-  rseed = seed;
-  last_random_value = 0;
-}
-
-static void
-seedrand ()
-{
-  struct timeval tv;
-
-  gettimeofday (&tv, NULL);
-  sbrand (tv.tv_sec ^ tv.tv_usec ^ getpid ());
-}
-
-static SHELL_VAR *
-assign_random (self, value, unused, key)
-     SHELL_VAR *self;
-     char *value;
-     arrayind_t unused;
-     char *key;
-{
-  sbrand (strtoul (value, (char **)NULL, 10));
-  if (subshell_environment)
-    seeded_subshell = getpid ();
-  return (self);
-}
-
-int
-get_random_number ()
-{
-  int rv, pid;
-
-  /* Reset for command and process substitution. */
-  pid = getpid ();
-  if (subshell_environment && seeded_subshell != pid)
-    {
-      seedrand ();
-      seeded_subshell = pid;
-    }
-
-  do
-    rv = brand ();
-  while (rv == last_random_value);
-  return rv;
-}
-
-static SHELL_VAR *
-get_random (var)
-     SHELL_VAR *var;
-{
-  int rv;
-  char *p;
-
-  rv = get_random_number ();
-  last_random_value = rv;
-  p = itos (rv);
-
-  FREE (value_cell (var));
-
-  VSETATTR (var, att_integer);
-  var_setvalue (var, p);
-  return (var);
-}
-
-static SHELL_VAR *
-assign_lineno (var, value, unused, key)
-     SHELL_VAR *var;
-     char *value;
-     arrayind_t unused;
-     char *key;
-{
-  intmax_t new_value;
-
-  if (value == 0 || *value == '\0' || legal_number (value, &new_value) == 0)
-    new_value = 0;
-  line_number = new_value;
-  return var;
-}
-
-/* Function which returns the current line number. */
-static SHELL_VAR *
-get_lineno (var)
-     SHELL_VAR *var;
-{
-  char *p;
-  int ln;
-
-  ln = executing_line_number ();
-  p = itos (ln);
-  FREE (value_cell (var));
-  var_setvalue (var, p);
-  return (var);
-}
-
-static SHELL_VAR *
-assign_subshell (var, value, unused, key)
-     SHELL_VAR *var;
-     char *value;
-     arrayind_t unused;
-     char *key;
-{
-  intmax_t new_value;
-
-  if (value == 0 || *value == '\0' || legal_number (value, &new_value) == 0)
-    new_value = 0;
-  subshell_level = new_value;
-  return var;
-}
-
-static SHELL_VAR *
-get_subshell (var)
-     SHELL_VAR *var;
-{
-  char *p;
-
-  p = itos (subshell_level);
-  FREE (value_cell (var));
-  var_setvalue (var, p);
-  return (var);
-}
-
-static SHELL_VAR *
-get_bashpid (var)
-     SHELL_VAR *var;
-{
-  int pid;
-  char *p;
-
-  pid = getpid ();
-  p = itos (pid);
-
-  FREE (value_cell (var));
-  VSETATTR (var, att_integer|att_readonly);
-  var_setvalue (var, p);
-  return (var);
-}
-
-static SHELL_VAR *
-get_bash_command (var)
-     SHELL_VAR *var;
-{
-  char *p;
-
-  if (the_printed_command_except_trap)
-    p = savestring (the_printed_command_except_trap);
-  else
-    {
-      p = (char *)xmalloc (1);
-      p[0] = '\0';
-    }
-  FREE (value_cell (var));
-  var_setvalue (var, p);
-  return (var);
-}
-
-#if defined (HISTORY)
-static SHELL_VAR *
-get_histcmd (var)
-     SHELL_VAR *var;
-{
-  char *p;
-
-  p = itos (history_number ());
-  FREE (value_cell (var));
-  var_setvalue (var, p);
-  return (var);
-}
-#endif
-
-#if defined (READLINE)
-/* When this function returns, VAR->value points to malloced memory. */
-static SHELL_VAR *
-get_comp_wordbreaks (var)
-     SHELL_VAR *var;
-{
-  /* If we don't have anything yet, assign a default value. */
-  if (rl_completer_word_break_characters == 0 && bash_readline_initialized == 0)
-    enable_hostname_completion (perform_hostname_completion);
-
-  FREE (value_cell (var));
-  var_setvalue (var, savestring (rl_completer_word_break_characters));
-
-  return (var);
-}
-
-/* When this function returns, rl_completer_word_break_characters points to
-   malloced memory. */
-static SHELL_VAR *
-assign_comp_wordbreaks (self, value, unused, key)
-     SHELL_VAR *self;
-     char *value;
-     arrayind_t unused;
-     char *key;
-{
-  if (rl_completer_word_break_characters &&
-      rl_completer_word_break_characters != rl_basic_word_break_characters)
-    free (rl_completer_word_break_characters);
-
-  rl_completer_word_break_characters = savestring (value);
-  return self;
-}
-#endif /* READLINE */
-
-#if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
-static SHELL_VAR *
-assign_dirstack (self, value, ind, key)
-     SHELL_VAR *self;
-     char *value;
-     arrayind_t ind;
-     char *key;
-{
-  set_dirstack_element (ind, 1, value);
-  return self;
-}
-
-static SHELL_VAR *
-get_dirstack (self)
-     SHELL_VAR *self;
-{
-  ARRAY *a;
-  WORD_LIST *l;
-
-  l = get_directory_stack (0);
-  a = array_from_word_list (l);
-  array_dispose (array_cell (self));
-  dispose_words (l);
-  var_setarray (self, a);
-  return self;
-}
-#endif /* PUSHD AND POPD && ARRAY_VARS */
-
-#if defined (ARRAY_VARS)
-/* We don't want to initialize the group set with a call to getgroups()
-   unless we're asked to, but we only want to do it once. */
-static SHELL_VAR *
-get_groupset (self)
-     SHELL_VAR *self;
-{
-  register int i;
-  int ng;
-  ARRAY *a;
-  static char **group_set = (char **)NULL;
-
-  if (group_set == 0)
-    {
-      group_set = get_group_list (&ng);
-      a = array_cell (self);
-      for (i = 0; i < ng; i++)
-       array_insert (a, i, group_set[i]);
-    }
-  return (self);
-}
-
-static SHELL_VAR *
-build_hashcmd (self)
-     SHELL_VAR *self;
-{
-  HASH_TABLE *h;
-  int i;
-  char *k, *v;
-  BUCKET_CONTENTS *item;
-
-  h = assoc_cell (self);
-  if (h)
-    assoc_dispose (h);
-
-  if (hashed_filenames == 0 || HASH_ENTRIES (hashed_filenames) == 0)
-    {
-      var_setvalue (self, (char *)NULL);
-      return self;
-    }
-
-  h = assoc_create (hashed_filenames->nbuckets);
-  for (i = 0; i < hashed_filenames->nbuckets; i++)
-    {
-      for (item = hash_items (i, hashed_filenames); item; item = item->next)
-       {
-         k = savestring (item->key);
-         v = pathdata(item)->path;
-         assoc_insert (h, k, v);
-       }
-    }
-
-  var_setvalue (self, (char *)h);
-  return self;
-}
-
-static SHELL_VAR *
-get_hashcmd (self)
-     SHELL_VAR *self;
-{
-  build_hashcmd (self);
-  return (self);
-}
-
-static SHELL_VAR *
-assign_hashcmd (self, value, ind, key)
-     SHELL_VAR *self;
-     char *value;
-     arrayind_t ind;
-     char *key;
-{
-  phash_insert (key, value, 0, 0);
-  return (build_hashcmd (self));
-}
-
-#if defined (ALIAS)
-static SHELL_VAR *
-build_aliasvar (self)
-     SHELL_VAR *self;
-{
-  HASH_TABLE *h;
-  int i;
-  char *k, *v;
-  BUCKET_CONTENTS *item;
-
-  h = assoc_cell (self);
-  if (h)
-    assoc_dispose (h);
-
-  if (aliases == 0 || HASH_ENTRIES (aliases) == 0)
-    {
-      var_setvalue (self, (char *)NULL);
-      return self;
-    }
-
-  h = assoc_create (aliases->nbuckets);
-  for (i = 0; i < aliases->nbuckets; i++)
-    {
-      for (item = hash_items (i, aliases); item; item = item->next)
-       {
-         k = savestring (item->key);
-         v = ((alias_t *)(item->data))->value;
-         assoc_insert (h, k, v);
-       }
-    }
-
-  var_setvalue (self, (char *)h);
-  return self;
-}
-
-static SHELL_VAR *
-get_aliasvar (self)
-     SHELL_VAR *self;
-{
-  build_aliasvar (self);
-  return (self);
-}
-
-static SHELL_VAR *
-assign_aliasvar (self, value, ind, key)
-     SHELL_VAR *self;
-     char *value;
-     arrayind_t ind;
-     char *key;
-{
-  add_alias (key, value);
-  return (build_aliasvar (self));
-}
-#endif /* ALIAS */
-
-#endif /* ARRAY_VARS */
-
-/* If ARRAY_VARS is not defined, this just returns the name of any
-   currently-executing function.  If we have arrays, it's a call stack. */
-static SHELL_VAR *
-get_funcname (self)
-     SHELL_VAR *self;
-{
-#if ! defined (ARRAY_VARS)
-  char *t;
-  if (variable_context && this_shell_function)
-    {
-      FREE (value_cell (self));
-      t = savestring (this_shell_function->name);
-      var_setvalue (self, t);
-    }
-#endif
-  return (self);
-}
-
-void
-make_funcname_visible (on_or_off)
-     int on_or_off;
-{
-  SHELL_VAR *v;
-
-  v = find_variable ("FUNCNAME");
-  if (v == 0 || v->dynamic_value == 0)
-    return;
-
-  if (on_or_off)
-    VUNSETATTR (v, att_invisible);
-  else
-    VSETATTR (v, att_invisible);
-}
-
-static SHELL_VAR *
-init_funcname_var ()
-{
-  SHELL_VAR *v;
-
-  v = find_variable ("FUNCNAME");
-  if (v)
-    return v;
-#if defined (ARRAY_VARS)
-  INIT_DYNAMIC_ARRAY_VAR ("FUNCNAME", get_funcname, null_array_assign);
-#else
-  INIT_DYNAMIC_VAR ("FUNCNAME", (char *)NULL, get_funcname, null_assign);
-#endif
-  VSETATTR (v, att_invisible|att_noassign);
-  return v;
-}
-
-static void
-initialize_dynamic_variables ()
-{
-  SHELL_VAR *v;
-
-  v = init_seconds_var ();
-
-  INIT_DYNAMIC_VAR ("BASH_COMMAND", (char *)NULL, get_bash_command, (sh_var_assign_func_t *)NULL);
-  INIT_DYNAMIC_VAR ("BASH_SUBSHELL", (char *)NULL, get_subshell, assign_subshell);
-
-  INIT_DYNAMIC_VAR ("RANDOM", (char *)NULL, get_random, assign_random);
-  VSETATTR (v, att_integer);
-  INIT_DYNAMIC_VAR ("LINENO", (char *)NULL, get_lineno, assign_lineno);
-  VSETATTR (v, att_integer);
-
-  INIT_DYNAMIC_VAR ("BASHPID", (char *)NULL, get_bashpid, null_assign);
-  VSETATTR (v, att_integer|att_readonly);
-
-#if defined (HISTORY)
-  INIT_DYNAMIC_VAR ("HISTCMD", (char *)NULL, get_histcmd, (sh_var_assign_func_t *)NULL);
-  VSETATTR (v, att_integer);
-#endif
-
-#if defined (READLINE)
-  INIT_DYNAMIC_VAR ("COMP_WORDBREAKS", (char *)NULL, get_comp_wordbreaks, assign_comp_wordbreaks);
-#endif
-
-#if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
-  v = init_dynamic_array_var ("DIRSTACK", get_dirstack, assign_dirstack, 0);
-#endif /* PUSHD_AND_POPD && ARRAY_VARS */
-
-#if defined (ARRAY_VARS)
-  v = init_dynamic_array_var ("GROUPS", get_groupset, null_array_assign, att_noassign);
-
-#  if defined (DEBUGGER)
-  v = init_dynamic_array_var ("BASH_ARGC", get_self, null_array_assign, att_noassign|att_nounset);
-  v = init_dynamic_array_var ("BASH_ARGV", get_self, null_array_assign, att_noassign|att_nounset);
-#  endif /* DEBUGGER */
-  v = init_dynamic_array_var ("BASH_SOURCE", get_self, null_array_assign, att_noassign|att_nounset);
-  v = init_dynamic_array_var ("BASH_LINENO", get_self, null_array_assign, att_noassign|att_nounset);
-
-  v = init_dynamic_assoc_var ("BASH_CMDS", get_hashcmd, assign_hashcmd, att_nofree);
-#  if defined (ALIAS)
-  v = init_dynamic_assoc_var ("BASH_ALIASES", get_aliasvar, assign_aliasvar, att_nofree);
-#  endif
-#endif
-
-  v = init_funcname_var ();
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*             Retrieving variables and values                     */
-/*                                                                 */
-/* **************************************************************** */
-
-/* How to get a pointer to the shell variable or function named NAME.
-   HASHED_VARS is a pointer to the hash table containing the list
-   of interest (either variables or functions). */
-
-static SHELL_VAR *
-hash_lookup (name, hashed_vars)
-     const char *name;
-     HASH_TABLE *hashed_vars;
-{
-  BUCKET_CONTENTS *bucket;
-
-  bucket = hash_search (name, hashed_vars, 0);
-  return (bucket ? (SHELL_VAR *)bucket->data : (SHELL_VAR *)NULL);
-}
-
-SHELL_VAR *
-var_lookup (name, vcontext)
-     const char *name;
-     VAR_CONTEXT *vcontext;
-{
-  VAR_CONTEXT *vc;
-  SHELL_VAR *v;
-
-  v = (SHELL_VAR *)NULL;
-  for (vc = vcontext; vc; vc = vc->down)
-    if (v = hash_lookup (name, vc->table))
-      break;
-
-  return v;
-}
-
-/* Look up the variable entry named NAME.  If SEARCH_TEMPENV is non-zero,
-   then also search the temporarily built list of exported variables.
-   The lookup order is:
-       temporary_env
-       shell_variables list
-*/
-
-SHELL_VAR *
-find_variable_internal (name, force_tempenv)
-     const char *name;
-     int force_tempenv;
-{
-  SHELL_VAR *var;
-  int search_tempenv;
-
-  var = (SHELL_VAR *)NULL;
-
-  /* If explicitly requested, first look in the temporary environment for
-     the variable.  This allows constructs such as "foo=x eval 'echo $foo'"
-     to get the `exported' value of $foo.  This happens if we are executing
-     a function or builtin, or if we are looking up a variable in a
-     "subshell environment". */
-  search_tempenv = force_tempenv || (expanding_redir == 0 && subshell_environment);
-
-  if (search_tempenv && temporary_env)         
-    var = hash_lookup (name, temporary_env);
-
-  if (var == 0)
-    var = var_lookup (name, shell_variables);
-
-  if (var == 0)
-    return ((SHELL_VAR *)NULL);
-
-  return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);
-}
-
-/* Look up the variable entry named NAME.  Returns the entry or NULL. */
-SHELL_VAR *
-find_variable (name)
-     const char *name;
-{
-  return (find_variable_internal (name, (expanding_redir == 0 && (assigning_in_environment || executing_builtin))));
-}
-
-/* Look up the function entry whose name matches STRING.
-   Returns the entry or NULL. */
-SHELL_VAR *
-find_function (name)
-     const char *name;
-{
-  return (hash_lookup (name, shell_functions));
-}
-
-/* Find the function definition for the shell function named NAME.  Returns
-   the entry or NULL. */
-FUNCTION_DEF *
-find_function_def (name)
-     const char *name;
-{
-#if defined (DEBUGGER)
-  return ((FUNCTION_DEF *)hash_lookup (name, shell_function_defs));
-#else
-  return ((FUNCTION_DEF *)0);
-#endif
-}
-
-/* Return the value of VAR.  VAR is assumed to have been the result of a
-   lookup without any subscript, if arrays are compiled into the shell. */
-char *
-get_variable_value (var)
-     SHELL_VAR *var;
-{
-  if (var == 0)
-    return ((char *)NULL);
-#if defined (ARRAY_VARS)
-  else if (array_p (var))
-    return (array_reference (array_cell (var), 0));
-  else if (assoc_p (var))
-    return (assoc_reference (assoc_cell (var), "0"));
-#endif
-  else
-    return (value_cell (var));
-}
-
-/* Return the string value of a variable.  Return NULL if the variable
-   doesn't exist.  Don't cons a new string.  This is a potential memory
-   leak if the variable is found in the temporary environment.  Since
-   functions and variables have separate name spaces, returns NULL if
-   var_name is a shell function only. */
-char *
-get_string_value (var_name)
-     const char *var_name;
-{
-  SHELL_VAR *var;
-
-  var = find_variable (var_name);
-  return ((var) ? get_variable_value (var) : (char *)NULL);
-}
-
-/* This is present for use by the tilde and readline libraries. */
-char *
-sh_get_env_value (v)
-     const char *v;
-{
-  return get_string_value (v);
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*               Creating and setting variables                    */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Set NAME to VALUE if NAME has no value. */
-SHELL_VAR *
-set_if_not (name, value)
-     char *name, *value;
-{
-  SHELL_VAR *v;
-
-  if (shell_variables == 0)
-    create_variable_tables ();
-
-  v = find_variable (name);
-  if (v == 0)
-    v = bind_variable_internal (name, value, global_variables->table, HASH_NOSRCH, 0);
-  return (v);
-}
-
-/* Create a local variable referenced by NAME. */
-SHELL_VAR *
-make_local_variable (name)
-     const char *name;
-{
-  SHELL_VAR *new_var, *old_var;
-  VAR_CONTEXT *vc;
-  int was_tmpvar;
-  char *tmp_value;
-
-  /* local foo; local foo;  is a no-op. */
-  old_var = find_variable (name);
-  if (old_var && local_p (old_var) && old_var->context == variable_context)
-    {
-      VUNSETATTR (old_var, att_invisible);
-      return (old_var);
-    }
-
-  was_tmpvar = old_var && tempvar_p (old_var);
-  if (was_tmpvar)
-    tmp_value = value_cell (old_var);
-
-  for (vc = shell_variables; vc; vc = vc->down)
-    if (vc_isfuncenv (vc) && vc->scope == variable_context)
-      break;
-
-  if (vc == 0)
-    {
-      internal_error (_("make_local_variable: no function context at current scope"));
-      return ((SHELL_VAR *)NULL);
-    }
-  else if (vc->table == 0)
-    vc->table = hash_create (TEMPENV_HASH_BUCKETS);
-
-  /* Since this is called only from the local/declare/typeset code, we can
-     call builtin_error here without worry (of course, it will also work
-     for anything that sets this_command_name).  Variables with the `noassign'
-     attribute may not be made local.  The test against old_var's context
-     level is to disallow local copies of readonly global variables (since I
-     believe that this could be a security hole).  Readonly copies of calling
-     function local variables are OK. */
-  if (old_var && (noassign_p (old_var) ||
-                (readonly_p (old_var) && old_var->context == 0)))
-    {
-      if (readonly_p (old_var))
-       sh_readonly (name);
-      return ((SHELL_VAR *)NULL);
-    }
-
-  if (old_var == 0)
-    new_var = make_new_variable (name, vc->table);
-  else
-    {
-      new_var = make_new_variable (name, vc->table);
-
-      /* If we found this variable in one of the temporary environments,
-        inherit its value.  Watch to see if this causes problems with
-        things like `x=4 local x'. */
-      if (was_tmpvar)
-       var_setvalue (new_var, savestring (tmp_value));
-
-      new_var->attributes = exported_p (old_var) ? att_exported : 0;
-    }
-
-  vc->flags |= VC_HASLOCAL;
-
-  new_var->context = variable_context;
-  VSETATTR (new_var, att_local);
-
-  if (ifsname (name))
-    setifs (new_var);
-
-  return (new_var);
-}
-
-/* Create a new shell variable with name NAME. */
-static SHELL_VAR *
-new_shell_variable (name)
-     const char *name;
-{
-  SHELL_VAR *entry;
-
-  entry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
-
-  entry->name = savestring (name);
-  var_setvalue (entry, (char *)NULL);
-  CLEAR_EXPORTSTR (entry);
-
-  entry->dynamic_value = (sh_var_value_func_t *)NULL;
-  entry->assign_func = (sh_var_assign_func_t *)NULL;
-
-  entry->attributes = 0;
-
-  /* Always assume variables are to be made at toplevel!
-     make_local_variable has the responsibilty of changing the
-     variable context. */
-  entry->context = 0;
-
-  return (entry);
-}
-
-/* Create a new shell variable with name NAME and add it to the hash table
-   TABLE. */
-static SHELL_VAR *
-make_new_variable (name, table)
-     const char *name;
-     HASH_TABLE *table;
-{
-  SHELL_VAR *entry;
-  BUCKET_CONTENTS *elt;
-
-  entry = new_shell_variable (name);
-
-  /* Make sure we have a shell_variables hash table to add to. */
-  if (shell_variables == 0)
-    create_variable_tables ();
-
-  elt = hash_insert (savestring (name), table, HASH_NOSRCH);
-  elt->data = (PTR_T)entry;
-
-  return entry;
-}
-
-#if defined (ARRAY_VARS)
-SHELL_VAR *
-make_new_array_variable (name)
-     char *name;
-{
-  SHELL_VAR *entry;
-  ARRAY *array;
-
-  entry = make_new_variable (name, global_variables->table);
-  array = array_create ();
-
-  var_setarray (entry, array);
-  VSETATTR (entry, att_array);
-  return entry;
-}
-
-SHELL_VAR *
-make_local_array_variable (name)
-     char *name;
-{
-  SHELL_VAR *var;
-  ARRAY *array;
-
-  var = make_local_variable (name);
-  if (var == 0 || array_p (var))
-    return var;
-
-  array = array_create ();
-
-  dispose_variable_value (var);
-  var_setarray (var, array);
-  VSETATTR (var, att_array);
-  return var;
-}
-
-SHELL_VAR *
-make_new_assoc_variable (name)
-     char *name;
-{
-  SHELL_VAR *entry;
-  HASH_TABLE *hash;
-
-  entry = make_new_variable (name, global_variables->table);
-  hash = assoc_create (0);
-
-  var_setassoc (entry, hash);
-  VSETATTR (entry, att_assoc);
-  return entry;
-}
-
-SHELL_VAR *
-make_local_assoc_variable (name)
-     char *name;
-{
-  SHELL_VAR *var;
-  HASH_TABLE *hash;
-
-  var = make_local_variable (name);
-  if (var == 0 || assoc_p (var))
-    return var;
-
-  dispose_variable_value (var);
-  hash = assoc_create (0);
-
-  var_setassoc (var, hash);
-  VSETATTR (var, att_assoc);
-  return var;
-}
-#endif
-
-char *
-make_variable_value (var, value, flags)
-     SHELL_VAR *var;
-     char *value;
-     int flags;
-{
-  char *retval, *oval;
-  intmax_t lval, rval;
-  int expok, olen, op;
-
-  /* If this variable has had its type set to integer (via `declare -i'),
-     then do expression evaluation on it and store the result.  The
-     functions in expr.c (evalexp()) and bind_int_variable() are responsible
-     for turning off the integer flag if they don't want further
-     evaluation done. */
-  if (integer_p (var))
-    {
-      if (flags & ASS_APPEND)
-       {
-         oval = value_cell (var);
-         lval = evalexp (oval, &expok);        /* ksh93 seems to do this */
-         if (expok == 0)
-           {
-             top_level_cleanup ();
-             jump_to_top_level (DISCARD);
-           }
-       }
-      rval = evalexp (value, &expok);
-      if (expok == 0)
-       {
-         top_level_cleanup ();
-         jump_to_top_level (DISCARD);
-       }
-      if (flags & ASS_APPEND)
-       rval += lval;
-      retval = itos (rval);
-    }
-#if defined (CASEMOD_ATTRS)
-  else if (capcase_p (var) || uppercase_p (var) || lowercase_p (var))
-    {
-      if (flags & ASS_APPEND)
-       {
-         oval = get_variable_value (var);
-         if (oval == 0)        /* paranoia */
-           oval = "";
-         olen = STRLEN (oval);
-         retval = (char *)xmalloc (olen + (value ? STRLEN (value) : 0) + 1);
-         strcpy (retval, oval);
-         if (value)
-           strcpy (retval+olen, value);
-       }
-      else if (*value)
-       retval = savestring (value);
-      else
-       {
-         retval = (char *)xmalloc (1);
-         retval[0] = '\0';
-       }
-      op = capcase_p (var) ? CASE_CAPITALIZE
-                        : (uppercase_p (var) ? CASE_UPPER : CASE_LOWER);
-      oval = sh_modcase (retval, (char *)0, op);
-      free (retval);
-      retval = oval;
-    }
-#endif /* CASEMOD_ATTRS */
-  else if (value)
-    {
-      if (flags & ASS_APPEND)
-       {
-         oval = get_variable_value (var);
-         if (oval == 0)        /* paranoia */
-           oval = "";
-         olen = STRLEN (oval);
-         retval = (char *)xmalloc (olen + (value ? STRLEN (value) : 0) + 1);
-         strcpy (retval, oval);
-         if (value)
-           strcpy (retval+olen, value);
-       }
-      else if (*value)
-       retval = savestring (value);
-      else
-       {
-         retval = (char *)xmalloc (1);
-         retval[0] = '\0';
-       }
-    }
-  else
-    retval = (char *)NULL;
-
-  return retval;
-}
-
-/* Bind a variable NAME to VALUE in the HASH_TABLE TABLE, which may be the
-   temporary environment (but usually is not). */
-static SHELL_VAR *
-bind_variable_internal (name, value, table, hflags, aflags)
-     const char *name;
-     char *value;
-     HASH_TABLE *table;
-     int hflags, aflags;
-{
-  char *newval;
-  SHELL_VAR *entry;
-
-  entry = (hflags & HASH_NOSRCH) ? (SHELL_VAR *)NULL : hash_lookup (name, table);
-
-  if (entry == 0)
-    {
-      entry = make_new_variable (name, table);
-      var_setvalue (entry, make_variable_value (entry, value, 0)); /* XXX */
-    }
-  else if (entry->assign_func) /* array vars have assign functions now */
-    {
-      INVALIDATE_EXPORTSTR (entry);
-      newval = (aflags & ASS_APPEND) ? make_variable_value (entry, value, aflags) : value;
-      entry = (*(entry->assign_func)) (entry, newval, -1, 0);
-      if (newval != value)
-       free (newval);
-      return (entry);
-    }
-  else
-    {
-      if (readonly_p (entry) || noassign_p (entry))
-       {
-         if (readonly_p (entry))
-           err_readonly (name);
-         return (entry);
-       }
-
-      /* Variables which are bound are visible. */
-      VUNSETATTR (entry, att_invisible);
-
-      newval = make_variable_value (entry, value, aflags);     /* XXX */
-
-      /* Invalidate any cached export string */
-      INVALIDATE_EXPORTSTR (entry);
-
-#if defined (ARRAY_VARS)
-      /* XXX -- this bears looking at again -- XXX */
-      /* If an existing array variable x is being assigned to with x=b or
-        `read x' or something of that nature, silently convert it to
-        x[0]=b or `read x[0]'. */
-      if (array_p (entry))
-       {
-         array_insert (array_cell (entry), 0, newval);
-         free (newval);
-       }
-      else if (assoc_p (entry))
-       {
-         assoc_insert (assoc_cell (entry), savestring ("0"), newval);
-         free (newval);
-       }
-      else
-#endif
-       {
-         FREE (value_cell (entry));
-         var_setvalue (entry, newval);
-       }
-    }
-
-  if (mark_modified_vars)
-    VSETATTR (entry, att_exported);
-
-  if (exported_p (entry))
-    array_needs_making = 1;
-
-  return (entry);
-}
-       
-/* Bind a variable NAME to VALUE.  This conses up the name
-   and value strings.  If we have a temporary environment, we bind there
-   first, then we bind into shell_variables. */
-
-SHELL_VAR *
-bind_variable (name, value, flags)
-     const char *name;
-     char *value;
-     int flags;
-{
-  SHELL_VAR *v;
-  VAR_CONTEXT *vc;
-
-  if (shell_variables == 0)
-    create_variable_tables ();
-
-  /* If we have a temporary environment, look there first for the variable,
-     and, if found, modify the value there before modifying it in the
-     shell_variables table.  This allows sourced scripts to modify values
-     given to them in a temporary environment while modifying the variable
-     value that the caller sees. */
-  if (temporary_env)
-    bind_tempenv_variable (name, value);
-
-  /* XXX -- handle local variables here. */
-  for (vc = shell_variables; vc; vc = vc->down)
-    {
-      if (vc_isfuncenv (vc) || vc_isbltnenv (vc))
-       {
-         v = hash_lookup (name, vc->table);
-         if (v)
-           return (bind_variable_internal (name, value, vc->table, 0, flags));
-       }
-    }
-  return (bind_variable_internal (name, value, global_variables->table, 0, flags));
-}
-
-/* Make VAR, a simple shell variable, have value VALUE.  Once assigned a
-   value, variables are no longer invisible.  This is a duplicate of part
-   of the internals of bind_variable.  If the variable is exported, or
-   all modified variables should be exported, mark the variable for export
-   and note that the export environment needs to be recreated. */
-SHELL_VAR *
-bind_variable_value (var, value, aflags)
-     SHELL_VAR *var;
-     char *value;
-     int aflags;
-{
-  char *t;
-
-  VUNSETATTR (var, att_invisible);
-
-  if (var->assign_func)
-    {
-      /* If we're appending, we need the old value, so use
-        make_variable_value */
-      t = (aflags & ASS_APPEND) ? make_variable_value (var, value, aflags) : value;
-      (*(var->assign_func)) (var, t, -1, 0);
-      if (t != value && t)
-       free (t);      
-    }
-  else
-    {
-      t = make_variable_value (var, value, aflags);
-      FREE (value_cell (var));
-      var_setvalue (var, t);
-    }
-
-  INVALIDATE_EXPORTSTR (var);
-
-  if (mark_modified_vars)
-    VSETATTR (var, att_exported);
-
-  if (exported_p (var))
-    array_needs_making = 1;
-
-  return (var);
-}
-
-/* Bind/create a shell variable with the name LHS to the RHS.
-   This creates or modifies a variable such that it is an integer.
-
-   This used to be in expr.c, but it is here so that all of the
-   variable binding stuff is localized.  Since we don't want any
-   recursive evaluation from bind_variable() (possible without this code,
-   since bind_variable() calls the evaluator for variables with the integer
-   attribute set), we temporarily turn off the integer attribute for each
-   variable we set here, then turn it back on after binding as necessary. */
-
-SHELL_VAR *
-bind_int_variable (lhs, rhs)
-     char *lhs, *rhs;
-{
-  register SHELL_VAR *v;
-  int isint, isarr;
-
-  isint = isarr = 0;
-#if defined (ARRAY_VARS)
-  if (valid_array_reference (lhs))
-    {
-      isarr = 1;
-      v = array_variable_part (lhs, (char **)0, (int *)0);
-    }
-  else
-#endif
-    v = find_variable (lhs);
-
-  if (v)
-    {
-      isint = integer_p (v);
-      VUNSETATTR (v, att_integer);
-    }
-
-#if defined (ARRAY_VARS)
-  if (isarr)
-    v = assign_array_element (lhs, rhs, 0);
-  else
-#endif
-    v = bind_variable (lhs, rhs, 0);
-
-  if (isint)
-    VSETATTR (v, att_integer);
-
-  return (v);
-}
-
-SHELL_VAR *
-bind_var_to_int (var, val)
-     char *var;
-     intmax_t val;
-{
-  char ibuf[INT_STRLEN_BOUND (intmax_t) + 1], *p;
-
-  p = fmtulong (val, 10, ibuf, sizeof (ibuf), 0);
-  return (bind_int_variable (var, p));
-}
-
-/* Do a function binding to a variable.  You pass the name and
-   the command to bind to.  This conses the name and command. */
-SHELL_VAR *
-bind_function (name, value)
-     const char *name;
-     COMMAND *value;
-{
-  SHELL_VAR *entry;
-
-  entry = find_function (name);
-  if (entry == 0)
-    {
-      BUCKET_CONTENTS *elt;
-
-      elt = hash_insert (savestring (name), shell_functions, HASH_NOSRCH);
-      entry = new_shell_variable (name);
-      elt->data = (PTR_T)entry;
-    }
-  else
-    INVALIDATE_EXPORTSTR (entry);
-
-  if (var_isset (entry))
-    dispose_command (function_cell (entry));
-
-  if (value)
-    var_setfunc (entry, copy_command (value));
-  else
-    var_setfunc (entry, 0);
-
-  VSETATTR (entry, att_function);
-
-  if (mark_modified_vars)
-    VSETATTR (entry, att_exported);
-
-  VUNSETATTR (entry, att_invisible);           /* Just to be sure */
-
-  if (exported_p (entry))
-    array_needs_making = 1;
-
-#if defined (PROGRAMMABLE_COMPLETION)
-  set_itemlist_dirty (&it_functions);
-#endif
-
-  return (entry);
-}
-
-#if defined (DEBUGGER)
-/* Bind a function definition, which includes source file and line number
-   information in addition to the command, into the FUNCTION_DEF hash table.*/
-void
-bind_function_def (name, value)
-     const char *name;
-     FUNCTION_DEF *value;
-{
-  FUNCTION_DEF *entry;
-  BUCKET_CONTENTS *elt;
-  COMMAND *cmd;
-
-  entry = find_function_def (name);
-  if (entry)
-    {
-      dispose_function_def_contents (entry);
-      entry = copy_function_def_contents (value, entry);
-    }
-  else
-    {
-      cmd = value->command;
-      value->command = 0;
-      entry = copy_function_def (value);
-      value->command = cmd;
-
-      elt = hash_insert (savestring (name), shell_function_defs, HASH_NOSRCH);
-      elt->data = (PTR_T *)entry;
-    }
-}
-#endif /* DEBUGGER */
-
-/* Add STRING, which is of the form foo=bar, to the temporary environment
-   HASH_TABLE (temporary_env).  The functions in execute_cmd.c are
-   responsible for moving the main temporary env to one of the other
-   temporary environments.  The expansion code in subst.c calls this. */
-int
-assign_in_env (word)
-     WORD_DESC *word;
-{
-  int offset;
-  char *name, *temp, *value;
-  SHELL_VAR *var;
-  const char *string;
-
-  string = word->word;
-
-  offset = assignment (string, 0);
-  name = savestring (string);
-  value = (char *)NULL;
-
-  if (name[offset] == '=')
-    {
-      name[offset] = 0;
-
-      /* ignore the `+' when assigning temporary environment */
-      if (name[offset - 1] == '+')
-       name[offset - 1] = '\0';
-
-      var = find_variable (name);
-      if (var && (readonly_p (var) || noassign_p (var)))
-       {
-         if (readonly_p (var))
-           err_readonly (name);
-         free (name);
-         return (0);
-       }
-
-      temp = name + offset + 1;
-      value = expand_assignment_string_to_string (temp, 0);
-    }
-
-  if (temporary_env == 0)
-    temporary_env = hash_create (TEMPENV_HASH_BUCKETS);
-
-  var = hash_lookup (name, temporary_env);
-  if (var == 0)
-    var = make_new_variable (name, temporary_env);
-  else
-    FREE (value_cell (var));
-
-  if (value == 0)
-    {
-      value = (char *)xmalloc (1);     /* like do_assignment_internal */
-      value[0] = '\0';
-    }
-
-  var_setvalue (var, value);
-  var->attributes |= (att_exported|att_tempvar);
-  var->context = variable_context;     /* XXX */
-
-  INVALIDATE_EXPORTSTR (var);
-  var->exportstr = mk_env_string (name, value);
-
-  array_needs_making = 1;
-
-  if (ifsname (name))
-    setifs (var);
-
-  if (echo_command_at_execute)
-    /* The Korn shell prints the `+ ' in front of assignment statements,
-       so we do too. */
-    xtrace_print_assignment (name, value, 0, 1);
-
-  free (name);
-  return 1;
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*                     Copying variables                           */
-/*                                                                 */
-/* **************************************************************** */
-
-#ifdef INCLUDE_UNUSED
-/* Copy VAR to a new data structure and return that structure. */
-SHELL_VAR *
-copy_variable (var)
-     SHELL_VAR *var;
-{
-  SHELL_VAR *copy = (SHELL_VAR *)NULL;
-
-  if (var)
-    {
-      copy = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
-
-      copy->attributes = var->attributes;
-      copy->name = savestring (var->name);
-
-      if (function_p (var))
-       var_setfunc (copy, copy_command (function_cell (var)));
-#if defined (ARRAY_VARS)
-      else if (array_p (var))
-       var_setarray (copy, array_copy (array_cell (var)));
-      else if (assoc_p (var))
-       var_setassoc (copy, assoc_copy (assoc_cell (var)));
-#endif
-      else if (value_cell (var))
-       var_setvalue (copy, savestring (value_cell (var)));
-      else
-       var_setvalue (copy, (char *)NULL);
-
-      copy->dynamic_value = var->dynamic_value;
-      copy->assign_func = var->assign_func;
-
-      copy->exportstr = COPY_EXPORTSTR (var);
-
-      copy->context = var->context;
-    }
-  return (copy);
-}
-#endif
-
-/* **************************************************************** */
-/*                                                                 */
-/*               Deleting and unsetting variables                  */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Dispose of the information attached to VAR. */
-static void
-dispose_variable_value (var)
-     SHELL_VAR *var;
-{
-  if (function_p (var))
-    dispose_command (function_cell (var));
-#if defined (ARRAY_VARS)
-  else if (array_p (var))
-    array_dispose (array_cell (var));
-  else if (assoc_p (var))
-    assoc_dispose (assoc_cell (var));
-#endif
-  else
-    FREE (value_cell (var));
-}
-
-void
-dispose_variable (var)
-     SHELL_VAR *var;
-{
-  if (var == 0)
-    return;
-
-  if (nofree_p (var) == 0)
-    dispose_variable_value (var);
-
-  FREE_EXPORTSTR (var);
-
-  free (var->name);
-
-  if (exported_p (var))
-    array_needs_making = 1;
-
-  free (var);
-}
-
-/* Unset the shell variable referenced by NAME. */
-int
-unbind_variable (name)
-     const char *name;
-{
-  return makunbound (name, shell_variables);
-}
-
-/* Unset the shell function named NAME. */
-int
-unbind_func (name)
-     const char *name;
-{
-  BUCKET_CONTENTS *elt;
-  SHELL_VAR *func;
-
-  elt = hash_remove (name, shell_functions, 0);
-
-  if (elt == 0)
-    return -1;
-
-#if defined (PROGRAMMABLE_COMPLETION)
-  set_itemlist_dirty (&it_functions);
-#endif
-
-  func = (SHELL_VAR *)elt->data;
-  if (func)
-    {
-      if (exported_p (func))
-       array_needs_making++;
-      dispose_variable (func);
-    }
-
-  free (elt->key);
-  free (elt);
-
-  return 0;  
-}
-
-#if defined (DEBUGGER)
-int
-unbind_function_def (name)
-     const char *name;
-{
-  BUCKET_CONTENTS *elt;
-  FUNCTION_DEF *funcdef;
-
-  elt = hash_remove (name, shell_function_defs, 0);
-
-  if (elt == 0)
-    return -1;
-
-  funcdef = (FUNCTION_DEF *)elt->data;
-  if (funcdef)
-    dispose_function_def (funcdef);
-
-  free (elt->key);
-  free (elt);
-
-  return 0;  
-}
-#endif /* DEBUGGER */
-
-/* Make the variable associated with NAME go away.  HASH_LIST is the
-   hash table from which this variable should be deleted (either
-   shell_variables or shell_functions).
-   Returns non-zero if the variable couldn't be found. */
-int
-makunbound (name, vc)
-     const char *name;
-     VAR_CONTEXT *vc;
-{
-  BUCKET_CONTENTS *elt, *new_elt;
-  SHELL_VAR *old_var;
-  VAR_CONTEXT *v;
-  char *t;
-
-  for (elt = (BUCKET_CONTENTS *)NULL, v = vc; v; v = v->down)
-    if (elt = hash_remove (name, v->table, 0))
-      break;
-
-  if (elt == 0)
-    return (-1);
-
-  old_var = (SHELL_VAR *)elt->data;
-
-  if (old_var && exported_p (old_var))
-    array_needs_making++;
-
-  /* If we're unsetting a local variable and we're still executing inside
-     the function, just mark the variable as invisible.  The function
-     eventually called by pop_var_context() will clean it up later.  This
-     must be done so that if the variable is subsequently assigned a new
-     value inside the function, the `local' attribute is still present.
-     We also need to add it back into the correct hash table. */
-  if (old_var && local_p (old_var) && variable_context == old_var->context)
-    {
-      if (nofree_p (old_var))
-       var_setvalue (old_var, (char *)NULL);
-#if defined (ARRAY_VARS)
-      else if (array_p (old_var))
-       array_dispose (array_cell (old_var));
-      else if (assoc_p (old_var))
-       assoc_dispose (assoc_cell (old_var));
-#endif
-      else
-       FREE (value_cell (old_var));
-      /* Reset the attributes.  Preserve the export attribute if the variable
-        came from a temporary environment.  Make sure it stays local, and
-        make it invisible. */ 
-      old_var->attributes = (exported_p (old_var) && tempvar_p (old_var)) ? att_exported : 0;
-      VSETATTR (old_var, att_local);
-      VSETATTR (old_var, att_invisible);
-      var_setvalue (old_var, (char *)NULL);
-      INVALIDATE_EXPORTSTR (old_var);
-
-      new_elt = hash_insert (savestring (old_var->name), v->table, 0);
-      new_elt->data = (PTR_T)old_var;
-      stupidly_hack_special_variables (old_var->name);
-
-      free (elt->key);
-      free (elt);
-      return (0);
-    }
-
-  /* Have to save a copy of name here, because it might refer to
-     old_var->name.  If so, stupidly_hack_special_variables will
-     reference freed memory. */
-  t = savestring (name);
-
-  free (elt->key);
-  free (elt);
-
-  dispose_variable (old_var);
-  stupidly_hack_special_variables (t);
-  free (t);
-
-  return (0);
-}
-
-/* Get rid of all of the variables in the current context. */
-void
-kill_all_local_variables ()
-{
-  VAR_CONTEXT *vc;
-
-  for (vc = shell_variables; vc; vc = vc->down)
-    if (vc_isfuncenv (vc) && vc->scope == variable_context)
-      break;
-  if (vc == 0)
-    return;            /* XXX */
-
-  if (vc->table && vc_haslocals (vc))
-    {
-      delete_all_variables (vc->table);
-      hash_dispose (vc->table);
-    }
-  vc->table = (HASH_TABLE *)NULL;
-}
-
-static void
-free_variable_hash_data (data)
-     PTR_T data;
-{
-  SHELL_VAR *var;
-
-  var = (SHELL_VAR *)data;
-  dispose_variable (var);
-}
-
-/* Delete the entire contents of the hash table. */
-void
-delete_all_variables (hashed_vars)
-     HASH_TABLE *hashed_vars;
-{
-  hash_flush (hashed_vars, free_variable_hash_data);
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*                  Setting variable attributes                    */
-/*                                                                 */
-/* **************************************************************** */
-
-#define FIND_OR_MAKE_VARIABLE(name, entry) \
-  do \
-    { \
-      entry = find_variable (name); \
-      if (!entry) \
-       { \
-         entry = bind_variable (name, "", 0); \
-         if (!no_invisible_vars) entry->attributes |= att_invisible; \
-       } \
-    } \
-  while (0)
-
-/* Make the variable associated with NAME be readonly.
-   If NAME does not exist yet, create it. */
-void
-set_var_read_only (name)
-     char *name;
-{
-  SHELL_VAR *entry;
-
-  FIND_OR_MAKE_VARIABLE (name, entry);
-  VSETATTR (entry, att_readonly);
-}
-
-#ifdef INCLUDE_UNUSED
-/* Make the function associated with NAME be readonly.
-   If NAME does not exist, we just punt, like auto_export code below. */
-void
-set_func_read_only (name)
-     const char *name;
-{
-  SHELL_VAR *entry;
-
-  entry = find_function (name);
-  if (entry)
-    VSETATTR (entry, att_readonly);
-}
-
-/* Make the variable associated with NAME be auto-exported.
-   If NAME does not exist yet, create it. */
-void
-set_var_auto_export (name)
-     char *name;
-{
-  SHELL_VAR *entry;
-
-  FIND_OR_MAKE_VARIABLE (name, entry);
-  set_auto_export (entry);
-}
-
-/* Make the function associated with NAME be auto-exported. */
-void
-set_func_auto_export (name)
-     const char *name;
-{
-  SHELL_VAR *entry;
-
-  entry = find_function (name);
-  if (entry)
-    set_auto_export (entry);
-}
-#endif
-
-/* **************************************************************** */
-/*                                                                 */
-/*                  Creating lists of variables                    */
-/*                                                                 */
-/* **************************************************************** */
-
-static VARLIST *
-vlist_alloc (nentries)
-     int nentries;
-{
-  VARLIST  *vlist;
-
-  vlist = (VARLIST *)xmalloc (sizeof (VARLIST));
-  vlist->list = (SHELL_VAR **)xmalloc ((nentries + 1) * sizeof (SHELL_VAR *));
-  vlist->list_size = nentries;
-  vlist->list_len = 0;
-  vlist->list[0] = (SHELL_VAR *)NULL;
-
-  return vlist;
-}
-
-static VARLIST *
-vlist_realloc (vlist, n)
-     VARLIST *vlist;
-     int n;
-{
-  if (vlist == 0)
-    return (vlist = vlist_alloc (n));
-  if (n > vlist->list_size)
-    {
-      vlist->list_size = n;
-      vlist->list = (SHELL_VAR **)xrealloc (vlist->list, (vlist->list_size + 1) * sizeof (SHELL_VAR *));
-    }
-  return vlist;
-}
-
-static void
-vlist_add (vlist, var, flags)
-     VARLIST *vlist;
-     SHELL_VAR *var;
-     int flags;
-{
-  register int i;
-
-  for (i = 0; i < vlist->list_len; i++)
-    if (STREQ (var->name, vlist->list[i]->name))
-      break;
-  if (i < vlist->list_len)
-    return;
-
-  if (i >= vlist->list_size)
-    vlist = vlist_realloc (vlist, vlist->list_size + 16);
-
-  vlist->list[vlist->list_len++] = var;
-  vlist->list[vlist->list_len] = (SHELL_VAR *)NULL;
-}
-
-/* Map FUNCTION over the variables in VAR_HASH_TABLE.  Return an array of the
-   variables for which FUNCTION returns a non-zero value.  A NULL value
-   for FUNCTION means to use all variables. */
-SHELL_VAR **
-map_over (function, vc)
-     sh_var_map_func_t *function;
-     VAR_CONTEXT *vc;
-{
-  VAR_CONTEXT *v;
-  VARLIST *vlist;
-  SHELL_VAR **ret;
-  int nentries;
-
-  for (nentries = 0, v = vc; v; v = v->down)
-    nentries += HASH_ENTRIES (v->table);
-
-  if (nentries == 0)
-    return (SHELL_VAR **)NULL;
-
-  vlist = vlist_alloc (nentries);
-
-  for (v = vc; v; v = v->down)
-    flatten (v->table, function, vlist, 0);
-
-  ret = vlist->list;
-  free (vlist);
-  return ret;
-}
-
-SHELL_VAR **
-map_over_funcs (function)
-     sh_var_map_func_t *function;
-{
-  VARLIST *vlist;
-  SHELL_VAR **ret;
-
-  if (shell_functions == 0 || HASH_ENTRIES (shell_functions) == 0)
-    return ((SHELL_VAR **)NULL);
-
-  vlist = vlist_alloc (HASH_ENTRIES (shell_functions));
-
-  flatten (shell_functions, function, vlist, 0);
-
-  ret = vlist->list;
-  free (vlist);
-  return ret;
-}
-
-/* Flatten VAR_HASH_TABLE, applying FUNC to each member and adding those
-   elements for which FUNC succeeds to VLIST->list.  FLAGS is reserved
-   for future use.  Only unique names are added to VLIST.  If FUNC is
-   NULL, each variable in VAR_HASH_TABLE is added to VLIST.  If VLIST is
-   NULL, FUNC is applied to each SHELL_VAR in VAR_HASH_TABLE.  If VLIST
-   and FUNC are both NULL, nothing happens. */
-static void
-flatten (var_hash_table, func, vlist, flags)
-     HASH_TABLE *var_hash_table;
-     sh_var_map_func_t *func;
-     VARLIST *vlist;
-     int flags;
-{
-  register int i;
-  register BUCKET_CONTENTS *tlist;
-  int r;
-  SHELL_VAR *var;
-
-  if (var_hash_table == 0 || (HASH_ENTRIES (var_hash_table) == 0) || (vlist == 0 && func == 0))
-    return;
-
-  for (i = 0; i < var_hash_table->nbuckets; i++)
-    {
-      for (tlist = hash_items (i, var_hash_table); tlist; tlist = tlist->next)
-       {
-         var = (SHELL_VAR *)tlist->data;
-
-         r = func ? (*func) (var) : 1;
-         if (r && vlist)
-           vlist_add (vlist, var, flags);
-       }
-    }
-}
-
-void
-sort_variables (array)
-     SHELL_VAR **array;
-{
-  qsort (array, strvec_len ((char **)array), sizeof (SHELL_VAR *), (QSFUNC *)qsort_var_comp);
-}
-
-static int
-qsort_var_comp (var1, var2)
-     SHELL_VAR **var1, **var2;
-{
-  int result;
-
-  if ((result = (*var1)->name[0] - (*var2)->name[0]) == 0)
-    result = strcmp ((*var1)->name, (*var2)->name);
-
-  return (result);
-}
-
-/* Apply FUNC to each variable in SHELL_VARIABLES, adding each one for
-   which FUNC succeeds to an array of SHELL_VAR *s.  Returns the array. */
-static SHELL_VAR **
-vapply (func)
-     sh_var_map_func_t *func;
-{
-  SHELL_VAR **list;
-
-  list = map_over (func, shell_variables);
-  if (list /* && posixly_correct */)
-    sort_variables (list);
-  return (list);
-}
-
-/* Apply FUNC to each variable in SHELL_FUNCTIONS, adding each one for
-   which FUNC succeeds to an array of SHELL_VAR *s.  Returns the array. */
-static SHELL_VAR **
-fapply (func)
-     sh_var_map_func_t *func;
-{
-  SHELL_VAR **list;
-
-  list = map_over_funcs (func);
-  if (list /* && posixly_correct */)
-    sort_variables (list);
-  return (list);
-}
-
-/* Create a NULL terminated array of all the shell variables. */
-SHELL_VAR **
-all_shell_variables ()
-{
-  return (vapply ((sh_var_map_func_t *)NULL));
-}
-
-/* Create a NULL terminated array of all the shell functions. */
-SHELL_VAR **
-all_shell_functions ()
-{
-  return (fapply ((sh_var_map_func_t *)NULL));
-}
-
-static int
-visible_var (var)
-     SHELL_VAR *var;
-{
-  return (invisible_p (var) == 0);
-}
-
-SHELL_VAR **
-all_visible_functions ()
-{
-  return (fapply (visible_var));
-}
-
-SHELL_VAR **
-all_visible_variables ()
-{
-  return (vapply (visible_var));
-}
-
-/* Return non-zero if the variable VAR is visible and exported.  Array
-   variables cannot be exported. */
-static int
-visible_and_exported (var)
-     SHELL_VAR *var;
-{
-  return (invisible_p (var) == 0 && exported_p (var));
-}
-
-/* Candidate variables for the export environment are either valid variables
-   with the export attribute or invalid variables inherited from the initial
-   environment and simply passed through. */
-static int
-export_environment_candidate (var)
-     SHELL_VAR *var;
-{
-  return (exported_p (var) && (invisible_p (var) == 0 || imported_p (var)));
-}
-
-/* Return non-zero if VAR is a local variable in the current context and
-   is exported. */
-static int
-local_and_exported (var)
-     SHELL_VAR *var;
-{
-  return (invisible_p (var) == 0 && local_p (var) && var->context == variable_context && exported_p (var));
-}
-
-SHELL_VAR **
-all_exported_variables ()
-{
-  return (vapply (visible_and_exported));
-}
-
-SHELL_VAR **
-local_exported_variables ()
-{
-  return (vapply (local_and_exported));
-}
-
-static int
-variable_in_context (var)
-     SHELL_VAR *var;
-{
-  return (invisible_p (var) == 0 && local_p (var) && var->context == variable_context);
-}
-
-SHELL_VAR **
-all_local_variables ()
-{
-  VARLIST *vlist;
-  SHELL_VAR **ret;
-  VAR_CONTEXT *vc;
-
-  vc = shell_variables;
-  for (vc = shell_variables; vc; vc = vc->down)
-    if (vc_isfuncenv (vc) && vc->scope == variable_context)
-      break;
-
-  if (vc == 0)
-    {
-      internal_error (_("all_local_variables: no function context at current scope"));
-      return (SHELL_VAR **)NULL;
-    }
-  if (vc->table == 0 || HASH_ENTRIES (vc->table) == 0 || vc_haslocals (vc) == 0)
-    return (SHELL_VAR **)NULL;
-    
-  vlist = vlist_alloc (HASH_ENTRIES (vc->table));
-
-  flatten (vc->table, variable_in_context, vlist, 0);
-
-  ret = vlist->list;
-  free (vlist);
-  if (ret)
-    sort_variables (ret);
-  return ret;
-}
-
-#if defined (ARRAY_VARS)
-/* Return non-zero if the variable VAR is visible and an array. */
-static int
-visible_array_vars (var)
-     SHELL_VAR *var;
-{
-  return (invisible_p (var) == 0 && array_p (var));
-}
-
-SHELL_VAR **
-all_array_variables ()
-{
-  return (vapply (visible_array_vars));
-}
-#endif /* ARRAY_VARS */
-
-char **
-all_variables_matching_prefix (prefix)
-     const char *prefix;
-{
-  SHELL_VAR **varlist;
-  char **rlist;
-  int vind, rind, plen;
-
-  plen = STRLEN (prefix);
-  varlist = all_visible_variables ();
-  for (vind = 0; varlist && varlist[vind]; vind++)
-    ;
-  if (varlist == 0 || vind == 0)
-    return ((char **)NULL);
-  rlist = strvec_create (vind + 1);
-  for (vind = rind = 0; varlist[vind]; vind++)
-    {
-      if (plen == 0 || STREQN (prefix, varlist[vind]->name, plen))
-       rlist[rind++] = savestring (varlist[vind]->name);
-    }
-  rlist[rind] = (char *)0;
-  free (varlist);
-
-  return rlist;
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*              Managing temporary variable scopes                 */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Make variable NAME have VALUE in the temporary environment. */
-static SHELL_VAR *
-bind_tempenv_variable (name, value)
-     const char *name;
-     char *value;
-{
-  SHELL_VAR *var;
-
-  var = temporary_env ? hash_lookup (name, temporary_env) : (SHELL_VAR *)NULL;
-
-  if (var)
-    {
-      FREE (value_cell (var));
-      var_setvalue (var, savestring (value));
-      INVALIDATE_EXPORTSTR (var);
-    }
-
-  return (var);
-}
-
-/* Find a variable in the temporary environment that is named NAME.
-   Return the SHELL_VAR *, or NULL if not found. */
-SHELL_VAR *
-find_tempenv_variable (name)
-     const char *name;
-{
-  return (temporary_env ? hash_lookup (name, temporary_env) : (SHELL_VAR *)NULL);
-}
-
-/* Push the variable described by (SHELL_VAR *)DATA down to the next
-   variable context from the temporary environment. */
-static void
-push_temp_var (data)
-     PTR_T data;
-{
-  SHELL_VAR *var, *v;
-  HASH_TABLE *binding_table;
-
-  var = (SHELL_VAR *)data;
-
-  binding_table = shell_variables->table;
-  if (binding_table == 0)
-    {
-      if (shell_variables == global_variables)
-       /* shouldn't happen */
-       binding_table = shell_variables->table = global_variables->table = hash_create (0);
-      else
-       binding_table = shell_variables->table = hash_create (TEMPENV_HASH_BUCKETS);
-    }
-
-  v = bind_variable_internal (var->name, value_cell (var), binding_table, 0, 0);
-
-  /* XXX - should we set the context here?  It shouldn't matter because of how
-     assign_in_env works, but might want to check. */
-  if (binding_table == global_variables->table)                /* XXX */
-    var->attributes &= ~(att_tempvar|att_propagate);
-  else
-    {
-      var->attributes |= att_propagate;
-      if  (binding_table == shell_variables->table)
-       shell_variables->flags |= VC_HASTMPVAR;
-    }
-  v->attributes |= var->attributes;
-
-  dispose_variable (var);
-}
-
-static void
-propagate_temp_var (data)
-     PTR_T data;
-{
-  SHELL_VAR *var;
-
-  var = (SHELL_VAR *)data;
-  if (tempvar_p (var) && (var->attributes & att_propagate))
-    push_temp_var (data);
-  else
-    dispose_variable (var);
-}
-
-/* Free the storage used in the hash table for temporary
-   environment variables.  PUSHF is a function to be called
-   to free each hash table entry.  It takes care of pushing variables
-   to previous scopes if appropriate. */
-static void
-dispose_temporary_env (pushf)
-     sh_free_func_t *pushf;
-{
-  hash_flush (temporary_env, pushf);
-  hash_dispose (temporary_env);
-  temporary_env = (HASH_TABLE *)NULL;
-
-  array_needs_making = 1;
-
-  sv_ifs ("IFS");              /* XXX here for now */
-}
-
-void
-dispose_used_env_vars ()
-{
-  if (temporary_env)
-    {
-      dispose_temporary_env (propagate_temp_var);
-      maybe_make_export_env ();
-    }
-}
-
-/* Take all of the shell variables in the temporary environment HASH_TABLE
-   and make shell variables from them at the current variable context. */
-void
-merge_temporary_env ()
-{
-  if (temporary_env)
-    dispose_temporary_env (push_temp_var);
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*          Creating and manipulating the environment              */
-/*                                                                 */
-/* **************************************************************** */
-
-static inline char *
-mk_env_string (name, value)
-     const char *name, *value;
-{
-  int name_len, value_len;
-  char *p;
-
-  name_len = strlen (name);
-  value_len = STRLEN (value);
-  p = (char *)xmalloc (2 + name_len + value_len);
-  strcpy (p, name);
-  p[name_len] = '=';
-  if (value && *value)
-    strcpy (p + name_len + 1, value);
-  else
-    p[name_len + 1] = '\0';
-  return (p);
-}
-
-#ifdef DEBUG
-/* Debugging */
-static int
-valid_exportstr (v)
-     SHELL_VAR *v;
-{
-  char *s;
-
-  s = v->exportstr;
-  if (legal_variable_starter ((unsigned char)*s) == 0)
-    {
-      internal_error (_("invalid character %d in exportstr for %s"), *s, v->name);
-      return (0);
-    }
-  for (s = v->exportstr + 1; s && *s; s++)
-    {
-      if (*s == '=')
-       break;
-      if (legal_variable_char ((unsigned char)*s) == 0)
-       {
-         internal_error (_("invalid character %d in exportstr for %s"), *s, v->name);
-         return (0);
-       }
-    }
-  if (*s != '=')
-    {
-      internal_error (_("no `=' in exportstr for %s"), v->name);
-      return (0);
-    }
-  return (1);
-}
-#endif
-
-static char **
-make_env_array_from_var_list (vars)
-     SHELL_VAR **vars;
-{
-  register int i, list_index;
-  register SHELL_VAR *var;
-  char **list, *value;
-
-  list = strvec_create ((1 + strvec_len ((char **)vars)));
-
-#define USE_EXPORTSTR (value == var->exportstr)
-
-  for (i = 0, list_index = 0; var = vars[i]; i++)
-    {
-#if defined (__CYGWIN__)
-      /* We don't use the exportstr stuff on Cygwin at all. */
-      INVALIDATE_EXPORTSTR (var);
-#endif
-      if (var->exportstr)
-       value = var->exportstr;
-      else if (function_p (var))
-       value = named_function_string ((char *)NULL, function_cell (var), 0);
-#if defined (ARRAY_VARS)
-      else if (array_p (var))
-#  if 0
-       value = array_to_assignment_string (array_cell (var));
-#  else
-       continue;       /* XXX array vars cannot yet be exported */
-#  endif
-      else if (assoc_p (var))
-#  if 0
-       value = assoc_to_assignment_string (assoc_cell (var));
-#  else
-       continue;       /* XXX associative array vars cannot yet be exported */
-#  endif
-#endif
-      else
-       value = value_cell (var);
-
-      if (value)
-       {
-         /* Gee, I'd like to get away with not using savestring() if we're
-            using the cached exportstr... */
-         list[list_index] = USE_EXPORTSTR ? savestring (value)
-                                          : mk_env_string (var->name, value);
-
-         if (USE_EXPORTSTR == 0)
-           SAVE_EXPORTSTR (var, list[list_index]);
-
-         list_index++;
-#undef USE_EXPORTSTR
-
-#if 0  /* not yet */
-#if defined (ARRAY_VARS)
-         if (array_p (var) || assoc_p (var))
-           free (value);
-#endif
-#endif
-       }
-    }
-
-  list[list_index] = (char *)NULL;
-  return (list);
-}
-
-/* Make an array of assignment statements from the hash table
-   HASHED_VARS which contains SHELL_VARs.  Only visible, exported
-   variables are eligible. */
-static char **
-make_var_export_array (vcxt)
-     VAR_CONTEXT *vcxt;
-{
-  char **list;
-  SHELL_VAR **vars;
-
-#if 0
-  vars = map_over (visible_and_exported, vcxt);
-#else
-  vars = map_over (export_environment_candidate, vcxt);
-#endif
-
-  if (vars == 0)
-    return (char **)NULL;
-
-  list = make_env_array_from_var_list (vars);
-
-  free (vars);
-  return (list);
-}
-
-static char **
-make_func_export_array ()
-{
-  char **list;
-  SHELL_VAR **vars;
-
-  vars = map_over_funcs (visible_and_exported);
-  if (vars == 0)
-    return (char **)NULL;
-
-  list = make_env_array_from_var_list (vars);
-
-  free (vars);
-  return (list);
-}
-
-/* Add ENVSTR to the end of the exported environment, EXPORT_ENV. */
-#define add_to_export_env(envstr,do_alloc) \
-do \
-  { \
-    if (export_env_index >= (export_env_size - 1)) \
-      { \
-       export_env_size += 16; \
-       export_env = strvec_resize (export_env, export_env_size); \
-       environ = export_env; \
-      } \
-    export_env[export_env_index++] = (do_alloc) ? savestring (envstr) : envstr; \
-    export_env[export_env_index] = (char *)NULL; \
-  } while (0)
-
-/* Add ASSIGN to EXPORT_ENV, or supercede a previous assignment in the
-   array with the same left-hand side.  Return the new EXPORT_ENV. */
-char **
-add_or_supercede_exported_var (assign, do_alloc)
-     char *assign;
-     int do_alloc;
-{
-  register int i;
-  int equal_offset;
-
-  equal_offset = assignment (assign, 0);
-  if (equal_offset == 0)
-    return (export_env);
-
-  /* If this is a function, then only supersede the function definition.
-     We do this by including the `=() {' in the comparison, like
-     initialize_shell_variables does. */
-  if (assign[equal_offset + 1] == '(' &&
-     strncmp (assign + equal_offset + 2, ") {", 3) == 0)               /* } */
-    equal_offset += 4;
-
-  for (i = 0; i < export_env_index; i++)
-    {
-      if (STREQN (assign, export_env[i], equal_offset + 1))
-       {
-         free (export_env[i]);
-         export_env[i] = do_alloc ? savestring (assign) : assign;
-         return (export_env);
-       }
-    }
-  add_to_export_env (assign, do_alloc);
-  return (export_env);
-}
-
-static void
-add_temp_array_to_env (temp_array, do_alloc, do_supercede)
-     char **temp_array;
-     int do_alloc, do_supercede;
-{
-  register int i;
-
-  if (temp_array == 0)
-    return;
-
-  for (i = 0; temp_array[i]; i++)
-    {
-      if (do_supercede)
-       export_env = add_or_supercede_exported_var (temp_array[i], do_alloc);
-      else
-       add_to_export_env (temp_array[i], do_alloc);
-    }
-
-  free (temp_array);
-}
-
-/* Make the environment array for the command about to be executed, if the
-   array needs making.  Otherwise, do nothing.  If a shell action could
-   change the array that commands receive for their environment, then the
-   code should `array_needs_making++'.
-
-   The order to add to the array is:
-       temporary_env
-       list of var contexts whose head is shell_variables
-       shell_functions
-
-  This is the shell variable lookup order.  We add only new variable
-  names at each step, which allows local variables and variables in
-  the temporary environments to shadow variables in the global (or
-  any previous) scope.
-*/
-
-static int
-n_shell_variables ()
-{
-  VAR_CONTEXT *vc;
-  int n;
-
-  for (n = 0, vc = shell_variables; vc; vc = vc->down)
-    n += HASH_ENTRIES (vc->table);
-  return n;
-}
-
-void
-maybe_make_export_env ()
-{
-  register char **temp_array;
-  int new_size;
-  VAR_CONTEXT *tcxt;
-
-  if (array_needs_making)
-    {
-      if (export_env)
-       strvec_flush (export_env);
-
-      /* Make a guess based on how many shell variables and functions we
-        have.  Since there will always be array variables, and array
-        variables are not (yet) exported, this will always be big enough
-        for the exported variables and functions. */
-      new_size = n_shell_variables () + HASH_ENTRIES (shell_functions) + 1 +
-                HASH_ENTRIES (temporary_env);
-      if (new_size > export_env_size)
-       {
-         export_env_size = new_size;
-         export_env = strvec_resize (export_env, export_env_size);
-         environ = export_env;
-       }
-      export_env[export_env_index = 0] = (char *)NULL;
-
-      /* Make a dummy variable context from the temporary_env, stick it on
-        the front of shell_variables, call make_var_export_array on the
-        whole thing to flatten it, and convert the list of SHELL_VAR *s
-        to the form needed by the environment. */
-      if (temporary_env)
-       {
-         tcxt = new_var_context ((char *)NULL, 0);
-         tcxt->table = temporary_env;
-         tcxt->down = shell_variables;
-       }
-      else
-       tcxt = shell_variables;
-      
-      temp_array = make_var_export_array (tcxt);
-      if (temp_array)
-       add_temp_array_to_env (temp_array, 0, 0);
-
-      if (tcxt != shell_variables)
-       free (tcxt);
-
-#if defined (RESTRICTED_SHELL)
-      /* Restricted shells may not export shell functions. */
-      temp_array = restricted ? (char **)0 : make_func_export_array ();
-#else
-      temp_array = make_func_export_array ();
-#endif
-      if (temp_array)
-       add_temp_array_to_env (temp_array, 0, 0);
-
-      array_needs_making = 0;
-    }
-}
-
-/* This is an efficiency hack.  PWD and OLDPWD are auto-exported, so
-   we will need to remake the exported environment every time we
-   change directories.  `_' is always put into the environment for
-   every external command, so without special treatment it will always
-   cause the environment to be remade.
-
-   If there is no other reason to make the exported environment, we can
-   just update the variables in place and mark the exported environment
-   as no longer needing a remake. */
-void
-update_export_env_inplace (env_prefix, preflen, value)
-     char *env_prefix;
-     int preflen;
-     char *value;
-{
-  char *evar;
-
-  evar = (char *)xmalloc (STRLEN (value) + preflen + 1);
-  strcpy (evar, env_prefix);
-  if (value)
-    strcpy (evar + preflen, value);
-  export_env = add_or_supercede_exported_var (evar, 0);
-}
-
-/* We always put _ in the environment as the name of this command. */
-void
-put_command_name_into_env (command_name)
-     char *command_name;
-{
-  update_export_env_inplace ("_=", 2, command_name);
-}
-
-#if 0  /* UNUSED -- it caused too many problems */
-void
-put_gnu_argv_flags_into_env (pid, flags_string)
-     intmax_t pid;
-     char *flags_string;
-{
-  char *dummy, *pbuf;
-  int l, fl;
-
-  pbuf = itos (pid);
-  l = strlen (pbuf);
-
-  fl = strlen (flags_string);
-
-  dummy = (char *)xmalloc (l + fl + 30);
-  dummy[0] = '_';
-  strcpy (dummy + 1, pbuf);
-  strcpy (dummy + 1 + l, "_GNU_nonoption_argv_flags_");
-  dummy[l + 27] = '=';
-  strcpy (dummy + l + 28, flags_string);
-
-  free (pbuf);
-
-  export_env = add_or_supercede_exported_var (dummy, 0);
-}
-#endif
-
-/* **************************************************************** */
-/*                                                                 */
-/*                   Managing variable contexts                    */
-/*                                                                 */
-/* **************************************************************** */
-
-/* Allocate and return a new variable context with NAME and FLAGS.
-   NAME can be NULL. */
-
-VAR_CONTEXT *
-new_var_context (name, flags)
-     char *name;
-     int flags;
-{
-  VAR_CONTEXT *vc;
-
-  vc = (VAR_CONTEXT *)xmalloc (sizeof (VAR_CONTEXT));
-  vc->name = name ? savestring (name) : (char *)NULL;
-  vc->scope = variable_context;
-  vc->flags = flags;
-
-  vc->up = vc->down = (VAR_CONTEXT *)NULL;
-  vc->table = (HASH_TABLE *)NULL;
-
-  return vc;
-}
-
-/* Free a variable context and its data, including the hash table.  Dispose
-   all of the variables. */
-void
-dispose_var_context (vc)
-     VAR_CONTEXT *vc;
-{
-  FREE (vc->name);
-
-  if (vc->table)
-    {
-      delete_all_variables (vc->table);
-      hash_dispose (vc->table);
-    }
-
-  free (vc);
-}
-
-/* Set VAR's scope level to the current variable context. */
-static int
-set_context (var)
-     SHELL_VAR *var;
-{
-  return (var->context = variable_context);
-}
-
-/* Make a new variable context with NAME and FLAGS and a HASH_TABLE of
-   temporary variables, and push it onto shell_variables.  This is
-   for shell functions. */
-VAR_CONTEXT *
-push_var_context (name, flags, tempvars)
-     char *name;
-     int flags;
-     HASH_TABLE *tempvars;
-{
-  VAR_CONTEXT *vc;
-
-  vc = new_var_context (name, flags);
-  vc->table = tempvars;
-  if (tempvars)
-    {
-      /* Have to do this because the temp environment was created before
-        variable_context was incremented. */
-      flatten (tempvars, set_context, (VARLIST *)NULL, 0);
-      vc->flags |= VC_HASTMPVAR;
-    }
-  vc->down = shell_variables;
-  shell_variables->up = vc;
-
-  return (shell_variables = vc);
-}
-
-static void
-push_func_var (data)
-     PTR_T data;
-{
-  SHELL_VAR *var, *v;
-
-  var = (SHELL_VAR *)data;
-
-  if (tempvar_p (var) && (posixly_correct || (var->attributes & att_propagate)))
-    {
-      /* XXX - should we set v->context here? */
-      v = bind_variable_internal (var->name, value_cell (var), shell_variables->table, 0, 0);
-      if (shell_variables == global_variables)
-       var->attributes &= ~(att_tempvar|att_propagate);
-      else
-       shell_variables->flags |= VC_HASTMPVAR;
-      v->attributes |= var->attributes;
-    }
-  else
-    stupidly_hack_special_variables (var->name);       /* XXX */
-
-  dispose_variable (var);
-}
-
-/* Pop the top context off of VCXT and dispose of it, returning the rest of
-   the stack. */
-void
-pop_var_context ()
-{
-  VAR_CONTEXT *ret, *vcxt;
-
-  vcxt = shell_variables;
-  if (vc_isfuncenv (vcxt) == 0)
-    {
-      internal_error (_("pop_var_context: head of shell_variables not a function context"));
-      return;
-    }
-
-  if (ret = vcxt->down)
-    {
-      ret->up = (VAR_CONTEXT *)NULL;
-      shell_variables = ret;
-      if (vcxt->table)
-       hash_flush (vcxt->table, push_func_var);
-      dispose_var_context (vcxt);
-    }
-  else
-    internal_error (_("pop_var_context: no global_variables context"));
-}
-
-/* Delete the HASH_TABLEs for all variable contexts beginning at VCXT, and
-   all of the VAR_CONTEXTs except GLOBAL_VARIABLES. */
-void
-delete_all_contexts (vcxt)
-     VAR_CONTEXT *vcxt;
-{
-  VAR_CONTEXT *v, *t;
-
-  for (v = vcxt; v != global_variables; v = t)
-    {
-      t = v->down;
-      dispose_var_context (v);
-    }    
-
-  delete_all_variables (global_variables->table);
-  shell_variables = global_variables;
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*        Pushing and Popping temporary variable scopes            */
-/*                                                                 */
-/* **************************************************************** */
-
-VAR_CONTEXT *
-push_scope (flags, tmpvars)
-     int flags;
-     HASH_TABLE *tmpvars;
-{
-  return (push_var_context ((char *)NULL, flags, tmpvars));
-}
-
-static void
-push_exported_var (data)
-     PTR_T data;
-{
-  SHELL_VAR *var, *v;
-
-  var = (SHELL_VAR *)data;
-
-  /* If a temp var had its export attribute set, or it's marked to be
-     propagated, bind it in the previous scope before disposing it. */
-  /* XXX - This isn't exactly right, because all tempenv variables have the
-    export attribute set. */
-#if 0
-  if (exported_p (var) || (var->attributes & att_propagate))
-#else
-  if (tempvar_p (var) && exported_p (var) && (var->attributes & att_propagate))
-#endif
-    {
-      var->attributes &= ~att_tempvar;         /* XXX */
-      v = bind_variable_internal (var->name, value_cell (var), shell_variables->table, 0, 0);
-      if (shell_variables == global_variables)
-       var->attributes &= ~att_propagate;
-      v->attributes |= var->attributes;
-    }
-  else
-    stupidly_hack_special_variables (var->name);       /* XXX */
-
-  dispose_variable (var);
-}
-
-void
-pop_scope (is_special)
-     int is_special;
-{
-  VAR_CONTEXT *vcxt, *ret;
-
-  vcxt = shell_variables;
-  if (vc_istempscope (vcxt) == 0)
-    {
-      internal_error (_("pop_scope: head of shell_variables not a temporary environment scope"));
-      return;
-    }
-
-  ret = vcxt->down;
-  if (ret)
-    ret->up = (VAR_CONTEXT *)NULL;
-
-  shell_variables = ret;
-
-  /* Now we can take care of merging variables in VCXT into set of scopes
-     whose head is RET (shell_variables). */
-  FREE (vcxt->name);
-  if (vcxt->table)
-    {
-      if (is_special)
-       hash_flush (vcxt->table, push_func_var);
-      else
-       hash_flush (vcxt->table, push_exported_var);
-      hash_dispose (vcxt->table);
-    }
-  free (vcxt);
-
-  sv_ifs ("IFS");      /* XXX here for now */
-}
-
-/* **************************************************************** */
-/*                                                                 */
-/*              Pushing and Popping function contexts              */
-/*                                                                 */
-/* **************************************************************** */
-
-static WORD_LIST **dollar_arg_stack = (WORD_LIST **)NULL;
-static int dollar_arg_stack_slots;
-static int dollar_arg_stack_index;
-
-/* XXX - we might want to consider pushing and popping the `getopts' state
-   when we modify the positional parameters. */
-void
-push_context (name, is_subshell, tempvars)
-     char *name;       /* function name */
-     int is_subshell;
-     HASH_TABLE *tempvars;
-{
-  if (is_subshell == 0)
-    push_dollar_vars ();
-  variable_context++;
-  push_var_context (name, VC_FUNCENV, tempvars);
-}
-
-/* Only called when subshell == 0, so we don't need to check, and can
-   unconditionally pop the dollar vars off the stack. */
-void
-pop_context ()
-{
-  pop_dollar_vars ();
-  variable_context--;
-  pop_var_context ();
-
-  sv_ifs ("IFS");              /* XXX here for now */
-}
-
-/* Save the existing positional parameters on a stack. */
-void
-push_dollar_vars ()
-{
-  if (dollar_arg_stack_index + 2 > dollar_arg_stack_slots)
-    {
-      dollar_arg_stack = (WORD_LIST **)
-       xrealloc (dollar_arg_stack, (dollar_arg_stack_slots += 10)
-                 * sizeof (WORD_LIST **));
-    }
-  dollar_arg_stack[dollar_arg_stack_index++] = list_rest_of_args ();
-  dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
-}
-
-/* Restore the positional parameters from our stack. */
-void
-pop_dollar_vars ()
-{
-  if (!dollar_arg_stack || dollar_arg_stack_index == 0)
-    return;
-
-  remember_args (dollar_arg_stack[--dollar_arg_stack_index], 1);
-  dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
-  dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
-  set_dollar_vars_unchanged ();
-}
-
-void
-dispose_saved_dollar_vars ()
-{
-  if (!dollar_arg_stack || dollar_arg_stack_index == 0)
-    return;
-
-  dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
-  dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
-}
-
-/* Manipulate the special BASH_ARGV and BASH_ARGC variables. */
-
-void
-push_args (list)
-     WORD_LIST *list;
-{
-#if defined (ARRAY_VARS) && defined (DEBUGGER)
-  SHELL_VAR *bash_argv_v, *bash_argc_v;
-  ARRAY *bash_argv_a, *bash_argc_a;
-  WORD_LIST *l;
-  arrayind_t i;
-  char *t;
-
-  GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
-  GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
-
-  for (l = list, i = 0; l; l = l->next, i++)
-    array_push (bash_argv_a, l->word->word);
-
-  t = itos (i);
-  array_push (bash_argc_a, t);
-  free (t);
-#endif /* ARRAY_VARS && DEBUGGER */
-}
-
-/* Remove arguments from BASH_ARGV array.  Pop top element off BASH_ARGC
-   array and use that value as the count of elements to remove from
-   BASH_ARGV. */
-void
-pop_args ()
-{
-#if defined (ARRAY_VARS) && defined (DEBUGGER)
-  SHELL_VAR *bash_argv_v, *bash_argc_v;
-  ARRAY *bash_argv_a, *bash_argc_a;
-  ARRAY_ELEMENT *ce;
-  intmax_t i;
-
-  GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
-  GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
-
-  ce = array_shift (bash_argc_a, 1, 0);
-  if (ce == 0 || legal_number (element_value (ce), &i) == 0)
-    i = 0;
-
-  for ( ; i > 0; i--)
-    array_pop (bash_argv_a);
-  array_dispose_element (ce);
-#endif /* ARRAY_VARS && DEBUGGER */
-}
-
-/*************************************************
- *                                              *
- *     Functions to manage special variables    *
- *                                              *
- *************************************************/
-
-/* Extern declarations for variables this code has to manage. */
-extern int eof_encountered, eof_encountered_limit, ignoreeof;
-
-#if defined (READLINE)
-extern int hostname_list_initialized;
-#endif
-
-/* An alist of name.function for each special variable.  Most of the
-   functions don't do much, and in fact, this would be faster with a
-   switch statement, but by the end of this file, I am sick of switch
-   statements. */
-
-#define SET_INT_VAR(name, intvar)  intvar = find_variable (name) != 0
-
-/* This table will be sorted with qsort() the first time it's accessed. */
-struct name_and_function {
-  char *name;
-  sh_sv_func_t *function;
-};
-
-static struct name_and_function special_vars[] = {
-  { "BASH_XTRACEFD", sv_xtracefd },
-
-#if defined (READLINE)
-#  if defined (STRICT_POSIX)
-  { "COLUMNS", sv_winsize },
-#  endif
-  { "COMP_WORDBREAKS", sv_comp_wordbreaks },
-#endif
-
-  { "GLOBIGNORE", sv_globignore },
-
-#if defined (HISTORY)
-  { "HISTCONTROL", sv_history_control },
-  { "HISTFILESIZE", sv_histsize },
-  { "HISTIGNORE", sv_histignore },
-  { "HISTSIZE", sv_histsize },
-  { "HISTTIMEFORMAT", sv_histtimefmt },
-#endif
-
-#if defined (__CYGWIN__)
-  { "HOME", sv_home },
-#endif
-
-#if defined (READLINE)
-  { "HOSTFILE", sv_hostfile },
-#endif
-
-  { "IFS", sv_ifs },
-  { "IGNOREEOF", sv_ignoreeof },
-
-  { "LANG", sv_locale },
-  { "LC_ALL", sv_locale },
-  { "LC_COLLATE", sv_locale },
-  { "LC_CTYPE", sv_locale },
-  { "LC_MESSAGES", sv_locale },
-  { "LC_NUMERIC", sv_locale },
-  { "LC_TIME", sv_locale },
-
-#if defined (READLINE) && defined (STRICT_POSIX)
-  { "LINES", sv_winsize },
-#endif
-
-  { "MAIL", sv_mail },
-  { "MAILCHECK", sv_mail },
-  { "MAILPATH", sv_mail },
-
-  { "OPTERR", sv_opterr },
-  { "OPTIND", sv_optind },
-
-  { "PATH", sv_path },
-  { "POSIXLY_CORRECT", sv_strict_posix },
-
-#if defined (READLINE)
-  { "TERM", sv_terminal },
-  { "TERMCAP", sv_terminal },
-  { "TERMINFO", sv_terminal },
-#endif /* READLINE */
-
-  { "TEXTDOMAIN", sv_locale },
-  { "TEXTDOMAINDIR", sv_locale },
-
-#if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
-  { "TZ", sv_tz },
-#endif
-
-#if defined (HISTORY) && defined (BANG_HISTORY)
-  { "histchars", sv_histchars },
-#endif /* HISTORY && BANG_HISTORY */
-
-  { "ignoreeof", sv_ignoreeof },
-
-  { (char *)0, (sh_sv_func_t *)0 }
-};
-
-#define N_SPECIAL_VARS (sizeof (special_vars) / sizeof (special_vars[0]) - 1)
-
-static int
-sv_compare (sv1, sv2)
-     struct name_and_function *sv1, *sv2;
-{
-  int r;
-
-  if ((r = sv1->name[0] - sv2->name[0]) == 0)
-    r = strcmp (sv1->name, sv2->name);
-  return r;
-}
-
-static inline int
-find_special_var (name)
-     const char *name;
-{
-  register int i, r;
-
-  for (i = 0; special_vars[i].name; i++)
-    {
-      r = special_vars[i].name[0] - name[0];
-      if (r == 0)
-       r = strcmp (special_vars[i].name, name);
-      if (r == 0)
-       return i;
-      else if (r > 0)
-       /* Can't match any of rest of elements in sorted list.  Take this out
-          if it causes problems in certain environments. */
-       break;
-    }
-  return -1;
-}
-
-/* The variable in NAME has just had its state changed.  Check to see if it
-   is one of the special ones where something special happens. */
-void
-stupidly_hack_special_variables (name)
-     char *name;
-{
-  static int sv_sorted = 0;
-  int i;
-
-  if (sv_sorted == 0)  /* shouldn't need, but it's fairly cheap. */
-    {
-      qsort (special_vars, N_SPECIAL_VARS, sizeof (special_vars[0]),
-               (QSFUNC *)sv_compare);
-      sv_sorted = 1;
-    }
-
-  i = find_special_var (name);
-  if (i != -1)
-    (*(special_vars[i].function)) (name);
-}
-
-/* Special variables that need hooks to be run when they are unset as part
-   of shell reinitialization should have their sv_ functions run here. */
-void
-reinit_special_variables ()
-{
-#if defined (READLINE)
-  sv_comp_wordbreaks ("COMP_WORDBREAKS");
-#endif
-  sv_globignore ("GLOBIGNORE");
-  sv_opterr ("OPTERR");
-}
-
-void
-sv_ifs (name)
-     char *name;
-{
-  SHELL_VAR *v;
-
-  v = find_variable ("IFS");
-  setifs (v);
-}
-
-/* What to do just after the PATH variable has changed. */
-void
-sv_path (name)
-     char *name;
-{
-  /* hash -r */
-  phash_flush ();
-}
-
-/* What to do just after one of the MAILxxxx variables has changed.  NAME
-   is the name of the variable.  This is called with NAME set to one of
-   MAIL, MAILCHECK, or MAILPATH.  */
-void
-sv_mail (name)
-     char *name;
-{
-  /* If the time interval for checking the files has changed, then
-     reset the mail timer.  Otherwise, one of the pathname vars
-     to the users mailbox has changed, so rebuild the array of
-     filenames. */
-  if (name[4] == 'C')  /* if (strcmp (name, "MAILCHECK") == 0) */
-    reset_mail_timer ();
-  else
-    {
-      free_mail_files ();
-      remember_mail_dates ();
-    }
-}
-
-/* What to do when GLOBIGNORE changes. */
-void
-sv_globignore (name)
-     char *name;
-{
-  if (privileged_mode == 0)
-    setup_glob_ignore (name);
-}
-
-#if defined (READLINE)
-void
-sv_comp_wordbreaks (name)
-     char *name;
-{
-  SHELL_VAR *sv;
-
-  sv = find_variable (name);
-  if (sv == 0)
-    reset_completer_word_break_chars ();
-}
-
-/* What to do just after one of the TERMxxx variables has changed.
-   If we are an interactive shell, then try to reset the terminal
-   information in readline. */
-void
-sv_terminal (name)
-     char *name;
-{
-  if (interactive_shell && no_line_editing == 0)
-    rl_reset_terminal (get_string_value ("TERM"));
-}
-
-void
-sv_hostfile (name)
-     char *name;
-{
-  SHELL_VAR *v;
-
-  v = find_variable (name);
-  if (v == 0)
-    clear_hostname_list ();
-  else
-    hostname_list_initialized = 0;
-}
-
-#if defined (STRICT_POSIX)
-/* In strict posix mode, we allow assignments to LINES and COLUMNS (and values
-   found in the initial environment) to override the terminal size reported by
-   the kernel. */
-void
-sv_winsize (name)
-     char *name;
-{
-  SHELL_VAR *v;
-  intmax_t xd;
-  int d;
-
-  if (posixly_correct == 0 || interactive_shell == 0 || no_line_editing)
-    return;
-
-  v = find_variable (name);
-  if (v == 0 || var_isnull (v))
-    rl_reset_screen_size ();
-  else
-    {
-      if (legal_number (value_cell (v), &xd) == 0)
-       return;
-      winsize_assignment = winsize_assigned = 1;
-      d = xd;                  /* truncate */
-      if (name[0] == 'L')      /* LINES */
-       rl_set_screen_size (d, -1);
-      else                     /* COLUMNS */
-       rl_set_screen_size (-1, d);
-      winsize_assignment = 0;
-    }
-}
-#endif /* STRICT_POSIX */
-#endif /* READLINE */
-
-/* Update the value of HOME in the export environment so tilde expansion will
-   work on cygwin. */
-#if defined (__CYGWIN__)
-sv_home (name)
-     char *name;
-{
-  array_needs_making = 1;
-  maybe_make_export_env ();
-}
-#endif
-
-#if defined (HISTORY)
-/* What to do after the HISTSIZE or HISTFILESIZE variables change.
-   If there is a value for this HISTSIZE (and it is numeric), then stifle
-   the history.  Otherwise, if there is NO value for this variable,
-   unstifle the history.  If name is HISTFILESIZE, and its value is
-   numeric, truncate the history file to hold no more than that many
-   lines. */
-void
-sv_histsize (name)
-     char *name;
-{
-  char *temp;
-  intmax_t num;
-  int hmax;
-
-  temp = get_string_value (name);
-
-  if (temp && *temp)
-    {
-      if (legal_number (temp, &num))
-       {
-         hmax = num;
-         if (name[4] == 'S')
-           {
-             stifle_history (hmax);
-             hmax = where_history ();
-             if (history_lines_this_session > hmax)
-               history_lines_this_session = hmax;
-           }
-         else
-           {
-             history_truncate_file (get_string_value ("HISTFILE"), hmax);
-             if (hmax <= history_lines_in_file)
-               history_lines_in_file = hmax;
-           }
-       }
-    }
-  else if (name[4] == 'S')
-    unstifle_history ();
-}
-
-/* What to do after the HISTIGNORE variable changes. */
-void
-sv_histignore (name)
-     char *name;
-{
-  setup_history_ignore (name);
-}
-
-/* What to do after the HISTCONTROL variable changes. */
-void
-sv_history_control (name)
-     char *name;
-{
-  char *temp;
-  char *val;
-  int tptr;
-
-  history_control = 0;
-  temp = get_string_value (name);
-
-  if (temp == 0 || *temp == 0)
-    return;
-
-  tptr = 0;
-  while (val = extract_colon_unit (temp, &tptr))
-    {
-      if (STREQ (val, "ignorespace"))
-       history_control |= HC_IGNSPACE;
-      else if (STREQ (val, "ignoredups"))
-       history_control |= HC_IGNDUPS;
-      else if (STREQ (val, "ignoreboth"))
-       history_control |= HC_IGNBOTH;
-      else if (STREQ (val, "erasedups"))
-       history_control |= HC_ERASEDUPS;
-
-      free (val);
-    }
-}
-
-#if defined (BANG_HISTORY)
-/* Setting/unsetting of the history expansion character. */
-void
-sv_histchars (name)
-     char *name;
-{
-  char *temp;
-
-  temp = get_string_value (name);
-  if (temp)
-    {
-      history_expansion_char = *temp;
-      if (temp[0] && temp[1])
-       {
-         history_subst_char = temp[1];
-         if (temp[2])
-             history_comment_char = temp[2];
-       }
-    }
-  else
-    {
-      history_expansion_char = '!';
-      history_subst_char = '^';
-      history_comment_char = '#';
-    }
-}
-#endif /* BANG_HISTORY */
-
-void
-sv_histtimefmt (name)
-     char *name;
-{
-  SHELL_VAR *v;
-
-  v = find_variable (name);
-  history_write_timestamps = (v != 0);
-}
-#endif /* HISTORY */
-
-#if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
-void
-sv_tz (name)
-     char *name;
-{
-  tzset ();
-}
-#endif
-
-/* If the variable exists, then the value of it can be the number
-   of times we actually ignore the EOF.  The default is small,
-   (smaller than csh, anyway). */
-void
-sv_ignoreeof (name)
-     char *name;
-{
-  SHELL_VAR *tmp_var;
-  char *temp;
-
-  eof_encountered = 0;
-
-  tmp_var = find_variable (name);
-  ignoreeof = tmp_var != 0;
-  temp = tmp_var ? value_cell (tmp_var) : (char *)NULL;
-  if (temp)
-    eof_encountered_limit = (*temp && all_digits (temp)) ? atoi (temp) : 10;
-  set_shellopts ();    /* make sure `ignoreeof' is/is not in $SHELLOPTS */
-}
-
-void
-sv_optind (name)
-     char *name;
-{
-  char *tt;
-  int s;
-
-  tt = get_string_value ("OPTIND");
-  if (tt && *tt)
-    {
-      s = atoi (tt);
-
-      /* According to POSIX, setting OPTIND=1 resets the internal state
-        of getopt (). */
-      if (s < 0 || s == 1)
-       s = 0;
-    }
-  else
-    s = 0;
-  getopts_reset (s);
-}
-
-void
-sv_opterr (name)
-     char *name;
-{
-  char *tt;
-
-  tt = get_string_value ("OPTERR");
-  sh_opterr = (tt && *tt) ? atoi (tt) : 1;
-}
-
-void
-sv_strict_posix (name)
-     char *name;
-{
-  SET_INT_VAR (name, posixly_correct);
-  posix_initialize (posixly_correct);
-#if defined (READLINE)
-  if (interactive_shell)
-    posix_readline_initialize (posixly_correct);
-#endif /* READLINE */
-  set_shellopts ();    /* make sure `posix' is/is not in $SHELLOPTS */
-}
-
-void
-sv_locale (name)
-     char *name;
-{
-  char *v;
-
-  v = get_string_value (name);
-  if (name[0] == 'L' && name[1] == 'A')        /* LANG */
-    set_lang (name, v);
-  else
-    set_locale_var (name, v);          /* LC_*, TEXTDOMAIN* */
-}
-
-#if defined (ARRAY_VARS)
-void
-set_pipestatus_array (ps, nproc)
-     int *ps;
-     int nproc;
-{
-  SHELL_VAR *v;
-  ARRAY *a;
-  ARRAY_ELEMENT *ae;
-  register int i;
-  char *t, tbuf[INT_STRLEN_BOUND(int) + 1];
-
-  v = find_variable ("PIPESTATUS");
-  if (v == 0)
-    v = make_new_array_variable ("PIPESTATUS");
-  if (array_p (v) == 0)
-    return;            /* Do nothing if not an array variable. */
-  a = array_cell (v);
-
-  if (a == 0 || array_num_elements (a) == 0)
-    {
-      for (i = 0; i < nproc; i++)      /* was ps[i] != -1, not i < nproc */
-       {
-         t = inttostr (ps[i], tbuf, sizeof (tbuf));
-         array_insert (a, i, t);
-       }
-      return;
-    }
-
-  /* Fast case */
-  if (array_num_elements (a) == nproc && nproc == 1)
-    {
-      ae = element_forw (a->head);
-      free (element_value (ae));
-      ae->value = itos (ps[0]);
-    }
-  else if (array_num_elements (a) <= nproc)
-    {
-      /* modify in array_num_elements members in place, then add */
-      ae = a->head;
-      for (i = 0; i < array_num_elements (a); i++)
-       {
-         ae = element_forw (ae);
-         free (element_value (ae));
-         ae->value = itos (ps[i]);
-       }
-      /* add any more */
-      for ( ; i < nproc; i++)
-       {
-         t = inttostr (ps[i], tbuf, sizeof (tbuf));
-         array_insert (a, i, t);
-       }
-    }
-  else
-    {
-      /* deleting elements.  it's faster to rebuild the array. */        
-      array_flush (a);
-      for (i = 0; ps[i] != -1; i++)
-       {
-         t = inttostr (ps[i], tbuf, sizeof (tbuf));
-         array_insert (a, i, t);
-       }
-    }
-}
-#endif
-
-void
-set_pipestatus_from_exit (s)
-     int s;
-{
-#if defined (ARRAY_VARS)
-  static int v[2] = { 0, -1 };
-
-  v[0] = s;
-  set_pipestatus_array (v, 1);
-#endif
-}
-
-void
-sv_xtracefd (name)
-     char *name;
-{
-  SHELL_VAR *v;
-  char *t, *e;
-  int fd;
-  FILE *fp;
-
-  v = find_variable (name);
-  if (v == 0)
-    {
-      xtrace_reset ();
-      return;
-    }
-
-  t = value_cell (v);
-  if (t == 0 || *t == 0)
-    xtrace_reset ();
-  else
-    {
-      fd = (int)strtol (t, &e, 10);
-      if (e != t && *e == '\0' && sh_validfd (fd))
-       {
-         fp = fdopen (fd, "w");
-         if (fp == 0)
-           internal_error (_("%s: %s: cannot open as FILE"), name, value_cell (v));
-         else
-           xtrace_set (fd, fp);
-       }
-      else
-       internal_error (_("%s: %s: invalid value for trace file descriptor"), name, value_cell (v));
-    }
-}
diff --git a/variables.h~ b/variables.h~
deleted file mode 100644 (file)
index dbc81fb..0000000
+++ /dev/null
@@ -1,385 +0,0 @@
-/* variables.h -- data structures for shell variables. */
-
-/* Copyright (C) 1987-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 (_VARIABLES_H_)
-#define _VARIABLES_H_
-
-#include "stdc.h"
-#include "array.h"
-#include "assoc.h"
-
-/* Shell variables and functions are stored in hash tables. */
-#include "hashlib.h"
-
-#include "conftypes.h"
-
-/* A variable context. */
-typedef struct var_context {
-  char *name;          /* empty or NULL means global context */
-  int scope;           /* 0 means global context */
-  int flags;
-  struct var_context *up;      /* previous function calls */
-  struct var_context *down;    /* down towards global context */
-  HASH_TABLE *table;           /* variables at this scope */
-} VAR_CONTEXT;
-
-/* Flags for var_context->flags */
-#define VC_HASLOCAL    0x01
-#define VC_HASTMPVAR   0x02
-#define VC_FUNCENV     0x04    /* also function if name != NULL */
-#define VC_BLTNENV     0x08    /* builtin_env */
-#define VC_TEMPENV     0x10    /* temporary_env */
-
-#define VC_TEMPFLAGS   (VC_FUNCENV|VC_BLTNENV|VC_TEMPENV)
-
-/* Accessing macros */
-#define vc_isfuncenv(vc)       (((vc)->flags & VC_FUNCENV) != 0)
-#define vc_isbltnenv(vc)       (((vc)->flags & VC_BLTNENV) != 0)
-#define vc_istempenv(vc)       (((vc)->flags & (VC_TEMPFLAGS)) == VC_TEMPENV)
-
-#define vc_istempscope(vc)     (((vc)->flags & (VC_TEMPENV|VC_BLTNENV)) != 0)
-
-#define vc_haslocals(vc)       (((vc)->flags & VC_HASLOCAL) != 0)
-#define vc_hastmpvars(vc)      (((vc)->flags & VC_HASTMPVAR) != 0)
-
-/* What a shell variable looks like. */
-
-typedef struct variable *sh_var_value_func_t __P((struct variable *));
-typedef struct variable *sh_var_assign_func_t __P((struct variable *, char *, arrayind_t, char *));
-
-/* For the future */
-union _value {
-  char *s;                     /* string value */
-  intmax_t i;                  /* int value */
-  COMMAND *f;                  /* function */
-  ARRAY *a;                    /* array */
-  HASH_TABLE *h;               /* associative array */
-  double d;                    /* floating point number */
-#if defined (HAVE_LONG_DOUBLE)
-  long double ld;              /* long double */
-#endif
-  struct variable *v;          /* possible indirect variable use */
-  void *opaque;                        /* opaque data for future use */
-};
-
-typedef struct variable {
-  char *name;                  /* Symbol that the user types. */
-  char *value;                 /* Value that is returned. */
-  char *exportstr;             /* String for the environment. */
-  sh_var_value_func_t *dynamic_value;  /* Function called to return a `dynamic'
-                                  value for a variable, like $SECONDS
-                                  or $RANDOM. */
-  sh_var_assign_func_t *assign_func; /* Function called when this `special
-                                  variable' is assigned a value in
-                                  bind_variable. */
-  int attributes;              /* export, readonly, array, invisible... */
-  int context;                 /* Which context this variable belongs to. */
-} SHELL_VAR;
-
-typedef struct _vlist {
-  SHELL_VAR **list;
-  int list_size;       /* allocated size */
-  int list_len;                /* current number of entries */
-} VARLIST;
-
-/* The various attributes that a given variable can have. */
-/* First, the user-visible attributes */
-#define att_exported   0x0000001       /* export to environment */
-#define att_readonly   0x0000002       /* cannot change */
-#define att_array      0x0000004       /* value is an array */
-#define att_function   0x0000008       /* value is a function */
-#define att_integer    0x0000010       /* internal representation is int */
-#define att_local      0x0000020       /* variable is local to a function */
-#define att_assoc      0x0000040       /* variable is an associative array */
-#define att_trace      0x0000080       /* function is traced with DEBUG trap */
-#define att_uppercase  0x0000100       /* word converted to uppercase on assignment */
-#define att_lowercase  0x0000200       /* word converted to lowercase on assignment */
-#define att_capcase    0x0000400       /* word capitalized on assignment */
-
-#define user_attrs     (att_exported|att_readonly|att_integer|att_local|att_trace|att_uppercase|att_lowercase|att_capcase)
-
-#define attmask_user   0x0000fff
-
-/* Internal attributes used for bookkeeping */
-#define att_invisible  0x0001000       /* cannot see */
-#define att_nounset    0x0002000       /* cannot unset */
-#define att_noassign   0x0004000       /* assignment not allowed */
-#define att_imported   0x0008000       /* came from environment */
-#define att_special    0x0010000       /* requires special handling */
-#define att_nofree     0x0020000       /* do not free value on unset */
-
-#define        attmask_int     0x00ff000
-
-/* Internal attributes used for variable scoping. */
-#define att_tempvar    0x0100000       /* variable came from the temp environment */
-#define att_propagate  0x0200000       /* propagate to previous scope */
-
-#define attmask_scope  0x0f00000
-
-#define exported_p(var)                ((((var)->attributes) & (att_exported)))
-#define readonly_p(var)                ((((var)->attributes) & (att_readonly)))
-#define array_p(var)           ((((var)->attributes) & (att_array)))
-#define function_p(var)                ((((var)->attributes) & (att_function)))
-#define integer_p(var)         ((((var)->attributes) & (att_integer)))
-#define local_p(var)           ((((var)->attributes) & (att_local)))
-#define assoc_p(var)           ((((var)->attributes) & (att_assoc)))
-#define trace_p(var)           ((((var)->attributes) & (att_trace)))
-#define uppercase_p(var)       ((((var)->attributes) & (att_uppercase)))
-#define lowercase_p(var)       ((((var)->attributes) & (att_lowercase)))
-#define capcase_p(var)         ((((var)->attributes) & (att_capcase)))
-
-#define invisible_p(var)       ((((var)->attributes) & (att_invisible)))
-#define non_unsettable_p(var)  ((((var)->attributes) & (att_nounset)))
-#define noassign_p(var)                ((((var)->attributes) & (att_noassign)))
-#define imported_p(var)                ((((var)->attributes) & (att_imported)))
-#define specialvar_p(var)      ((((var)->attributes) & (att_special)))
-#define nofree_p(var)          ((((var)->attributes) & (att_nofree)))
-
-#define tempvar_p(var)         ((((var)->attributes) & (att_tempvar)))
-
-/* Acessing variable values: rvalues */
-#define value_cell(var)                ((var)->value)
-#define function_cell(var)     (COMMAND *)((var)->value)
-#define array_cell(var)                (ARRAY *)((var)->value)
-#define assoc_cell(var)                (HASH_TABLE *)((var)->value)
-
-#define var_isnull(var)                ((var)->value == 0)
-#define var_isset(var)         ((var)->value != 0)
-
-/* Assigning variable values: lvalues */
-#define var_setvalue(var, str) ((var)->value = (str))
-#define var_setfunc(var, func) ((var)->value = (char *)(func))
-#define var_setarray(var, arr) ((var)->value = (char *)(arr))
-#define var_setassoc(var, arr) ((var)->value = (char *)(arr))
-
-/* Make VAR be auto-exported. */
-#define set_auto_export(var) \
-  do { (var)->attributes |= att_exported; array_needs_making = 1; } while (0)
-
-#define SETVARATTR(var, attr, undo) \
-       ((undo == 0) ? ((var)->attributes |= (attr)) \
-                    : ((var)->attributes &= ~(attr)))
-
-#define VSETATTR(var, attr)    ((var)->attributes |= (attr))
-#define VUNSETATTR(var, attr)  ((var)->attributes &= ~(attr))
-
-#define VGETFLAGS(var)         ((var)->attributes)
-
-#define VSETFLAGS(var, flags)  ((var)->attributes = (flags))
-#define VCLRFLAGS(var)         ((var)->attributes = 0)
-
-/* Macros to perform various operations on `exportstr' member of a SHELL_VAR. */
-#define CLEAR_EXPORTSTR(var)   (var)->exportstr = (char *)NULL
-#define COPY_EXPORTSTR(var)    ((var)->exportstr) ? savestring ((var)->exportstr) : (char *)NULL
-#define SET_EXPORTSTR(var, value)  (var)->exportstr = (value)
-#define SAVE_EXPORTSTR(var, value) (var)->exportstr = (value) ? savestring (value) : (char *)NULL
-
-#define FREE_EXPORTSTR(var) \
-       do { if ((var)->exportstr) free ((var)->exportstr); } while (0)
-
-#define CACHE_IMPORTSTR(var, value) \
-       (var)->exportstr = savestring (value)
-
-#define INVALIDATE_EXPORTSTR(var) \
-       do { \
-         if ((var)->exportstr) \
-           { \
-             free ((var)->exportstr); \
-             (var)->exportstr = (char *)NULL; \
-           } \
-       } while (0)
-       
-/* Stuff for hacking variables. */
-typedef int sh_var_map_func_t __P((SHELL_VAR *));
-
-/* Where we keep the variables and functions */
-extern VAR_CONTEXT *global_variables;
-extern VAR_CONTEXT *shell_variables;
-
-extern HASH_TABLE *shell_functions;
-extern HASH_TABLE *temporary_env;
-
-extern int variable_context;
-extern char *dollar_vars[];
-extern char **export_env;
-
-extern void initialize_shell_variables __P((char **, int));
-extern SHELL_VAR *set_if_not __P((char *, char *));
-
-extern void sh_set_lines_and_columns __P((int, int));
-extern void set_pwd __P((void));
-extern void set_ppid __P((void));
-extern void make_funcname_visible __P((int));
-
-extern SHELL_VAR *var_lookup __P((const char *, VAR_CONTEXT *));
-
-extern SHELL_VAR *find_function __P((const char *));
-extern FUNCTION_DEF *find_function_def __P((const char *));
-extern SHELL_VAR *find_variable __P((const char *));
-extern SHELL_VAR *find_variable_internal __P((const char *, int));
-extern SHELL_VAR *find_tempenv_variable __P((const char *));
-extern SHELL_VAR *copy_variable __P((SHELL_VAR *));
-extern SHELL_VAR *make_local_variable __P((const char *));
-extern SHELL_VAR *bind_variable __P((const char *, char *, int));
-extern SHELL_VAR *bind_function __P((const char *, COMMAND *));
-
-extern void bind_function_def __P((const char *, FUNCTION_DEF *));
-
-extern SHELL_VAR **map_over __P((sh_var_map_func_t *, VAR_CONTEXT *));
-SHELL_VAR **map_over_funcs __P((sh_var_map_func_t *));
-     
-extern SHELL_VAR **all_shell_variables __P((void));
-extern SHELL_VAR **all_shell_functions __P((void));
-extern SHELL_VAR **all_visible_variables __P((void));
-extern SHELL_VAR **all_visible_functions __P((void));
-extern SHELL_VAR **all_exported_variables __P((void));
-extern SHELL_VAR **local_exported_variables __P((void));
-extern SHELL_VAR **all_local_variables __P((void));
-#if defined (ARRAY_VARS)
-extern SHELL_VAR **all_array_variables __P((void));
-#endif
-extern char **all_variables_matching_prefix __P((const char *));
-
-extern char **make_var_array __P((HASH_TABLE *));
-extern char **add_or_supercede_exported_var __P((char *, int));
-
-extern char *get_variable_value __P((SHELL_VAR *));
-extern char *get_string_value __P((const char *));
-extern char *sh_get_env_value __P((const char *));
-extern char *make_variable_value __P((SHELL_VAR *, char *, int));
-
-extern SHELL_VAR *bind_variable_value __P((SHELL_VAR *, char *, int));
-extern SHELL_VAR *bind_int_variable __P((char *, char *));
-extern SHELL_VAR *bind_var_to_int __P((char *, intmax_t));
-
-extern int assign_in_env __P((WORD_DESC *));
-
-extern int unbind_variable __P((const char *));
-extern int unbind_func __P((const char *));
-extern int unbind_function_def __P((const char *));
-extern int makunbound __P((const char *, VAR_CONTEXT *));
-extern int kill_local_variable __P((const char *));
-extern void delete_all_variables __P((HASH_TABLE *));
-extern void delete_all_contexts __P((VAR_CONTEXT *));
-
-extern VAR_CONTEXT *new_var_context __P((char *, int));
-extern void dispose_var_context __P((VAR_CONTEXT *));
-extern VAR_CONTEXT *push_var_context __P((char *, int, HASH_TABLE *));
-extern void pop_var_context __P((void));
-extern VAR_CONTEXT *push_scope __P((int, HASH_TABLE *));
-extern void pop_scope __P((int));
-
-extern void push_context __P((char *, int, HASH_TABLE *));
-extern void pop_context __P((void));
-extern void push_dollar_vars __P((void));
-extern void pop_dollar_vars __P((void));
-extern void dispose_saved_dollar_vars __P((void));
-
-extern void push_args __P((WORD_LIST *));
-extern void pop_args __P((void));
-
-extern void adjust_shell_level __P((int));
-extern void non_unsettable __P((char *));
-extern void dispose_variable __P((SHELL_VAR *));
-extern void dispose_used_env_vars __P((void));
-extern void dispose_function_env __P((void));
-extern void dispose_builtin_env __P((void));
-extern void merge_temporary_env __P((void));
-extern void merge_builtin_env __P((void));
-extern void kill_all_local_variables __P((void));
-
-extern void set_var_read_only __P((char *));
-extern void set_func_read_only __P((const char *));
-extern void set_var_auto_export __P((char *));
-extern void set_func_auto_export __P((const char *));
-
-extern void sort_variables __P((SHELL_VAR **));
-
-extern void maybe_make_export_env __P((void));
-extern void update_export_env_inplace __P((char *, int, char *));
-extern void put_command_name_into_env __P((char *));
-extern void put_gnu_argv_flags_into_env __P((intmax_t, char *));
-
-extern void print_var_list __P((SHELL_VAR **));
-extern void print_func_list __P((SHELL_VAR **));
-extern void print_assignment __P((SHELL_VAR *));
-extern void print_var_value __P((SHELL_VAR *, int));
-extern void print_var_function __P((SHELL_VAR *));
-
-#if defined (ARRAY_VARS)
-extern SHELL_VAR *make_new_array_variable __P((char *));
-extern SHELL_VAR *make_local_array_variable __P((char *));
-
-extern SHELL_VAR *make_new_assoc_variable __P((char *));
-extern SHELL_VAR *make_local_assoc_variable __P((char *));
-
-extern void set_pipestatus_array __P((int *, int));
-#endif
-
-extern void set_pipestatus_from_exit __P((int));
-
-/* The variable in NAME has just had its state changed.  Check to see if it
-   is one of the special ones where something special happens. */
-extern void stupidly_hack_special_variables __P((char *));
-
-/* Reinitialize some special variables that have external effects upon unset
-   when the shell reinitializes itself. */
-extern void reinit_special_variables __P((void));
-
-extern int get_random_number __P((void));
-
-/* The `special variable' functions that get called when a particular
-   variable is set. */
-extern void sv_ifs __P((char *));
-extern void sv_path __P((char *));
-extern void sv_mail __P((char *));
-extern void sv_globignore __P((char *));
-extern void sv_ignoreeof __P((char *));
-extern void sv_strict_posix __P((char *));
-extern void sv_optind __P((char *));
-extern void sv_opterr __P((char *));
-extern void sv_locale __P((char *));
-
-#if defined (READLINE)
-extern void sv_comp_wordbreaks __P((char *));
-extern void sv_terminal __P((char *));
-extern void sv_hostfile __P((char *));
-extern void sv_winsize __P((char *));
-#endif
-
-#if defined (__CYGWIN__)
-extern void sv_home __P((char *));
-#endif
-
-#if defined (HISTORY)
-extern void sv_histsize __P((char *));
-extern void sv_histignore __P((char *));
-extern void sv_history_control __P((char *));
-#  if defined (BANG_HISTORY)
-extern void sv_histchars __P((char *));
-#  endif
-extern void sv_histtimefmt __P((char *));
-#endif /* HISTORY */
-
-#if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
-extern void sv_tz __P((char *));
-#endif
-
-#endif /* !_VARIABLES_H_ */
diff --git a/xmalloc.c~ b/xmalloc.c~
deleted file mode 100644 (file)
index 54dd722..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-/* xmalloc.c -- safe versions of malloc and realloc */
-
-/* Copyright (C) 1991-2009 Free Software Foundation, Inc.
-
-   This file is part of GNU Bash, the GNU 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
-
-#include "bashtypes.h"
-#include <stdio.h>
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#if defined (HAVE_STDLIB_H)
-#  include <stdlib.h>
-#else
-#  include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#include "error.h"
-
-#include "bashintl.h"
-
-#if !defined (PTR_T)
-#  if defined (__STDC__)
-#    define PTR_T void *
-#  else
-#    define PTR_T char *
-#  endif /* !__STDC__ */
-#endif /* !PTR_T */
-
-#if defined (HAVE_SBRK) && !HAVE_DECL_SBRK
-extern char *sbrk();
-#endif
-
-static PTR_T lbreak;
-static int brkfound;
-static size_t allocated;
-
-/* **************************************************************** */
-/*                                                                 */
-/*                Memory Allocation and Deallocation.              */
-/*                                                                 */
-/* **************************************************************** */
-
-#if defined (HAVE_SBRK)
-#define FINDBRK() \
-do { \
-  if (brkfound == 0) \
-    { \
-      lbreak = (PTR_T)sbrk (0); \
-      brkfound++; \
-    } \
-} while (0)
-
-static size_t
-findbrk ()
-{
-  FINDBRK();
-  return (char *)sbrk (0) - (char *)lbreak;
-}
-#else
-#define FINDBRK()
-#endif
-
-static void
-allocerr (func, bytes)
-     const char *func;
-     size_t bytes;
-{
-#if defined (HAVE_SBRK)
-      allocated = findbrk ();
-      fatal_error (_("%s: cannot allocate %lu bytes (%lu bytes allocated)"), func, (unsigned long)bytes, (unsigned long)allocated);
-#else
-      fatal_error (_("%s: cannot allocate %lu bytes"), func, (unsigned long)bytes);
-#endif /* !HAVE_SBRK */
-}
-
-/* Return a pointer to free()able block of memory large enough
-   to hold BYTES number of bytes.  If the memory cannot be allocated,
-   print an error message and abort. */
-PTR_T
-xmalloc (bytes)
-     size_t bytes;
-{
-  PTR_T temp;
-
-  if (bytes == 0)
-    internal_warning("xmalloc: size argument is 0");
-
-  FINDBRK();
-  temp = malloc (bytes);
-
-  if (temp == 0)
-    allocerr ("xmalloc", bytes);
-
-  return (temp);
-}
-
-PTR_T
-xrealloc (pointer, bytes)
-     PTR_T pointer;
-     size_t bytes;
-{
-  PTR_T temp;
-
-  if (bytes == 0)
-    internal_warning("xrealloc: size argument is 0");
-
-  FINDBRK();
-  temp = pointer ? realloc (pointer, bytes) : malloc (bytes);
-
-  if (temp == 0)
-    allocerr ("xrealloc", bytes);
-
-  return (temp);
-}
-
-/* Use this as the function to call when adding unwind protects so we
-   don't need to know what free() returns. */
-void
-xfree (string)
-     PTR_T string;
-{
-  if (string)
-    free (string);
-}
-
-#ifdef USING_BASH_MALLOC
-#include <malloc/shmalloc.h>
-
-static void
-sh_allocerr (func, bytes, file, line)
-     const char *func;
-     size_t bytes;
-     char *file;
-     int line;
-{
-#if defined (HAVE_SBRK)
-      allocated = findbrk ();
-      fatal_error (_("%s: %s:%d: cannot allocate %lu bytes (%lu bytes allocated)"), func, file, line, (unsigned long)bytes, (unsigned long)allocated);
-#else
-      fatal_error (_("%s: %s:%d: cannot allocate %lu bytes"), func, file, line, (unsigned long)bytes);
-#endif /* !HAVE_SBRK */
-}
-
-PTR_T
-sh_xmalloc (bytes, file, line)
-     size_t bytes;
-     char *file;
-     int line;
-{
-  PTR_T temp;
-
-  FINDBRK();
-  temp = sh_malloc (bytes, file, line);
-
-  if (temp == 0)
-    sh_allocerr ("xmalloc", bytes, file, line);
-
-  return (temp);
-}
-
-PTR_T
-sh_xrealloc (pointer, bytes, file, line)
-     PTR_T pointer;
-     size_t bytes;
-     char *file;
-     int line;
-{
-  PTR_T temp;
-
-  FINDBRK();
-  temp = pointer ? sh_realloc (pointer, bytes, file, line) : sh_malloc (bytes, file, line);
-
-  if (temp == 0)
-    sh_allocerr ("xrealloc", bytes, file, line);
-
-  return (temp);
-}
-
-void
-sh_xfree (string, file, line)
-     PTR_T string;
-     char *file;
-     int line;
-{
-  if (string)
-    sh_free (string, file, line);
-}
-#endif