]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
commit bash-20090723 snapshot
authorChet Ramey <chet.ramey@case.edu>
Fri, 9 Dec 2011 01:13:04 +0000 (20:13 -0500)
committerChet Ramey <chet.ramey@case.edu>
Fri, 9 Dec 2011 01:13:04 +0000 (20:13 -0500)
18 files changed:
COMPAT
COMPAT~ [new file with mode: 0644]
CWRU/CWRU.chlog
CWRU/CWRU.chlog~
bashline.c
bashline.c~
builtins/printf.def
builtins/printf.def~ [new file with mode: 0644]
ddd1~
execute_cmd.c
execute_cmd.c~
lib/readline/complete.c
lib/readline/complete.c.save1 [new file with mode: 0644]
lib/readline/complete.c~ [new file with mode: 0644]
lib/readline/display.c
po/de.po
subst.c
subst.c~

diff --git a/COMPAT b/COMPAT
index 13512acb234e76db830542f1f65ad1795052bcf5..c635c8a1385232ac1ae6e48a9862f3a398b7668e 100644 (file)
--- a/COMPAT
+++ b/COMPAT
@@ -318,3 +318,8 @@ bash-2.0 were significant.)
     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.
diff --git a/COMPAT~ b/COMPAT~
new file mode 100644 (file)
index 0000000..13512ac
--- /dev/null
+++ b/COMPAT~
@@ -0,0 +1,320 @@
+This document details the incompatibilities between this version of bash,
+bash-4.0, and the previous widely-available versions, bash-1.14 (which is
+still the `standard' version for a few Linux distributions) and bash-2.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.  (The differences between bash-1.14 and
+bash-2.0 were significant.)
+
+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'.
+
+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.
+
+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.
index 0a2f63f33757c44bdaada96b5eb1fb51bd3b5e10..4b428cc2485dfc6d1a858d875e62b4c670cf47a4 100644 (file)
@@ -8226,3 +8226,43 @@ 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>
index d58971eabecdd2387af3eddf983237dc5f19cddd..3069cb0a24e7e17f5326fda725d7b6d73cd95d9f 100644 (file)
@@ -8224,5 +8224,37 @@ trap.c
                                   ----
 subst.c
        - fix off-by-one error in pos_params when computing positional
-         parameters beginning with 0.  Bug and fix from Isaac Good
+         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>
index acd32dbf285c445e7d8292fb412a68e65e168836..b07fd61236ed26a0fca95d6ff6adb89dbb83ba8c 100644 (file)
@@ -82,6 +82,9 @@
 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. */
@@ -146,6 +149,7 @@ 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 *));
@@ -3379,6 +3383,13 @@ bash_quote_filename (s, rtype, qcp)
 /* 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 */
@@ -3386,10 +3397,10 @@ bash_execute_unix_command (count, key)
 {
   Keymap ckmap;                /* current keymap */
   Keymap xkmap;                /* unix command executing keymap */
-  register int i;
+  register int i, r;
   intmax_t mi;
   sh_parser_state_t ps;
-  char *cmd, *value, *l;
+  char *cmd, *value, *l, *ce;
   SHELL_VAR *v;
   char ibuf[INT_STRLEN_BOUND(int) + 1];
 
@@ -3425,7 +3436,15 @@ bash_execute_unix_command (count, key)
       return 1;
     }
 
-  rl_crlf ();  /* move to a new line */
+  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)
@@ -3438,7 +3457,7 @@ bash_execute_unix_command (count, key)
   array_needs_making = 1;
 
   save_parser_state (&ps);
-  parse_and_execute (cmd, "bash_execute_unix_command", SEVAL_NOHIST|SEVAL_NOFREE);
+  r = parse_and_execute (cmd, "bash_execute_unix_command", SEVAL_NOHIST|SEVAL_NOFREE);
   restore_parser_state (&ps);
 
   v = find_variable ("READLINE_LINE");
index bff8e5c2ff2f4a17c3900789fa5430b7938b8175..d081a062e028b66163d915b8e25425c82ca6760d 100644 (file)
@@ -146,6 +146,7 @@ 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 *));
@@ -3379,6 +3380,13 @@ bash_quote_filename (s, rtype, qcp)
 /* 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 */
@@ -3386,11 +3394,10 @@ bash_execute_unix_command (count, key)
 {
   Keymap ckmap;                /* current keymap */
   Keymap xkmap;                /* unix command executing keymap */
-  register int i;
+  register int i, r;
   intmax_t mi;
-  int save_point;
   sh_parser_state_t ps;
-  char *cmd, *value, *l;
+  char *cmd, *value, *l, *ce;
   SHELL_VAR *v;
   char ibuf[INT_STRLEN_BOUND(int) + 1];
 
@@ -3426,13 +3433,20 @@ bash_execute_unix_command (count, key)
       return 1;
     }
 
-  rl_crlf ();  /* move to a new line */
+  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 = value_cell (v);
-  save_point = rl_point;
   value = inttostr (rl_point, ibuf, sizeof (ibuf));
   v = bind_int_variable ("READLINE_POINT", value);
   if (v)
@@ -3440,7 +3454,7 @@ bash_execute_unix_command (count, key)
   array_needs_making = 1;
 
   save_parser_state (&ps);
-  parse_and_execute (cmd, "bash_execute_unix_command", SEVAL_NOHIST|SEVAL_NOFREE);
+  r = parse_and_execute (cmd, "bash_execute_unix_command", SEVAL_NOHIST|SEVAL_NOFREE);
   restore_parser_state (&ps);
 
   v = find_variable ("READLINE_LINE");
index 757fcea2cd17303f88fb7aaad143a3b925fa2b4f..8740bf70503286ccd6e342e5c995d210eeb186d5 100644 (file)
@@ -135,7 +135,7 @@ extern int errno;
     { \
       if (vflag) \
        { \
-         bind_variable  (vname, vbuf, 0); \
+         bind_printf_variable  (vname, vbuf, 0); \
          stupidly_hack_special_variables (vname); \
        } \
       if (conv_bufsize > 4096 ) \
@@ -186,6 +186,7 @@ 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;
@@ -234,7 +235,12 @@ printf_builtin (list)
       switch (ch)
        {
        case 'v':
-         if (legal_identifier (vname = list_optarg))
+         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;
@@ -1091,3 +1097,19 @@ asciicode ()
   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/printf.def~ b/builtins/printf.def~
new file mode 100644 (file)
index 0000000..236b401
--- /dev/null
@@ -0,0 +1,1110 @@
+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)) \
+       { \
+         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':
+         if (legal_identifier (vname = list_optarg))
+           {
+             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. */
+      ret = 0;
+      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/ddd1~ b/ddd1~
index a1fa9461193d4b180ace75ffdd59fbc167b134fd..a0ce497c4b588e9c2127a18a1cdb57d59d5291af 100644 (file)
--- a/ddd1~
+++ b/ddd1~
-*** ../bash-4.0-patched/variables.c    2009-01-04 14:32:46.000000000 -0500
---- variables.c        2009-06-29 09:17:20.000000000 -0400
+*** ../bash-4.0-patched/bashline.c     2009-01-08 09:29:24.000000000 -0500
+--- bashline.c 2009-07-16 14:13:41.000000000 -0400
 ***************
-*** 222,228 ****
---- 222,230 ----
-  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
+*** 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);
   
 ***************
-*** 253,256 ****
---- 255,259 ----
-  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 *));
+*** 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;
 ***************
-*** 376,383 ****
-  #  endif
-  #endif
-        else if (legal_identifier (name))
-       {
-         temp_var = bind_variable (name, string, 0);
-!        VSETATTR (temp_var, (att_exported | att_imported));
-         array_needs_making = 1;
+*** 3226,3230 ****
+         *r++ = *++p;
+         if (*p == '\0')
+!          break;
+         continue;
        }
---- 379,393 ----
-  #  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;
+--- 3226,3230 ----
+         *r++ = *++p;
+         if (*p == '\0')
+!          return ret;         /* XXX - was break; */
+         continue;
        }
 ***************
-*** 868,872 ****
-    av = array_cell (vv);
-    strcpy (d, dist_version);
-!   s = xstrchr (d, '.');
-    if (s)
-      *s++ = '\0';
---- 878,882 ----
-    av = array_cell (vv);
-    strcpy (d, dist_version);
-!   s = strchr (d, '.');
-    if (s)
-      *s++ = '\0';
-***************
-*** 1549,1552 ****
---- 1559,1563 ----
-  }
-  
-+ #if defined (ALIAS)
-  static SHELL_VAR *
-  build_aliasvar (self)
+*** 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 */
 ***************
-*** 1601,1604 ****
---- 1612,1617 ----
-    return (build_aliasvar (self));
-  }
-+ #endif /* ALIAS */
-+ 
-  #endif /* ARRAY_VARS */
-  
+*** 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 == '"')
 ***************
-*** 1696,1700 ****
---- 1709,1715 ----
+*** 3322,3330 ****
+  #if defined (BANG_HISTORY)
+    else if (*qcp == '\0' && history_expansion && cs == COMPLETE_DQUOTE &&
+!         history_expansion_inhibited == 0 && xstrchr (s, '!'))
+      cs = COMPLETE_BSQUOTE;
   
-    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
+    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;
 ***************
-*** 3083,3086 ****
---- 3098,3111 ----
-  }
-  
-+ /* 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. */
+*** 3389,3393 ****
+    register int i;
+    intmax_t mi;
+-   int save_point;
+    sh_parser_state_t ps;
+    char *cmd, *value, *l;
+--- 3389,3392 ----
 ***************
-*** 3439,3443 ****
---- 3464,3472 ----
-    SHELL_VAR **vars;
-  
-+ #if 0
-    vars = map_over (visible_and_exported, vcxt);
-+ #else
-+   vars = map_over (export_environment_candidate, vcxt);
-+ #endif
-  
-    if (vars == 0)
+*** 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 ----
 ***************
-*** 3588,3592 ****
-        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
---- 3617,3621 ----
-        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
+*** 3451,3455 ****
+      {
+        i = mi;
+!       if (i != save_point)
+       {
+         rl_point = i;
+--- 3449,3453 ----
+      {
+        i = mi;
+!       if (i != rl_point)
+       {
+         rl_point = i;
index 204dd348c7f3c2d457d488bec307d9a9f6ef21c0..95866ddcc45e2d1354712b4af301acf16eb98994 100644 (file)
@@ -3814,25 +3814,35 @@ execute_builtin (builtin, words, 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, then
-     restore it when the command completes.  This is also a problem (as
-     below) for the command and source/. builtins. */
+     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;
     }
@@ -3883,6 +3893,11 @@ execute_builtin (builtin, words, flags, subshell)
   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");
     }
 
index 09a382a6d2ca7b3398a5bb4120be4fb7aa0b7176..b7b3c87cafcdeb712d7d5211f515eead0835d1dc 100644 (file)
@@ -3814,6 +3814,7 @@ execute_builtin (builtin, words, flags, subshell)
 {
   int old_e_flag, result, eval_unwind;
   int isbltinenv;
+  char *error_trap;
 
 #if 0
   /* XXX -- added 12/11 */
@@ -3825,14 +3826,22 @@ execute_builtin (builtin, words, flags, subshell)
      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, then
-     restore it when the command completes.  This is also a problem (as
-     below) for the command and source/. builtins. */
+     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;
     }
@@ -3883,6 +3892,11 @@ execute_builtin (builtin, words, flags, subshell)
   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");
     }
 
@@ -4372,7 +4386,7 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
 
 #if defined (RESTRICTED_SHELL)
   command = (char *)NULL;
-  if (restricted && xstrchr (pathname, '/'))
+  if (restricted && mbschr (pathname, '/'))
     {
       internal_error (_("%s: restricted: cannot specify `/' in command names"),
                    pathname);
index 20bb1eaacd2a0de096fd7007a0d39839f763b2db..b4a468a416ca6928a63074205e9fc61c3be88e9c 100644 (file)
@@ -2220,6 +2220,8 @@ rl_old_menu_complete (count, invoking_key)
 
       rl_completion_invoking_key = invoking_key;
 
+      RL_SETSTATE(RL_STATE_COMPLETING);
+
       /* Only the completion entry function can change these. */
       set_completion_defaults ('%');
 
@@ -2259,9 +2261,12 @@ rl_old_menu_complete (count, invoking_key)
          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
@@ -2337,6 +2342,8 @@ rl_menu_complete (count, ignore)
 
       full_completion = 0;
 
+      RL_SETSTATE(RL_STATE_COMPLETING);
+
       /* Only the completion entry function can change these. */
       set_completion_defaults ('%');
 
@@ -2378,9 +2385,12 @@ rl_menu_complete (count, ignore)
          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++)
         ;
 
