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.
--- /dev/null
+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.
- 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>
----
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>
extern int bash_brace_completion __P((int, int));
#endif /* BRACE_COMPLETION */
+/* To avoid including curses.h/term.h/termcap.h and that whole mess. */
+extern int tputs __P((const char *string, int nlines, int (*outx)(int)));
+
/* Forward declarations */
/* Functions bound to keys in Readline for Bash users. */
static 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 *));
/* 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 */
{
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];
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)
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");
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 *));
/* 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 */
{
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];
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)
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");
{ \
if (vflag) \
{ \
- bind_variable (vname, vbuf, 0); \
+ bind_printf_variable (vname, vbuf, 0); \
stupidly_hack_special_variables (vname); \
} \
if (conv_bufsize > 4096 ) \
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;
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;
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 */
+}
--- /dev/null
+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 */
+}
-*** ../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;
{
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;
}
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");
}
{
int old_e_flag, result, eval_unwind;
int isbltinenv;
+ char *error_trap;
#if 0
/* XXX -- added 12/11 */
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;
}
if (eval_unwind)
{
exit_immediately_on_error += old_e_flag;
+ if (error_trap)
+ {
+ set_error_trap (error_trap);
+ xfree (error_trap);
+ }
discard_unwind_frame ("eval_builtin");
}
#if defined (RESTRICTED_SHELL)
command = (char *)NULL;
- if (restricted && xstrchr (pathname, '/'))
+ if (restricted && mbschr (pathname, '/'))
{
internal_error (_("%s: restricted: cannot specify `/' in command names"),
pathname);
rl_completion_invoking_key = invoking_key;
+ RL_SETSTATE(RL_STATE_COMPLETING);
+
/* Only the completion entry function can change these. */
set_completion_defaults ('%');
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
full_completion = 0;
+ RL_SETSTATE(RL_STATE_COMPLETING);
+
/* Only the completion entry function can change these. */
set_completion_defaults ('%');
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++)
;
--- /dev/null
+/* 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, "e_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, "e_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, "e_char);
+ }
+ else
+ {
+ insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, "e_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, "e_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, "e_char);
+ }
+ else
+ {
+ insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, "e_char);
+ append_to_match (matches[match_list_index], delimiter, quote_char,
+ strcmp (orig_text, matches[match_list_index]));
+ }
+
+ completion_changed_buffer = 1;
+ return (0);
+}
--- /dev/null
+/* 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, "e_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, "e_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, "e_char);
+ }
+ else
+ {
+ insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, "e_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, "e_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, "e_char);
+ }
+ else
+ {
+ insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, "e_char);
+ append_to_match (matches[match_list_index], delimiter, quote_char,
+ strcmp (orig_text, matches[match_list_index]));
+ }
+
+ completion_changed_buffer = 1;
+ return (0);
+}
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;
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;
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);
# 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"
#: 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
#: 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
#: 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
#: 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"
#: builtins/fg_bg.def:149 builtins/jobs.def:282
msgid "current"
-msgstr ""
+msgstr "gegenwärtig"
#: builtins/fg_bg.def:158
#, c-format
#: 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
" \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 ""
#: 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"
#: 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
#: 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"
#: error.c:405
msgid "unknown command error"
-msgstr ""
+msgstr "Unbekanntes Kommando"
#: error.c:406
msgid "bad command type"
msgstr ""
#: error.c:408
-#, fuzzy
msgid "bad jump"
-msgstr "Falscher Sprung %d."
+msgstr "Falscher Sprung"
#: error.c:446
#, c-format
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."
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"
#: 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"
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"
# 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"
# 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
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
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
msgstr ""
#: parse.y:3813
-#, fuzzy
msgid "expected `)'"
msgstr "`)' erwartet."
#: 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
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
#: 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
#: 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
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]"
#: 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]"
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]"
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]"
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"
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
" -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"
" 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"
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"
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"
" \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"
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"
" -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
"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"
" 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"
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"
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"
"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"
" -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
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 ""
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"
" 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
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"
"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"
" 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
" \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."
" 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"
"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"
" \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"
" -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 ""
" 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"
" -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"
"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"
" -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"
" 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"
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"
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"
" 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
" 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"
" 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 ""
" 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 ""
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"
"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"
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"
" \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"
"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"
" -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 ""
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"
"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"
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"
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"
" 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"
#~ 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] [&]"
#~ 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."
# 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."
#~ 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."
#~ 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."
# 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."
# 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"
#~ 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."
# 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."
#~ 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"
#~ 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."
# 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:"
#~ 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"
#~ 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"
#~ 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"
#~ 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
#~ 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"
#~ 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"
#~ 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."
#~ 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."
#~ 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."
#~ 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."
#~ 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."
# 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."
#~ 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 "
#~ 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."
# 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."
#~ 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."
#~ 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."
#~ 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."
#~ 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"
#~ 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."
#~ 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."
#~ 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):"
#~ 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"
#~ 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:"
#~ 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:"
#~ 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."
#~ 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."
#~ 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"
#~ 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."
# 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."
# 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."
#~ 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."
# 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."
#~ 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"
#~ 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."
#~ 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"
#~ 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 "
#~ 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"
#~ 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"
#~ 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"
# 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"
#~ 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."
#~ 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"
#~ 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'"
#~ 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."
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++)
;
/* 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]))
{
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++)
;
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]))
{
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);