diff --git a/lib/readline/complete.c.save1 b/lib/readline/complete.c.save1
new file mode 100644 (file)
index 0000000..20bb1ea
--- /dev/null
@@ -0,0 +1,2462 @@
+/* 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~
new file mode 100644 (file)
index 0000000..c90588a
--- /dev/null
@@ -0,0 +1,2469 @@
+/* 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;
+
+      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;
+          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;
+
+      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);
+}
index e8cbf91e1cc6bc08296263bc2a6874344b7c04aa..c47cf1f37e9ab97e653f955402495dfc20201cd8 100644 (file)
@@ -1899,6 +1899,7 @@ _rl_move_cursor_relative (new, 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;
@@ -1914,15 +1915,34 @@ _rl_move_cursor_relative (new, data)
      as long as we are past them and they are counted by _rl_col_width. */
   if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     {
-      dpos = _rl_col_width (data, 0, new);
+      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 ((new > prompt_last_invisible) ||             /* XXX - don't use woff here */
+      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)))
+          new > (prompt_last_invisible-(_rl_screenwidth*_rl_last_v_pos)-wrap_offset))))
           /* XXX last comparison might need to be >= */
        {
          dpos -= woff;
@@ -2586,6 +2606,20 @@ _rl_ttymsg ("_rl_col_width: called with MB_CUR_MAX == 1");
   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 */
+      tmp += _rl_col_width (str, local_prompt_len, end);
+      return (tmp);
+    }
+
   while (point < start)
     {
       tmp = mbrlen (str + point, max, &ps);
index 2f3932514236ab548ae58d751416c0f0a5174f7d..dff22818bfdf7f34b5f723587f8c569dae0c2008 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -4,10 +4,10 @@
 # Nils Naumann <nnau@gmx.net>, 1996, 2008.
 msgid ""
 msgstr ""
-"Project-Id-Version: bash 4.0-pre1\n"
+"Project-Id-Version: bash 4.0\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2009-02-19 14:53-0500\n"
-"PO-Revision-Date: 2008-12-20 16:56+0100\n"
+"PO-Revision-Date: 2009-07-21 21:11+0200\n"
 "Last-Translator: Nils Naumann <nnau@gmx.net>\n"
 "Language-Team: German <translation-team-de@lists.sourceforge.net>\n"
 "MIME-Version: 1.0\n"
@@ -45,7 +45,7 @@ msgstr "%s: Kann die Datei %s nicht erzeugen."
 
 #: bashline.c:3413
 msgid "bash_execute_unix_command: cannot find keymap for command"
-msgstr ""
+msgstr "bash_execute_unix_command: Kann nicht die Tastenzuordnung für das Kommando finden."
 
 #: bashline.c:3491
 #, c-format
@@ -64,7 +64,7 @@ msgstr "%s: Fehlender Doppelpunkt."
 
 #: builtins/bind.def:120 builtins/bind.def:123
 msgid "line editing not enabled"
-msgstr ""
+msgstr "Zeileneditierung ist nicht aktiviert."
 
 #: builtins/bind.def:206
 #, c-format
@@ -246,12 +246,12 @@ msgstr "Schreibfehler: %s."
 #: builtins/common.c:329
 #, c-format
 msgid "error setting terminal attributes: %s"
-msgstr ""
+msgstr "Fehler beim Setzen der Terminalattribute: %s"
 
 #: builtins/common.c:331
 #, c-format
 msgid "error getting terminal attributes: %s"
-msgstr ""
+msgstr "Fehler beim Ermitteln der Terminalattribute: %s"
 
 #: builtins/common.c:563
 #, c-format
@@ -307,7 +307,7 @@ msgstr "%s: Kann Feldvariablen nicht auf diese Art l
 #: builtins/declare.def:468
 #, c-format
 msgid "%s: cannot convert associative to indexed array"
-msgstr ""
+msgstr "%s: Konvertieren von assoziativen in indizierte Arrays ist nicht möglich."
 
 #: builtins/enable.def:137 builtins/enable.def:145
 msgid "dynamic loading not available"
@@ -393,7 +393,7 @@ msgstr "%s: Kann die tempr
 
 #: builtins/fg_bg.def:149 builtins/jobs.def:282
 msgid "current"
-msgstr ""
+msgstr "gegenwärtig"
 
 #: builtins/fg_bg.def:158
 #, c-format
@@ -433,8 +433,7 @@ msgstr[1] ""
 
 #: builtins/help.def:168
 #, c-format
-msgid ""
-"no help topics match `%s'.  Try `help help' or `man -k %s' or `info %s'."
+msgid "no help topics match `%s'.  Try `help help' or `man -k %s' or `info %s'."
 msgstr ""
 
 #: builtins/help.def:185
@@ -580,12 +579,10 @@ msgid ""
 "    \twith its position in the stack\n"
 "    \n"
 "    Arguments:\n"
-"      +N\tDisplays the Nth entry counting from the left of the list shown "
-"by\n"
+"      +N\tDisplays the Nth entry counting from the left of the list shown by\n"
 "    \tdirs when invoked without options, starting with zero.\n"
 "    \n"
-"      -N\tDisplays the Nth entry counting from the right of the list shown "
-"by\n"
+"      -N\tDisplays the Nth entry counting from the right of the list shown by\n"
 "\tdirs when invoked without options, starting with zero."
 msgstr ""
 
@@ -712,7 +709,7 @@ msgstr ""
 #: builtins/setattr.def:186
 #, c-format
 msgid "%s: not a function"
-msgstr ""
+msgstr "%s: Ist keine Funktion."
 
 #: builtins/shift.def:71 builtins/shift.def:77
 msgid "shift count"
@@ -720,7 +717,7 @@ msgstr ""
 
 #: builtins/shopt.def:254
 msgid "cannot set and unset shell options simultaneously"
-msgstr ""
+msgstr "Kann nicht Shell Optinen gleichzeitig aktivieren und deaktivieren."
 
 #: builtins/shopt.def:319
 #, c-format
@@ -788,7 +785,7 @@ msgstr "`%c': Falsches Kommando."
 #: builtins/ulimit.def:427
 #, c-format
 msgid "%s: cannot get limit: %s"
-msgstr ""
+msgstr "%s: Kann die nicht Grenze setzen: %s"
 
 #: builtins/ulimit.def:453
 msgid "limit"
@@ -829,7 +826,7 @@ msgstr "Abbruch..."
 
 #: error.c:405
 msgid "unknown command error"
-msgstr ""
+msgstr "Unbekanntes Kommando"
 
 #: error.c:406
 msgid "bad command type"
@@ -841,9 +838,8 @@ msgid "bad connector"
 msgstr ""
 
 #: error.c:408
-#, fuzzy
 msgid "bad jump"
-msgstr "Falscher Sprung %d."
+msgstr "Falscher Sprung"
 
 #: error.c:446
 #, c-format
@@ -880,21 +876,20 @@ msgid "%s: command not found"
 msgstr "%s: Kommando nicht gefunden."
 
 #: execute_cmd.c:4708
-#, fuzzy, c-format
+#, c-format
 msgid "%s: %s: bad interpreter"
-msgstr "%s: ist ein Verzeichnis."
+msgstr "%s: %s: Defekter Interpreter"
 
 #: execute_cmd.c:4857
-#, fuzzy, c-format
+#, c-format
 msgid "cannot duplicate fd %d to fd %d"
-msgstr "Kann fd %d nicht auf fd 0 verdoppeln: %s"
+msgstr "Kann fd %d nicht auf fd %d verdoppeln."
 
 #: expr.c:241
 msgid "expression recursion level exceeded"
 msgstr "Zu viele Rekursionen in Ausdruck."
 
 #: expr.c:265
-#, fuzzy
 msgid "recursion stack underflow"
 msgstr "Rekursionsstapel leer."
 
@@ -911,9 +906,8 @@ msgid "division by 0"
 msgstr "Division durch 0."
 
 #: expr.c:471
-#, fuzzy
 msgid "bug: bad expassign token"
-msgstr "Fehler: Falsches Zuweisungszeichen %d."
+msgstr "Fehler: Falscher Zuweisungsoperator."
 
 #: expr.c:513
 msgid "`:' expected for conditional expression"
@@ -925,26 +919,24 @@ msgstr "Der Exponent ist kleiner als 0."
 
 #: expr.c:826
 msgid "identifier expected after pre-increment or pre-decrement"
-msgstr ""
-"Nach einem Präinkrement oder Prädekrement wird ein Bezeichner erwartet."
+msgstr "Nach einem Präinkrement oder Prädekrement wird ein Bezeichner erwartet."
 
 #: expr.c:854
 msgid "missing `)'"
 msgstr "Fehlende `)'"
 
 #: expr.c:897 expr.c:1175
-#, fuzzy
 msgid "syntax error: operand expected"
-msgstr "Syntax Fehler: Unerwartetes Dateiende."
+msgstr "Syntax Fehler: Operator erwartet."
 
 #: expr.c:1177
 msgid "syntax error: invalid arithmetic operator"
 msgstr "Syntaxfehler: Ungültiger arithmetischer Operator."
 
 #: expr.c:1201
-#, fuzzy, c-format
+#, c-format
 msgid "%s%s%s: %s (error token is \"%s\")"
-msgstr "%s: %s: %s (Fehlerverursachendes Wort ist \\\"%s\\\").\n"
+msgstr "%s%s%s: %s (Fehlerverursachendes Zeichen ist \\\"%s\\\")."
 
 #: expr.c:1259
 msgid "invalid arithmetic base"
@@ -955,9 +947,9 @@ msgid "value too great for base"
 msgstr "Der Wert ist zu groß für die aktuelle Basis."
 
 #: expr.c:1328
-#, fuzzy, c-format
+#, c-format
 msgid "%s: expression error\n"
-msgstr "Umlenkfehler"
+msgstr "%s: Fehler im Ausdruck.\n"
 
 #: general.c:61
 msgid "getcwd: cannot access parent directories"
@@ -975,9 +967,9 @@ msgstr "Kann keinen neuen Filedeskriptor f
 
 # Debug Ausgabe
 #: input.c:266
-#, fuzzy, c-format
+#, c-format
 msgid "save_bash_input: buffer already exists for new fd %d"
-msgstr "check_bash_input: buffer already exists for new fd %d"
+msgstr "save_bash_input: Es existiert bereits ein Puffer für den neuen fd %d."
 
 #: jobs.c:466
 msgid "start_pipeline: pgrp pipe"
@@ -1005,9 +997,9 @@ msgstr ""
 
 # Programmierfehler
 #: jobs.c:1401
-#, fuzzy, c-format
+#, c-format
 msgid "describe_pid: %ld: no such pid"
-msgstr "describe_pid: Prozeß-Nummer existiert nicht (%d)!\n"
+msgstr "describe_pid: %ld: Prozeßnummer existiert nicht."
 
 #: jobs.c:1416
 #, c-format
@@ -1227,19 +1219,17 @@ msgid "The mail in %s has been read\n"
 msgstr "Die Post in %s wurde bereits gelesen.\n"
 
 #: make_cmd.c:322
-#, fuzzy
 msgid "syntax error: arithmetic expression required"
-msgstr "Syntaxfehler im Ausdruck."
+msgstr "Syntaxfehler: Ein arithmetischer Ausdruck wird verlangt."
 
 #: make_cmd.c:324
-#, fuzzy
 msgid "syntax error: `;' unexpected"
-msgstr "Syntax Fehler: Unerwartetes Dateiende."
+msgstr "Syntax Fehler: unerwartetes `;'."
 
 #: make_cmd.c:325
-#, fuzzy, c-format
+#, c-format
 msgid "syntax error: `((%s))'"
-msgstr "Syntax Fehler"
+msgstr "Syntax Fehler: `((%s))'."
 
 # interner Fehler
 #: make_cmd.c:567
@@ -1258,24 +1248,22 @@ msgid "make_redirection: redirection instruction `%d' out of range"
 msgstr ""
 
 #: parse.y:2986 parse.y:3218
-#, fuzzy, c-format
+#, c-format
 msgid "unexpected EOF while looking for matching `%c'"
 msgstr "Dateiende beim Suchen nach `%c' erreicht."
 
 #: parse.y:3722
-#, fuzzy
 msgid "unexpected EOF while looking for `]]'"
-msgstr "Dateiende beim Suchen nach `%c' erreicht."
+msgstr "Dateiende beim Suchen nach `]]' erreicht."
 
 #: parse.y:3727
-#, fuzzy, c-format
+#, c-format
 msgid "syntax error in conditional expression: unexpected token `%s'"
-msgstr "Syntaxfehler beim unerwarteten Wort `%s'"
+msgstr "Syntaxfehler im bedingten Ausdruck: Unerwartetes Zeichen `%s'."
 
 #: parse.y:3731
-#, fuzzy
 msgid "syntax error in conditional expression"
-msgstr "Syntaxfehler im Ausdruck."
+msgstr "Syntaxfehler im bedingen Ausdruck."
 
 #: parse.y:3809
 #, c-format
@@ -1283,7 +1271,6 @@ msgid "unexpected token `%s', expected `)'"
 msgstr ""
 
 #: parse.y:3813
-#, fuzzy
 msgid "expected `)'"
 msgstr "`)' erwartet."
 
@@ -1768,8 +1755,7 @@ msgstr ""
 
 #: trap.c:328
 #, c-format
-msgid ""
-"run_pending_traps: signal handler is SIG_DFL, resending %d (%s) to myself"
+msgid "run_pending_traps: signal handler is SIG_DFL, resending %d (%s) to myself"
 msgstr ""
 
 # Programmierfehler
@@ -1819,17 +1805,12 @@ msgid "pop_scope: head of shell_variables not a temporary environment scope"
 msgstr ""
 
 #: version.c:46
-#, fuzzy
 msgid "Copyright (C) 2009 Free Software Foundation, Inc."
-msgstr "Copyright (C) 2008 Free Software Foundation, Inc."
+msgstr "Copyright (C) 2009 Free Software Foundation, Inc."
 
 #: version.c:47
-msgid ""
-"License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl."
-"html>\n"
-msgstr ""
-"Lizenz GPLv3+: GNU GPL Version 3 oder jünger <http://gnu.org/licenses/gpl."
-"html>\n"
+msgid "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n"
+msgstr "Lizenz GPLv3+: GNU GPL Version 3 oder jünger <http://gnu.org/licenses/gpl.html>\n"
 
 #: version.c:86
 #, c-format
@@ -1869,8 +1850,7 @@ msgstr "xrealloc: Kann nicht %lu Bytes reservieren."
 #: xmalloc.c:150
 #, c-format
 msgid "xmalloc: %s:%d: cannot allocate %lu bytes (%lu bytes allocated)"
-msgstr ""
-"xmalloc: %s:%d: Kann nicht %lu Bytes reservieren (%lu bytes reserviert)."
+msgstr "xmalloc: %s:%d: Kann nicht %lu Bytes reservieren (%lu bytes reserviert)."
 
 #: xmalloc.c:152
 #, c-format
@@ -1880,8 +1860,7 @@ msgstr "xmalloc: %s:%d: Kann nicht %lu Bytes reservieren."
 #: xmalloc.c:174
 #, c-format
 msgid "xrealloc: %s:%d: cannot reallocate %lu bytes (%lu bytes allocated)"
-msgstr ""
-"xrealloc: %s:%d: Kann nicht %lu Bytes reservieren (%lu bytes reserviert)."
+msgstr "xrealloc: %s:%d: Kann nicht %lu Bytes reservieren (%lu bytes reserviert)."
 
 #: xmalloc.c:176
 #, c-format
@@ -1897,12 +1876,8 @@ msgid "unalias [-a] name [name ...]"
 msgstr "unalias [-a] Name [Name ...]"
 
 #: builtins.c:51
-msgid ""
-"bind [-lpvsPVS] [-m keymap] [-f filename] [-q name] [-u name] [-r keyseq] [-"
-"x keyseq:shell-command] [keyseq:readline-function or readline-command]"
-msgstr ""
-"bind [-lpvsPVS] [-m Tastaturtabelle] [-f Dateiname] [-q Name] [-u Name] [-r "
-"Tastenfolge:Shell Kommando] [Tastenfolge:readline Funktion oder Kommando]"
+msgid "bind [-lpvsPVS] [-m keymap] [-f filename] [-q name] [-u name] [-r keyseq] [-x keyseq:shell-command] [keyseq:readline-function or readline-command]"
+msgstr "bind [-lpvsPVS] [-m Tastaturtabelle] [-f Dateiname] [-q Name] [-u Name] [-r Tastenfolge:Shell Kommando] [Tastenfolge:readline Funktion oder Kommando]"
 
 #: builtins.c:54
 msgid "break [n]"
@@ -1991,9 +1966,7 @@ msgstr "logout [n]"
 
 #: builtins.c:103
 msgid "fc [-e ename] [-lnr] [first] [last] or fc -s [pat=rep] [command]"
-msgstr ""
-"fc [-e Editor] [-lnr] [Anfang] [Ende] oder fc -s [Muster=Ersetzung] "
-"[Kommando]"
+msgstr "fc [-e Editor] [-lnr] [Anfang] [Ende] oder fc -s [Muster=Ersetzung] [Kommando]"
 
 #: builtins.c:107
 msgid "fg [job_spec]"
@@ -2012,12 +1985,8 @@ msgid "help [-ds] [pattern ...]"
 msgstr "help [-ds] [Muster ...]"
 
 #: builtins.c:121
-msgid ""
-"history [-c] [-d offset] [n] or history -anrw [filename] or history -ps arg "
-"[arg...]"
-msgstr ""
-"history [-c] [-d Offset] [n] oder history -anrw [Dateiname] oder history -ps "
-"Argument [Argument...]"
+msgid "history [-c] [-d offset] [n] or history -anrw [filename] or history -ps arg [arg...]"
+msgstr "history [-c] [-d Offset] [n] oder history -anrw [Dateiname] oder history -ps Argument [Argument...]"
 
 #: builtins.c:125
 msgid "jobs [-lnprs] [jobspec ...] or jobs -x command [args]"
@@ -2028,24 +1997,16 @@ msgid "disown [-h] [-ar] [jobspec ...]"
 msgstr "disown [-h] [-ar] [Jobbezeichnung ...]"
 
 #: builtins.c:132
-msgid ""
-"kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l "
-"[sigspec]"
-msgstr ""
-"kill [-s Signalname | -n Signalnummer | -Signalname] [pid | job] ... oder "
-"kill -l [Signalname]"
+msgid "kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]"
+msgstr "kill [-s Signalname | -n Signalnummer | -Signalname] [pid | job] ... oder kill -l [Signalname]"
 
 #: builtins.c:134
 msgid "let arg [arg ...]"
 msgstr "let Argument [Argument ...]"
 
 #: builtins.c:136
-msgid ""
-"read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-p prompt] [-t "
-"timeout] [-u fd] [name ...]"
-msgstr ""
-"read [-ers] [-a Feld] [-d Begrenzer] [-i Text] [-n Zeichenanzahl] [-p "
-"Prompt] [-t Zeitlimit] [-u fd] [Name ...]"
+msgid "read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-p prompt] [-t timeout] [-u fd] [name ...]"
+msgstr "read [-ers] [-a Feld] [-d Begrenzer] [-i Text] [-n Zeichenanzahl] [-p Prompt] [-t Zeitlimit] [-u fd] [Name ...]"
 
 #: builtins.c:138
 msgid "return [n]"
@@ -2140,9 +2101,7 @@ msgid "case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac"
 msgstr "case Wort in [Muster [| Muster]...) Kommandos ;;]... esac"
 
 #: builtins.c:192
-msgid ""
-"if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else "
-"COMMANDS; ] fi"
+msgid "if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi"
 msgstr ""
 "if Kommandos; then Kommandos; [ elif Kommandos; then Kommandos; ]... \n"
 "\t[ else Kommandos; ] fi"
@@ -2204,38 +2163,23 @@ msgid "printf [-v var] format [arguments]"
 msgstr "printf [-v var] Format [Argumente]"
 
 #: builtins.c:229
-msgid ""
-"complete [-abcdefgjksuv] [-pr] [-o option] [-A action] [-G globpat] [-W "
-"wordlist]  [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] "
-"[name ...]"
-msgstr ""
-"complete [-abcdefgjksuv] [-pr] [-o Option] [-A Aktion] [-G Suchmuster] [-W "
-"Wortliste]  [-F Funktion] [-C Kommando] [-X Filtermuster] [-P Prefix] [-S "
-"Suffix] [Name ...]"
+msgid "complete [-abcdefgjksuv] [-pr] [-o option] [-A action] [-G globpat] [-W wordlist]  [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...]"
+msgstr "complete [-abcdefgjksuv] [-pr] [-o Option] [-A Aktion] [-G Suchmuster] [-W Wortliste]  [-F Funktion] [-C Kommando] [-X Filtermuster] [-P Prefix] [-S Suffix] [Name ...]"
 
 #: builtins.c:233
-msgid ""
-"compgen [-abcdefgjksuv] [-o option]  [-A action] [-G globpat] [-W wordlist]  "
-"[-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]"
-msgstr ""
-"compgen [-abcdefgjksuv] [-o Option]  [-A Aktion] [-G Suchmuster] [-W "
-"Wortliste]  [-F Funktion] [-C Kommando] [-X Filtermuster] [-P Prefix] [-S "
-"Suffix] [Wort]"
+msgid "compgen [-abcdefgjksuv] [-o option]  [-A action] [-G globpat] [-W wordlist]  [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]"
+msgstr "compgen [-abcdefgjksuv] [-o Option]  [-A Aktion] [-G Suchmuster] [-W Wortliste]  [-F Funktion] [-C Kommando] [-X Filtermuster] [-P Prefix] [-S Suffix] [Wort]"
 
 #: builtins.c:237
 msgid "compopt [-o|+o option] [name ...]"
 msgstr "compopt [-o|+o Option] [Name ...]"
 
 #: builtins.c:240
-msgid ""
-"mapfile [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c "
-"quantum] [array]"
+msgid "mapfile [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]"
 msgstr ""
 
 #: builtins.c:242
-msgid ""
-"readarray [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c "
-"quantum] [array]"
+msgid "readarray [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]"
 msgstr ""
 
 #: builtins.c:254
@@ -2253,8 +2197,7 @@ msgid ""
 "      -p\tPrint all defined aliases in a reusable format\n"
 "    \n"
 "    Exit Status:\n"
-"    alias returns true unless a NAME is supplied for which no alias has "
-"been\n"
+"    alias returns true unless a NAME is supplied for which no alias has been\n"
 "    defined."
 msgstr ""
 "Definiert Aliase oder zeigt sie an.\n"
@@ -2301,24 +2244,20 @@ msgid ""
 "    Options:\n"
 "      -m  keymap         Use KEYMAP as the keymap for the duration of this\n"
 "                         command.  Acceptable keymap names are emacs,\n"
-"                         emacs-standard, emacs-meta, emacs-ctlx, vi, vi-"
-"move,\n"
+"                         emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move,\n"
 "                         vi-command, and vi-insert.\n"
 "      -l                 List names of functions.\n"
 "      -P                 List function names and bindings.\n"
 "      -p                 List functions and bindings in a form that can be\n"
 "                         reused as input.\n"
-"      -S                 List key sequences that invoke macros and their "
-"values\n"
-"      -s                 List key sequences that invoke macros and their "
-"values\n"
+"      -S                 List key sequences that invoke macros and their values\n"
+"      -s                 List key sequences that invoke macros and their values\n"
 "                         in a form that can be reused as input.\n"
 "      -V                 List variable names and values\n"
 "      -v                 List variable names and values in a form that can\n"
 "                         be reused as input.\n"
 "      -q  function-name  Query about which keys invoke the named function.\n"
-"      -u  function-name  Unbind all keys which are bound to the named "
-"function.\n"
+"      -u  function-name  Unbind all keys which are bound to the named function.\n"
 "      -r  keyseq         Remove the binding for KEYSEQ.\n"
 "      -f  filename       Read key bindings from FILENAME.\n"
 "      -x  keyseq:shell-command\tCause SHELL-COMMAND to be executed when\n"
@@ -2340,8 +2279,7 @@ msgid ""
 msgstr ""
 "Beendet for, while oder until Schleifen.\n"
 "    \n"
-"    Break beendet eine FOR, WHILE oder UNTIL Schleife.  Wenn N angegeben "
-"ist, werden N geschachtelte\n"
+"    Break beendet eine FOR, WHILE oder UNTIL Schleife.  Wenn N angegeben ist, werden N geschachtelte\n"
 "    Schleifen beendet.\n"
 "    \n"
 "    Rückgabewert:\n"
@@ -2359,8 +2297,7 @@ msgid ""
 msgstr ""
 "Springt zum Schleifenanfang von for, while, oder until Schleifen.\n"
 "    \n"
-"    Continoue springt zum Schleifenanfang der aktuellen FOR, WHILE oder "
-"UNTIL \n"
+"    Continoue springt zum Schleifenanfang der aktuellen FOR, WHILE oder UNTIL \n"
 "    Schleife. Wenn N angegeben ist, werden N wird zum Beginn der N-ten\n"
 "    übergeordneten Schleife gesprungen.\n"
 "    \n"
@@ -2373,8 +2310,7 @@ msgid ""
 "    \n"
 "    Execute SHELL-BUILTIN with arguments ARGs without performing command\n"
 "    lookup.  This is useful when you wish to reimplement a shell builtin\n"
-"    as a shell function, but need to execute the builtin within the "
-"function.\n"
+"    as a shell function, but need to execute the builtin within the function.\n"
 "    \n"
 "    Exit Status:\n"
 "    Returns the exit status of SHELL-BUILTIN, or false if SHELL-BUILTIN is\n"
@@ -2401,22 +2337,16 @@ msgstr ""
 msgid ""
 "Change the shell working directory.\n"
 "    \n"
-"    Change the current directory to DIR.  The default DIR is the value of "
-"the\n"
+"    Change the current directory to DIR.  The default DIR is the value of the\n"
 "    HOME shell variable.\n"
 "    \n"
-"    The variable CDPATH defines the search path for the directory "
-"containing\n"
-"    DIR.  Alternative directory names in CDPATH are separated by a colon "
-"(:).\n"
-"    A null directory name is the same as the current directory.  If DIR "
-"begins\n"
+"    The variable CDPATH defines the search path for the directory containing\n"
+"    DIR.  Alternative directory names in CDPATH are separated by a colon (:).\n"
+"    A null directory name is the same as the current directory.  If DIR begins\n"
 "    with a slash (/), then CDPATH is not used.\n"
 "    \n"
-"    If the directory is not found, and the shell option `cdable_vars' is "
-"set,\n"
-"    the word is assumed to be  a variable name.  If that variable has a "
-"value,\n"
+"    If the directory is not found, and the shell option `cdable_vars' is set,\n"
+"    the word is assumed to be  a variable name.  If that variable has a value,\n"
 "    its value is used for DIR.\n"
 "    \n"
 "    Options:\n"
@@ -2451,14 +2381,12 @@ msgstr ""
 "      -L\tGibt den Wert der $PWD Umgebungsvariable aus, wenn diese\n"
 "\tauf das aktuelle Arbeitsverzeichnis verweist.\n"
 "\n"
-"      -P\tGibt den wirklichen Verzeichnisnahen aus, ohne symbolische "
-"Verweise.\n"
+"      -P\tGibt den wirklichen Verzeichnisnahen aus, ohne symbolische Verweise.\n"
 "    \n"
 "    Standardmäßig wird die -L Option verwendet.\n"
 "    \n"
 "    Rückgabewert:\n"
-"    Der Rückgabewert ist 0, außer wenn eine ungültige Option angegeben oder "
-"das aktuelle\n"
+"    Der Rückgabewert ist 0, außer wenn eine ungültige Option angegeben oder das aktuelle\n"
 "    Verzeichnis nicht gelesen werden kann."
 
 # colon
@@ -2499,8 +2427,7 @@ msgid ""
 "Execute a simple command or display information about commands.\n"
 "    \n"
 "    Runs COMMAND with ARGS suppressing  shell function lookup, or display\n"
-"    information about the specified COMMANDs.  Can be used to invoke "
-"commands\n"
+"    information about the specified COMMANDs.  Can be used to invoke commands\n"
 "    on disk when a function with the same name exists.\n"
 "    \n"
 "    Options:\n"
@@ -2541,8 +2468,7 @@ msgid ""
 "    Variables with the integer attribute have arithmetic evaluation (see\n"
 "    the `let' command) performed when the variable is assigned a value.\n"
 "    \n"
-"    When used in a function, `declare' makes NAMEs local, as with the "
-"`local'\n"
+"    When used in a function, `declare' makes NAMEs local, as with the `local'\n"
 "    command.\n"
 "    \n"
 "    Exit Status:\n"
@@ -2575,14 +2501,11 @@ msgid ""
 msgstr ""
 "Definiert lokale Vatiablen.\n"
 "    \n"
-"    Erzeugt eine Lokale Variable NAME und weist ihr den Wert VALUE zu.  "
-"OPTION\n"
+"    Erzeugt eine Lokale Variable NAME und weist ihr den Wert VALUE zu.  OPTION\n"
 "    kann eine beliebige von `declare' akzeptierte Option sein.\n"
 "\n"
-"    Lokale Variablen können nur innerhalb einer Funktion benutzt werden. "
-"Sie\n"
-"    sind nur in der sie erzeugenden Funktion und ihren Kindern "
-"sichtbar.    \n"
+"    Lokale Variablen können nur innerhalb einer Funktion benutzt werden. Sie\n"
+"    sind nur in der sie erzeugenden Funktion und ihren Kindern sichtbar.    \n"
 "    \n"
 "    Rückgabewert:\n"
 "    Liefert \"Erfolg\" außer bei einer ungültigen Option, einem Fehler oder\n"
@@ -2663,8 +2586,7 @@ msgstr ""
 msgid ""
 "Execute arguments as a shell command.\n"
 "    \n"
-"    Combine ARGs into a single string, use the result as input to the "
-"shell,\n"
+"    Combine ARGs into a single string, use the result as input to the shell,\n"
 "    and execute the resulting commands.\n"
 "    \n"
 "    Exit Status:\n"
@@ -2717,8 +2639,7 @@ msgid ""
 "Replace the shell with the given command.\n"
 "    \n"
 "    Execute COMMAND, replacing this shell with the specified program.\n"
-"    ARGUMENTS become the arguments to COMMAND.  If COMMAND is not "
-"specified,\n"
+"    ARGUMENTS become the arguments to COMMAND.  If COMMAND is not specified,\n"
 "    any redirections take effect in the current shell.\n"
 "    \n"
 "    Options:\n"
@@ -2726,13 +2647,11 @@ msgid ""
 "      -c\t\texecute COMMAND with an empty environment\n"
 "      -l\t\tplace a dash in the zeroth argument to COMMAND\n"
 "    \n"
-"    If the command cannot be executed, a non-interactive shell exits, "
-"unless\n"
+"    If the command cannot be executed, a non-interactive shell exits, unless\n"
 "    the shell option `execfail' is set.\n"
 "    \n"
 "    Exit Status:\n"
-"    Returns success unless COMMAND is not found or a redirection error "
-"occurs."
+"    Returns success unless COMMAND is not found or a redirection error occurs."
 msgstr ""
 
 # exit
@@ -2745,16 +2664,14 @@ msgid ""
 msgstr ""
 "Beendet die aktuelle Shell.\n"
 "\n"
-"    Beendt die die aktuelle Shell mit dem Rückgabewert N.  Wenn N nicht "
-"angegeben ist,\n"
+"    Beendt die die aktuelle Shell mit dem Rückgabewert N.  Wenn N nicht angegeben ist,\n"
 "    wird der Rückgabewert des letzten ausgeführten Kommandos übernommen."
 
 #: builtins.c:698
 msgid ""
 "Exit a login shell.\n"
 "    \n"
-"    Exits a login shell with exit status N.  Returns an error if not "
-"executed\n"
+"    Exits a login shell with exit status N.  Returns an error if not executed\n"
 "    in a login shell."
 msgstr ""
 
@@ -2762,15 +2679,13 @@ msgstr ""
 msgid ""
 "Display or execute commands from the history list.\n"
 "    \n"
-"    fc is used to list or edit and re-execute commands from the history "
-"list.\n"
+"    fc is used to list or edit and re-execute commands from the history list.\n"
 "    FIRST and LAST can be numbers specifying the range, or FIRST can be a\n"
 "    string, which means the most recent command beginning with that\n"
 "    string.\n"
 "    \n"
 "    Options:\n"
-"      -e ENAME\tselect which editor to use.  Default is FCEDIT, then "
-"EDITOR,\n"
+"      -e ENAME\tselect which editor to use.  Default is FCEDIT, then EDITOR,\n"
 "    \t\tthen vi\n"
 "      -l \tlist lines instead of editing\n"
 "      -n\tomit line numbers when listing\n"
@@ -2784,8 +2699,7 @@ msgid ""
 "    the last command.\n"
 "    \n"
 "    Exit Status:\n"
-"    Returns success or status of executed command; non-zero if an error "
-"occurs."
+"    Returns success or status of executed command; non-zero if an error occurs."
 msgstr ""
 
 #: builtins.c:738
@@ -2804,10 +2718,8 @@ msgstr ""
 msgid ""
 "Move jobs to the background.\n"
 "    \n"
-"    Place the jobs identified by each JOB_SPEC in the background, as if "
-"they\n"
-"    had been started with `&'.  If JOB_SPEC is not present, the shell's "
-"notion\n"
+"    Place the jobs identified by each JOB_SPEC in the background, as if they\n"
+"    had been started with `&'.  If JOB_SPEC is not present, the shell's notion\n"
 "    of the current job is used.\n"
 "    \n"
 "    Exit Status:\n"
@@ -2819,8 +2731,7 @@ msgid ""
 "Remember or display program locations.\n"
 "    \n"
 "    Determine and remember the full pathname of each command NAME.  If\n"
-"    no arguments are given, information about remembered commands is "
-"displayed.\n"
+"    no arguments are given, information about remembered commands is displayed.\n"
 "    \n"
 "    Options:\n"
 "      -d\t\tforget the remembered location of each NAME\n"
@@ -2856,8 +2767,7 @@ msgid ""
 "      PATTERN\tPattern specifiying a help topic\n"
 "    \n"
 "    Exit Status:\n"
-"    Returns success unless PATTERN is not found or an invalid option is "
-"given."
+"    Returns success unless PATTERN is not found or an invalid option is given."
 msgstr ""
 
 #: builtins.c:816
@@ -2887,8 +2797,7 @@ msgid ""
 "    \n"
 "    If the $HISTTIMEFORMAT variable is set and not null, its value is used\n"
 "    as a format string for strftime(3) to print the time stamp associated\n"
-"    with each displayed history entry.  No time stamps are printed "
-"otherwise.\n"
+"    with each displayed history entry.  No time stamps are printed otherwise.\n"
 "    \n"
 "    Exit Status:\n"
 "    Returns success unless an invalid option is given or an error occurs."
@@ -2964,8 +2873,7 @@ msgid ""
 "    Evaluate each ARG as an arithmetic expression.  Evaluation is done in\n"
 "    fixed-width integers with no check for overflow, though division by 0\n"
 "    is trapped and flagged as an error.  The following list of operators is\n"
-"    grouped into levels of equal-precedence operators.  The levels are "
-"listed\n"
+"    grouped into levels of equal-precedence operators.  The levels are listed\n"
 "    in order of decreasing precedence.\n"
 "    \n"
 "    \tid++, id--\tvariable post-increment, post-decrement\n"
@@ -3007,16 +2915,13 @@ msgid ""
 "Read a line from the standard input and split it into fields.\n"
 "    \n"
 "    Reads a single line from the standard input, or from file descriptor FD\n"
-"    if the -u option is supplied.  The line is split into fields as with "
-"word\n"
+"    if the -u option is supplied.  The line is split into fields as with word\n"
 "    splitting, and the first word is assigned to the first NAME, the second\n"
 "    word to the second NAME, and so on, with any leftover words assigned to\n"
-"    the last NAME.  Only the characters found in $IFS are recognized as "
-"word\n"
+"    the last NAME.  Only the characters found in $IFS are recognized as word\n"
 "    delimiters.\n"
 "    \n"
-"    If no NAMEs are supplied, the line read is stored in the REPLY "
-"variable.\n"
+"    If no NAMEs are supplied, the line read is stored in the REPLY variable.\n"
 "    \n"
 "    Options:\n"
 "      -a array\tassign the words read to sequential indices of the array\n"
@@ -3031,8 +2936,7 @@ msgid ""
 "    \t\tattempting to read\n"
 "      -r\t\tdo not allow backslashes to escape any characters\n"
 "      -s\t\tdo not echo input coming from a terminal\n"
-"      -t timeout\ttime out and return failure if a complete line of input "
-"is\n"
+"      -t timeout\ttime out and return failure if a complete line of input is\n"
 "    \t\tnot read withint TIMEOUT seconds.  The value of the TMOUT\n"
 "    \t\tvariable is the default timeout.  TIMEOUT may be a\n"
 "    \t\tfractional number.  If TIMEOUT is 0, read returns success only\n"
@@ -3041,8 +2945,7 @@ msgid ""
 "      -u fd\t\tread from file descriptor FD instead of the standard input\n"
 "    \n"
 "    Exit Status:\n"
-"    The return code is zero, unless end-of-file is encountered, read times "
-"out,\n"
+"    The return code is zero, unless end-of-file is encountered, read times out,\n"
 "    or an invalid file descriptor is supplied as the argument to -u."
 msgstr ""
 
@@ -3101,8 +3004,7 @@ msgid ""
 "              physical     same as -P\n"
 "              pipefail     the return value of a pipeline is the status of\n"
 "                           the last command to exit with a non-zero status,\n"
-"                           or zero if no command exited with a non-zero "
-"status\n"
+"                           or zero if no command exited with a non-zero status\n"
 "              posix        change the behavior of bash where the default\n"
 "                           operation differs from the Posix standard to\n"
 "                           match the standard\n"
@@ -3150,8 +3052,7 @@ msgid ""
 "      -f\ttreat each NAME as a shell function\n"
 "      -v\ttreat each NAME as a shell variable\n"
 "    \n"
-"    Without options, unset first tries to unset a variable, and if that "
-"fails,\n"
+"    Without options, unset first tries to unset a variable, and if that fails,\n"
 "    tries to unset a function.\n"
 "    \n"
 "    Some variables cannot be unset; also see `readonly'.\n"
@@ -3165,8 +3066,7 @@ msgid ""
 "Set export attribute for shell variables.\n"
 "    \n"
 "    Marks each NAME for automatic export to the environment of subsequently\n"
-"    executed commands.  If VALUE is supplied, assign VALUE before "
-"exporting.\n"
+"    executed commands.  If VALUE is supplied, assign VALUE before exporting.\n"
 "    \n"
 "    Options:\n"
 "      -f\trefer to shell functions\n"
@@ -3269,8 +3169,7 @@ msgid ""
 "      -x FILE        True if the file is executable by you.\n"
 "      -O FILE        True if the file is effectively owned by you.\n"
 "      -G FILE        True if the file is effectively owned by your group.\n"
-"      -N FILE        True if the file has been modified since it was last "
-"read.\n"
+"      -N FILE        True if the file has been modified since it was last read.\n"
 "    \n"
 "      FILE1 -nt FILE2  True if file1 is newer than file2 (according to\n"
 "                       modification date).\n"
@@ -3291,8 +3190,7 @@ msgid ""
 "      STRING1 != STRING2\n"
 "                     True if the strings are not equal.\n"
 "      STRING1 < STRING2\n"
-"                     True if STRING1 sorts before STRING2 "
-"lexicographically.\n"
+"                     True if STRING1 sorts before STRING2 lexicographically.\n"
 "      STRING1 > STRING2\n"
 "                     True if STRING1 sorts after STRING2 lexicographically.\n"
 "    \n"
@@ -3327,8 +3225,7 @@ msgstr ""
 msgid ""
 "Display process times.\n"
 "    \n"
-"    Prints the accumulated user and system times for the shell and all of "
-"its\n"
+"    Prints the accumulated user and system times for the shell and all of its\n"
 "    child processes.\n"
 "    \n"
 "    Exit Status:\n"
@@ -3339,8 +3236,7 @@ msgstr ""
 msgid ""
 "Trap signals and other events.\n"
 "    \n"
-"    Defines and activates handlers to be run when the shell receives "
-"signals\n"
+"    Defines and activates handlers to be run when the shell receives signals\n"
 "    or other conditions.\n"
 "    \n"
 "    ARG is a command to be read and executed when the shell receives the\n"
@@ -3349,26 +3245,22 @@ msgid ""
 "    value.  If ARG is the null string each SIGNAL_SPEC is ignored by the\n"
 "    shell and by the commands it invokes.\n"
 "    \n"
-"    If a SIGNAL_SPEC is EXIT (0) ARG is executed on exit from the shell.  "
-"If\n"
+"    If a SIGNAL_SPEC is EXIT (0) ARG is executed on exit from the shell.  If\n"
 "    a SIGNAL_SPEC is DEBUG, ARG is executed before every simple command.\n"
 "    \n"
-"    If no arguments are supplied, trap prints the list of commands "
-"associated\n"
+"    If no arguments are supplied, trap prints the list of commands associated\n"
 "    with each signal.\n"
 "    \n"
 "    Options:\n"
 "      -l\tprint a list of signal names and their corresponding numbers\n"
 "      -p\tdisplay the trap commands associated with each SIGNAL_SPEC\n"
 "    \n"
-"    Each SIGNAL_SPEC is either a signal name in <signal.h> or a signal "
-"number.\n"
+"    Each SIGNAL_SPEC is either a signal name in <signal.h> or a signal number.\n"
 "    Signal names are case insensitive and the SIG prefix is optional.  A\n"
 "    signal may be sent to the shell with \"kill -signal $$\".\n"
 "    \n"
 "    Exit Status:\n"
-"    Returns success unless a SIGSPEC is invalid or an invalid option is "
-"given."
+"    Returns success unless a SIGSPEC is invalid or an invalid option is given."
 msgstr ""
 
 #: builtins.c:1349
@@ -3397,16 +3289,14 @@ msgid ""
 "      NAME\tCommand name to be interpreted.\n"
 "    \n"
 "    Exit Status:\n"
-"    Returns success if all of the NAMEs are found; fails if any are not "
-"found."
+"    Returns success if all of the NAMEs are found; fails if any are not found."
 msgstr ""
 
 #: builtins.c:1380
 msgid ""
 "Modify shell resource limits.\n"
 "    \n"
-"    Provides control over the resources available to the shell and "
-"processes\n"
+"    Provides control over the resources available to the shell and processes\n"
 "    it creates, on systems that allow such control.\n"
 "    \n"
 "    Options:\n"
@@ -3470,13 +3360,11 @@ msgid ""
 "    Waits for the process identified by ID, which may be a process ID or a\n"
 "    job specification, and reports its termination status.  If ID is not\n"
 "    given, waits for all currently active child processes, and the return\n"
-"    status is zero.  If ID is a a job specification, waits for all "
-"processes\n"
+"    status is zero.  If ID is a a job specification, waits for all processes\n"
 "    in the job's pipeline.\n"
 "    \n"
 "    Exit Status:\n"
-"    Returns the status of ID; fails if ID is invalid or an invalid option "
-"is\n"
+"    Returns the status of ID; fails if ID is invalid or an invalid option is\n"
 "    given."
 msgstr ""
 
@@ -3489,8 +3377,7 @@ msgid ""
 "    and the return code is zero.  PID must be a process ID.\n"
 "    \n"
 "    Exit Status:\n"
-"    Returns the status of ID; fails if ID is invalid or an invalid option "
-"is\n"
+"    Returns the status of ID; fails if ID is invalid or an invalid option is\n"
 "    given."
 msgstr ""
 
@@ -3575,17 +3462,12 @@ msgstr ""
 msgid ""
 "Execute commands based on conditional.\n"
 "    \n"
-"    The `if COMMANDS' list is executed.  If its exit status is zero, then "
-"the\n"
-"    `then COMMANDS' list is executed.  Otherwise, each `elif COMMANDS' list "
-"is\n"
+"    The `if COMMANDS' list is executed.  If its exit status is zero, then the\n"
+"    `then COMMANDS' list is executed.  Otherwise, each `elif COMMANDS' list is\n"
 "    executed in turn, and if its exit status is zero, the corresponding\n"
-"    `then COMMANDS' list is executed and the if command completes.  "
-"Otherwise,\n"
-"    the `else COMMANDS' list is executed, if present.  The exit status of "
-"the\n"
-"    entire construct is the exit status of the last command executed, or "
-"zero\n"
+"    `then COMMANDS' list is executed and the if command completes.  Otherwise,\n"
+"    the `else COMMANDS' list is executed, if present.  The exit status of the\n"
+"    entire construct is the exit status of the last command executed, or zero\n"
 "    if no condition tested true.\n"
 "    \n"
 "    Exit Status:\n"
@@ -3632,8 +3514,7 @@ msgid ""
 "Define shell function.\n"
 "    \n"
 "    Create a shell function named NAME.  When invoked as a simple command,\n"
-"    NAME runs COMMANDs in the calling shell's context.  When NAME is "
-"invoked,\n"
+"    NAME runs COMMANDs in the calling shell's context.  When NAME is invoked,\n"
 "    the arguments are passed to the function as $1...$n, and the function's\n"
 "    name is in $FUNCNAME.\n"
 "    \n"
@@ -3681,12 +3562,9 @@ msgstr ""
 msgid ""
 "Execute conditional command.\n"
 "    \n"
-"    Returns a status of 0 or 1 depending on the evaluation of the "
-"conditional\n"
-"    expression EXPRESSION.  Expressions are composed of the same primaries "
-"used\n"
-"    by the `test' builtin, and may be combined using the following "
-"operators:\n"
+"    Returns a status of 0 or 1 depending on the evaluation of the conditional\n"
+"    expression EXPRESSION.  Expressions are composed of the same primaries used\n"
+"    by the `test' builtin, and may be combined using the following operators:\n"
 "    \n"
 "      ( EXPRESSION )\tReturns the value of EXPRESSION\n"
 "      ! EXPRESSION\t\tTrue if EXPRESSION is false; else false\n"
@@ -3834,12 +3712,10 @@ msgid ""
 "    \twith its position in the stack\n"
 "    \n"
 "    Arguments:\n"
-"      +N\tDisplays the Nth entry counting from the left of the list shown "
-"by\n"
+"      +N\tDisplays the Nth entry counting from the left of the list shown by\n"
 "    \tdirs when invoked without options, starting with zero.\n"
 "    \n"
-"      -N\tDisplays the Nth entry counting from the right of the list shown "
-"by\n"
+"      -N\tDisplays the Nth entry counting from the right of the list shown by\n"
 "    \tdirs when invoked without options, starting with zero.\n"
 "    \n"
 "    Exit Status:\n"
@@ -3851,8 +3727,7 @@ msgid ""
 "Set and unset shell options.\n"
 "    \n"
 "    Change the setting of each shell option OPTNAME.  Without any option\n"
-"    arguments, list all shell options with an indication of whether or not "
-"each\n"
+"    arguments, list all shell options with an indication of whether or not each\n"
 "    is set.\n"
 "    \n"
 "    Options:\n"
@@ -3875,25 +3750,20 @@ msgid ""
 "      -v var\tassign the output to shell variable VAR rather than\n"
 "    \t\tdisplay it on the standard output\n"
 "    \n"
-"    FORMAT is a character string which contains three types of objects: "
-"plain\n"
-"    characters, which are simply copied to standard output; character "
-"escape\n"
+"    FORMAT is a character string which contains three types of objects: plain\n"
+"    characters, which are simply copied to standard output; character escape\n"
 "    sequences, which are converted and copied to the standard output; and\n"
-"    format specifications, each of which causes printing of the next "
-"successive\n"
+"    format specifications, each of which causes printing of the next successive\n"
 "    argument.\n"
 "    \n"
-"    In addition to the standard format specifications described in printf"
-"(1)\n"
+"    In addition to the standard format specifications described in printf(1)\n"
 "    and printf(3), printf interprets:\n"
 "    \n"
 "      %b\texpand backslash escape sequences in the corresponding argument\n"
 "      %q\tquote the argument in a way that can be reused as shell input\n"
 "    \n"
 "    Exit Status:\n"
-"    Returns success unless an invalid option is given or a write or "
-"assignment\n"
+"    Returns success unless an invalid option is given or a write or assignment\n"
 "    error occurs."
 msgstr ""
 
@@ -3901,10 +3771,8 @@ msgstr ""
 msgid ""
 "Specify how arguments are to be completed by Readline.\n"
 "    \n"
-"    For each NAME, specify how arguments are to be completed.  If no "
-"options\n"
-"    are supplied, existing completion specifications are printed in a way "
-"that\n"
+"    For each NAME, specify how arguments are to be completed.  If no options\n"
+"    are supplied, existing completion specifications are printed in a way that\n"
 "    allows them to be reused as input.\n"
 "    \n"
 "    Options:\n"
@@ -3924,8 +3792,7 @@ msgid ""
 "Display possible completions depending on the options.\n"
 "    \n"
 "    Intended to be used from within a shell function generating possible\n"
-"    completions.  If the optional WORD argument is supplied, matches "
-"against\n"
+"    completions.  If the optional WORD argument is supplied, matches against\n"
 "    WORD are generated.\n"
 "    \n"
 "    Exit Status:\n"
@@ -3936,12 +3803,9 @@ msgstr ""
 msgid ""
 "Modify or display completion options.\n"
 "    \n"
-"    Modify the completion options for each NAME, or, if no NAMEs are "
-"supplied,\n"
-"    the completion currently begin executed.  If no OPTIONs are givenm, "
-"print\n"
-"    the completion options for each NAME or the current completion "
-"specification.\n"
+"    Modify the completion options for each NAME, or, if no NAMEs are supplied,\n"
+"    the completion currently begin executed.  If no OPTIONs are givenm, print\n"
+"    the completion options for each NAME or the current completion specification.\n"
 "    \n"
 "    Options:\n"
 "    \t-o option\tSet completion option OPTION for each NAME\n"
@@ -3965,24 +3829,18 @@ msgstr ""
 msgid ""
 "Read lines from the standard input into an array variable.\n"
 "    \n"
-"    Read lines from the standard input into the array variable ARRAY, or "
-"from\n"
-"    file descriptor FD if the -u option is supplied.  The variable MAPFILE "
-"is\n"
+"    Read lines from the standard input into the array variable ARRAY, or from\n"
+"    file descriptor FD if the -u option is supplied.  The variable MAPFILE is\n"
 "    the default ARRAY.\n"
 "    \n"
 "    Options:\n"
-"      -n count\tCopy at most COUNT lines.  If COUNT is 0, all lines are "
-"copied.\n"
-"      -O origin\tBegin assigning to ARRAY at index ORIGIN.  The default "
-"index is 0.\n"
+"      -n count\tCopy at most COUNT lines.  If COUNT is 0, all lines are copied.\n"
+"      -O origin\tBegin assigning to ARRAY at index ORIGIN.  The default index is 0.\n"
 "      -s count \tDiscard the first COUNT lines read.\n"
 "      -t\t\tRemove a trailing newline from each line read.\n"
-"      -u fd\t\tRead lines from file descriptor FD instead of the standard "
-"input.\n"
+"      -u fd\t\tRead lines from file descriptor FD instead of the standard input.\n"
 "      -C callback\tEvaluate CALLBACK each time QUANTUM lines are read.\n"
-"      -c quantum\tSpecify the number of lines read between each call to "
-"CALLBACK.\n"
+"      -c quantum\tSpecify the number of lines read between each call to CALLBACK.\n"
 "    \n"
 "    Arguments:\n"
 "      ARRAY\t\tArray variable name to use for file data.\n"
@@ -3991,8 +3849,7 @@ msgid ""
 "    CALLBACK is evaluated, it is supplied the index of the next array\n"
 "    element to be assigned as an additional argument.\n"
 "    \n"
-"    If not supplied with an explicit origin, mapfile will clear ARRAY "
-"before\n"
+"    If not supplied with an explicit origin, mapfile will clear ARRAY before\n"
 "    assigning to it.\n"
 "    \n"
 "    Exit Status:\n"
@@ -4199,8 +4056,7 @@ msgstr ""
 #~ msgstr "mkbuiltins: Virtueller Speicher erschöpft!\n"
 
 #~ msgid "read [-r] [-p prompt] [-a array] [-e] [name ...]"
-#~ msgstr ""
-#~ "read [-r] [-p Eingabeaufforderung] [-a Feldvariable] [-e] [Name ...]"
+#~ msgstr "read [-r] [-p Eingabeaufforderung] [-a Feldvariable] [-e] [Name ...]"
 
 #~ msgid "%[DIGITS | WORD] [&]"
 #~ msgstr "%[Ziffern | Wort] [&]"
@@ -4216,25 +4072,19 @@ msgstr ""
 #~ msgstr "Synonyme in der Form NAME=WERT auf die Standardausgabe aus."
 
 #~ msgid "Otherwise, an alias is defined for each NAME whose VALUE is given."
-#~ msgstr ""
-#~ "Sonst wird ein Synonym für jeden NAMEN definiert, dessen WERT angegeben "
-#~ "wird."
+#~ msgstr "Sonst wird ein Synonym für jeden NAMEN definiert, dessen WERT angegeben wird."
 
 #~ msgid "A trailing space in VALUE causes the next word to be checked for"
-#~ msgstr ""
-#~ "Ein Leerzeichen nach WERT bewirkt, daß das nächste WORT auf ein Synonym"
+#~ msgstr "Ein Leerzeichen nach WERT bewirkt, daß das nächste WORT auf ein Synonym"
 
 #~ msgid "alias substitution when the alias is expanded.  Alias returns"
-#~ msgstr ""
-#~ "untersucht wird wenn SYNONYM ausgewertet wird. `Alias' gibt wahr zurück,"
+#~ msgstr "untersucht wird wenn SYNONYM ausgewertet wird. `Alias' gibt wahr zurück,"
 
 #~ msgid "true unless a NAME is given for which no alias has been defined."
-#~ msgstr ""
-#~ "außer wenn ein NAME angegeben wurde, für den kein SYNONYM vorhanden ist."
+#~ msgstr "außer wenn ein NAME angegeben wurde, für den kein SYNONYM vorhanden ist."
 
 # unalias
-#~ msgid ""
-#~ "Remove NAMEs from the list of defined aliases.  If the -a option is given,"
+#~ msgid "Remove NAMEs from the list of defined aliases.  If the -a option is given,"
 #~ msgstr "Entfernt NAMEn aus der Liste der Synonyme. Wenn die Option -a"
 
 #~ msgid "then remove all alias definitions."
@@ -4242,35 +4092,25 @@ msgstr ""
 
 # readline
 #~ msgid "Bind a key sequence to a Readline function, or to a macro.  The"
-#~ msgstr ""
-#~ "Verbindet eine Tastenfolge mit einer Readline-Funktion oder einem Makro. "
-#~ "Die"
+#~ msgstr "Verbindet eine Tastenfolge mit einer Readline-Funktion oder einem Makro. Die"
 
 #~ msgid "syntax is equivalent to that found in ~/.inputrc, but must be"
-#~ msgstr ""
-#~ "Syntax entspricht der der Datei `~/.inputrc', sie muß jedoch als Argument"
+#~ msgstr "Syntax entspricht der der Datei `~/.inputrc', sie muß jedoch als Argument"
 
-#~ msgid ""
-#~ "passed as a single argument: bind '\"\\C-x\\C-r\": re-read-init-file'."
+#~ msgid "passed as a single argument: bind '\"\\C-x\\C-r\": re-read-init-file'."
 #~ msgstr "angegeben werden. Z.B.: bind '\"\\C-x\\C-r\": re-read-init-file'."
 
 #~ msgid "Arguments we accept:"
 #~ msgstr "Gültige Argumente:"
 
-#~ msgid ""
-#~ "  -m  keymap         Use `keymap' as the keymap for the duration of this"
-#~ msgstr ""
-#~ "  -m Tastaturtabelle wählt die Tastaturtabelle für die Dauer dieses "
-#~ "Kommandos."
+#~ msgid "  -m  keymap         Use `keymap' as the keymap for the duration of this"
+#~ msgstr "  -m Tastaturtabelle wählt die Tastaturtabelle für die Dauer dieses Kommandos."
 
 #~ msgid "                     command.  Acceptable keymap names are emacs,"
-#~ msgstr ""
-#~ "                     Mögliche Namen für Tastaturtabellen sind: emacs"
+#~ msgstr "                     Mögliche Namen für Tastaturtabellen sind: emacs"
 
-#~ msgid ""
-#~ "                     emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move,"
-#~ msgstr ""
-#~ "                     emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move,"
+#~ msgid "                     emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move,"
+#~ msgstr "                     emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move,"
 
 #~ msgid "                     vi-command, and vi-insert."
 #~ msgstr "                     vi-command, und vi-insert."
@@ -4279,19 +4119,13 @@ msgstr ""
 #~ msgstr "  -l                 Listet die Namen der Funktionen."
 
 #~ msgid "  -P                 List function names and bindings."
-#~ msgstr ""
-#~ "  -P                 Listet die Namen der Funktion und deren "
-#~ "Tastenzuordnung."
+#~ msgstr "  -P                 Listet die Namen der Funktion und deren Tastenzuordnung."
 
-#~ msgid ""
-#~ "  -p                 List functions and bindings in a form that can be"
-#~ msgstr ""
-#~ "  -p                 Listet die Funktionsnamen und deren Tastenzuordnung "
-#~ "so,"
+#~ msgid "  -p                 List functions and bindings in a form that can be"
+#~ msgstr "  -p                 Listet die Funktionsnamen und deren Tastenzuordnung so,"
 
 #~ msgid "                     reused as input."
-#~ msgstr ""
-#~ "                     daß sie als Eingabe wiederverwendet werden können."
+#~ msgstr "                     daß sie als Eingabe wiederverwendet werden können."
 
 #~ msgid "  -r  keyseq         Remove the binding for KEYSEQ."
 #~ msgstr "  -r  Tastenfolge    Entfernt die Zuordnung für Tastenfolge."
@@ -4299,58 +4133,44 @@ msgstr ""
 #~ msgid "  -f  filename       Read key bindings from FILENAME."
 #~ msgstr "  -f  Dateiname      Liest die Tastenzuordnungen von Dateiname."
 
-#~ msgid ""
-#~ "  -q  function-name  Query about which keys invoke the named function."
-#~ msgstr ""
-#~ "  -q  Funktionsname  Gibt die Tastenzuordnung für den Funktionsnamen aus."
+#~ msgid "  -q  function-name  Query about which keys invoke the named function."
+#~ msgstr "  -q  Funktionsname  Gibt die Tastenzuordnung für den Funktionsnamen aus."
 
 #~ msgid "  -V                 List variable names and values"
 #~ msgstr "  -V                 Gibt Variablennamen und deren Werte aus."
 
-#~ msgid ""
-#~ "  -v                 List variable names and values in a form that can"
-#~ msgstr ""
-#~ "  -v                 Gibt Variablennamen und deren Werte in einer Form "
-#~ "aus,"
+#~ msgid "  -v                 List variable names and values in a form that can"
+#~ msgstr "  -v                 Gibt Variablennamen und deren Werte in einer Form aus,"
 
 #~ msgid "                     be reused as input."
 #~ msgstr "                     die als Eingabe wiederverwendet werden kann."
 
-#~ msgid ""
-#~ "  -S                 List key sequences that invoke macros and their "
-#~ "values"
+#~ msgid "  -S                 List key sequences that invoke macros and their values"
 #~ msgstr "  -S                 Gibt Tastenfolgen aus, die Makros aufrufen."
 
-#~ msgid ""
-#~ "  -s                 List key sequences that invoke macros and their "
-#~ "values in"
+#~ msgid "  -s                 List key sequences that invoke macros and their values in"
 #~ msgstr "  -s                 Gibt Tastenfolgen aus, die Makros aufrufen."
 
 #~ msgid "                     a form that can be reused as input."
-#~ msgstr ""
-#~ "                     Die Ausgabe kann als Eingabe wiederverwendet werden."
+#~ msgstr "                     Die Ausgabe kann als Eingabe wiederverwendet werden."
 
 # break
 #~ msgid "Exit from within a FOR, WHILE or UNTIL loop.  If N is specified,"
-#~ msgstr ""
-#~ "Bricht eine for, while oder until Schleife ab. Wenn N angegeben ist, dann"
+#~ msgstr "Bricht eine for, while oder until Schleife ab. Wenn N angegeben ist, dann"
 
 #~ msgid "break N levels."
 #~ msgstr "werden N Schleifenebenen verlassen."
 
 # continue
 #~ msgid "Resume the next iteration of the enclosing FOR, WHILE or UNTIL loop."
-#~ msgstr ""
-#~ "Springt zur nächsten Iteration der for, while oder until Schleife. Wenn N"
+#~ msgstr "Springt zur nächsten Iteration der for, while oder until Schleife. Wenn N"
 
 #~ msgid "If N is specified, resume at the N-th enclosing loop."
-#~ msgstr ""
-#~ "angegeben ist, wird mit der N-ten übergeordneten Schleife fortgefahren."
+#~ msgstr "angegeben ist, wird mit der N-ten übergeordneten Schleife fortgefahren."
 
 # builtin
 #~ msgid "Run a shell builtin.  This is useful when you wish to rename a"
-#~ msgstr ""
-#~ "Führt eine Shellfunktion aus. Das ist nützlich, wenn eine Shellfunktion"
+#~ msgstr "Führt eine Shellfunktion aus. Das ist nützlich, wenn eine Shellfunktion"
 
 #~ msgid "shell builtin to be a function, but need the functionality of the"
 #~ msgstr "umbenannt wurde, aber das ursprüngliche Verhalten benötigt wird."
@@ -4360,44 +4180,33 @@ msgstr ""
 
 # cd
 #~ msgid "Change the current directory to DIR.  The variable $HOME is the"
-#~ msgstr ""
-#~ "Setzt das Arbeitsverzeichnis auf Verz. Wenn Verz. nicht angegeben ist, "
-#~ "dann"
+#~ msgstr "Setzt das Arbeitsverzeichnis auf Verz. Wenn Verz. nicht angegeben ist, dann"
 
 #~ msgid "default DIR.  The variable $CDPATH defines the search path for"
-#~ msgstr ""
-#~ "wird in das $HOME-Verzeichnis gewechselt. In der Variable $CDPATH kann "
-#~ "eine"
+#~ msgstr "wird in das $HOME-Verzeichnis gewechselt. In der Variable $CDPATH kann eine"
 
 #~ msgid "the directory containing DIR.  Alternative directory names in CDPATH"
-#~ msgstr ""
-#~ "durch Doppelpunkt (:) getrennte Liste angegeben werden, in denen Verz. "
-#~ "gesucht"
+#~ msgstr "durch Doppelpunkt (:) getrennte Liste angegeben werden, in denen Verz. gesucht"
 
 #~ msgid "are separated by a colon (:).  A null directory name is the same as"
 #~ msgstr "wird. Beginnt Verz. mit einem `/', wird $CDPATH nicht benutzt."
 
 #~ msgid "the current directory, i.e. `.'.  If DIR begins with a slash (/),"
-#~ msgstr ""
-#~ "Wenn das Verzeichnis nicht gefunden wird und die Shelloption `cdable_vars'"
+#~ msgstr "Wenn das Verzeichnis nicht gefunden wird und die Shelloption `cdable_vars'"
 
 #~ msgid "then $CDPATH is not used.  If the directory is not found, and the"
-#~ msgstr ""
-#~ "gesetzt ist, dann wird Verz. als ein Variablenname interpretiert. Ergibt"
+#~ msgstr "gesetzt ist, dann wird Verz. als ein Variablenname interpretiert. Ergibt"
 
 #~ msgid "shell option `cdable_vars' is set, then try the word as a variable"
 #~ msgstr "dies einen Wert für die Variable, dann wird das aktuelle"
 
 #~ msgid "name.  If that variable has a value, then cd to the value of that"
-#~ msgstr ""
-#~ "Verzeichnis auf diesen Wert gesetzt. Option -P veranlaßt cd symbolische"
+#~ msgstr "Verzeichnis auf diesen Wert gesetzt. Option -P veranlaßt cd symbolische"
 
-#~ msgid ""
-#~ "variable.  The -P option says to use the physical directory structure"
+#~ msgid "variable.  The -P option says to use the physical directory structure"
 #~ msgstr "Verweise zu ignorieren;  -L erzwingt das Benutzen symbolischer"
 
-#~ msgid ""
-#~ "instead of following symbolic links; the -L option forces symbolic links"
+#~ msgid "instead of following symbolic links; the -L option forces symbolic links"
 #~ msgstr "Verweise."
 
 #~ msgid "to be followed."
@@ -4405,8 +4214,7 @@ msgstr ""
 
 # pwd
 #~ msgid "Print the current working directory.  With the -P option, pwd prints"
-#~ msgstr ""
-#~ "Gibt das Arbeitsverzeichnis aus. Die Angabe von -P ignoriert symbolische"
+#~ msgstr "Gibt das Arbeitsverzeichnis aus. Die Angabe von -P ignoriert symbolische"
 
 #~ msgid "the physical directory, without any symbolic links; the -L option"
 #~ msgstr "Verweise. Mit -L wird das Verwenden von symbolischen Verweisen"
@@ -4415,24 +4223,19 @@ msgstr ""
 #~ msgstr "erzwungen."
 
 # command
-#~ msgid ""
-#~ "Runs COMMAND with ARGS ignoring shell functions.  If you have a shell"
-#~ msgstr ""
-#~ "Führt das Kommando mit den Argumenten aus, ohne die Shellfunktionen zu"
+#~ msgid "Runs COMMAND with ARGS ignoring shell functions.  If you have a shell"
+#~ msgstr "Führt das Kommando mit den Argumenten aus, ohne die Shellfunktionen zu"
 
 #~ msgid "function called `ls', and you wish to call the command `ls', you can"
 #~ msgstr "berücksichtigen.  Wenn eine Shellfunktion `ls' definiert ist, führt"
 
-#~ msgid ""
-#~ "say \"command ls\".  If the -p option is given, a default value is used"
+#~ msgid "say \"command ls\".  If the -p option is given, a default value is used"
 #~ msgstr "\"command ls\" das Kommando `ls' aus.  Mit der Option -p wird ein"
 
-#~ msgid ""
-#~ "for PATH that is guaranteed to find all of the standard utilities.  If"
+#~ msgid "for PATH that is guaranteed to find all of the standard utilities.  If"
 #~ msgstr "Standardwert für PATH verwendet.  -v gibt eine kurze Beschreibung"
 
-#~ msgid ""
-#~ "the -V or -v option is given, a string is printed describing COMMAND."
+#~ msgid "the -V or -v option is given, a string is printed describing COMMAND."
 #~ msgstr "des Kommandos aus; -V eine ausführliche."
 
 #~ msgid "The -V option produces a more verbose description."
@@ -4440,12 +4243,10 @@ msgstr ""
 
 # declare
 #~ msgid "Declare variables and/or give them attributes.  If no NAMEs are"
-#~ msgstr ""
-#~ "Deklariert Variablen oder weist ihnen Werte zu.  Wenn kein Name angegeben"
+#~ msgstr "Deklariert Variablen oder weist ihnen Werte zu.  Wenn kein Name angegeben"
 
 #~ msgid "given, then display the values of variables instead.  The -p option"
-#~ msgstr ""
-#~ "ist, dann wird der Wert der Variablen ausgegeben.  Option -p gibt die"
+#~ msgstr "ist, dann wird der Wert der Variablen ausgegeben.  Option -p gibt die"
 
 #~ msgid "will display the attributes and values of each NAME."
 #~ msgstr "Merkmale und Werte der Namen aus."
@@ -4472,15 +4273,13 @@ msgstr ""
 #~ msgstr "  -i\tSetzt den Typ von Name auf Ganzzahl."
 
 #~ msgid "Variables with the integer attribute have arithmetic evaluation (see"
-#~ msgstr ""
-#~ "Wenn der Variablen ein Wert zugewiesen wird (siehe `let'), findet eine"
+#~ msgstr "Wenn der Variablen ein Wert zugewiesen wird (siehe `let'), findet eine"
 
 #~ msgid "`let') done when the variable is assigned to."
 #~ msgstr "arithmetische Auswertung statt."
 
 #~ msgid "When displaying values of variables, -f displays a function's name"
-#~ msgstr ""
-#~ "Wenn Variablenwerte angezeigt werden, gibt die Option -f Funktionsnamen"
+#~ msgstr "Wenn Variablenwerte angezeigt werden, gibt die Option -f Funktionsnamen"
 
 #~ msgid "and definition.  The -F option restricts the display to function"
 #~ msgstr "und -definitionen aus. Die Option -F beschränkt die Ausgabe auf"
@@ -4488,8 +4287,7 @@ msgstr ""
 #~ msgid "name only."
 #~ msgstr "Funktionsnamen."
 
-#~ msgid ""
-#~ "Using `+' instead of `-' turns off the given attribute instead.  When"
+#~ msgid "Using `+' instead of `-' turns off the given attribute instead.  When"
 #~ msgstr "`+' statt `-' schaltet das angegebene Merkmal ab. `declare'"
 
 #~ msgid "used in a function, makes NAMEs local, as with the `local' command."
@@ -4501,22 +4299,17 @@ msgstr ""
 
 # local
 #~ msgid "Create a local variable called NAME, and give it VALUE.  LOCAL"
-#~ msgstr ""
-#~ "Erzeugt eine lokale Variable Name und weist ihr Wert zu. Die Anweisung "
-#~ "kann"
+#~ msgstr "Erzeugt eine lokale Variable Name und weist ihr Wert zu. Die Anweisung kann"
 
 #~ msgid "have a visible scope restricted to that function and its children."
 #~ msgstr "nur innerhalb dieser Funktion und allen Unterfunktionen zugänglich."
 
 # echo
 #~ msgid "Output the ARGs.  If -n is specified, the trailing newline is"
-#~ msgstr ""
-#~ "Gibt die Argumente aus. Wenn -n angegeben ist, wird kein Zeilenumbruch"
+#~ msgstr "Gibt die Argumente aus. Wenn -n angegeben ist, wird kein Zeilenumbruch"
 
 #~ msgid "suppressed.  If the -e option is given, interpretation of the"
-#~ msgstr ""
-#~ "angefügt. Die Option -e interpretiert folgende Sonderzeichen zur "
-#~ "Formatierung"
+#~ msgstr "angefügt. Die Option -e interpretiert folgende Sonderzeichen zur Formatierung"
 
 #~ msgid "following backslash-escaped characters is turned on:"
 #~ msgstr "der Ausgabe:"
@@ -4554,19 +4347,14 @@ msgstr ""
 #~ msgid "\t\\num\tthe character whose ASCII code is NUM (octal)."
 #~ msgstr "\t\\num\tDas Zeichen mit dem (oktalen) ASCII-Code num."
 
-#~ msgid ""
-#~ "You can explicitly turn off the interpretation of the above characters"
-#~ msgstr ""
-#~ "Die Option -E schaltet die Auswertung der oben angegebenen Sonderzeichen"
+#~ msgid "You can explicitly turn off the interpretation of the above characters"
+#~ msgstr "Die Option -E schaltet die Auswertung der oben angegebenen Sonderzeichen"
 
 #~ msgid "with the -E option."
 #~ msgstr "ab."
 
-#~ msgid ""
-#~ "Output the ARGs.  If -n is specified, the trailing newline is suppressed."
-#~ msgstr ""
-#~ "Gibt ARGUMENTE aus. Die Option -n verhindert den abschließenden "
-#~ "Zeilenumbruch."
+#~ msgid "Output the ARGs.  If -n is specified, the trailing newline is suppressed."
+#~ msgstr "Gibt ARGUMENTE aus. Die Option -n verhindert den abschließenden Zeilenumbruch."
 
 # enable
 #~ msgid "Enable and disable builtin shell commands.  This allows"
@@ -4582,16 +4370,13 @@ msgstr ""
 #~ msgstr "Um z.B. die externe Funktion `test' zu verwenden,"
 
 #~ msgid "path instead of the shell builtin version, type `enable -n test'."
-#~ msgstr ""
-#~ "muß `enable -n test' eingegeben werden. Auf Systemen, die Bibiliotheken"
+#~ msgstr "muß `enable -n test' eingegeben werden. Auf Systemen, die Bibiliotheken"
 
 #~ msgid "On systems supporting dynamic loading, the -f option may be used"
-#~ msgstr ""
-#~ "dynamisch nachladen können, kann die Option -f genutzt werden, um neue"
+#~ msgstr "dynamisch nachladen können, kann die Option -f genutzt werden, um neue"
 
 #~ msgid "to load new builtins from the shared object FILENAME.  The -d"
-#~ msgstr ""
-#~ "Shellfunktionen aus der dynamischen Bibiliothek Dateiname zu laden. -d"
+#~ msgstr "Shellfunktionen aus der dynamischen Bibiliothek Dateiname zu laden. -d"
 
 #~ msgid "option will delete a builtin previously loaded with -f.  If no"
 #~ msgstr "entlädt dynamisch geladene Shellfunktionen wieder. Wenn"
@@ -4603,8 +4388,7 @@ msgstr ""
 #~ msgstr "Shellfunktionen ausgegeben. -a gibt eine Liste der Shellfunktionen"
 
 #~ msgid "with an indication of whether or not it is enabled.  The -s option"
-#~ msgstr ""
-#~ "aus, in der ein- und ausgeschaltete Funktionen gekennzeichnet sind; -s"
+#~ msgstr "aus, in der ein- und ausgeschaltete Funktionen gekennzeichnet sind; -s"
 
 #~ msgid "restricts the output to the Posix.2 `special' builtins.  The -n"
 #~ msgstr "beschränkt die Ausgabe auf Posix.2-Shellfunktionen. -n"
@@ -4613,8 +4397,7 @@ msgstr ""
 #~ msgstr "zeigt eine Liste aller abgeschalteter Funktionen an."
 
 # eval
-#~ msgid ""
-#~ "Read ARGs as input to the shell and execute the resulting command(s)."
+#~ msgid "Read ARGs as input to the shell and execute the resulting command(s)."
 #~ msgstr "Verbindet die Argumente zu einer Kommandozeile und führt sie aus."
 
 # getopts
@@ -4622,9 +4405,7 @@ msgstr ""
 #~ msgstr "Shellprozeduren benutzen getopts, um die Kommandozeole auszuwerten."
 
 #~ msgid "OPTSTRING contains the option letters to be recognized; if a letter"
-#~ msgstr ""
-#~ "Optstring enthält die zu erkennenden Buchstaben. Folgt einem Buchstaben "
-#~ "ein"
+#~ msgstr "Optstring enthält die zu erkennenden Buchstaben. Folgt einem Buchstaben ein"
 
 #~ msgid "is followed by a colon, the option is expected to have an argument,"
 #~ msgstr "Doppelpunkt, dann erwartet die Funktion ein Argument, das durch ein"
@@ -4633,9 +4414,7 @@ msgstr ""
 #~ msgstr "Leerzeichen vom Optionszeichen getrennt ist."
 
 #~ msgid "Each time it is invoked, getopts will place the next option in the"
-#~ msgstr ""
-#~ "Bei jedem Aufruf weist getopt die nächste Option der Shell-Variablen "
-#~ "$name zu,"
+#~ msgstr "Bei jedem Aufruf weist getopt die nächste Option der Shell-Variablen $name zu,"
 
 #~ msgid "shell variable $name, initializing name if it does not exist, and"
 #~ msgstr "erzeugt sie gegebenenfalls und setzt den Zeiger in der"
@@ -4653,65 +4432,46 @@ msgstr ""
 #~ msgstr "Shellvariablen OPTARG zurückgegeben."
 
 #~ msgid "getopts reports errors in one of two ways.  If the first character"
-#~ msgstr ""
-#~ "Es gibt zwei Möglichkeiten der Fehlerbehandlung.  Wenn das erste Zeichen "
-#~ "von"
+#~ msgstr "Es gibt zwei Möglichkeiten der Fehlerbehandlung.  Wenn das erste Zeichen von"
 
 #~ msgid "of OPTSTRING is a colon, getopts uses silent error reporting.  In"
-#~ msgstr ""
-#~ "OPTSTRING ein Doppelpunkt ist, wird keine Fehlermeldung angezeigt "
-#~ "(\"stille"
+#~ msgstr "OPTSTRING ein Doppelpunkt ist, wird keine Fehlermeldung angezeigt (\"stille"
 
 #~ msgid "this mode, no error messages are printed.  If an illegal option is"
-#~ msgstr ""
-#~ "Fehlermeldung\") Wenn ein ungültiges Optionszeichen erkannt wird, dann "
-#~ "wird"
+#~ msgstr "Fehlermeldung\") Wenn ein ungültiges Optionszeichen erkannt wird, dann wird"
 
 #~ msgid "seen, getopts places the option character found into OPTARG.  If a"
-#~ msgstr ""
-#~ "es der Shellvariablen OPTARG zugewiesen.  Wenn ein Argument fehlt, dann"
+#~ msgstr "es der Shellvariablen OPTARG zugewiesen.  Wenn ein Argument fehlt, dann"
 
 #~ msgid "required argument is not found, getopts places a ':' into NAME and"
 #~ msgstr "wird der Shellvariablen NAME ein ':' zugewiesen und an OPTARG das "
 
 #~ msgid "sets OPTARG to the option character found.  If getopts is not in"
-#~ msgstr ""
-#~ "Optionszeichen übergeben.  Wenn getopt sich nicht im \"stillen\" Modus"
+#~ msgstr "Optionszeichen übergeben.  Wenn getopt sich nicht im \"stillen\" Modus"
 
 #~ msgid "silent mode, and an illegal option is seen, getopts places '?' into"
-#~ msgstr ""
-#~ "befindet und ein ungültiges Optionszeichen erkannt wird, weist getopt der"
+#~ msgstr "befindet und ein ungültiges Optionszeichen erkannt wird, weist getopt der"
 
 #~ msgid "NAME and unsets OPTARG.  If a required option is not found, a '?'"
-#~ msgstr ""
-#~ "Variable Name '?' zu und löscht OPTARG.  Wenn eine erforderliche Option "
-#~ "nicht"
+#~ msgstr "Variable Name '?' zu und löscht OPTARG.  Wenn eine erforderliche Option nicht"
 
 #~ msgid "is placed in NAME, OPTARG is unset, and a diagnostic message is"
-#~ msgstr ""
-#~ "gefunden wurde, wird `?` an NAME zugewiesen, OPTARG gelöscht und eine "
-#~ "Fehler-"
+#~ msgstr "gefunden wurde, wird `?` an NAME zugewiesen, OPTARG gelöscht und eine Fehler-"
 
 #~ msgid "printed."
 #~ msgstr "meldung ausgegeben."
 
 #~ msgid "If the shell variable OPTERR has the value 0, getopts disables the"
-#~ msgstr ""
-#~ "Wenn die Shellvariable OPTERR den Wert 0 besitzt, unterdrückt getopts die "
-#~ "Aus-"
+#~ msgstr "Wenn die Shellvariable OPTERR den Wert 0 besitzt, unterdrückt getopts die Aus-"
 
 #~ msgid "printing of error messages, even if the first character of"
-#~ msgstr ""
-#~ "gabe von Fehlermeldungen, auch dann, wenn das erste Zeichen von OPTSTRING "
-#~ "kein"
+#~ msgstr "gabe von Fehlermeldungen, auch dann, wenn das erste Zeichen von OPTSTRING kein"
 
 #~ msgid "OPTSTRING is not a colon.  OPTERR has the value 1 by default."
 #~ msgstr "Doppelpunkt ist.  OPTERR hat standardmäßig den Wert 1."
 
 #~ msgid "Getopts normally parses the positional parameters ($0 - $9), but if"
-#~ msgstr ""
-#~ "Getopts wertet normalerweise die übergebenen Parameter $0 - $9 aus, aber "
-#~ "wenn"
+#~ msgstr "Getopts wertet normalerweise die übergebenen Parameter $0 - $9 aus, aber wenn"
 
 #~ msgid "more arguments are given, they are parsed instead."
 #~ msgstr "mehr Argumente angegeben sind, werden diese auch ausgewertet."
@@ -4721,35 +4481,25 @@ msgstr ""
 #~ msgstr "Fürt Datei aus und ersetzt die Shell durch das angegebene Programm."
 
 #~ msgid "If FILE is not specified, the redirections take effect in this"
-#~ msgstr ""
-#~ "Wenn kein Kommando angegeben ist, werden die Ein-/Ausgabeumleitungen auf "
-#~ "die"
+#~ msgstr "Wenn kein Kommando angegeben ist, werden die Ein-/Ausgabeumleitungen auf die"
 
 #~ msgid "shell.  If the first argument is `-l', then place a dash in the"
-#~ msgstr ""
-#~ "aufrufende Shell angewendet.  Wenn das erste Argument -l ist, dann wird "
-#~ "dieses"
+#~ msgstr "aufrufende Shell angewendet.  Wenn das erste Argument -l ist, dann wird dieses"
 
 #~ msgid "zeroth arg passed to FILE, as login does.  If the `-c' option"
-#~ msgstr ""
-#~ "als nulltes Argument an die Datei übergeben (wie login).  Mit der -c "
-#~ "Option"
+#~ msgstr "als nulltes Argument an die Datei übergeben (wie login).  Mit der -c Option"
 
 #~ msgid "is supplied, FILE is executed with a null environment.  The `-a'"
-#~ msgstr ""
-#~ "wird die Datei ohne gesetzte Umgebungsvariablen ausgeführt.  Die -a Option"
+#~ msgstr "wird die Datei ohne gesetzte Umgebungsvariablen ausgeführt.  Die -a Option"
 
 #~ msgid "option means to make set argv[0] of the executed process to NAME."
 #~ msgstr "setzt argv[0] des ausgeführten Prozeßes auf Name."
 
 #~ msgid "If the file cannot be executed and the shell is not interactive,"
-#~ msgstr ""
-#~ "Wenn die Datei nicht ausgeführt werden kann und die Shell nicht "
-#~ "interaktiv ist,"
+#~ msgstr "Wenn die Datei nicht ausgeführt werden kann und die Shell nicht interaktiv ist,"
 
 #~ msgid "then the shell exits, unless the variable \"no_exit_on_failed_exec\""
-#~ msgstr ""
-#~ "dann wird sie verlassen, außer die Variable \"no_exit_on_failed_exec\" ist"
+#~ msgstr "dann wird sie verlassen, außer die Variable \"no_exit_on_failed_exec\" ist"
 
 #~ msgid "is set."
 #~ msgstr "gesetzt."
@@ -4758,11 +4508,8 @@ msgstr ""
 #~ msgstr "der Rückkehrstatus des zuletzt ausgeführten Kommandos verwendet."
 
 # fc
-#~ msgid ""
-#~ "FIRST and LAST can be numbers specifying the range, or FIRST can be a"
-#~ msgstr ""
-#~ "Anfang und Ende bezeichnen einen Bereich oder, wenn Anfang eine "
-#~ "Zeichenkette"
+#~ msgid "FIRST and LAST can be numbers specifying the range, or FIRST can be a"
+#~ msgstr "Anfang und Ende bezeichnen einen Bereich oder, wenn Anfang eine Zeichenkette"
 
 #~ msgid "string, which means the most recent command beginning with that"
 #~ msgstr "ist, das letzte Kommando welches mit dieser Zeichkette beginnt."
@@ -4770,16 +4517,11 @@ msgstr ""
 #~ msgid "string."
 #~ msgstr " "
 
-#~ msgid ""
-#~ "   -e ENAME selects which editor to use.  Default is FCEDIT, then EDITOR,"
-#~ msgstr ""
-#~ "   -e Editor ist der aufzurufende Texteditor.  Standardmäßig wird FCEDIT, "
-#~ "dann"
+#~ msgid "   -e ENAME selects which editor to use.  Default is FCEDIT, then EDITOR,"
+#~ msgstr "   -e Editor ist der aufzurufende Texteditor.  Standardmäßig wird FCEDIT, dann"
 
-#~ msgid ""
-#~ "      then the editor which corresponds to the current readline editing"
-#~ msgstr ""
-#~ "      EDITOR, anschließend der dem readline Modus entsprechende Editor"
+#~ msgid "      then the editor which corresponds to the current readline editing"
+#~ msgstr "      EDITOR, anschließend der dem readline Modus entsprechende Editor"
 
 #~ msgid "      mode, then vi."
 #~ msgstr "      und sonst vi aufgerufen."
@@ -4790,200 +4532,136 @@ msgstr ""
 #~ msgid "   -n means no line numbers listed."
 #~ msgstr "   -n unterdrückt das Anzeigen von Zeilennummern."
 
-#~ msgid ""
-#~ "   -r means reverse the order of the lines (making it newest listed "
-#~ "first)."
-#~ msgstr ""
-#~ "   -r dreht die Sortierreihenfolge um (jüngster Eintrag wird zuerst "
-#~ "angezeigt)."
+#~ msgid "   -r means reverse the order of the lines (making it newest listed first)."
+#~ msgstr "   -r dreht die Sortierreihenfolge um (jüngster Eintrag wird zuerst angezeigt)."
 
 #~ msgid "With the `fc -s [pat=rep ...] [command]' format, the command is"
-#~ msgstr ""
-#~ "Mit `fc -s [Muster=Ersetzung ...] [command]' wird das Kommando wiederholt,"
+#~ msgstr "Mit `fc -s [Muster=Ersetzung ...] [command]' wird das Kommando wiederholt,"
 
 #~ msgid "re-executed after the substitution OLD=NEW is performed."
 #~ msgstr "nachdem die Substitution Alt=Neu durchgeführt wurde."
 
 #~ msgid "A useful alias to use with this is r='fc -s', so that typing `r cc'"
-#~ msgstr ""
-#~ "Eine nützliche Aliasersetzung kann r='fc -s' sein, mit der z.B. durch `r "
-#~ "cc`"
+#~ msgstr "Eine nützliche Aliasersetzung kann r='fc -s' sein, mit der z.B. durch `r cc`"
 
 #~ msgid "runs the last command beginning with `cc' and typing `r' re-executes"
-#~ msgstr ""
-#~ "das letzte Kommando welches mit `cc' beginnt aufgerufen wird und die "
-#~ "Eingabe"
+#~ msgstr "das letzte Kommando welches mit `cc' beginnt aufgerufen wird und die Eingabe"
 
 # fg
 #~ msgid "Place JOB_SPEC in the foreground, and make it the current job.  If"
 #~ msgstr "Bringt den mit `^Z' angehaltenen Job in den Vordergrund.  Wenn eine"
 
 #~ msgid "JOB_SPEC is not present, the shell's notion of the current job is"
-#~ msgstr ""
-#~ "Jobbezeichnung angegeben ist, dann wird der zuletzt angehaltene Job im"
+#~ msgstr "Jobbezeichnung angegeben ist, dann wird der zuletzt angehaltene Job im"
 
 #~ msgid "used."
 #~ msgstr "Vordergrund gestartet."
 
 # bg
 #~ msgid "Place JOB_SPEC in the background, as if it had been started with"
-#~ msgstr ""
-#~ "Startet einen mit `^Z' angehaltenen Job im Hintergrund, als ob er mit `&'"
+#~ msgstr "Startet einen mit `^Z' angehaltenen Job im Hintergrund, als ob er mit `&'"
 
 #~ msgid "`&'.  If JOB_SPEC is not present, the shell's notion of the current"
-#~ msgstr ""
-#~ "gestartet worden wäre. Ist keine Jobbezeichnung angegeben, wird der "
-#~ "zuletzt"
+#~ msgstr "gestartet worden wäre. Ist keine Jobbezeichnung angegeben, wird der zuletzt"
 
 #~ msgid "job is used."
 #~ msgstr "angehaltene Job im Hintergrund gestartet."
 
 # hash
 #~ msgid "For each NAME, the full pathname of the command is determined and"
-#~ msgstr ""
-#~ "Für jeden angegebenen Namen wird der vollständige Pfadname des Kommandos"
+#~ msgstr "Für jeden angegebenen Namen wird der vollständige Pfadname des Kommandos"
 
 #~ msgid "remembered.  If the -p option is supplied, PATHNAME is used as the"
-#~ msgstr ""
-#~ "ermittelt und gemerkt.  Wenn die -p Option angegeben wird, dann wird der"
+#~ msgstr "ermittelt und gemerkt.  Wenn die -p Option angegeben wird, dann wird der"
 
 #~ msgid "full pathname of NAME, and no path search is performed.  The -r"
-#~ msgstr ""
-#~ "Pfadname verwendet und keine Suche durchgeführt.  Die -r Option löscht die"
+#~ msgstr "Pfadname verwendet und keine Suche durchgeführt.  Die -r Option löscht die"
 
 #~ msgid "option causes the shell to forget all remembered locations.  If no"
-#~ msgstr ""
-#~ "gespeicherten Pfade.  Wenn keine Option angegeben ist, dann werden alle"
+#~ msgstr "gespeicherten Pfade.  Wenn keine Option angegeben ist, dann werden alle"
 
-#~ msgid ""
-#~ "arguments are given, information about remembered commands is displayed."
+#~ msgid "arguments are given, information about remembered commands is displayed."
 #~ msgstr "gespeicherten Kommandos angezeigt."
 
 # help
 #~ msgid "Display helpful information about builtin commands.  If PATTERN is"
-#~ msgstr ""
-#~ "Gibt Hilfetexte für die eingebauten Kommandos aus.  Wenn ein Muster "
-#~ "angegeben"
+#~ msgstr "Gibt Hilfetexte für die eingebauten Kommandos aus.  Wenn ein Muster angegeben"
 
 #~ msgid "specified, gives detailed help on all commands matching PATTERN,"
-#~ msgstr ""
-#~ "ist, dann wird eine detailierte Beschreibung der Kommandos angezeigt, die "
-#~ "dem"
+#~ msgstr "ist, dann wird eine detailierte Beschreibung der Kommandos angezeigt, die dem"
 
 #~ msgid "otherwise a list of the builtins is printed."
-#~ msgstr ""
-#~ "Muster entsprechen.  Sonst werden die eingebauten Kommandos gelistet."
+#~ msgstr "Muster entsprechen.  Sonst werden die eingebauten Kommandos gelistet."
 
 # history
 #~ msgid "Display the history list with line numbers.  Lines listed with"
-#~ msgstr ""
-#~ "Zeigt den Kommandozeilenspeicher mit Zeilennummern an.  Mit `*' markierte"
+#~ msgstr "Zeigt den Kommandozeilenspeicher mit Zeilennummern an.  Mit `*' markierte"
 
 #~ msgid "with a `*' have been modified.  Argument of N says to list only"
-#~ msgstr ""
-#~ "Zeilen wurden verändert.  Mit einer Zahl als Argument wird nur die "
-#~ "angegebene"
+#~ msgstr "Zeilen wurden verändert.  Mit einer Zahl als Argument wird nur die angegebene"
 
 #~ msgid "the last N lines.  The -c option causes the history list to be"
-#~ msgstr ""
-#~ "Anzahl Zeilen ausgegeben.  Mit der `-c' Option kann der "
-#~ "Kommandozeilenspeicher"
+#~ msgstr "Anzahl Zeilen ausgegeben.  Mit der `-c' Option kann der Kommandozeilenspeicher"
 
-#~ msgid ""
-#~ "cleared by deleting all of the entries.  The `-w' option writes out the"
-#~ msgstr ""
-#~ "gelöscht werden.  Ist die `-w' Option angegeben,  wird der Kommandozeilen-"
+#~ msgid "cleared by deleting all of the entries.  The `-w' option writes out the"
+#~ msgstr "gelöscht werden.  Ist die `-w' Option angegeben,  wird der Kommandozeilen-"
 
-#~ msgid ""
-#~ "current history to the history file;  `-r' means to read the file and"
-#~ msgstr ""
-#~ "speicher in die history Datei geschrieben. `-r' liest diese Datei und fügt"
+#~ msgid "current history to the history file;  `-r' means to read the file and"
+#~ msgstr "speicher in die history Datei geschrieben. `-r' liest diese Datei und fügt"
 
 #~ msgid "append the contents to the history list instead.  `-a' means"
-#~ msgstr ""
-#~ "ihren Inhalt an den Kommandozeilenspeicher an.  Durch die Option `-a' "
-#~ "kann der"
+#~ msgstr "ihren Inhalt an den Kommandozeilenspeicher an.  Durch die Option `-a' kann der"
 
 #~ msgid "to append history lines from this session to the history file."
-#~ msgstr ""
-#~ "Kommandozeilenspeicher der Sitzung an die history Datei angefügt werden."
+#~ msgstr "Kommandozeilenspeicher der Sitzung an die history Datei angefügt werden."
 
 #~ msgid "Argument `-n' means to read all history lines not already read"
-#~ msgstr ""
-#~ "Das Argument `-n' bewirkt, daß alle Zeilen die noch nicht aus der history "
-#~ "Datei"
+#~ msgstr "Das Argument `-n' bewirkt, daß alle Zeilen die noch nicht aus der history Datei"
 
 #~ msgid "from the history file and append them to the history list.  If"
-#~ msgstr ""
-#~ "gelesen wurden an den Kommandozeilenspeicher angefügt werden.  Wenn ein "
-#~ "Datei-"
+#~ msgstr "gelesen wurden an den Kommandozeilenspeicher angefügt werden.  Wenn ein Datei-"
 
 #~ msgid "FILENAME is given, then that is used as the history file else"
-#~ msgstr ""
-#~ "name angegeben ist, dann wird dieser als Name der history Datei "
-#~ "verwendet.  Sonst"
+#~ msgstr "name angegeben ist, dann wird dieser als Name der history Datei verwendet.  Sonst"
 
 #~ msgid "if $HISTFILE has a value, that is used, else ~/.bash_history."
-#~ msgstr ""
-#~ "wird der Inhalt der Variablen $HISTFILE und anschließend ~/.bash_history "
-#~ "verwendet."
+#~ msgstr "wird der Inhalt der Variablen $HISTFILE und anschließend ~/.bash_history verwendet."
 
 #~ msgid "If the -s option is supplied, the non-option ARGs are appended to"
-#~ msgstr ""
-#~ "Durch die -s Option wird bewirkt, daß die Nicht-Options-Argumente als "
-#~ "eigene"
+#~ msgstr "Durch die -s Option wird bewirkt, daß die Nicht-Options-Argumente als eigene"
 
 #~ msgid "the history list as a single entry.  The -p option means to perform"
-#~ msgstr ""
-#~ "Zeile an den Kommandospeicher angefügt werden.  Mit -p wird für jedes "
-#~ "Argument"
+#~ msgstr "Zeile an den Kommandospeicher angefügt werden.  Mit -p wird für jedes Argument"
 
-#~ msgid ""
-#~ "history expansion on each ARG and display the result, without storing"
-#~ msgstr ""
-#~ "die Kommandosubstitution durchgeführt und das Ergebnis angezeigt,  ohne "
-#~ "jedoch"
+#~ msgid "history expansion on each ARG and display the result, without storing"
+#~ msgstr "die Kommandosubstitution durchgeführt und das Ergebnis angezeigt,  ohne jedoch"
 
 #~ msgid "anything in the history list."
 #~ msgstr "etwas im Kommandozeilenspeicher abzulegen."
 
 # jobs
 #~ msgid "Lists the active jobs.  The -l option lists process id's in addition"
-#~ msgstr ""
-#~ "Gibt eine Liste der aktiven Jobs aus.  Mit der -l Option werden "
-#~ "zusätzlich die"
+#~ msgstr "Gibt eine Liste der aktiven Jobs aus.  Mit der -l Option werden zusätzlich die"
 
 #~ msgid "to the normal information; the -p option lists process id's only."
-#~ msgstr ""
-#~ "Prozeßnummern und mit der -p Option nur die Prozeßnummern ausgsgegeben."
+#~ msgstr "Prozeßnummern und mit der -p Option nur die Prozeßnummern ausgsgegeben."
 
-#~ msgid ""
-#~ "If -n is given, only processes that have changed status since the last"
-#~ msgstr ""
-#~ "Die Option -n bewirkt, daß nur Jobs angezeigt werden, die ihren Status "
-#~ "seid dem"
+#~ msgid "If -n is given, only processes that have changed status since the last"
+#~ msgstr "Die Option -n bewirkt, daß nur Jobs angezeigt werden, die ihren Status seid dem"
 
-#~ msgid ""
-#~ "notification are printed.  JOBSPEC restricts output to that job.  The"
-#~ msgstr ""
-#~ "letzten Aufruf geändert haben. Jobbez. beschränkt die Anzeige auf diesen "
-#~ "Job."
+#~ msgid "notification are printed.  JOBSPEC restricts output to that job.  The"
+#~ msgstr "letzten Aufruf geändert haben. Jobbez. beschränkt die Anzeige auf diesen Job."
 
 #~ msgid "-r and -s options restrict output to running and stopped jobs only,"
-#~ msgstr ""
-#~ "-r zeigt nur laufende und -s nur gestoppte Jobs an.  Wenn keine Optionen"
+#~ msgstr "-r zeigt nur laufende und -s nur gestoppte Jobs an.  Wenn keine Optionen"
 
 #~ msgid "respectively.  Without options, the status of all active jobs is"
 #~ msgstr "angegeben sind, dann wird der Status aller aktiven Jobs angezeigt."
 
-#~ msgid ""
-#~ "printed.  If -x is given, COMMAND is run after all job specifications"
-#~ msgstr ""
-#~ "Wenn -x in der Kommandozeile angegeben ist, wird das Kommando ausgeführt "
-#~ "und"
+#~ msgid "printed.  If -x is given, COMMAND is run after all job specifications"
+#~ msgstr "Wenn -x in der Kommandozeile angegeben ist, wird das Kommando ausgeführt und"
 
-#~ msgid ""
-#~ "that appear in ARGS have been replaced with the process ID of that job's"
+#~ msgid "that appear in ARGS have been replaced with the process ID of that job's"
 #~ msgstr "vorher alle vorkommenden Jobspezifikationen durch ihre Prozeßnummer"
 
 #~ msgid "process group leader."
@@ -4995,56 +4673,35 @@ msgstr ""
 
 # kill
 #~ msgid "Send the processes named by PID (or JOB) the signal SIGSPEC.  If"
-#~ msgstr ""
-#~ "Sendet den durch pid (oder job) angegebenen Prozessen das Signal "
-#~ "SIGSPEC.  Wenn"
+#~ msgstr "Sendet den durch pid (oder job) angegebenen Prozessen das Signal SIGSPEC.  Wenn"
 
-#~ msgid ""
-#~ "SIGSPEC is not present, then SIGTERM is assumed.  An argument of `-l'"
-#~ msgstr ""
-#~ "kein Signal angegeben ist wird SIGTERM gesendet.  Mit der Option -l kann "
-#~ "eine"
+#~ msgid "SIGSPEC is not present, then SIGTERM is assumed.  An argument of `-l'"
+#~ msgstr "kein Signal angegeben ist wird SIGTERM gesendet.  Mit der Option -l kann eine"
 
 #~ msgid "lists the signal names; if arguments follow `-l' they are assumed to"
-#~ msgstr ""
-#~ "Liste der möglichen Signalnamen angezeigt werden.  Wenn Zahlen nach der "
-#~ "Option"
+#~ msgstr "Liste der möglichen Signalnamen angezeigt werden.  Wenn Zahlen nach der Option"
 
 #~ msgid "be signal numbers for which names should be listed.  Kill is a shell"
-#~ msgstr ""
-#~ "angegeben werden,  wird deren Signalbezeichnung angezeigt.  Kill ist aus "
-#~ "zwei"
+#~ msgstr "angegeben werden,  wird deren Signalbezeichnung angezeigt.  Kill ist aus zwei"
 
 #~ msgid "builtin for two reasons: it allows job IDs to be used instead of"
-#~ msgstr ""
-#~ "Gründen eine Shellfunktion: es können Jobbezeichnungen anstatt "
-#~ "Prozeßnummern"
+#~ msgstr "Gründen eine Shellfunktion: es können Jobbezeichnungen anstatt Prozeßnummern"
 
 #~ msgid "process IDs, and, if you have reached the limit on processes that"
-#~ msgstr ""
-#~ "genutzt werden und, wenn die maximale Anzahl laufender Prozesse erreicht "
-#~ "ist"
+#~ msgstr "genutzt werden und, wenn die maximale Anzahl laufender Prozesse erreicht ist"
 
-#~ msgid ""
-#~ "you can create, you don't have to start a process to kill another one."
-#~ msgstr ""
-#~ "braucht kein weiterer Prozeß gestartet zu werden, um einen anderen zu "
-#~ "beenden."
+#~ msgid "you can create, you don't have to start a process to kill another one."
+#~ msgstr "braucht kein weiterer Prozeß gestartet zu werden, um einen anderen zu beenden."
 
 # let
 #~ msgid "Each ARG is an arithmetic expression to be evaluated.  Evaluation"
-#~ msgstr ""
-#~ "Jedes Argument ist ein auszuwertender arithmetischer Ausdruck.  Es werden "
-#~ "long"
+#~ msgstr "Jedes Argument ist ein auszuwertender arithmetischer Ausdruck.  Es werden long"
 
 #~ msgid "is done in long integers with no check for overflow, though division"
-#~ msgstr ""
-#~ "integer Variablen verwendet.  Ein Überlauftest wird nicht ausgeführt, "
-#~ "jedoch"
+#~ msgstr "integer Variablen verwendet.  Ein Überlauftest wird nicht ausgeführt, jedoch"
 
 #~ msgid "by 0 is trapped and flagged as an error.  The following list of"
-#~ msgstr ""
-#~ "wird eine Division durch 0 erkannt und als Fehler gekennzeichnet.  Die"
+#~ msgstr "wird eine Division durch 0 erkannt und als Fehler gekennzeichnet.  Die"
 
 #~ msgid "operators is grouped into levels of equal-precedence operators."
 #~ msgstr "Liste von Operatoren ist in Gruppen gleichen Vorrangs geordnet."
@@ -5104,8 +4761,7 @@ msgstr ""
 #~ msgstr "\t&=, ^=, |=\tZuweisungen."
 
 #~ msgid "is replaced by its value (coerced to a long integer) within"
-#~ msgstr ""
-#~ "Ausdruck durch ihren in long integer umgewandelten Wert ersetzt. Um "
+#~ msgstr "Ausdruck durch ihren in long integer umgewandelten Wert ersetzt. Um "
 
 #~ msgid "an expression.  The variable need not have its integer attribute"
 #~ msgstr "die Variable in einem Ausdruck verwenden zu können, muß ihr "
@@ -5117,8 +4773,7 @@ msgstr ""
 #~ msgstr "Die Operatoren werden in Reihenfolge ihres Vorrangs ausgewertet."
 
 #~ msgid "parentheses are evaluated first and may override the precedence"
-#~ msgstr ""
-#~ "Geklammerte Teilausdrücke werden zuerst ausgewertet und können von den"
+#~ msgstr "Geklammerte Teilausdrücke werden zuerst ausgewertet und können von den"
 
 #~ msgid "rules above."
 #~ msgstr "oben angegebenen Vorrangregeln abweichen."
@@ -5131,92 +4786,57 @@ msgstr ""
 
 # read
 #~ msgid "One line is read from the standard input, and the first word is"
-#~ msgstr ""
-#~ "Es wird eine Zeile von der Standardeingabe gelesen und das erste Wort der"
+#~ msgstr "Es wird eine Zeile von der Standardeingabe gelesen und das erste Wort der"
 
-#~ msgid ""
-#~ "assigned to the first NAME, the second word to the second NAME, and so"
-#~ msgstr ""
-#~ "ersten Variablen NAME zugewiesen, das zweite Wort der zweiten Variablen "
-#~ "und so"
+#~ msgid "assigned to the first NAME, the second word to the second NAME, and so"
+#~ msgstr "ersten Variablen NAME zugewiesen, das zweite Wort der zweiten Variablen und so"
 
-#~ msgid ""
-#~ "on, with leftover words assigned to the last NAME.  Only the characters"
-#~ msgstr ""
-#~ "weiter,  bis ein Wort der letzten Variablen zugewiesen wurde.  Nur die in "
-#~ "$IFS"
+#~ msgid "on, with leftover words assigned to the last NAME.  Only the characters"
+#~ msgstr "weiter,  bis ein Wort der letzten Variablen zugewiesen wurde.  Nur die in $IFS"
 
 #~ msgid "found in $IFS are recognized as word delimiters.  The return code is"
-#~ msgstr ""
-#~ "angegebenen Zeichen werden als Trennzeichen erkannt.  Wenn kein EOF "
-#~ "Zeichen"
+#~ msgstr "angegebenen Zeichen werden als Trennzeichen erkannt.  Wenn kein EOF Zeichen"
 
-#~ msgid ""
-#~ "zero, unless end-of-file is encountered.  If no NAMEs are supplied, the"
-#~ msgstr ""
-#~ "aufgetreten ist, ist der Rückgabewert Null.  Wenn kein NAME angegeben "
-#~ "wurde,"
+#~ msgid "zero, unless end-of-file is encountered.  If no NAMEs are supplied, the"
+#~ msgstr "aufgetreten ist, ist der Rückgabewert Null.  Wenn kein NAME angegeben wurde,"
 
-#~ msgid ""
-#~ "line read is stored in the REPLY variable.  If the -r option is given,"
-#~ msgstr ""
-#~ "verwendet read die REPLY Variable.  Durch die Option -r wird das "
-#~ "Auswerten von"
+#~ msgid "line read is stored in the REPLY variable.  If the -r option is given,"
+#~ msgstr "verwendet read die REPLY Variable.  Durch die Option -r wird das Auswerten von"
 
 #~ msgid "this signifies `raw' input, and backslash escaping is disabled.  If"
-#~ msgstr ""
-#~ "mit `\\' markierten  Sonderzeichen unterdrückt.  Wenn die Option -r "
-#~ "angegeben"
+#~ msgstr "mit `\\' markierten  Sonderzeichen unterdrückt.  Wenn die Option -r angegeben"
 
 #~ msgid "the `-p' option is supplied, the string supplied as an argument is"
-#~ msgstr ""
-#~ "ist, dann wird die Eingabeaufforderung ohne einen abschließenden "
-#~ "Zeilenumbruch"
+#~ msgstr "ist, dann wird die Eingabeaufforderung ohne einen abschließenden Zeilenumbruch"
 
-#~ msgid ""
-#~ "output without a trailing newline before attempting to read.  If -a is"
-#~ msgstr ""
-#~ "angezeigt.  Wenn die Option -a angegeben ist, dann wird die Eingabe an die"
+#~ msgid "output without a trailing newline before attempting to read.  If -a is"
+#~ msgstr "angezeigt.  Wenn die Option -a angegeben ist, dann wird die Eingabe an die"
 
-#~ msgid ""
-#~ "supplied, the words read are assigned to sequential indices of ARRAY,"
-#~ msgstr ""
-#~ "Feldvariable ARRAY übergeben und für jeden Eintrag der Index von Null "
-#~ "beginnend"
+#~ msgid "supplied, the words read are assigned to sequential indices of ARRAY,"
+#~ msgstr "Feldvariable ARRAY übergeben und für jeden Eintrag der Index von Null beginnend"
 
 #~ msgid "starting at zero.  If -e is supplied and the shell is interactive,"
-#~ msgstr ""
-#~ "um Eins erhöht wird.  Mit der -e Option wird bei einer interaktiven Shell "
-#~ "die"
+#~ msgstr "um Eins erhöht wird.  Mit der -e Option wird bei einer interaktiven Shell die"
 
 #~ msgid "readline is used to obtain the line."
-#~ msgstr ""
-#~ "die readline Funktionen aktiviert, um die Eingabezeile zu editieren."
+#~ msgstr "die readline Funktionen aktiviert, um die Eingabezeile zu editieren."
 
 # return
-#~ msgid ""
-#~ "Causes a function to exit with the return value specified by N.  If N"
-#~ msgstr ""
-#~ "Beendet eine Shellfunktion und setzt den Rückgabewert auf N.  Wenn kein "
-#~ "Rückga-"
+#~ msgid "Causes a function to exit with the return value specified by N.  If N"
+#~ msgstr "Beendet eine Shellfunktion und setzt den Rückgabewert auf N.  Wenn kein Rückga-"
 
 #~ msgid "is omitted, the return status is that of the last command."
-#~ msgstr ""
-#~ "bewert angegeben ist, wird der des zuletzt ausgeführten Kommandos "
-#~ "verwendet."
+#~ msgstr "bewert angegeben ist, wird der des zuletzt ausgeführten Kommandos verwendet."
 
 # set
 #~ msgid "    -a  Mark variables which are modified or created for export."
-#~ msgstr ""
-#~ "    -a  Markiert erzeugte oder veränderte Variablen als exportierbar."
+#~ msgstr "    -a  Markiert erzeugte oder veränderte Variablen als exportierbar."
 
 #~ msgid "    -b  Notify of job termination immediately."
 #~ msgstr "    -b  Zeigt das Beenden von Prozessen sofort an."
 
 #~ msgid "    -e  Exit immediately if a command exits with a non-zero status."
-#~ msgstr ""
-#~ "    -e  Beendet die Shell sofort, wenn ein Kommando ein Fehler "
-#~ "zurückliefert."
+#~ msgstr "    -e  Beendet die Shell sofort, wenn ein Kommando ein Fehler zurückliefert."
 
 #~ msgid "    -f  Disable file name generation (globbing)."
 #~ msgstr "    -f  Unterdrückt das Erzeugen von Dateinamen."
@@ -5224,22 +4844,17 @@ msgstr ""
 #~ msgid "    -h  Remember the location of commands as they are looked up."
 #~ msgstr "    -h  Speichert die eingegebenen Kommandos sofort."
 
-#~ msgid ""
-#~ "    -i  Force the shell to be an \"interactive\" one.  Interactive shells"
-#~ msgstr ""
-#~ "    -i  Erzwingt, daß die Shell interaktiv arbeitet.  Interaktive Shells"
+#~ msgid "    -i  Force the shell to be an \"interactive\" one.  Interactive shells"
+#~ msgstr "    -i  Erzwingt, daß die Shell interaktiv arbeitet.  Interaktive Shells"
 
 #~ msgid "        always read `~/.bashrc' on startup."
-#~ msgstr ""
-#~ "        interpretieren beim Aufrufen den Inhalt der Datei  `~/.bashrc'."
+#~ msgstr "        interpretieren beim Aufrufen den Inhalt der Datei  `~/.bashrc'."
 
 #~ msgid "    -k  All assignment arguments are placed in the environment for a"
-#~ msgstr ""
-#~ "    -k  Die komplette Kommandozeile wird in die Umgebung der Funktion"
+#~ msgstr "    -k  Die komplette Kommandozeile wird in die Umgebung der Funktion"
 
 #~ msgid "        command, not just those that precede the command name."
-#~ msgstr ""
-#~ "        geschrieben, nicht bloß die Argumente nach dem Funktionsnamen."
+#~ msgstr "        geschrieben, nicht bloß die Argumente nach dem Funktionsnamen."
 
 #~ msgid "    -m  Job control is enabled."
 #~ msgstr "    -m  Jobsteuerung wird aktiviert."
@@ -5260,9 +4875,7 @@ msgstr ""
 #~ msgstr "            braceexpand  Wie die Option -B."
 
 #~ msgid "            emacs        use an emacs-style line editing interface"
-#~ msgstr ""
-#~ "            emacs        Schaltet den Kommandozeileneditor in den emacs-"
-#~ "Stil."
+#~ msgstr "            emacs        Schaltet den Kommandozeileneditor in den emacs-Stil."
 
 #~ msgid "            errexit      same as -e"
 #~ msgstr "            errexit      Wie die Option -e."
@@ -5274,18 +4887,13 @@ msgstr ""
 #~ msgstr "            histexpand   Wie die Option -H."
 
 #~ msgid "            ignoreeof    the shell will not exit upon reading EOF"
-#~ msgstr ""
-#~ "            ignoreeof    Shell wird nach dem  Lesen von EOF nicht "
-#~ "verlassen ."
+#~ msgstr "            ignoreeof    Shell wird nach dem  Lesen von EOF nicht verlassen ."
 
 #~ msgid "            interactive-comments"
 #~ msgstr "            interactive-comments"
 
-#~ msgid ""
-#~ "                         allow comments to appear in interactive commands"
-#~ msgstr ""
-#~ "                         Kommentare werden auch in der Kommandozeile "
-#~ "erlaubt."
+#~ msgid "                         allow comments to appear in interactive commands"
+#~ msgstr "                         Kommentare werden auch in der Kommandozeile erlaubt."
 
 #~ msgid "            keyword      same as -k"
 #~ msgstr "            keyword      Wie die Option -k."
@@ -5314,13 +4922,10 @@ msgstr ""
 #~ msgid "            physical     same as -P"
 #~ msgstr "            physical     Wie die Option -P."
 
-#~ msgid ""
-#~ "            posix        change the behavior of bash where the default"
-#~ msgstr ""
-#~ "            posix        Ändert das Verhalten der Shell, wo sie vom,"
+#~ msgid "            posix        change the behavior of bash where the default"
+#~ msgstr "            posix        Ändert das Verhalten der Shell, wo sie vom,"
 
-#~ msgid ""
-#~ "                         operation differs from the 1003.2 standard to"
+#~ msgid "                         operation differs from the 1003.2 standard to"
 #~ msgstr "                         1003.2 Standard abweicht, zu einem POSIX "
 
 #~ msgid "                         match the standard"
@@ -5333,255 +4938,179 @@ msgstr ""
 #~ msgstr "            verbose      Wie die Option -v."
 
 #~ msgid "            vi           use a vi-style line editing interface"
-#~ msgstr ""
-#~ "            vi           Schaltet den Kommandozeileneditor in den vi-Stil."
+#~ msgstr "            vi           Schaltet den Kommandozeileneditor in den vi-Stil."
 
 #~ msgid "            xtrace       same as -x"
 #~ msgstr "            xtrace       Wie die Option -x."
 
-#~ msgid ""
-#~ "    -p  Turned on whenever the real and effective user ids do not match."
-#~ msgstr ""
-#~ "    -p  Ist aktiviert, wenn die reale und effektive Nutzer ID nicht "
-#~ "überein-"
+#~ msgid "    -p  Turned on whenever the real and effective user ids do not match."
+#~ msgstr "    -p  Ist aktiviert, wenn die reale und effektive Nutzer ID nicht überein-"
 
 #~ msgid "        Disables processing of the $ENV file and importing of shell"
-#~ msgstr ""
-#~ "        stimmen.  Die $ENV Datei wird nicht ausgeführt und keine "
-#~ "Shellfunk-"
+#~ msgstr "        stimmen.  Die $ENV Datei wird nicht ausgeführt und keine Shellfunk-"
 
-#~ msgid ""
-#~ "        functions.  Turning this option off causes the effective uid and"
-#~ msgstr ""
-#~ "        tionen importiert.  Das Deaktivieren dieser Option setzt die "
-#~ "Effektive"
+#~ msgid "        functions.  Turning this option off causes the effective uid and"
+#~ msgstr "        tionen importiert.  Das Deaktivieren dieser Option setzt die Effektive"
 
 #~ msgid "        gid to be set to the real uid and gid."
 #~ msgstr "        uid und gid auf die Reale uid und gid."
 
 #~ msgid "    -t  Exit after reading and executing one command."
-#~ msgstr ""
-#~ "    -t  Beendet die Shell sofort nach Ausfühern eines einzelnen Kommandos."
+#~ msgstr "    -t  Beendet die Shell sofort nach Ausfühern eines einzelnen Kommandos."
 
 #~ msgid "    -u  Treat unset variables as an error when substituting."
-#~ msgstr ""
-#~ "    -u  Der Versuch leere (ungesetzte) Variablen zu erweitern erzeugt "
-#~ "einen Fehler."
+#~ msgstr "    -u  Der Versuch leere (ungesetzte) Variablen zu erweitern erzeugt einen Fehler."
 
 #~ msgid "    -v  Print shell input lines as they are read."
 #~ msgstr "    -v  Gibt die Kommandozeilen aus wie sie gelesenen wurden."
 
 #~ msgid "    -x  Print commands and their arguments as they are executed."
-#~ msgstr ""
-#~ "    -x  Gibt die Kommandos mit ihren Argumenten aus wie es ausgeführt "
-#~ "wird."
+#~ msgstr "    -x  Gibt die Kommandos mit ihren Argumenten aus wie es ausgeführt wird."
 
 #~ msgid "    -B  the shell will perform brace expansion"
 #~ msgstr "    -B  Schaltet die Klammernerweiterung der Shell ein."
 
 #~ msgid "    -H  Enable ! style history substitution.  This flag is on"
-#~ msgstr ""
-#~ "    -H  Schaltet den Zugriff auf den Kommandozeilenspeicher durch `!' ein."
+#~ msgstr "    -H  Schaltet den Zugriff auf den Kommandozeilenspeicher durch `!' ein."
 
 #~ msgid "        by default."
 #~ msgstr "        Diese Option ist standardmäßig aktiviert."
 
 #~ msgid "    -C  If set, disallow existing regular files to be overwritten"
-#~ msgstr ""
-#~ "    -C  Verhindert das Überschreiben von existierenden Dateien durch"
+#~ msgstr "    -C  Verhindert das Überschreiben von existierenden Dateien durch"
 
 #~ msgid "        by redirection of output."
 #~ msgstr "        Umleiten der Ausgabe (wie noclobber)."
 
 #~ msgid "    -P  If set, do not follow symbolic links when executing commands"
-#~ msgstr ""
-#~ "    -P  Symbolische Verweise werden beim Ausführen von Kommandos, wie z."
-#~ "B. cd"
+#~ msgstr "    -P  Symbolische Verweise werden beim Ausführen von Kommandos, wie z.B. cd"
 
 #~ msgid "        such as cd which change the current directory."
 #~ msgstr "        welches das aktuelle Arbeitsverzeichnis ändert, ignoriert."
 
 #~ msgid "Using + rather than - causes these flags to be turned off.  The"
-#~ msgstr ""
-#~ "Durch `+' an Stelle von `-' kann eine Option deaktiviert werden.  Die "
-#~ "Optionen"
+#~ msgstr "Durch `+' an Stelle von `-' kann eine Option deaktiviert werden.  Die Optionen"
 
 #~ msgid "flags can also be used upon invocation of the shell.  The current"
-#~ msgstr ""
-#~ "können auch beim Aufruf der Shell benutzt werden.  Die gegenwärtig "
-#~ "aktivierten"
+#~ msgstr "können auch beim Aufruf der Shell benutzt werden.  Die gegenwärtig aktivierten"
 
-#~ msgid ""
-#~ "set of flags may be found in $-.  The remaining n ARGs are positional"
-#~ msgstr ""
-#~ "Optionen sind in der Variablen $- gespeichert.  Die verbleibenden n "
-#~ "Argumente"
+#~ msgid "set of flags may be found in $-.  The remaining n ARGs are positional"
+#~ msgstr "Optionen sind in der Variablen $- gespeichert.  Die verbleibenden n Argumente"
 
 #~ msgid "parameters and are assigned, in order, to $1, $2, .. $n.  If no"
-#~ msgstr ""
-#~ "sind Parameter und werden den Variablen $1, $2, .. $n zugewiesen.  Wenn "
-#~ "kein"
+#~ msgstr "sind Parameter und werden den Variablen $1, $2, .. $n zugewiesen.  Wenn kein"
 
 #~ msgid "ARGs are given, all shell variables are printed."
 #~ msgstr "Argument angegeben ist, dann werden alle Shellvariablen ausgegeben."
 
 # unset
 #~ msgid "For each NAME, remove the corresponding variable or function.  Given"
-#~ msgstr ""
-#~ "Für jeden angegebenen NAMEn wird die entsprechende Variable oder Funktion "
-#~ "ge-"
+#~ msgstr "Für jeden angegebenen NAMEn wird die entsprechende Variable oder Funktion ge-"
 
 #~ msgid "the `-v', unset will only act on variables.  Given the `-f' flag,"
-#~ msgstr ""
-#~ "löscht.  Mit `-v' werden nur Variablen und mit `-f' nur Funktionen "
-#~ "gelöscht."
+#~ msgstr "löscht.  Mit `-v' werden nur Variablen und mit `-f' nur Funktionen gelöscht."
 
 #~ msgid "unset will only act on functions.  With neither flag, unset first"
-#~ msgstr ""
-#~ "Wenn kein Schalter angegeben ist, wird zunächst eine Variable gesucht und "
-#~ "wenn"
+#~ msgstr "Wenn kein Schalter angegeben ist, wird zunächst eine Variable gesucht und wenn"
 
 #~ msgid "tries to unset a variable, and if that fails, then tries to unset a"
-#~ msgstr ""
-#~ "eine solche nicht gefunden wurde, dann wird versucht eine Funktion zu "
-#~ "löschen."
+#~ msgstr "eine solche nicht gefunden wurde, dann wird versucht eine Funktion zu löschen."
 
-#~ msgid ""
-#~ "function.  Some variables (such as PATH and IFS) cannot be unset; also"
-#~ msgstr ""
-#~ "Einige Variablen (z.B. PATH und IFS) können nicht gelöscht werden.  Siehe"
+#~ msgid "function.  Some variables (such as PATH and IFS) cannot be unset; also"
+#~ msgstr "Einige Variablen (z.B. PATH und IFS) können nicht gelöscht werden.  Siehe"
 
 #~ msgid "see readonly."
 #~ msgstr "diesbezüglich auch die Hilfe der Funktion readonly."
 
 # export
 #~ msgid "NAMEs are marked for automatic export to the environment of"
-#~ msgstr ""
-#~ "Die NAMEn werden für den automatischen Export in die Umgebung von der "
-#~ "Shell"
+#~ msgstr "Die NAMEn werden für den automatischen Export in die Umgebung von der Shell"
 
 #~ msgid "subsequently executed commands.  If the -f option is given,"
-#~ msgstr ""
-#~ "gestarteten Prozesse markiert.  Wenn die -f Option angegenen ist, dann "
-#~ "bezeich-"
+#~ msgstr "gestarteten Prozesse markiert.  Wenn die -f Option angegenen ist, dann bezeich-"
 
 #~ msgid "the NAMEs refer to functions.  If no NAMEs are given, or if `-p'"
-#~ msgstr ""
-#~ "nen die NAME'n Funktionen.  Wenn keine NAMEn angegeben sind, oder die `-p'"
+#~ msgstr "nen die NAME'n Funktionen.  Wenn keine NAMEn angegeben sind, oder die `-p'"
 
 #~ msgid "is given, a list of all names that are exported in this shell is"
-#~ msgstr ""
-#~ "Option angegeben ist, dann wird eine Liste aller von der Shell "
-#~ "exportierter"
+#~ msgstr "Option angegeben ist, dann wird eine Liste aller von der Shell exportierter"
 
 #~ msgid "printed.  An argument of `-n' says to remove the export property"
-#~ msgstr ""
-#~ "Namen ausgegeben.  Mit dem Argument `-n' wird die Exporteigenschaft des "
-#~ "NAMENs"
+#~ msgstr "Namen ausgegeben.  Mit dem Argument `-n' wird die Exporteigenschaft des NAMENs"
 
 #~ msgid "from subsequent NAMEs.  An argument of `--' disables further option"
-#~ msgstr ""
-#~ "gelöscht.  Ein Argument `--' verhindert, daß nach diesem Zeichen weitere"
+#~ msgstr "gelöscht.  Ein Argument `--' verhindert, daß nach diesem Zeichen weitere"
 
 #~ msgid "processing."
 #~ msgstr "Optionen ausgewertet werden."
 
 # readonly
-#~ msgid ""
-#~ "The given NAMEs are marked readonly and the values of these NAMEs may"
-#~ msgstr ""
-#~ "Die angegebenen NAMEn werden als Nur-Lesen markiert.  Deren Inhalte können"
+#~ msgid "The given NAMEs are marked readonly and the values of these NAMEs may"
+#~ msgstr "Die angegebenen NAMEn werden als Nur-Lesen markiert.  Deren Inhalte können"
 
 #~ msgid "not be changed by subsequent assignment.  If the -f option is given,"
-#~ msgstr ""
-#~ "nicht mehr geändert werden.  Wenn die -f Option angegeben wird, dann "
-#~ "werden nur"
+#~ msgstr "nicht mehr geändert werden.  Wenn die -f Option angegeben wird, dann werden nur"
 
 #~ msgid "then functions corresponding to the NAMEs are so marked.  If no"
-#~ msgstr ""
-#~ "Funktionen markiert.  Ohne oder mit dem `-p' Argument, werden alle auf "
-#~ "Nur- "
+#~ msgstr "Funktionen markiert.  Ohne oder mit dem `-p' Argument, werden alle auf Nur- "
 
-#~ msgid ""
-#~ "arguments are given, or if `-p' is given, a list of all readonly names"
-#~ msgstr ""
-#~ "Lesen gesetzte Namen ausgegeben.  Mit dem Argument `-n' kann die Nur-Lese"
+#~ msgid "arguments are given, or if `-p' is given, a list of all readonly names"
+#~ msgstr "Lesen gesetzte Namen ausgegeben.  Mit dem Argument `-n' kann die Nur-Lese"
 
-#~ msgid ""
-#~ "is printed.  An argument of `-n' says to remove the readonly property"
-#~ msgstr ""
-#~ "Eigenschaft für die angegebenen Namen entfernt werden.  Der `-a' Schalter"
+#~ msgid "is printed.  An argument of `-n' says to remove the readonly property"
+#~ msgstr "Eigenschaft für die angegebenen Namen entfernt werden.  Der `-a' Schalter"
 
 #~ msgid "from subsequent NAMEs.  The `-a' option means to treat each NAME as"
-#~ msgstr ""
-#~ "bewirkt, daß jeder Name als Feldvariable behandelt wird.  Das Argument "
-#~ "`--'"
+#~ msgstr "bewirkt, daß jeder Name als Feldvariable behandelt wird.  Das Argument `--'"
 
 #~ msgid "an array variable.  An argument of `--' disables further option"
 #~ msgstr "unterdrückt das Auswerten weiterer Optionen."
 
 # shift
-#~ msgid ""
-#~ "The positional parameters from $N+1 ... are renamed to $1 ...  If N is"
-#~ msgstr ""
-#~ "Die Positionsvariablen $N+1 ... werden nach $1 ... umbenannt.  Wenn N "
-#~ "nicht"
+#~ msgid "The positional parameters from $N+1 ... are renamed to $1 ...  If N is"
+#~ msgstr "Die Positionsvariablen $N+1 ... werden nach $1 ... umbenannt.  Wenn N nicht"
 
 #~ msgid "not given, it is assumed to be 1."
 #~ msgstr "angegeben ist, dann wird 1 verwendet."
 
 # source
 #~ msgid "Read and execute commands from FILENAME and return.  The pathnames"
-#~ msgstr ""
-#~ "Liest und führt anschließend die Kommandos in DATEINAME aus.  $PATH wird"
+#~ msgstr "Liest und führt anschließend die Kommandos in DATEINAME aus.  $PATH wird"
 
 #~ msgid "in $PATH are used to find the directory containing FILENAME."
 #~ msgstr "als Suchpfad benutzt, um DATEINAME zu finden."
 
 # suspend
 #~ msgid "Suspend the execution of this shell until it receives a SIGCONT"
-#~ msgstr ""
-#~ "Hält das Ausführen der Shell solange an, bis sie das Signal SIGCONT "
-#~ "empfängt."
+#~ msgstr "Hält das Ausführen der Shell solange an, bis sie das Signal SIGCONT empfängt."
 
 #~ msgid "signal.  The `-f' if specified says not to complain about this"
-#~ msgstr ""
-#~ "Die `-f' Option unterdrückt eine Warnung, wenn es sich um eine Login Shell"
+#~ msgstr "Die `-f' Option unterdrückt eine Warnung, wenn es sich um eine Login Shell"
 
 #~ msgid "being a login shell if it is; just suspend anyway."
 #~ msgstr "handelt und hält auch deren Abarbeitung an."
 
 # test
 #~ msgid "Exits with a status of 0 (trueness) or 1 (falseness) depending on"
-#~ msgstr ""
-#~ "Liefert den Rückgabewert 0 (wahr) oder 1 (falsch), abhängig vom Ergebnis "
-#~ "des"
+#~ msgstr "Liefert den Rückgabewert 0 (wahr) oder 1 (falsch), abhängig vom Ergebnis des"
 
 #~ msgid "the evaluation of EXPR.  Expressions may be unary or binary.  Unary"
-#~ msgstr ""
-#~ "Ausdruckes EXPR.  Die Ausdrücke können ein- (unär) oder zweistellig "
-#~ "(binär) sein."
+#~ msgstr "Ausdruckes EXPR.  Die Ausdrücke können ein- (unär) oder zweistellig (binär) sein."
 
 #~ msgid "expressions are often used to examine the status of a file.  There"
-#~ msgstr ""
-#~ "Einstellige Ausdrücke werden oft zum Ermitteln eines Dateizustandes "
-#~ "verwendet."
+#~ msgstr "Einstellige Ausdrücke werden oft zum Ermitteln eines Dateizustandes verwendet."
 
 #~ msgid "are string operators as well, and numeric comparison operators."
-#~ msgstr ""
-#~ "Es gibt außerden Zeichenketten- und numerische Vergleichsoperatoren."
+#~ msgstr "Es gibt außerden Zeichenketten- und numerische Vergleichsoperatoren."
 
 #~ msgid "File operators:"
 #~ msgstr "Datei Operatoren:"
 
 #~ msgid "    -b FILE        True if file is block special."
-#~ msgstr ""
-#~ "    -b DATEI       Wahr, wenn der Dateiname ein Blockgerät bezeichnet."
+#~ msgstr "    -b DATEI       Wahr, wenn der Dateiname ein Blockgerät bezeichnet."
 
 #~ msgid "    -c FILE        True if file is character special."
-#~ msgstr ""
-#~ "    -c DATEI       Wahr, wenn der Dateiname ein sequentielles Gerät "
-#~ "bezeichnet."
+#~ msgstr "    -c DATEI       Wahr, wenn der Dateiname ein sequentielles Gerät bezeichnet."
 
 #~ msgid "    -d FILE        True if file is a directory."
 #~ msgstr "    -d DATEI       Wahr, wenn es ein Verzeichnis ist."
@@ -5590,76 +5119,52 @@ msgstr ""
 #~ msgstr "    -e DATEI       Wahr, wenn die Datei existiert."
 
 #~ msgid "    -f FILE        True if file exists and is a regular file."
-#~ msgstr ""
-#~ "    -f DATEI       Wahr, wenn die Datei existiert und eine reguläre Datei "
-#~ "ist."
+#~ msgstr "    -f DATEI       Wahr, wenn die Datei existiert und eine reguläre Datei ist."
 
 #~ msgid "    -g FILE        True if file is set-group-id."
 #~ msgstr "    -g DATEI       Wahr, wenn das SGID Bit gesetzt ist."
 
 #~ msgid "    -h FILE        True if file is a symbolic link.  Use \"-L\"."
-#~ msgstr ""
-#~ "    -h DATEI       Wahr, wenn FILE symbolischer Verweis ist. (Besser -L "
-#~ "verw.)"
+#~ msgstr "    -h DATEI       Wahr, wenn FILE symbolischer Verweis ist. (Besser -L verw.)"
 
 #~ msgid "    -L FILE        True if file is a symbolic link."
 #~ msgstr "    -L DATEI       Wahr, wenn FIIE einen symbolischen Verweis ist."
 
 #~ msgid "    -k FILE        True if file has its \"sticky\" bit set."
-#~ msgstr ""
-#~ "    -k DATEI       Wahr, wenn nur der Besitzer die Datei ändern darf "
-#~ "(sticky)."
+#~ msgstr "    -k DATEI       Wahr, wenn nur der Besitzer die Datei ändern darf (sticky)."
 
 #~ msgid "    -p FILE        True if file is a named pipe."
-#~ msgstr ""
-#~ "    -p DATEI       Wahr, wenn FILE eine benannte Pipeline (named pipe) "
-#~ "ist."
+#~ msgstr "    -p DATEI       Wahr, wenn FILE eine benannte Pipeline (named pipe) ist."
 
 #~ msgid "    -r FILE        True if file is readable by you."
-#~ msgstr ""
-#~ "    -r DATEI       Wahr, wenn die Datei vom aktuellen Benutzer lesbar ist."
+#~ msgstr "    -r DATEI       Wahr, wenn die Datei vom aktuellen Benutzer lesbar ist."
 
 #~ msgid "    -s FILE        True if file exists and is not empty."
-#~ msgstr ""
-#~ "    -s DATEI       Wahr, wenn die Datei existiert und nicht leer ist."
+#~ msgstr "    -s DATEI       Wahr, wenn die Datei existiert und nicht leer ist."
 
 #~ msgid "    -S FILE        True if file is a socket."
 #~ msgstr "    -S DATEI       Wahr, wenn die Datei ein \"Socket\" ist."
 
 #~ msgid "    -t FD          True if FD is opened on a terminal."
-#~ msgstr ""
-#~ "    -t FD          Wahr, wenn die Dateinummer FD für ein Terminal "
-#~ "geöffnet ist."
+#~ msgstr "    -t FD          Wahr, wenn die Dateinummer FD für ein Terminal geöffnet ist."
 
 #~ msgid "    -u FILE        True if the file is set-user-id."
-#~ msgstr ""
-#~ "    -u DATEI       Wahr, wenn für diese Datei das SUID Bit gesetzt ist."
+#~ msgstr "    -u DATEI       Wahr, wenn für diese Datei das SUID Bit gesetzt ist."
 
 #~ msgid "    -w FILE        True if the file is writable by you."
-#~ msgstr ""
-#~ "    -w DATEI       Wahr, wenn die Datei vom aktuellen Benutzer schreibbar "
-#~ "ist."
+#~ msgstr "    -w DATEI       Wahr, wenn die Datei vom aktuellen Benutzer schreibbar ist."
 
 #~ msgid "    -x FILE        True if the file is executable by you."
-#~ msgstr ""
-#~ "    -x DATEI       Wahr, wenn die Datei vom aktuellen Benutzer ausführbar "
-#~ "ist."
+#~ msgstr "    -x DATEI       Wahr, wenn die Datei vom aktuellen Benutzer ausführbar ist."
 
 #~ msgid "    -O FILE        True if the file is effectively owned by you."
-#~ msgstr ""
-#~ "    -O DATEI       Wahr, wenn der aktuelle Benutzer Eigentümer der Datei "
-#~ "ist."
+#~ msgstr "    -O DATEI       Wahr, wenn der aktuelle Benutzer Eigentümer der Datei ist."
 
-#~ msgid ""
-#~ "    -G FILE        True if the file is effectively owned by your group."
-#~ msgstr ""
-#~ "    -G DATEI       Wahr, wenn GID des Benutzers und der Datei "
-#~ "übereinstimmen."
+#~ msgid "    -G FILE        True if the file is effectively owned by your group."
+#~ msgstr "    -G DATEI       Wahr, wenn GID des Benutzers und der Datei übereinstimmen."
 
 #~ msgid "  FILE1 -nt FILE2  True if file1 is newer than (according to"
-#~ msgstr ""
-#~ "  DATEI1 -nt DATEI2  Wahr, wenn der letzte Änderungszeitpunkt von DATEI1 "
-#~ "jünger"
+#~ msgstr "  DATEI1 -nt DATEI2  Wahr, wenn der letzte Änderungszeitpunkt von DATEI1 jünger"
 
 #~ msgid "                   modification date) file2."
 #~ msgstr "                   ist als der von DATEI2."
@@ -5668,8 +5173,7 @@ msgstr ""
 #~ msgstr "  DATEI1 -ot DATEI2  Wahr, wenn DATEI1 älter ist als DATEI2."
 
 #~ msgid "  FILE1 -ef FILE2  True if file1 is a hard link to file2."
-#~ msgstr ""
-#~ "  DATEI1 -ef DATEI2  Wahr, wenn beide Inodes übereinstimmen (hard link)."
+#~ msgstr "  DATEI1 -ef DATEI2  Wahr, wenn beide Inodes übereinstimmen (hard link)."
 
 #~ msgid "String operators:"
 #~ msgstr "Operatoren für Zeichenketten (Strings):"
@@ -5681,9 +5185,7 @@ msgstr ""
 #~ msgstr "    -n STRING"
 
 #~ msgid "    STRING         True if string is not empty."
-#~ msgstr ""
-#~ "    STRING         Wahr, wenn die Länge der Zeichenkette größer als Null "
-#~ "ist."
+#~ msgstr "    STRING         Wahr, wenn die Länge der Zeichenkette größer als Null ist."
 
 #~ msgid "    STRING1 = STRING2"
 #~ msgstr "    STRING1 = STRING2"
@@ -5695,26 +5197,19 @@ msgstr ""
 #~ msgstr "    STRING1 != STRING2"
 
 #~ msgid "                   True if the strings are not equal."
-#~ msgstr ""
-#~ "                   Wahr, wenn die Zeichenketten unterschiedlich sind."
+#~ msgstr "                   Wahr, wenn die Zeichenketten unterschiedlich sind."
 
 #~ msgid "    STRING1 < STRING2"
 #~ msgstr "    STRING1 < STRING2"
 
-#~ msgid ""
-#~ "                   True if STRING1 sorts before STRING2 lexicographically"
-#~ msgstr ""
-#~ "                   Wahr, wenn STRING1 vor STRING2 alphabetisch geordnet "
-#~ "ist."
+#~ msgid "                   True if STRING1 sorts before STRING2 lexicographically"
+#~ msgstr "                   Wahr, wenn STRING1 vor STRING2 alphabetisch geordnet ist."
 
 #~ msgid "    STRING1 > STRING2"
 #~ msgstr "    STRING1 > STRING2"
 
-#~ msgid ""
-#~ "                   True if STRING1 sorts after STRING2 lexicographically"
-#~ msgstr ""
-#~ "                   Wahr, wenn STRING1 nach STRING2 alphabetisch geordnet "
-#~ "ist."
+#~ msgid "                   True if STRING1 sorts after STRING2 lexicographically"
+#~ msgstr "                   Wahr, wenn STRING1 nach STRING2 alphabetisch geordnet ist."
 
 #~ msgid "Other operators:"
 #~ msgstr "Andere Operatoren:"
@@ -5723,176 +5218,123 @@ msgstr ""
 #~ msgstr "    ! EXPR         Wahr, wenn der Ausdruck EXPR `falsch' liefert."
 
 #~ msgid "    EXPR1 -a EXPR2 True if both expr1 AND expr2 are true."
-#~ msgstr ""
-#~ "    EXPR1 -a EXPR2 Wahr, wenn die Ausdrücke EXPR1 und EXPR2 `wahr' "
-#~ "liefern."
+#~ msgstr "    EXPR1 -a EXPR2 Wahr, wenn die Ausdrücke EXPR1 und EXPR2 `wahr' liefern."
 
 #~ msgid "    EXPR1 -o EXPR2 True if either expr1 OR expr2 is true."
-#~ msgstr ""
-#~ "    EXPR1 -o EXPR2 Wahr, wenn entweder EXPR1 oder EXPR2 wahr liefern."
+#~ msgstr "    EXPR1 -o EXPR2 Wahr, wenn entweder EXPR1 oder EXPR2 wahr liefern."
 
 #~ msgid "    arg1 OP arg2   Arithmetic tests.  OP is one of -eq, -ne,"
-#~ msgstr ""
-#~ "    arg1 OP arg2   Arithmetische Operatoren. OP kann -eq, -ne, -lt, -le, -"
-#~ "gt"
+#~ msgstr "    arg1 OP arg2   Arithmetische Operatoren. OP kann -eq, -ne, -lt, -le, -gt"
 
 #~ msgid "                   -lt, -le, -gt, or -ge."
 #~ msgstr "                   oder -ge sein."
 
 #~ msgid "Arithmetic binary operators return true if ARG1 is equal, not-equal,"
-#~ msgstr ""
-#~ "Diese binären arithmetischen Operatoren liefern Wahr, wenn ARG1 gleich,"
+#~ msgstr "Diese binären arithmetischen Operatoren liefern Wahr, wenn ARG1 gleich,"
 
-#~ msgid ""
-#~ "less-than, less-than-or-equal, greater-than, or greater-than-or-equal"
-#~ msgstr ""
-#~ "ungleich, kleiner als, kleiner gleich, größer als oder größer gleich"
+#~ msgid "less-than, less-than-or-equal, greater-than, or greater-than-or-equal"
+#~ msgstr "ungleich, kleiner als, kleiner gleich, größer als oder größer gleich"
 
 #~ msgid "than ARG2."
 #~ msgstr "ARG2 ist."
 
 # [
 #~ msgid "This is a synonym for the \"test\" builtin, but the last"
-#~ msgstr ""
-#~ "Dies ist ein Synonym für die Shellfunktion test.  Das letzte Argument muß "
-#~ "ein"
+#~ msgstr "Dies ist ein Synonym für die Shellfunktion test.  Das letzte Argument muß ein"
 
 #~ msgid "argument must be a literal `]', to match the opening `['."
 #~ msgstr "`]' sein, das mit dem öffnenden `[' korrespondiert."
 
 # times
 #~ msgid "Print the accumulated user and system times for processes run from"
-#~ msgstr ""
-#~ "Gibt die verbrauchte Benutzer- und Systemzeit für die Shell und der von"
+#~ msgstr "Gibt die verbrauchte Benutzer- und Systemzeit für die Shell und der von"
 
 #~ msgid "the shell."
 #~ msgstr "ihr gestarteten Prozesse aus."
 
 # trap
 #~ msgid "The command ARG is to be read and executed when the shell receives"
-#~ msgstr ""
-#~ "Die Shell fängt die in SIG_SPEC angegebenen Signale ab führt das Kommando "
-#~ "ARG"
+#~ msgstr "Die Shell fängt die in SIG_SPEC angegebenen Signale ab führt das Kommando ARG"
 
 #~ msgid "signal(s) SIGNAL_SPEC.  If ARG is absent all specified signals are"
-#~ msgstr ""
-#~ "aus.  Wenn kein ARG angegeben ist, werden alle bezeichneten Signale "
-#~ "zurück-"
+#~ msgstr "aus.  Wenn kein ARG angegeben ist, werden alle bezeichneten Signale zurück-"
 
 #~ msgid "reset to their original values.  If ARG is the null string each"
-#~ msgstr ""
-#~ "gesetzt.  Ist ARG eine leere Zeichenkette, dann wird jedes angegebne Sig-"
+#~ msgstr "gesetzt.  Ist ARG eine leere Zeichenkette, dann wird jedes angegebne Sig-"
 
 #~ msgid "SIGNAL_SPEC is ignored by the shell and by the commands it invokes."
-#~ msgstr ""
-#~ "nal von der Shell und den von ihr aufgerufenen Kommandos ignoriert.  Wenn "
-#~ "das"
+#~ msgstr "nal von der Shell und den von ihr aufgerufenen Kommandos ignoriert.  Wenn das"
 
 #~ msgid "If SIGNAL_SPEC is EXIT (0) the command ARG is executed on exit from"
-#~ msgstr ""
-#~ "Signal EXIT (0) abgefangen wird, dann wird ARG bei Verlassen der Shell "
-#~ "ausge-"
+#~ msgstr "Signal EXIT (0) abgefangen wird, dann wird ARG bei Verlassen der Shell ausge-"
 
 #~ msgid "the shell.  If SIGNAL_SPEC is DEBUG, ARG is executed after every"
-#~ msgstr ""
-#~ "führt.  Durch Abfangen des Signals DEBUG, wird ARG nach jedem Kommando"
+#~ msgstr "führt.  Durch Abfangen des Signals DEBUG, wird ARG nach jedem Kommando"
 
 #~ msgid "command.  If ARG is `-p' then the trap commands associated with"
-#~ msgstr ""
-#~ "aufgerufen.  Mit `-p' werden Kommandos angezeigt, die für jedes "
-#~ "abgefangene"
+#~ msgstr "aufgerufen.  Mit `-p' werden Kommandos angezeigt, die für jedes abgefangene"
 
 #~ msgid "each SIGNAL_SPEC are displayed.  If no arguments are supplied or if"
-#~ msgstr ""
-#~ "Signal ausgeführt werden.  Wenn keine Argumente angegeben sind, oder wenn "
-#~ "das"
+#~ msgstr "Signal ausgeführt werden.  Wenn keine Argumente angegeben sind, oder wenn das"
 
 #~ msgid "only `-p' is given, trap prints the list of commands associated with"
-#~ msgstr ""
-#~ "Argument `-p' angegeben ist, wird eine  Liste der Kommandos für jedes "
-#~ "abgefan-"
+#~ msgstr "Argument `-p' angegeben ist, wird eine  Liste der Kommandos für jedes abgefan-"
 
-#~ msgid ""
-#~ "each signal number.  SIGNAL_SPEC is either a signal name in <signal.h>"
-#~ msgstr ""
-#~ "gene Signal angezeigt.  SIGNAL_SPEC ist entweder ein Signalname (aus "
-#~ "signal.h)"
+#~ msgid "each signal number.  SIGNAL_SPEC is either a signal name in <signal.h>"
+#~ msgstr "gene Signal angezeigt.  SIGNAL_SPEC ist entweder ein Signalname (aus signal.h)"
 
-#~ msgid ""
-#~ "or a signal number.  `trap -l' prints a list of signal names and their"
-#~ msgstr ""
-#~ "oder eine Signalnummer.  `trap -l' gibt eine Liste der Signalnamen und "
-#~ "der ent-"
+#~ msgid "or a signal number.  `trap -l' prints a list of signal names and their"
+#~ msgstr "oder eine Signalnummer.  `trap -l' gibt eine Liste der Signalnamen und der ent-"
 
 #~ msgid "corresponding numbers.  Note that a signal can be sent to the shell"
-#~ msgstr ""
-#~ "sprechenden Nummern aus.  Ein Signal kann an eine Shell mit dem Befehl "
-#~ "\"kill"
+#~ msgstr "sprechenden Nummern aus.  Ein Signal kann an eine Shell mit dem Befehl \"kill"
 
 #~ msgid "with \"kill -signal $$\"."
 #~ msgstr "-signal $$\" gesendet werden."
 
 # type
 #~ msgid "For each NAME, indicate how it would be interpreted if used as a"
-#~ msgstr ""
-#~ "Gibt aus, wie der angegebene NAME interpretiert würde, wenn er in der"
+#~ msgstr "Gibt aus, wie der angegebene NAME interpretiert würde, wenn er in der"
 
 #~ msgid "If the -t option is used, returns a single word which is one of"
-#~ msgstr ""
-#~ "Die Option -t bewirkt, daß eins der Worte: `alias', `keyword', `function',"
+#~ msgstr "Die Option -t bewirkt, daß eins der Worte: `alias', `keyword', `function',"
 
-#~ msgid ""
-#~ "`alias', `keyword', `function', `builtin', `file' or `', if NAME is an"
-#~ msgstr ""
-#~ "`file' oder `' ausgegeben wird, wenn NAME ein Alias, ein in der Shell "
-#~ "reser-"
+#~ msgid "`alias', `keyword', `function', `builtin', `file' or `', if NAME is an"
+#~ msgstr "`file' oder `' ausgegeben wird, wenn NAME ein Alias, ein in der Shell reser-"
 
-#~ msgid ""
-#~ "alias, shell reserved word, shell function, shell builtin, disk file,"
-#~ msgstr ""
-#~ "viertes Wort, eine Skriptfunktion, eine eingebaute Shellfunktion, eine "
-#~ "Datei"
+#~ msgid "alias, shell reserved word, shell function, shell builtin, disk file,"
+#~ msgstr "viertes Wort, eine Skriptfunktion, eine eingebaute Shellfunktion, eine Datei"
 
 #~ msgid "or unfound, respectively."
 #~ msgstr "ist oder kein Kommandotyp gefunden wurde."
 
 #~ msgid "If the -p flag is used, either returns the name of the disk file"
-#~ msgstr ""
-#~ "Wenn der -p Schalter angegeben ist, dann wird, wenn eine entsprechende "
-#~ "Datei"
+#~ msgstr "Wenn der -p Schalter angegeben ist, dann wird, wenn eine entsprechende Datei"
 
 #~ msgid "that would be executed, or nothing if -t would not return `file'."
 #~ msgstr "existiert, ihr Name ausgegegeben,"
 
 #~ msgid "If the -a flag is used, displays all of the places that contain an"
-#~ msgstr ""
-#~ "Mit dem -a Schalter werden alle ausführbaren Dateien mit dem Namen `file'"
+#~ msgstr "Mit dem -a Schalter werden alle ausführbaren Dateien mit dem Namen `file'"
 
-#~ msgid ""
-#~ "executable named `file'.  This includes aliases and functions, if and"
-#~ msgstr ""
-#~ "angezeigt.  Dieses schließt Aliase und Funktionen ein, aber nur dann"
+#~ msgid "executable named `file'.  This includes aliases and functions, if and"
+#~ msgstr "angezeigt.  Dieses schließt Aliase und Funktionen ein, aber nur dann"
 
 #~ msgid "only if the -p flag is not also used."
 #~ msgstr "wenn nicht gleichzeitig der -p Schalter gesetzt ist."
 
 #~ msgid "Type accepts -all, -path, and -type in place of -a, -p, and -t,"
-#~ msgstr ""
-#~ "Type akzeptiert auch die Argumente -all, -path und -type an Stelle von -a,"
+#~ msgstr "Type akzeptiert auch die Argumente -all, -path und -type an Stelle von -a,"
 
 #~ msgid "respectively."
 #~ msgstr "-p und -t."
 
 # ulimit
 #~ msgid "Ulimit provides control over the resources available to processes"
-#~ msgstr ""
-#~ "Ulimit steuert die Ressourcen, die den von der Shell aufgerufenen "
-#~ "Prozessen"
+#~ msgstr "Ulimit steuert die Ressourcen, die den von der Shell aufgerufenen Prozessen"
 
 #~ msgid "started by the shell, on systems that allow such control.  If an"
-#~ msgstr ""
-#~ "zur Verfügung stehen, wenn das System Ressourcensteuerung unterstützt.  "
-#~ "Wenn"
+#~ msgstr "zur Verfügung stehen, wenn das System Ressourcensteuerung unterstützt.  Wenn"
 
 #~ msgid "option is given, it is interpreted as follows:"
 #~ msgstr "eine Option angegebe ist, dann wird sie wie folgt interpretiert:"
@@ -5914,9 +5356,7 @@ msgstr ""
 #~ msgstr "    -d\tDie maximale Größe des Datensegmentes eines Prozesses."
 
 #~ msgid "    -m\tthe maximum resident set size"
-#~ msgstr ""
-#~ "    -m\tMaximale Größe des nicht auszulagenden (residenten) "
-#~ "Prozeßspeichers."
+#~ msgstr "    -m\tMaximale Größe des nicht auszulagenden (residenten) Prozeßspeichers."
 
 #~ msgid "    -s\tthe maximum stack size"
 #~ msgstr "    -s\tDie maximale Größe des Stapelspeichers."
@@ -5925,8 +5365,7 @@ msgstr ""
 #~ msgstr "    -t\tDie maximal verfügbare CPU-Zeit (in Sekunden)."
 
 #~ msgid "    -f\tthe maximum size of files created by the shell"
-#~ msgstr ""
-#~ "    -f\tDie maximal erlaubte Größe für von der Shell erzeugte Dateien."
+#~ msgstr "    -f\tDie maximal erlaubte Größe für von der Shell erzeugte Dateien."
 
 #~ msgid "    -p\tthe pipe buffer size"
 #~ msgstr "    -p\tDie Größe des Pipeline-Puffers."
@@ -5941,21 +5380,16 @@ msgstr ""
 #~ msgstr "    -v\tDie Größe des virtuellen Arbeitsspeichers."
 
 #~ msgid "If LIMIT is given, it is the new value of the specified resource."
-#~ msgstr ""
-#~ "Wenn eine Grenze angegeben ist, wird die Resouce auf diesen Wert gesetzt."
+#~ msgstr "Wenn eine Grenze angegeben ist, wird die Resouce auf diesen Wert gesetzt."
 
 #~ msgid "Otherwise, the current value of the specified resource is printed."
-#~ msgstr ""
-#~ "Sonst wird der gegenwärtig eingestellte Wert ausgegeben.  Wenn keine "
-#~ "Option"
+#~ msgstr "Sonst wird der gegenwärtig eingestellte Wert ausgegeben.  Wenn keine Option"
 
 #~ msgid "If no option is given, then -f is assumed.  Values are in 1k"
-#~ msgstr ""
-#~ "angegeben ist wird -f verwendet.  Die Einheit ist 1k außer für -t, deren"
+#~ msgstr "angegeben ist wird -f verwendet.  Die Einheit ist 1k außer für -t, deren"
 
 #~ msgid "increments, except for -t, which is in seconds, -p, which is in"
-#~ msgstr ""
-#~ "Wert in Sekunden angegeben wird,  -p, dessen Einheit 512 bytes ist und -u,"
+#~ msgstr "Wert in Sekunden angegeben wird,  -p, dessen Einheit 512 bytes ist und -u,"
 
 #~ msgid "increments of 512 bytes, and -u, which is an unscaled number of"
 #~ msgstr "für das die Anzahl der Prozesse verwendet"
@@ -5964,55 +5398,36 @@ msgstr ""
 #~ msgstr "wird."
 
 # umask
-#~ msgid ""
-#~ "The user file-creation mask is set to MODE.  If MODE is omitted, or if"
-#~ msgstr ""
-#~ "Die Dateierzeugungsmaske wird auf MODE gesetzt.  Wenn MODE nicht, oder -S"
+#~ msgid "The user file-creation mask is set to MODE.  If MODE is omitted, or if"
+#~ msgstr "Die Dateierzeugungsmaske wird auf MODE gesetzt.  Wenn MODE nicht, oder -S"
 
-#~ msgid ""
-#~ "`-S' is supplied, the current value of the mask is printed.  The `-S'"
-#~ msgstr ""
-#~ "angegeben ist, dann wird die aktuelle Dateierzeugungsmaske ausgegeben."
+#~ msgid "`-S' is supplied, the current value of the mask is printed.  The `-S'"
+#~ msgstr "angegeben ist, dann wird die aktuelle Dateierzeugungsmaske ausgegeben."
 
-#~ msgid ""
-#~ "option makes the output symbolic; otherwise an octal number is output."
-#~ msgstr ""
-#~ "Die `-S' Option bewirkt, daß die symbolische Entsprechung ausgegeben "
-#~ "wird. "
+#~ msgid "option makes the output symbolic; otherwise an octal number is output."
+#~ msgstr "Die `-S' Option bewirkt, daß die symbolische Entsprechung ausgegeben wird. "
 
 #~ msgid "If MODE begins with a digit, it is interpreted as an octal number,"
-#~ msgstr ""
-#~ "Wenn MODE mit einer Ziffer beginnt, wird diese als Oktalzahl "
-#~ "interpretiert."
+#~ msgstr "Wenn MODE mit einer Ziffer beginnt, wird diese als Oktalzahl interpretiert."
 
-#~ msgid ""
-#~ "otherwise it is a symbolic mode string like that accepted by chmod(1)."
-#~ msgstr ""
-#~ "Ansonsten wird eine symbolische Notation (analog chmod(1)) angenommen."
+#~ msgid "otherwise it is a symbolic mode string like that accepted by chmod(1)."
+#~ msgstr "Ansonsten wird eine symbolische Notation (analog chmod(1)) angenommen."
 
 # wait
-#~ msgid ""
-#~ "Wait for the specified process and report its termination status.  If"
-#~ msgstr ""
-#~ "Wartet auf das Beenden der angegebenen Prozesse und gibt deren "
-#~ "Rückgabewert"
+#~ msgid "Wait for the specified process and report its termination status.  If"
+#~ msgstr "Wartet auf das Beenden der angegebenen Prozesse und gibt deren Rückgabewert"
 
 #~ msgid "N is not given, all currently active child processes are waited for,"
 #~ msgstr "aus.  Wenn keine Prozesse angegeben sind, wird auf alle aktiven"
 
 #~ msgid "and the return code is zero.  N may be a process ID or a job"
-#~ msgstr ""
-#~ "Hintergrundprozesse gewartet und Null zurückgegeben.  An wait können"
+#~ msgstr "Hintergrundprozesse gewartet und Null zurückgegeben.  An wait können"
 
 #~ msgid "specification; if a job spec is given, all processes in the job's"
-#~ msgstr ""
-#~ "Prozeßnummern und Jobbezeichnungen übergeben werden.  Wenn "
-#~ "Jobbezeichnungen"
+#~ msgstr "Prozeßnummern und Jobbezeichnungen übergeben werden.  Wenn Jobbezeichnungen"
 
 #~ msgid "pipeline are waited for."
-#~ msgstr ""
-#~ "angegeben sind, dann wird auf alle Prozesse in der Job-Pipeline gewartet "
-#~ "und"
+#~ msgstr "angegeben sind, dann wird auf alle Prozesse in der Job-Pipeline gewartet und"
 
 #~ msgid "and the return code is zero.  N is a process ID; if it is not given,"
 #~ msgstr "Null zurückgegeben."
@@ -6022,15 +5437,12 @@ msgstr ""
 
 # for
 #~ msgid "The `for' loop executes a sequence of commands for each member in a"
-#~ msgstr ""
-#~ "`for' führt eine Reihe von Kommandos für jeden Eintrag einer Liste aus."
+#~ msgstr "`for' führt eine Reihe von Kommandos für jeden Eintrag einer Liste aus."
 
-#~ msgid ""
-#~ "list of items.  If `in WORDS ...;' is not present, then `in \"$@\"' is"
+#~ msgid "list of items.  If `in WORDS ...;' is not present, then `in \"$@\"' is"
 #~ msgstr "Ohne `in WORTLISTE' wird als Argument `in \"$@\"' verwendet."
 
-#~ msgid ""
-#~ "assumed.  For each element in WORDS, NAME is set to that element, and"
+#~ msgid "assumed.  For each element in WORDS, NAME is set to that element, and"
 #~ msgstr "NAME wird nacheinander ein Element aus WORTLISTE zugewiesen"
 
 #~ msgid "the COMMANDS are executed."
@@ -6038,48 +5450,34 @@ msgstr ""
 
 # select
 #~ msgid "The WORDS are expanded, generating a list of words.  The"
-#~ msgstr ""
-#~ "Die WORTE werden erweitert und erzeugen eine Wortliste.  Diese wird als"
+#~ msgstr "Die WORTE werden erweitert und erzeugen eine Wortliste.  Diese wird als"
 
 #~ msgid "set of expanded words is printed on the standard error, each"
 #~ msgstr "numerierte Liste auf dem Standardfehlerkanal ausgegeben."
 
 #~ msgid "preceded by a number.  If `in WORDS' is not present, `in \"$@\"'"
-#~ msgstr ""
-#~ "Wenn `in WORTE' nicht angegeben ist, dann wird `in \"$@\"' verwendet."
+#~ msgstr "Wenn `in WORTE' nicht angegeben ist, dann wird `in \"$@\"' verwendet."
 
 #~ msgid "is assumed.  The PS3 prompt is then displayed and a line read"
-#~ msgstr ""
-#~ "Das PS3-Promt wird angezeigt und eine Zeile von der Standardeingabe "
-#~ "gelesen."
+#~ msgstr "Das PS3-Promt wird angezeigt und eine Zeile von der Standardeingabe gelesen."
 
 #~ msgid "from the standard input.  If the line consists of the number"
-#~ msgstr ""
-#~ "Wenn die gelesene Zeile eine Zeilennummer der angezeigten Liste enhält, "
-#~ "dann"
+#~ msgstr "Wenn die gelesene Zeile eine Zeilennummer der angezeigten Liste enhält, dann"
 
 #~ msgid "corresponding to one of the displayed words, then NAME is set"
 #~ msgstr "wird NAME entsprechend dem WORT in der bezeichneten Zeile gesetzt."
 
 #~ msgid "to that word.  If the line is empty, WORDS and the prompt are"
-#~ msgstr ""
-#~ "Wird eine leere Zeichenkette gelesen,  dann wird die Liste erneut "
-#~ "angezeigt."
+#~ msgstr "Wird eine leere Zeichenkette gelesen,  dann wird die Liste erneut angezeigt."
 
 #~ msgid "redisplayed.  If EOF is read, the command completes.  Any other"
-#~ msgstr ""
-#~ "Mir einem EOF Zeichen wird die Eingabe abgebrochen.  Jeder andere Inhalt "
-#~ "der"
+#~ msgstr "Mir einem EOF Zeichen wird die Eingabe abgebrochen.  Jeder andere Inhalt der"
 
 #~ msgid "value read causes NAME to be set to null.  The line read is saved"
-#~ msgstr ""
-#~ "Zeichenkette bewirkt, daß NAME auf Null gesetzt wird.  Die gelesene Zeile "
-#~ "wird"
+#~ msgstr "Zeichenkette bewirkt, daß NAME auf Null gesetzt wird.  Die gelesene Zeile wird"
 
 #~ msgid "in the variable REPLY.  COMMANDS are executed after each selection"
-#~ msgstr ""
-#~ "in der Variable REPLY gespeichert.  Die KOMMANDOS werden so lange "
-#~ "wiederholt,"
+#~ msgstr "in der Variable REPLY gespeichert.  Die KOMMANDOS werden so lange wiederholt,"
 
 #~ msgid "until a break or return command is executed."
 #~ msgstr "bis die Schleife mit break oder return verlassen wird."
@@ -6092,47 +5490,34 @@ msgstr ""
 #~ msgstr "Das Zeichen `|' trennt mehrere Muster."
 
 # if
-#~ msgid ""
-#~ "The if COMMANDS are executed.  If the exit status is zero, then the then"
-#~ msgstr ""
-#~ "Die KOMMANDOS werden ausgewertet. Ist der Rückgabewert Null, dann werden "
-#~ "die"
+#~ msgid "The if COMMANDS are executed.  If the exit status is zero, then the then"
+#~ msgstr "Die KOMMANDOS werden ausgewertet. Ist der Rückgabewert Null, dann werden die"
 
-#~ msgid ""
-#~ "COMMANDS are executed.  Otherwise, each of the elif COMMANDS are executed"
-#~ msgstr ""
-#~ "then KOMMANDOS ausgeführt. Ansonsten werden die elif KOMMANDOS der Reihe "
-#~ "nach"
+#~ msgid "COMMANDS are executed.  Otherwise, each of the elif COMMANDS are executed"
+#~ msgstr "then KOMMANDOS ausgeführt. Ansonsten werden die elif KOMMANDOS der Reihe nach"
 
-#~ msgid ""
-#~ "in turn, and if the exit status is zero, the corresponding then COMMANDS"
-#~ msgstr ""
-#~ "ausgewertet und bei einem Rückgabewert Null die dazugehörigen KOMMANDOS"
+#~ msgid "in turn, and if the exit status is zero, the corresponding then COMMANDS"
+#~ msgstr "ausgewertet und bei einem Rückgabewert Null die dazugehörigen KOMMANDOS"
 
-#~ msgid ""
-#~ "are executed and the if command completes.  Otherwise, the else COMMANDS"
+#~ msgid "are executed and the if command completes.  Otherwise, the else COMMANDS"
 #~ msgstr "ausgeführt und if beendet. Sonst wird, wenn ein else Kommandozweig"
 
-#~ msgid ""
-#~ "are executed, if present.  The exit status is the exit status of the last"
-#~ msgstr ""
-#~ "existiert, dieser ausgeführt. Der Exitstatus ist der des letzten Kommandos"
+#~ msgid "are executed, if present.  The exit status is the exit status of the last"
+#~ msgstr "existiert, dieser ausgeführt. Der Exitstatus ist der des letzten Kommandos"
 
 #~ msgid "command executed, or zero if no condition tested true."
 #~ msgstr "oder Null, wenn keine Bedingung wahr ergab."
 
 # while
 #~ msgid "Expand and execute COMMANDS as long as the final command in the"
-#~ msgstr ""
-#~ "Wiederholt den Schleifenkörper `do KOMMANDOS done' so lange die letzte"
+#~ msgstr "Wiederholt den Schleifenkörper `do KOMMANDOS done' so lange die letzte"
 
 #~ msgid "`while' COMMANDS has an exit status of zero."
 #~ msgstr "Kommando `while KOMMANDOS' einen Rückkehrstatus Null liefert."
 
 # until
 #~ msgid "`until' COMMANDS has an exit status which is not zero."
-#~ msgstr ""
-#~ "Kommando in `until KOMMANDOS' einen Rückkehrstatus ungleich Null liefert."
+#~ msgstr "Kommando in `until KOMMANDOS' einen Rückkehrstatus ungleich Null liefert."
 
 # function
 #~ msgid "Create a simple command invoked by NAME which runs COMMANDS."
@@ -6146,29 +5531,20 @@ msgstr ""
 
 # grouping_braces
 #~ msgid "Run a set of commands in a group.  This is one way to redirect an"
-#~ msgstr ""
-#~ "Führt Kommandos in einer Gruppe aus.  Das ist eine Möglichkeit die "
-#~ "Ausgabe von"
+#~ msgstr "Führt Kommandos in einer Gruppe aus.  Das ist eine Möglichkeit die Ausgabe von"
 
 #~ msgid "entire set of commands."
 #~ msgstr "einer Gruppe Kommandos umzuleiten."
 
 # fg_percent
 #~ msgid "This is similar to the `fg' command.  Resume a stopped or background"
-#~ msgstr ""
-#~ "Ist ähnlich dem `fg' Kommando.  Nimmt einen angehaltenen oder hintergrund "
-#~ "Job"
+#~ msgstr "Ist ähnlich dem `fg' Kommando.  Nimmt einen angehaltenen oder hintergrund Job"
 
 #~ msgid "job.  If you specifiy DIGITS, then that job is used.  If you specify"
-#~ msgstr ""
-#~ "wieder auf.  Wenn eine Jobnummer angegeben ist, dann wird dieser "
-#~ "aufgenommen."
+#~ msgstr "wieder auf.  Wenn eine Jobnummer angegeben ist, dann wird dieser aufgenommen."
 
-#~ msgid ""
-#~ "WORD, then the job whose name begins with WORD is used.  Following the"
-#~ msgstr ""
-#~ "Wenn eine Zeichenkette angegeben ist, dann wird der Job der mit diesen "
-#~ "Zeichen"
+#~ msgid "WORD, then the job whose name begins with WORD is used.  Following the"
+#~ msgstr "Wenn eine Zeichenkette angegeben ist, dann wird der Job der mit diesen Zeichen"
 
 #~ msgid "job specification with a `&' places the job in the background."
 #~ msgstr "beginnt wieder aufgenommen.  `&' bringt den Job in den Hintergrund."
@@ -6178,9 +5554,7 @@ msgstr ""
 #~ msgstr "BASH_VERSION    Versionsnummer der Bash."
 
 #~ msgid "CDPATH          A colon separated list of directories to search"
-#~ msgstr ""
-#~ "CDPATH          Eine durch Doppelpunkt getrennte Liste von "
-#~ "Verzeichnissen, die"
+#~ msgstr "CDPATH          Eine durch Doppelpunkt getrennte Liste von Verzeichnissen, die"
 
 #~ msgid "\t\twhen the argument to `cd' is not found in the current"
 #~ msgstr "\t\tdurchsucht werden, wenn das Argument von `cd' nicht im"
@@ -6188,17 +5562,14 @@ msgstr ""
 #~ msgid "\t\tdirectory."
 #~ msgstr "\t\taktuellen Verzeichnis gefunden wird."
 
-#~ msgid ""
-#~ "HISTFILE        The name of the file where your command history is stored."
+#~ msgid "HISTFILE        The name of the file where your command history is stored."
 #~ msgstr "HISTFILE        Datei, die den Kommandozeilenspeicher enthält.  "
 
 #~ msgid "HISTFILESIZE    The maximum number of lines this file can contain."
-#~ msgstr ""
-#~ "HISTFILESIZE    Maximale Zeilenanzahl, die diese Datei enthalten darf."
+#~ msgstr "HISTFILESIZE    Maximale Zeilenanzahl, die diese Datei enthalten darf."
 
 #~ msgid "HISTSIZE        The maximum number of history lines that a running"
-#~ msgstr ""
-#~ "HISTSIZE        Maximale Anzahl von Zeilen, auf die der Historymechanismus"
+#~ msgstr "HISTSIZE        Maximale Anzahl von Zeilen, auf die der Historymechanismus"
 
 #~ msgid "\t\tshell can access."
 #~ msgstr "\t\tder Shell zurückgreifen kann."
@@ -6206,15 +5577,11 @@ msgstr ""
 #~ msgid "HOME            The complete pathname to your login directory."
 #~ msgstr "HOME            Heimatverzeichnis des aktuellen Benutzers."
 
-#~ msgid ""
-#~ "HOSTTYPE        The type of CPU this version of Bash is running under."
-#~ msgstr ""
-#~ "HOSTTYPE        CPU-Typ des Rechners, auf dem die Bash gegenwärtig läuft."
+#~ msgid "HOSTTYPE        The type of CPU this version of Bash is running under."
+#~ msgstr "HOSTTYPE        CPU-Typ des Rechners, auf dem die Bash gegenwärtig läuft."
 
-#~ msgid ""
-#~ "IGNOREEOF       Controls the action of the shell on receipt of an EOF"
-#~ msgstr ""
-#~ "IGNOREEOF       Legt die Reaktion der Shell auf ein EOF-Zeichen fest."
+#~ msgid "IGNOREEOF       Controls the action of the shell on receipt of an EOF"
+#~ msgstr "IGNOREEOF       Legt die Reaktion der Shell auf ein EOF-Zeichen fest."
 
 #~ msgid "\t\tcharacter as the sole input.  If set, then the value"
 #~ msgstr "\t\tWenn die Variable eine ganze Zahl enthält, wird diese Anzahl"
@@ -6229,19 +5596,16 @@ msgstr ""
 #~ msgstr "\t\tsignalisiert EOF das Ende der Eingabe."
 
 #~ msgid "MAILCHECK\tHow often, in seconds, Bash checks for new mail."
-#~ msgstr ""
-#~ "MAILCHECK\tZeitintervall [s], in dem nach angekommener Post gesucht wird."
+#~ msgstr "MAILCHECK\tZeitintervall [s], in dem nach angekommener Post gesucht wird."
 
 #~ msgid "MAILPATH\tA colon-separated list of filenames which Bash checks"
-#~ msgstr ""
-#~ "MAILPATH\tEine durch Doppelpunkt getrennte Liste von Dateien, die nach"
+#~ msgstr "MAILPATH\tEine durch Doppelpunkt getrennte Liste von Dateien, die nach"
 
 #~ msgid "\t\tfor new mail."
 #~ msgstr "\t\tneu angekommener Post durchsucht werden."
 
 #~ msgid "OSTYPE\t\tThe version of Unix this version of Bash is running on."
-#~ msgstr ""
-#~ "OSTYPE\t\tBetriebssystemversion, auf der die Bash gegenwärtig läuft."
+#~ msgstr "OSTYPE\t\tBetriebssystemversion, auf der die Bash gegenwärtig läuft."
 
 #~ msgid "PATH            A colon-separated list of directories to search when"
 #~ msgstr "PATH\t\tDurch Doppelpunkt getrennte Liste von Verzeichnissen, die "
@@ -6250,29 +5614,22 @@ msgstr ""
 #~ msgstr "\t\tnach Kommandos durchsucht werden."
 
 #~ msgid "PROMPT_COMMAND  A command to be executed before the printing of each"
-#~ msgstr ""
-#~ "PROMPT_COMMAND  Kommando, das vor der Anzeige einer primären "
-#~ "Eingabeaufforderung"
+#~ msgstr "PROMPT_COMMAND  Kommando, das vor der Anzeige einer primären Eingabeaufforderung"
 
 #~ msgid "\t\tprimary prompt."
 #~ msgstr "\t\t(PS1) ausgeführt wird."
 
 #~ msgid "PS1             The primary prompt string."
-#~ msgstr ""
-#~ "PS1             Zeichenkette, die die primäre Eingabeaufforderung enthält."
+#~ msgstr "PS1             Zeichenkette, die die primäre Eingabeaufforderung enthält."
 
 #~ msgid "PS2             The secondary prompt string."
-#~ msgstr ""
-#~ "PS2             Zeichenkette, die die sekundäre Eingabeaufforderung "
-#~ "enthält."
+#~ msgstr "PS2             Zeichenkette, die die sekundäre Eingabeaufforderung enthält."
 
 #~ msgid "TERM            The name of the current terminal type."
 #~ msgstr "TERM            Name des aktuellen Terminaltyps."
 
 #~ msgid "auto_resume     Non-null means a command word appearing on a line by"
-#~ msgstr ""
-#~ "auto_resume     Ein Wert ungleich Null bewirkt, daß ein einzelnes "
-#~ "Kommando auf"
+#~ msgstr "auto_resume     Ein Wert ungleich Null bewirkt, daß ein einzelnes Kommando auf"
 
 #~ msgid "\t\titself is first looked for in the list of currently"
 #~ msgstr "\t\teiner Zeile zunächst in der Liste gegenwärtig gestoppter Jobs"
@@ -6298,17 +5655,14 @@ msgstr ""
 #~ msgid "command_oriented_history"
 #~ msgstr "command_oriented_history"
 
-#~ msgid ""
-#~ "                Non-null means to save multiple-line commands together on"
+#~ msgid "                Non-null means to save multiple-line commands together on"
 #~ msgstr "\t\tMehrzeilige Kommandos werden im Kommandozeilenspeicher in einer"
 
 #~ msgid "                a single history line."
 #~ msgstr "\t\tZeile abgelegt, wenn die Variable ungleich Null gesetzt ist."
 
 #~ msgid "histchars       Characters controlling history expansion and quick"
-#~ msgstr ""
-#~ "histchars       Zeichen, die die Befehlswiederholung und die "
-#~ "Schnellersetzung"
+#~ msgstr "histchars       Zeichen, die die Befehlswiederholung und die Schnellersetzung"
 
 #~ msgid "\t\tsubstitution.  The first character is the history"
 #~ msgstr "\t\tsteuern. An erster Stelle steht das Befehlswiederholungszeichen"
@@ -6326,8 +5680,7 @@ msgstr ""
 #~ msgstr "HISTCONTROL\tGesetzt auf `ignorespace' werden keine mit einem"
 
 #~ msgid "\t\tlines which begin with a space or tab on the history"
-#~ msgstr ""
-#~ "\t\tLeerzeichen oder Tabulator beginnenden Zeilen im Kommandospeicher"
+#~ msgstr "\t\tLeerzeichen oder Tabulator beginnenden Zeilen im Kommandospeicher"
 
 #~ msgid "\t\tlist.  Set to a value of `ignoredups', it means don't"
 #~ msgstr "\t\tabgelegt. Der Wert `ignoredups' verhindert das Speichern"
@@ -6346,9 +5699,7 @@ msgstr ""
 
 # pushd
 #~ msgid "Adds a directory to the top of the directory stack, or rotates"
-#~ msgstr ""
-#~ "Legt ein Verzeichnisnamen auf den Verzeichnisstapel oder rotiert diesen "
-#~ "so,"
+#~ msgstr "Legt ein Verzeichnisnamen auf den Verzeichnisstapel oder rotiert diesen so,"
 
 # Gibt's denn auch andere als "aktuelle" Arbeitsverzeichnisse?
 # "Arbeit" impliziert .m.E. "aktuell"
@@ -6357,20 +5708,16 @@ msgstr ""
 #~ msgstr "daß das Arbeitsverzeichnis auf der Spitze des Stapels liegt. Ohne"
 
 #~ msgid "directory.  With no arguments, exchanges the top two directories."
-#~ msgstr ""
-#~ "Argumente werden die obersten zwei Verzeichnisse auf dem Stapel "
-#~ "vertauscht."
+#~ msgstr "Argumente werden die obersten zwei Verzeichnisse auf dem Stapel vertauscht."
 
 #~ msgid "+N\tRotates the stack so that the Nth directory (counting"
-#~ msgstr ""
-#~ "+N\tRotiert den Stapel so, daß das N'te Verzeichnis (angezeigt von `dirs',"
+#~ msgstr "+N\tRotiert den Stapel so, daß das N'te Verzeichnis (angezeigt von `dirs',"
 
 #~ msgid "\tfrom the left of the list shown by `dirs') is at the top."
 #~ msgstr "gezählt von links) sich an der Spitze des Stapels befindet."
 
 #~ msgid "-N\tRotates the stack so that the Nth directory (counting"
-#~ msgstr ""
-#~ "-N\tRotiert den Stapel so, daß das N'te Verzeichnis (angezeigt von `dirs',"
+#~ msgstr "-N\tRotiert den Stapel so, daß das N'te Verzeichnis (angezeigt von `dirs',"
 
 #~ msgid "\tfrom the right) is at the top."
 #~ msgstr "gezählt von rechts) sich an der Spitze des Stapels befindet."
@@ -6385,22 +5732,17 @@ msgstr ""
 #~ msgstr "DIR\tLegt DIR auf die Spitze des Verzeichnisstapels und wechselt"
 
 #~ msgid "You can see the directory stack with the `dirs' command."
-#~ msgstr ""
-#~ "Der Verzeichnisstapel kann mit dem Kommando `dirs' angezeigt werden."
+#~ msgstr "Der Verzeichnisstapel kann mit dem Kommando `dirs' angezeigt werden."
 
 # pushd
 #~ msgid "Removes entries from the directory stack.  With no arguments,"
-#~ msgstr ""
-#~ "Entfernt Einträge vom Verzeichnisstapel. Ohne Argumente wird die Spitze "
-#~ "des"
+#~ msgstr "Entfernt Einträge vom Verzeichnisstapel. Ohne Argumente wird die Spitze des"
 
 #~ msgid "removes the top directory from the stack, and cd's to the new"
 #~ msgstr "Stapels entfernt und in das Verzeichnis gewechselt, das dann an der"
 
 #~ msgid "+N\tremoves the Nth entry counting from the left of the list"
-#~ msgstr ""
-#~ "+N\tEntfernt den N'ten Eintrag vom Stapel,  gezählt von Null von der "
-#~ "Liste,"
+#~ msgstr "+N\tEntfernt den N'ten Eintrag vom Stapel,  gezählt von Null von der Liste,"
 
 #~ msgid "\tshown by `dirs', starting with zero.  For example: `popd +0'"
 #~ msgstr "\tdie `dirs' anzeigt. Beispielsweise entfernen `popd +0' das"
@@ -6409,8 +5751,7 @@ msgstr ""
 #~ msgstr "\terste Verzeichnis und `popd +1' das zweite."
 
 #~ msgid "-N\tremoves the Nth entry counting from the right of the list"
-#~ msgstr ""
-#~ "-N\tEntfernt den N'ten Eintrag vom Stapel, beginend rechts bei Null in der"
+#~ msgstr "-N\tEntfernt den N'ten Eintrag vom Stapel, beginend rechts bei Null in der"
 
 #~ msgid "\tshown by `dirs', starting with zero.  For example: `popd -0'"
 #~ msgstr "\tListe, die `dirs' angeigt. Beispielsweise entfernen `popd -0'"
@@ -6418,110 +5759,73 @@ msgstr ""
 #~ msgid "\tremoves the last directory, `popd -1' the next to last."
 #~ msgstr "\tdas letzte Verzeichnis und `popd -1' das vorletzte."
 
-#~ msgid ""
-#~ "-n\tsuppress the normal change of directory when removing directories"
-#~ msgstr ""
-#~ "-n\tVerhindert das Wechseln des Arbeitsverzeichnisses wenn Verzeichnisse"
+#~ msgid "-n\tsuppress the normal change of directory when removing directories"
+#~ msgstr "-n\tVerhindert das Wechseln des Arbeitsverzeichnisses wenn Verzeichnisse"
 
 #~ msgid "\tfrom the stack, so only the stack is manipulated."
 #~ msgstr "\tvom Stapel entfernt werden, so daß nur der Stapel verändert wird."
 
 # dirs
 #~ msgid "Display the list of currently remembered directories.  Directories"
-#~ msgstr ""
-#~ "Zeigt die Liste der gegenwärtig gespeicherten Verzeichnisse an.  "
-#~ "Gespeichert"
+#~ msgstr "Zeigt die Liste der gegenwärtig gespeicherten Verzeichnisse an.  Gespeichert"
 
 #~ msgid "find their way onto the list with the `pushd' command; you can get"
-#~ msgstr ""
-#~ "werden die Verzeichnisse durch das `popd' Kommando und können durch das "
-#~ "`pushd'"
+#~ msgstr "werden die Verzeichnisse durch das `popd' Kommando und können durch das `pushd'"
 
 #~ msgid "back up through the list with the `popd' command."
 #~ msgstr "Kommando wieder vom Stapel entfernt werden."
 
-#~ msgid ""
-#~ "The -l flag specifies that `dirs' should not print shorthand versions"
-#~ msgstr ""
-#~ "Wenn die -l Option angegeben ist, dann werden keine Kurzversionen der "
-#~ "Verzeich-"
+#~ msgid "The -l flag specifies that `dirs' should not print shorthand versions"
+#~ msgstr "Wenn die -l Option angegeben ist, dann werden keine Kurzversionen der Verzeich-"
 
-#~ msgid ""
-#~ "of directories which are relative to your home directory.  This means"
-#~ msgstr ""
-#~ "nisse angezeigt, die relativ zum Heimatverzeichnis sind.  Es wird also an"
+#~ msgid "of directories which are relative to your home directory.  This means"
+#~ msgstr "nisse angezeigt, die relativ zum Heimatverzeichnis sind.  Es wird also an"
 
 #~ msgid "that `~/bin' might be displayed as `/homes/bfox/bin'.  The -v flag"
-#~ msgstr ""
-#~ "Stelle von `~/bin' der absolute Pfad `/home/foo/bin' angezeigt.  Mit der -"
-#~ "v"
+#~ msgstr "Stelle von `~/bin' der absolute Pfad `/home/foo/bin' angezeigt.  Mit der -v"
 
 #~ msgid "causes `dirs' to print the directory stack with one entry per line,"
-#~ msgstr ""
-#~ "Option wird von `dirs' ein Eintrag pro Zeile ausgegeben.  Die Position im"
+#~ msgstr "Option wird von `dirs' ein Eintrag pro Zeile ausgegeben.  Die Position im"
 
-#~ msgid ""
-#~ "prepending the directory name with its position in the stack.  The -p"
-#~ msgstr ""
-#~ "Stapel wird vorangestellt.  Die -p Option wirkt ähnlich, es wird "
-#~ "allerdings"
+#~ msgid "prepending the directory name with its position in the stack.  The -p"
+#~ msgstr "Stapel wird vorangestellt.  Die -p Option wirkt ähnlich, es wird allerdings"
 
 #~ msgid "flag does the same thing, but the stack position is not prepended."
-#~ msgstr ""
-#~ "nicht die Position im Stapel angezeigt.  Wenn -c angegeben ist, damm "
-#~ "werden"
+#~ msgstr "nicht die Position im Stapel angezeigt.  Wenn -c angegeben ist, damm werden"
 
-#~ msgid ""
-#~ "The -c flag clears the directory stack by deleting all of the elements."
+#~ msgid "The -c flag clears the directory stack by deleting all of the elements."
 #~ msgstr "alle Einträge vom Verzeichnisstapel gelöscht."
 
-#~ msgid ""
-#~ "+N\tdisplays the Nth entry counting from the left of the list shown by"
-#~ msgstr ""
-#~ "+N\tZeigt den N'ten Eintrag, gezählt von links begginnend bei Null, aus"
+#~ msgid "+N\tdisplays the Nth entry counting from the left of the list shown by"
+#~ msgstr "+N\tZeigt den N'ten Eintrag, gezählt von links begginnend bei Null, aus"
 
 #~ msgid "\tdirs when invoked without options, starting with zero."
 #~ msgstr "\tder Liste, die von `dirs' ohne Optionen angezeigt wird."
 
-#~ msgid ""
-#~ "-N\tdisplays the Nth entry counting from the right of the list shown by"
-#~ msgstr ""
-#~ "-N\tZeigt den N'ten Eintrag, gezählt von rechts begginnend bei Null, aus"
+#~ msgid "-N\tdisplays the Nth entry counting from the right of the list shown by"
+#~ msgstr "-N\tZeigt den N'ten Eintrag, gezählt von rechts begginnend bei Null, aus"
 
 # shopt_builtin
 #~ msgid "Toggle the values of variables controlling optional behavior."
-#~ msgstr ""
-#~ "Ändert die Werte von Variablen die zusätzliche Eigenschaften der Shell "
-#~ "steuern."
+#~ msgstr "Ändert die Werte von Variablen die zusätzliche Eigenschaften der Shell steuern."
 
 #~ msgid "The -s flag means to enable (set) each OPTNAME; the -u flag"
-#~ msgstr ""
-#~ "Mit der -s Option wird jeder OPTIONSMAME gesetzt.  Die -u Option setzt "
-#~ "jeden"
+#~ msgstr "Mit der -s Option wird jeder OPTIONSMAME gesetzt.  Die -u Option setzt jeden"
 
 #~ msgid "unsets each OPTNAME.  The -q flag suppresses output; the exit"
-#~ msgstr ""
-#~ "OPTIONSNAMEN zurück.  Die -q Option unterdrückt Ausgaben.  Der "
-#~ "Rückgabewert"
+#~ msgstr "OPTIONSNAMEN zurück.  Die -q Option unterdrückt Ausgaben.  Der Rückgabewert"
 
 #~ msgid "status indicates whether each OPTNAME is set or unset.  The -o"
-#~ msgstr ""
-#~ "des Kommandos gibt an ob der OPTIONSNAME ein- oder ausgeschalten wurde.  "
-#~ "Die"
+#~ msgstr "des Kommandos gibt an ob der OPTIONSNAME ein- oder ausgeschalten wurde.  Die"
 
 #~ msgid "option restricts the OPTNAMEs to those defined for use with"
-#~ msgstr ""
-#~ "Option beschränkt die OPTIONSNAMEN auf jene die mit `set -o' benutzt "
-#~ "werden"
+#~ msgstr "Option beschränkt die OPTIONSNAMEN auf jene die mit `set -o' benutzt werden"
 
 #~ msgid "`set -o'.  With no options, or with the -p option, a list of all"
-#~ msgstr ""
-#~ "können.  Ohne oder mit der -p Option wird eine Liste aller `settable' "
-#~ "Optionen"
+#~ msgstr "können.  Ohne oder mit der -p Option wird eine Liste aller `settable' Optionen"
 
 #~ msgid "settable options is displayed, with an indication of whether or"
-#~ msgstr ""
-#~ "mit einer Markierung ob die angegebene Option gesetzt oder nicht gesetzt"
+#~ msgstr "mit einer Markierung ob die angegebene Option gesetzt oder nicht gesetzt"
 
 #~ msgid "not each is set."
 #~ msgstr "ist angezeigt."
diff --git a/subst.c b/subst.c
index 589ff1d334bbf3fe13fe1450f0e37e0a475e2e43..bb73131b6f03b8b5ad08a1327f9db39f284198a0 100644 (file)
--- a/subst.c
+++ b/subst.c
@@ -1740,7 +1740,7 @@ split_at_delims (string, slen, delims, sentinel, nwp, cwp)
 
   ret = (WORD_LIST *)NULL;
 
-  /* Remove sequences of whitspace characters at the start of the string, as
+  /* 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++)
     ;
@@ -1810,9 +1810,10 @@ split_at_delims (string, slen, delims, sentinel, nwp, cwp)
 
   /* 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)
+     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]))
        {
index 42ad976917a54e46da7e7e4438106781307b5663..c8d1cf4995b831047f8252233babb031508581fc 100644 (file)
--- a/subst.c~
+++ b/subst.c~
@@ -1740,7 +1740,7 @@ split_at_delims (string, slen, delims, sentinel, nwp, cwp)
 
   ret = (WORD_LIST *)NULL;
 
-  /* Remove sequences of whitspace characters at the start of the string, as
+  /* 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++)
     ;
@@ -1812,7 +1812,7 @@ split_at_delims (string, slen, delims, sentinel, nwp, cwp)
      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 (cwp && cw == -1 && (sentinel >= slen || sentinel >= te))
     {
       if (whitespace (string[sentinel - 1]))
        {
@@ -2742,7 +2742,7 @@ pos_params (string, start, end, quoted)
       save = params = t;
     }
 
-  for (i = 1; params && i < start; i++)
+  for (i = start ? 1 : 0; params && i < start; i++)
     params = params->next;
   if (params == 0)
     return ((char *)NULL);