doc/{bash.1,bashref.texi}
- documented [[ command new locale-sensitive treatment of < and >
+
+ 9/24
+ ----
+configure.in
+ - add "darwin10" cases like darwin8 and darwin9 to handle linking with
+ included readline and history libraries
+
+ 9/26
+ ----
+lib/readline/display.c
+ - modify change of 7/24 to use prompt_physical_chars instead of
+ prompt_visible_length to account for visible multibyte characters in
+ the line (usually in the prompt). Fixes debian bug #547264
+ reported by Pietro Battiston <toobaz@email.it>
+ - add flags argument to _rl_col_width; changed callers. flags > 0
+ means that it's ok to use the already-computed prompt information;
+ flags == 0 means that we're expanding the prompt and we should not
+ short-circuit
+
+parse.y
+ - in decode_prompt_string, when expanding \w and \W on Mac OS X,
+ use fnx_fromfs to convert from "filesystem" form to "input" form.
+ This makes $PWD with multibyte characters work in the prompt
+ string on Mac OS X
+
+lib/sh/fnxform.c
+ - in fnx_fromfs and fnx_tofs, use templen instead of outlen as last
+ argument in calls to iconv, since outlen is used to keep track of
+ the size of the buffer, and iconv potentially modifies its
+ `outbytesleft' argument
- execute_cond_node sets TEST_LOCALE so [[ str1 < str2 ]] (and >)
obey the locale. Fixes bug/incompatibility reported by Greg
Wooledge <wooledg@eeg.ccf.org>
+
+doc/{bash.1,bashref.texi}
+ - documented [[ command new locale-sensitive treatment of < and >
+
+ 9/24
+ ----
+configure.in
+ - add "darwin10" cases like darwin8 and darwin9 to handle linking with
+ included readline and history libraries
+
+ 9/25
+ ----
+lib/readline/display.c
+ - modify change of 7/24 to use prompt_physical_chars instead of
+ prompt_visible_length to account for visible multibyte characters in
+ the line (usually in the prompt). Fixes debian bug #547264
+ reported by Pietro Battiston <toobaz@email.it>
+ - add flags argument to _rl_col_width; changed callers. flags > 0
+ means that it's ok to use the already-computed prompt information;
+ flags == 0 means that we're expanding the prompt and we should not
+ short-circuit
+
+parse.y
+ - in decode_prompt_string, when expanding \w and \W on Mac OS X,
+ use fnx_fromfs to convert from "filesystem" form to "input" form.
+ This makes $PWD with multibyte characters work in the prompt
+ string on Mac OS X
+
+lib/sh/fnxform.c
+ - in fnx_fromfs and fnx_tofs, use templen instead of outlen as last
+ argument in calls to iconv, since outlen is used to keep track of
+ the size of the buffer, and iconv potentially modifies its
+ `outbytesleft' argument
tests/set-e2.sub f
tests/set-e.right f
tests/set-x.tests f
+tests/set-x1.tests f
tests/set-x.right f
tests/shopt.tests f
tests/shopt.right f
# static version specified as -llibname to override the
# dynamic version
case "${host_os}" in
- darwin[89]*) READLINE_LIB='${READLINE_LIBRARY}' ;;
+ darwin[89]*|darwin10*) READLINE_LIB='${READLINE_LIBRARY}' ;;
*) READLINE_LIB=-lreadline ;;
esac
fi
# static version specified as -llibname to override the
# dynamic version
case "${host_os}" in
- darwin[89]*) HISTORY_LIB='${HISTORY_LIBRARY}' ;;
+ darwin[89]*|darwin10*) HISTORY_LIB='${HISTORY_LIBRARY}' ;;
*) HISTORY_LIB=-lhistory ;;
esac
fi
'configure.in'
],
{
- '_LT_AC_TAGCONFIG' => 1,
'AM_PROG_F77_C_O' => 1,
- 'AC_INIT' => 1,
+ '_LT_AC_TAGCONFIG' => 1,
'm4_pattern_forbid' => 1,
- '_AM_COND_IF' => 1,
+ 'AC_INIT' => 1,
'AC_CANONICAL_TARGET' => 1,
- 'AC_SUBST' => 1,
+ '_AM_COND_IF' => 1,
'AC_CONFIG_LIBOBJ_DIR' => 1,
- 'AC_FC_SRCEXT' => 1,
+ 'AC_SUBST' => 1,
'AC_CANONICAL_HOST' => 1,
+ 'AC_FC_SRCEXT' => 1,
'AC_PROG_LIBTOOL' => 1,
'AM_INIT_AUTOMAKE' => 1,
'AC_CONFIG_SUBDIRS' => 1,
'AM_AUTOMAKE_VERSION' => 1,
'LT_CONFIG_LTDL_DIR' => 1,
- 'AC_REQUIRE_AUX_FILE' => 1,
'AC_CONFIG_LINKS' => 1,
- 'm4_sinclude' => 1,
+ 'AC_REQUIRE_AUX_FILE' => 1,
'LT_SUPPORTED_TAG' => 1,
+ 'm4_sinclude' => 1,
'AM_MAINTAINER_MODE' => 1,
'AM_GNU_GETTEXT_INTL_SUBDIR' => 1,
'_m4_warn' => 1,
'AC_CANONICAL_BUILD' => 1,
'AC_FC_FREEFORM' => 1,
'AH_OUTPUT' => 1,
- '_AM_SUBST_NOTMAKE' => 1,
'AC_CONFIG_AUX_DIR' => 1,
- 'sinclude' => 1,
- 'm4_pattern_allow' => 1,
+ '_AM_SUBST_NOTMAKE' => 1,
'AM_PROG_CC_C_O' => 1,
- 'AC_CANONICAL_SYSTEM' => 1,
+ 'm4_pattern_allow' => 1,
+ 'sinclude' => 1,
'AM_CONDITIONAL' => 1,
+ 'AC_CANONICAL_SYSTEM' => 1,
'AC_CONFIG_HEADERS' => 1,
'AC_DEFINE_TRACE_LITERAL' => 1,
'm4_include' => 1,
# static version specified as -llibname to override the
# dynamic version
case "${host_os}" in
- darwin[89]*) READLINE_LIB='${READLINE_LIBRARY}' ;;
+ darwin[89]*|darwin10*) READLINE_LIB='${READLINE_LIBRARY}' ;;
*) READLINE_LIB=-lreadline ;;
esac
fi
# static version specified as -llibname to override the
# dynamic version
case "${host_os}" in
- darwin[89]*) HISTORY_LIB='${HISTORY_LIBRARY}' ;;
+ darwin[89]*|darwin10*) HISTORY_LIB='${HISTORY_LIBRARY}' ;;
*) HISTORY_LIB=-lhistory ;;
esac
fi
# static version specified as -llibname to override the
# dynamic version
case "${host_os}" in
- darwin[[89]]*) READLINE_LIB='${READLINE_LIBRARY}' ;;
+ darwin[[89]]*|darwin10*) READLINE_LIB='${READLINE_LIBRARY}' ;;
*) READLINE_LIB=-lreadline ;;
esac
fi
# static version specified as -llibname to override the
# dynamic version
case "${host_os}" in
- darwin[[89]]*) HISTORY_LIB='${HISTORY_LIBRARY}' ;;
+ darwin[[89]]*|darwin10*) HISTORY_LIB='${HISTORY_LIBRARY}' ;;
*) HISTORY_LIB=-lhistory ;;
esac
fi
#define invisible_line (line_state_invisible->line)
#if defined (HANDLE_MULTIBYTE)
-static int _rl_col_width PARAMS((const char *, int, int));
+static int _rl_col_width PARAMS((const char *, int, int, int));
#else
-# define _rl_col_width(l, s, e) (((e) <= (s)) ? 0 : (e) - (s))
+# define _rl_col_width(l, s, e, f) (((e) <= (s)) ? 0 : (e) - (s))
#endif
/* Heuristic used to decide whether it is faster to move from CUR to NEW
not be the same as the number of physical characters
on the screen in the presence of multibyte characters */
rl += ind - pind;
- physchars += _rl_col_width (pmt, pind, ind);
+ physchars += _rl_col_width (pmt, pind, ind, 0);
}
else
ninvis += ind - pind;
temp = local_prompt_len;
while (num < temp)
{
- z = _rl_col_width (local_prompt, n0, num);
+ z = _rl_col_width (local_prompt, n0, num, 1);
if (z > _rl_screenwidth)
{
num = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY);
inv_lbreaks[++newlines] = temp;
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0)
- lpos -= _rl_col_width (local_prompt, n0, num);
+ lpos -= _rl_col_width (local_prompt, n0, num, 1);
else
#endif
lpos -= _rl_screenwidth;
_rl_output_some_chars (local_prompt, nleft);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- _rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft) - wrap_offset + modmark;
+ _rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft, 1) - wrap_offset + modmark;
else
_rl_last_c_pos = nleft + modmark;
}
{
/* TX == new physical cursor position in multibyte locale. */
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- tx = _rl_col_width (&visible_line[pos], 0, nleft) - visible_wrap_offset;
+ tx = _rl_col_width (&visible_line[pos], 0, nleft, 1) - visible_wrap_offset;
else
tx = nleft;
if (tx >= 0 && _rl_last_c_pos > tx)
{
/* We take wrap_offset into account here so we can pass correct
information to _rl_move_cursor_relative. */
- _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff) - wrap_offset + modmark;
+ _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff, 1) - wrap_offset + modmark;
cpos_adjusted = 1;
}
else
When not using multibyte characters, these are equal */
lendiff = (nls - nfd) - (ols - ofd);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- col_lendiff = _rl_col_width (new, nfd - new, nls - new) - _rl_col_width (old, ofd - old, ols - old);
+ col_lendiff = _rl_col_width (new, nfd - new, nls - new, 1) - _rl_col_width (old, ofd - old, ols - old, 1);
else
col_lendiff = lendiff;
/* Insert (diff (len (old), len (new)) ch. */
temp = ne - nfd;
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- col_temp = _rl_col_width (new, nfd - new, ne - new);
+ col_temp = _rl_col_width (new, nfd - new, ne - new, 1);
else
col_temp = temp;
if (lendiff < 0)
{
_rl_output_some_chars (nfd, temp);
- _rl_last_c_pos += _rl_col_width (nfd, 0, temp);
+ _rl_last_c_pos += _rl_col_width (nfd, 0, temp, 1);
/* If nfd begins before any invisible characters in the prompt,
adjust _rl_last_c_pos to account for wrap_offset and set
cpos_adjusted to let the caller know. */
multibyte characters and prompt strings with invisible
characters, but was previously disabled. */
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- twidth = _rl_col_width (nfd+lendiff, 0, temp-col_lendiff);
+ twidth = _rl_col_width (nfd+lendiff, 0, temp-col_lendiff, 1);
else
twidth = temp - lendiff;
_rl_last_c_pos += twidth;
_rl_output_some_chars (nfd, temp);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
- _rl_last_c_pos += _rl_col_width (nfd, 0, temp);
+ _rl_last_c_pos += _rl_col_width (nfd, 0, temp, 1);
if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
{
_rl_last_c_pos -= wrap_offset;
}
lendiff = (oe - old) - (ne - new);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- col_lendiff = _rl_col_width (old, 0, oe - old) - _rl_col_width (new, 0, ne - new);
+ col_lendiff = _rl_col_width (old, 0, oe - old, 1) - _rl_col_width (new, 0, ne - new, 1);
else
col_lendiff = lendiff;
l = strlen (prompt_last_line);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- _rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l); /* XXX */
+ _rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l, 1); /* XXX */
else
_rl_last_c_pos = l;
/* 1. prompt string */
if (new == local_prompt_len && memcmp (data, local_prompt, new) == 0)
{
- dpos = prompt_visible_length;
+ dpos = prompt_physical_chars;
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);
+ dpos = prompt_physical_chars + _rl_col_width (data, local_prompt_len, new, 1);
cpos_adjusted = 1;
adjust = 0;
}
else
- dpos = _rl_col_width (data, 0, new);
+ dpos = _rl_col_width (data, 0, new, 1);
/* Use NEW when comparing against the last invisible character in the
prompt string, since they're both buffer indices and DPOS is a
In the case of multibyte characters with stateful encoding, we have to
scan from the beginning of the string to take the state into account. */
static int
-_rl_col_width (str, start, end)
+_rl_col_width (str, start, end, flags)
const char *str;
- int start, end;
+ int start, end, flags;
{
wchar_t wc;
mbstate_t ps;
/* 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);
+ if (flags && start == 0 && end == local_prompt_len && memcmp (str, local_prompt, local_prompt_len) == 0)
+ return (prompt_physical_chars + 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)
+ else if (flags && start == 0 && local_prompt_len > 0 && end > local_prompt_len && local_prompt && memcmp (str, local_prompt, local_prompt_len) == 0)
{
- tmp = prompt_visible_length + wrap_offset;
+ tmp = prompt_physical_chars + wrap_offset;
/* XXX - try to call ourselves recursively with non-prompt portion */
- tmp += _rl_col_width (str, local_prompt_len, end);
+ tmp += _rl_col_width (str, local_prompt_len, end, flags);
return (tmp);
}
--- /dev/null
+/* display.c -- readline redisplay facility. */
+
+/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library (Readline), a library
+ for reading lines of text with interactive input and history editing.
+
+ Readline is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Readline is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Readline. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#define READLINE_LIBRARY
+
+#if defined (HAVE_CONFIG_H)
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include "posixstat.h"
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#include <stdio.h>
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+#include "rlmbutil.h"
+
+/* Termcap library stuff. */
+#include "tcap.h"
+
+/* Some standard library routines. */
+#include "readline.h"
+#include "history.h"
+
+#include "rlprivate.h"
+#include "xmalloc.h"
+
+#if !defined (strchr) && !defined (__STDC__)
+extern char *strchr (), *strrchr ();
+#endif /* !strchr && !__STDC__ */
+
+static void update_line PARAMS((char *, char *, int, int, int, int));
+static void space_to_eol PARAMS((int));
+static void delete_chars PARAMS((int));
+static void insert_some_chars PARAMS((char *, int, int));
+static void cr PARAMS((void));
+
+/* State of visible and invisible lines. */
+struct line_state
+ {
+ char *line;
+ int *lbreaks;
+ int lbsize;
+#if defined (HANDLE_MULTIBYTE)
+ int *wrapped_line;
+ int wbsize;
+#endif
+ };
+
+/* The line display buffers. One is the line currently displayed on
+ the screen. The other is the line about to be displayed. */
+static struct line_state line_state_array[2];
+static struct line_state *line_state_visible = &line_state_array[0];
+static struct line_state *line_state_invisible = &line_state_array[1];
+static int line_structures_initialized = 0;
+
+/* Backwards-compatible names. */
+#define inv_lbreaks (line_state_invisible->lbreaks)
+#define inv_lbsize (line_state_invisible->lbsize)
+#define vis_lbreaks (line_state_visible->lbreaks)
+#define vis_lbsize (line_state_visible->lbsize)
+
+#define visible_line (line_state_visible->line)
+#define invisible_line (line_state_invisible->line)
+
+#if defined (HANDLE_MULTIBYTE)
+static int _rl_col_width PARAMS((const char *, int, int));
+#else
+# define _rl_col_width(l, s, e) (((e) <= (s)) ? 0 : (e) - (s))
+#endif
+
+/* Heuristic used to decide whether it is faster to move from CUR to NEW
+ by backing up or outputting a carriage return and moving forward. CUR
+ and NEW are either both buffer positions or absolute screen positions. */
+#define CR_FASTER(new, cur) (((new) + 1) < ((cur) - (new)))
+
+/* _rl_last_c_pos is an absolute cursor position in multibyte locales and a
+ buffer index in others. This macro is used when deciding whether the
+ current cursor position is in the middle of a prompt string containing
+ invisible characters. XXX - might need to take `modmark' into account. */
+#define PROMPT_ENDING_INDEX \
+ ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) ? prompt_physical_chars : prompt_last_invisible+1)
+
+
+/* **************************************************************** */
+/* */
+/* Display stuff */
+/* */
+/* **************************************************************** */
+
+/* This is the stuff that is hard for me. I never seem to write good
+ display routines in C. Let's see how I do this time. */
+
+/* (PWP) Well... Good for a simple line updater, but totally ignores
+ the problems of input lines longer than the screen width.
+
+ update_line and the code that calls it makes a multiple line,
+ automatically wrapping line update. Careful attention needs
+ to be paid to the vertical position variables. */
+
+/* Keep two buffers; one which reflects the current contents of the
+ screen, and the other to draw what we think the new contents should
+ be. Then compare the buffers, and make whatever changes to the
+ screen itself that we should. Finally, make the buffer that we
+ just drew into be the one which reflects the current contents of the
+ screen, and place the cursor where it belongs.
+
+ Commands that want to can fix the display themselves, and then let
+ this function know that the display has been fixed by setting the
+ RL_DISPLAY_FIXED variable. This is good for efficiency. */
+
+/* Application-specific redisplay function. */
+rl_voidfunc_t *rl_redisplay_function = rl_redisplay;
+
+/* Global variables declared here. */
+/* What YOU turn on when you have handled all redisplay yourself. */
+int rl_display_fixed = 0;
+
+int _rl_suppress_redisplay = 0;
+int _rl_want_redisplay = 0;
+
+/* The stuff that gets printed out before the actual text of the line.
+ This is usually pointing to rl_prompt. */
+char *rl_display_prompt = (char *)NULL;
+
+/* Pseudo-global variables declared here. */
+
+/* The visible cursor position. If you print some text, adjust this. */
+/* NOTE: _rl_last_c_pos is used as a buffer index when not in a locale
+ supporting multibyte characters, and an absolute cursor position when
+ in such a locale. This is an artifact of the donated multibyte support.
+ Care must be taken when modifying its value. */
+int _rl_last_c_pos = 0;
+int _rl_last_v_pos = 0;
+
+static int cpos_adjusted;
+static int cpos_buffer_position;
+static int prompt_multibyte_chars;
+
+/* Number of lines currently on screen minus 1. */
+int _rl_vis_botlin = 0;
+
+/* Variables used only in this file. */
+/* The last left edge of text that was displayed. This is used when
+ doing horizontal scrolling. It shifts in thirds of a screenwidth. */
+static int last_lmargin;
+
+/* A buffer for `modeline' messages. */
+static char msg_buf[128];
+
+/* Non-zero forces the redisplay even if we thought it was unnecessary. */
+static int forced_display;
+
+/* Default and initial buffer size. Can grow. */
+static int line_size = 1024;
+
+/* Variables to keep track of the expanded prompt string, which may
+ include invisible characters. */
+
+static char *local_prompt, *local_prompt_prefix;
+static int local_prompt_len;
+static int prompt_visible_length, prompt_prefix_length;
+
+/* The number of invisible characters in the line currently being
+ displayed on the screen. */
+static int visible_wrap_offset;
+
+/* The number of invisible characters in the prompt string. Static so it
+ can be shared between rl_redisplay and update_line */
+static int wrap_offset;
+
+/* The index of the last invisible character in the prompt string. */
+static int prompt_last_invisible;
+
+/* The length (buffer offset) of the first line of the last (possibly
+ multi-line) buffer displayed on the screen. */
+static int visible_first_line_len;
+
+/* Number of invisible characters on the first physical line of the prompt.
+ Only valid when the number of physical characters in the prompt exceeds
+ (or is equal to) _rl_screenwidth. */
+static int prompt_invis_chars_first_line;
+
+static int prompt_last_screen_line;
+
+static int prompt_physical_chars;
+
+/* set to a non-zero value by rl_redisplay if we are marking modified history
+ lines and the current line is so marked. */
+static int modmark;
+
+/* Variables to save and restore prompt and display information. */
+
+/* These are getting numerous enough that it's time to create a struct. */
+
+static char *saved_local_prompt;
+static char *saved_local_prefix;
+static int saved_last_invisible;
+static int saved_visible_length;
+static int saved_prefix_length;
+static int saved_local_length;
+static int saved_invis_chars_first_line;
+static int saved_physical_chars;
+
+/* Expand the prompt string S and return the number of visible
+ characters in *LP, if LP is not null. This is currently more-or-less
+ a placeholder for expansion. LIP, if non-null is a place to store the
+ index of the last invisible character in the returned string. NIFLP,
+ if non-zero, is a place to store the number of invisible characters in
+ the first prompt line. The previous are used as byte counts -- indexes
+ into a character buffer. */
+
+/* Current implementation:
+ \001 (^A) start non-visible characters
+ \002 (^B) end non-visible characters
+ all characters except \001 and \002 (following a \001) are copied to
+ the returned string; all characters except those between \001 and
+ \002 are assumed to be `visible'. */
+
+static char *
+expand_prompt (pmt, lp, lip, niflp, vlp)
+ char *pmt;
+ int *lp, *lip, *niflp, *vlp;
+{
+ char *r, *ret, *p, *igstart;
+ int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars;
+
+ /* Short-circuit if we can. */
+ if ((MB_CUR_MAX <= 1 || rl_byte_oriented) && strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
+ {
+ r = savestring (pmt);
+ if (lp)
+ *lp = strlen (r);
+ if (lip)
+ *lip = 0;
+ if (niflp)
+ *niflp = 0;
+ if (vlp)
+ *vlp = lp ? *lp : strlen (r);
+ return r;
+ }
+
+ l = strlen (pmt);
+ r = ret = (char *)xmalloc (l + 1);
+
+ invfl = 0; /* invisible chars in first line of prompt */
+ invflset = 0; /* we only want to set invfl once */
+
+ igstart = 0;
+ for (rl = ignoring = last = ninvis = physchars = 0, p = pmt; p && *p; p++)
+ {
+ /* This code strips the invisible character string markers
+ RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
+ if (ignoring == 0 && *p == RL_PROMPT_START_IGNORE) /* XXX - check ignoring? */
+ {
+ ignoring = 1;
+ igstart = p;
+ continue;
+ }
+ else if (ignoring && *p == RL_PROMPT_END_IGNORE)
+ {
+ ignoring = 0;
+ if (p != (igstart + 1))
+ last = r - ret - 1;
+ continue;
+ }
+ else
+ {
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ pind = p - pmt;
+ ind = _rl_find_next_mbchar (pmt, pind, 1, MB_FIND_NONZERO);
+ l = ind - pind;
+ while (l--)
+ *r++ = *p++;
+ if (!ignoring)
+ {
+ /* rl ends up being assigned to prompt_visible_length,
+ which is the number of characters in the buffer that
+ contribute to characters on the screen, which might
+ not be the same as the number of physical characters
+ on the screen in the presence of multibyte characters */
+ rl += ind - pind;
+ physchars += _rl_col_width (pmt, pind, ind);
+ }
+ else
+ ninvis += ind - pind;
+ p--; /* compensate for later increment */
+ }
+ else
+#endif
+ {
+ *r++ = *p;
+ if (!ignoring)
+ {
+ rl++; /* visible length byte counter */
+ physchars++;
+ }
+ else
+ ninvis++; /* invisible chars byte counter */
+ }
+
+ if (invflset == 0 && rl >= _rl_screenwidth)
+ {
+ invfl = ninvis;
+ invflset = 1;
+ }
+ }
+ }
+
+ if (rl < _rl_screenwidth)
+ invfl = ninvis;
+
+ *r = '\0';
+ if (lp)
+ *lp = rl;
+ if (lip)
+ *lip = last;
+ if (niflp)
+ *niflp = invfl;
+ if (vlp)
+ *vlp = physchars;
+ return ret;
+}
+
+/* Just strip out RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE from
+ PMT and return the rest of PMT. */
+char *
+_rl_strip_prompt (pmt)
+ char *pmt;
+{
+ char *ret;
+
+ ret = expand_prompt (pmt, (int *)NULL, (int *)NULL, (int *)NULL, (int *)NULL);
+ return ret;
+}
+
+/*
+ * Expand the prompt string into the various display components, if
+ * necessary.
+ *
+ * local_prompt = expanded last line of string in rl_display_prompt
+ * (portion after the final newline)
+ * local_prompt_prefix = portion before last newline of rl_display_prompt,
+ * expanded via expand_prompt
+ * prompt_visible_length = number of visible characters in local_prompt
+ * prompt_prefix_length = number of visible characters in local_prompt_prefix
+ *
+ * This function is called once per call to readline(). It may also be
+ * called arbitrarily to expand the primary prompt.
+ *
+ * The return value is the number of visible characters on the last line
+ * of the (possibly multi-line) prompt.
+ */
+int
+rl_expand_prompt (prompt)
+ char *prompt;
+{
+ char *p, *t;
+ int c;
+
+ /* Clear out any saved values. */
+ FREE (local_prompt);
+ FREE (local_prompt_prefix);
+
+ local_prompt = local_prompt_prefix = (char *)0;
+ local_prompt_len = 0;
+ prompt_last_invisible = prompt_invis_chars_first_line = 0;
+ prompt_visible_length = prompt_physical_chars = 0;
+
+ if (prompt == 0 || *prompt == 0)
+ return (0);
+
+ p = strrchr (prompt, '\n');
+ if (!p)
+ {
+ /* The prompt is only one logical line, though it might wrap. */
+ local_prompt = expand_prompt (prompt, &prompt_visible_length,
+ &prompt_last_invisible,
+ &prompt_invis_chars_first_line,
+ &prompt_physical_chars);
+ local_prompt_prefix = (char *)0;
+ local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
+ return (prompt_visible_length);
+ }
+ else
+ {
+ /* The prompt spans multiple lines. */
+ t = ++p;
+ local_prompt = expand_prompt (p, &prompt_visible_length,
+ &prompt_last_invisible,
+ &prompt_invis_chars_first_line,
+ &prompt_physical_chars);
+ c = *t; *t = '\0';
+ /* The portion of the prompt string up to and including the
+ final newline is now null-terminated. */
+ local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length,
+ (int *)NULL,
+ (int *)NULL,
+ (int *)NULL);
+ *t = c;
+ local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
+ return (prompt_prefix_length);
+ }
+}
+
+/* Initialize the VISIBLE_LINE and INVISIBLE_LINE arrays, and their associated
+ arrays of line break markers. MINSIZE is the minimum size of VISIBLE_LINE
+ and INVISIBLE_LINE; if it is greater than LINE_SIZE, LINE_SIZE is
+ increased. If the lines have already been allocated, this ensures that
+ they can hold at least MINSIZE characters. */
+static void
+init_line_structures (minsize)
+ int minsize;
+{
+ register int n;
+
+ if (invisible_line == 0) /* initialize it */
+ {
+ if (line_size < minsize)
+ line_size = minsize;
+ visible_line = (char *)xmalloc (line_size);
+ invisible_line = (char *)xmalloc (line_size);
+ }
+ else if (line_size < minsize) /* ensure it can hold MINSIZE chars */
+ {
+ line_size *= 2;
+ if (line_size < minsize)
+ line_size = minsize;
+ visible_line = (char *)xrealloc (visible_line, line_size);
+ invisible_line = (char *)xrealloc (invisible_line, line_size);
+ }
+
+ for (n = minsize; n < line_size; n++)
+ {
+ visible_line[n] = 0;
+ invisible_line[n] = 1;
+ }
+
+ if (vis_lbreaks == 0)
+ {
+ /* should be enough. */
+ inv_lbsize = vis_lbsize = 256;
+
+#if defined (HANDLE_MULTIBYTE)
+ line_state_visible->wbsize = vis_lbsize;
+ line_state_visible->wrapped_line = (int *)xmalloc (line_state_visible->wbsize * sizeof (int));
+
+ line_state_invisible->wbsize = inv_lbsize;
+ line_state_invisible->wrapped_line = (int *)xmalloc (line_state_invisible->wbsize * sizeof (int));
+#endif
+
+ inv_lbreaks = (int *)xmalloc (inv_lbsize * sizeof (int));
+ vis_lbreaks = (int *)xmalloc (vis_lbsize * sizeof (int));
+ inv_lbreaks[0] = vis_lbreaks[0] = 0;
+ }
+
+ line_structures_initialized = 1;
+}
+
+/* Basic redisplay algorithm. */
+void
+rl_redisplay ()
+{
+ register int in, out, c, linenum, cursor_linenum;
+ register char *line;
+ int inv_botlin, lb_botlin, lb_linenum, o_cpos;
+ int newlines, lpos, temp, n0, num, prompt_lines_estimate;
+ char *prompt_this_line;
+#if defined (HANDLE_MULTIBYTE)
+ wchar_t wc;
+ size_t wc_bytes;
+ int wc_width;
+ mbstate_t ps;
+ int _rl_wrapped_multicolumn = 0;
+#endif
+
+ if (_rl_echoing_p == 0)
+ return;
+
+ /* Block keyboard interrupts because this function manipulates global
+ data structures. */
+ _rl_block_sigint ();
+ RL_SETSTATE (RL_STATE_REDISPLAYING);
+
+ if (!rl_display_prompt)
+ rl_display_prompt = "";
+
+ if (line_structures_initialized == 0)
+ {
+ init_line_structures (0);
+ rl_on_new_line ();
+ }
+
+ /* Draw the line into the buffer. */
+ cpos_buffer_position = -1;
+
+ prompt_multibyte_chars = prompt_visible_length - prompt_physical_chars;
+
+ line = invisible_line;
+ out = inv_botlin = 0;
+
+ /* Mark the line as modified or not. We only do this for history
+ lines. */
+ modmark = 0;
+ if (_rl_mark_modified_lines && current_history () && rl_undo_list)
+ {
+ line[out++] = '*';
+ line[out] = '\0';
+ modmark = 1;
+ }
+
+ /* If someone thought that the redisplay was handled, but the currently
+ visible line has a different modification state than the one about
+ to become visible, then correct the caller's misconception. */
+ if (visible_line[0] != invisible_line[0])
+ rl_display_fixed = 0;
+
+ /* If the prompt to be displayed is the `primary' readline prompt (the
+ one passed to readline()), use the values we have already expanded.
+ If not, use what's already in rl_display_prompt. WRAP_OFFSET is the
+ number of non-visible characters in the prompt string. */
+ if (rl_display_prompt == rl_prompt || local_prompt)
+ {
+ if (local_prompt_prefix && forced_display)
+ _rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix));
+
+ if (local_prompt_len > 0)
+ {
+ temp = local_prompt_len + out + 2;
+ if (temp >= line_size)
+ {
+ line_size = (temp + 1024) - (temp % 1024);
+ visible_line = (char *)xrealloc (visible_line, line_size);
+ line = invisible_line = (char *)xrealloc (invisible_line, line_size);
+ }
+ strncpy (line + out, local_prompt, local_prompt_len);
+ out += local_prompt_len;
+ }
+ line[out] = '\0';
+ wrap_offset = local_prompt_len - prompt_visible_length;
+ }
+ else
+ {
+ int pmtlen;
+ prompt_this_line = strrchr (rl_display_prompt, '\n');
+ if (!prompt_this_line)
+ prompt_this_line = rl_display_prompt;
+ else
+ {
+ prompt_this_line++;
+ pmtlen = prompt_this_line - rl_display_prompt; /* temp var */
+ if (forced_display)
+ {
+ _rl_output_some_chars (rl_display_prompt, pmtlen);
+ /* Make sure we are at column zero even after a newline,
+ regardless of the state of terminal output processing. */
+ if (pmtlen < 2 || prompt_this_line[-2] != '\r')
+ cr ();
+ }
+ }
+
+ prompt_physical_chars = pmtlen = strlen (prompt_this_line);
+ temp = pmtlen + out + 2;
+ if (temp >= line_size)
+ {
+ line_size = (temp + 1024) - (temp % 1024);
+ visible_line = (char *)xrealloc (visible_line, line_size);
+ line = invisible_line = (char *)xrealloc (invisible_line, line_size);
+ }
+ strncpy (line + out, prompt_this_line, pmtlen);
+ out += pmtlen;
+ line[out] = '\0';
+ wrap_offset = prompt_invis_chars_first_line = 0;
+ }
+
+#define CHECK_INV_LBREAKS() \
+ do { \
+ if (newlines >= (inv_lbsize - 2)) \
+ { \
+ inv_lbsize *= 2; \
+ inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
+ } \
+ } while (0)
+
+#if defined (HANDLE_MULTIBYTE)
+#define CHECK_LPOS() \
+ do { \
+ lpos++; \
+ if (lpos >= _rl_screenwidth) \
+ { \
+ if (newlines >= (inv_lbsize - 2)) \
+ { \
+ inv_lbsize *= 2; \
+ inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
+ } \
+ inv_lbreaks[++newlines] = out; \
+ if (newlines >= (line_state_invisible->wbsize - 1)) \
+ { \
+ line_state_invisible->wbsize *= 2; \
+ line_state_invisible->wrapped_line = (int *)xrealloc (line_state_invisible->wrapped_line, line_state_invisible->wbsize * sizeof(int)); \
+ } \
+ line_state_invisible->wrapped_line[newlines] = _rl_wrapped_multicolumn; \
+ lpos = 0; \
+ } \
+ } while (0)
+#else
+#define CHECK_LPOS() \
+ do { \
+ lpos++; \
+ if (lpos >= _rl_screenwidth) \
+ { \
+ if (newlines >= (inv_lbsize - 2)) \
+ { \
+ inv_lbsize *= 2; \
+ inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
+ } \
+ inv_lbreaks[++newlines] = out; \
+ lpos = 0; \
+ } \
+ } while (0)
+#endif
+
+ /* inv_lbreaks[i] is where line i starts in the buffer. */
+ inv_lbreaks[newlines = 0] = 0;
+ lpos = prompt_physical_chars + modmark;
+
+#if defined (HANDLE_MULTIBYTE)
+ memset (line_state_invisible->wrapped_line, 0, line_state_invisible->wbsize * sizeof (int));
+ num = 0;
+#endif
+
+ /* prompt_invis_chars_first_line is the number of invisible characters in
+ the first physical line of the prompt.
+ wrap_offset - prompt_invis_chars_first_line is the number of invis
+ chars on the second (or, more generally, last) line. */
+
+ /* This is zero-based, used to set the newlines */
+ prompt_lines_estimate = lpos / _rl_screenwidth;
+
+ /* what if lpos is already >= _rl_screenwidth before we start drawing the
+ contents of the command line? */
+ while (lpos >= _rl_screenwidth)
+ {
+ int z;
+ /* fix from Darin Johnson <darin@acuson.com> for prompt string with
+ invisible characters that is longer than the screen width. The
+ prompt_invis_chars_first_line variable could be made into an array
+ saying how many invisible characters there are per line, but that's
+ probably too much work for the benefit gained. How many people have
+ prompts that exceed two physical lines?
+ Additional logic fix from Edward Catmur <ed@catmur.co.uk> */
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0)
+ {
+ n0 = num;
+ temp = local_prompt_len;
+ while (num < temp)
+ {
+ z = _rl_col_width (local_prompt, n0, num);
+ if (z > _rl_screenwidth)
+ {
+ num = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY);
+ break;
+ }
+ else if (z == _rl_screenwidth)
+ break;
+ num++;
+ }
+ temp = num;
+ }
+ else
+#endif /* !HANDLE_MULTIBYTE */
+ temp = ((newlines + 1) * _rl_screenwidth);
+
+ /* Now account for invisible characters in the current line. */
+ /* XXX - this assumes that the invisible characters may be split, but only
+ between the first and the last lines. */
+ temp += ((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line
+ : ((newlines == prompt_lines_estimate) ? wrap_offset : prompt_invis_chars_first_line))
+ : ((newlines == 0) ? wrap_offset : 0));
+
+ inv_lbreaks[++newlines] = temp;
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0)
+ lpos -= _rl_col_width (local_prompt, n0, num);
+ else
+#endif
+ lpos -= _rl_screenwidth;
+ }
+
+ prompt_last_screen_line = newlines;
+
+ /* Draw the rest of the line (after the prompt) into invisible_line, keeping
+ track of where the cursor is (cpos_buffer_position), the number of the line containing
+ the cursor (lb_linenum), the last line number (lb_botlin and inv_botlin).
+ It maintains an array of line breaks for display (inv_lbreaks).
+ This handles expanding tabs for display and displaying meta characters. */
+ lb_linenum = 0;
+#if defined (HANDLE_MULTIBYTE)
+ in = 0;
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ memset (&ps, 0, sizeof (mbstate_t));
+ /* XXX - what if wc_bytes ends up <= 0? check for MB_INVALIDCH */
+ wc_bytes = mbrtowc (&wc, rl_line_buffer, rl_end, &ps);
+ }
+ else
+ wc_bytes = 1;
+ while (in < rl_end)
+#else
+ for (in = 0; in < rl_end; in++)
+#endif
+ {
+ c = (unsigned char)rl_line_buffer[in];
+
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ if (MB_INVALIDCH (wc_bytes))
+ {
+ /* Byte sequence is invalid or shortened. Assume that the
+ first byte represents a character. */
+ wc_bytes = 1;
+ /* Assume that a character occupies a single column. */
+ wc_width = 1;
+ memset (&ps, 0, sizeof (mbstate_t));
+ }
+ else if (MB_NULLWCH (wc_bytes))
+ break; /* Found '\0' */
+ else
+ {
+ temp = wcwidth (wc);
+ wc_width = (temp >= 0) ? temp : 1;
+ }
+ }
+#endif
+
+ if (out + 8 >= line_size) /* XXX - 8 for \t */
+ {
+ line_size *= 2;
+ visible_line = (char *)xrealloc (visible_line, line_size);
+ invisible_line = (char *)xrealloc (invisible_line, line_size);
+ line = invisible_line;
+ }
+
+ if (in == rl_point)
+ {
+ cpos_buffer_position = out;
+ lb_linenum = newlines;
+ }
+
+#if defined (HANDLE_MULTIBYTE)
+ if (META_CHAR (c) && _rl_output_meta_chars == 0) /* XXX - clean up */
+#else
+ if (META_CHAR (c))
+#endif
+ {
+ if (_rl_output_meta_chars == 0)
+ {
+ sprintf (line + out, "\\%o", c);
+
+ if (lpos + 4 >= _rl_screenwidth)
+ {
+ temp = _rl_screenwidth - lpos;
+ CHECK_INV_LBREAKS ();
+ inv_lbreaks[++newlines] = out + temp;
+ lpos = 4 - temp;
+ }
+ else
+ lpos += 4;
+
+ out += 4;
+ }
+ else
+ {
+ line[out++] = c;
+ CHECK_LPOS();
+ }
+ }
+#if defined (DISPLAY_TABS)
+ else if (c == '\t')
+ {
+ register int newout;
+
+#if 0
+ newout = (out | (int)7) + 1;
+#else
+ newout = out + 8 - lpos % 8;
+#endif
+ temp = newout - out;
+ if (lpos + temp >= _rl_screenwidth)
+ {
+ register int temp2;
+ temp2 = _rl_screenwidth - lpos;
+ CHECK_INV_LBREAKS ();
+ inv_lbreaks[++newlines] = out + temp2;
+ lpos = temp - temp2;
+ while (out < newout)
+ line[out++] = ' ';
+ }
+ else
+ {
+ while (out < newout)
+ line[out++] = ' ';
+ lpos += temp;
+ }
+ }
+#endif
+ else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
+ {
+ line[out++] = '\0'; /* XXX - sentinel */
+ CHECK_INV_LBREAKS ();
+ inv_lbreaks[++newlines] = out;
+ lpos = 0;
+ }
+ else if (CTRL_CHAR (c) || c == RUBOUT)
+ {
+ line[out++] = '^';
+ CHECK_LPOS();
+ line[out++] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
+ CHECK_LPOS();
+ }
+ else
+ {
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ register int i;
+
+ _rl_wrapped_multicolumn = 0;
+
+ if (_rl_screenwidth < lpos + wc_width)
+ for (i = lpos; i < _rl_screenwidth; i++)
+ {
+ /* The space will be removed in update_line() */
+ line[out++] = ' ';
+ _rl_wrapped_multicolumn++;
+ CHECK_LPOS();
+ }
+ if (in == rl_point)
+ {
+ cpos_buffer_position = out;
+ lb_linenum = newlines;
+ }
+ for (i = in; i < in+wc_bytes; i++)
+ line[out++] = rl_line_buffer[i];
+ for (i = 0; i < wc_width; i++)
+ CHECK_LPOS();
+ }
+ else
+ {
+ line[out++] = c;
+ CHECK_LPOS();
+ }
+#else
+ line[out++] = c;
+ CHECK_LPOS();
+#endif
+ }
+
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ in += wc_bytes;
+ /* XXX - what if wc_bytes ends up <= 0? check for MB_INVALIDCH */
+ wc_bytes = mbrtowc (&wc, rl_line_buffer + in, rl_end - in, &ps);
+ }
+ else
+ in++;
+#endif
+
+ }
+ line[out] = '\0';
+ if (cpos_buffer_position < 0)
+ {
+ cpos_buffer_position = out;
+ lb_linenum = newlines;
+ }
+
+ inv_botlin = lb_botlin = newlines;
+ CHECK_INV_LBREAKS ();
+ inv_lbreaks[newlines+1] = out;
+ cursor_linenum = lb_linenum;
+
+ /* CPOS_BUFFER_POSITION == position in buffer where cursor should be placed.
+ CURSOR_LINENUM == line number where the cursor should be placed. */
+
+ /* PWP: now is when things get a bit hairy. The visible and invisible
+ line buffers are really multiple lines, which would wrap every
+ (screenwidth - 1) characters. Go through each in turn, finding
+ the changed region and updating it. The line order is top to bottom. */
+
+ /* If we can move the cursor up and down, then use multiple lines,
+ otherwise, let long lines display in a single terminal line, and
+ horizontally scroll it. */
+
+ if (_rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
+ {
+ int nleft, pos, changed_screen_line, tx;
+
+ if (!rl_display_fixed || forced_display)
+ {
+ forced_display = 0;
+
+ /* If we have more than a screenful of material to display, then
+ only display a screenful. We should display the last screen,
+ not the first. */
+ if (out >= _rl_screenchars)
+ {
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ out = _rl_find_prev_mbchar (line, _rl_screenchars, MB_FIND_ANY);
+ else
+ out = _rl_screenchars - 1;
+ }
+
+ /* The first line is at character position 0 in the buffer. The
+ second and subsequent lines start at inv_lbreaks[N], offset by
+ OFFSET (which has already been calculated above). */
+
+#define INVIS_FIRST() (prompt_physical_chars > _rl_screenwidth ? prompt_invis_chars_first_line : wrap_offset)
+#define WRAP_OFFSET(line, offset) ((line == 0) \
+ ? (offset ? INVIS_FIRST() : 0) \
+ : ((line == prompt_last_screen_line) ? wrap_offset-prompt_invis_chars_first_line : 0))
+#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
+#define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
+#define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l])
+#define VIS_CHARS(line) (visible_line + vis_lbreaks[line])
+#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
+#define INV_LINE(line) (invisible_line + inv_lbreaks[line])
+
+#define OLD_CPOS_IN_PROMPT() (cpos_adjusted == 0 && \
+ _rl_last_c_pos != o_cpos && \
+ _rl_last_c_pos > wrap_offset && \
+ o_cpos < prompt_last_invisible)
+
+ /* For each line in the buffer, do the updating display. */
+ for (linenum = 0; linenum <= inv_botlin; linenum++)
+ {
+ /* This can lead us astray if we execute a program that changes
+ the locale from a non-multibyte to a multibyte one. */
+ o_cpos = _rl_last_c_pos;
+ cpos_adjusted = 0;
+ update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum,
+ VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin);
+
+ /* update_line potentially changes _rl_last_c_pos, but doesn't
+ take invisible characters into account, since _rl_last_c_pos
+ is an absolute cursor position in a multibyte locale. See
+ if compensating here is the right thing, or if we have to
+ change update_line itself. There are several cases in which
+ update_line adjusts _rl_last_c_pos itself (so it can pass
+ _rl_move_cursor_relative accurate values); it communicates
+ this back by setting cpos_adjusted. If we assume that
+ _rl_last_c_pos is correct (an absolute cursor position) each
+ time update_line is called, then we can assume in our
+ calculations that o_cpos does not need to be adjusted by
+ wrap_offset. */
+ if (linenum == 0 && (MB_CUR_MAX > 1 && rl_byte_oriented == 0) && OLD_CPOS_IN_PROMPT())
+ _rl_last_c_pos -= prompt_invis_chars_first_line; /* XXX - was wrap_offset */
+ else if (linenum == prompt_last_screen_line && prompt_physical_chars > _rl_screenwidth &&
+ (MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
+ cpos_adjusted == 0 &&
+ _rl_last_c_pos != o_cpos &&
+ _rl_last_c_pos > (prompt_last_invisible - _rl_screenwidth - prompt_invis_chars_first_line))
+ _rl_last_c_pos -= (wrap_offset-prompt_invis_chars_first_line);
+
+ /* If this is the line with the prompt, we might need to
+ compensate for invisible characters in the new line. Do
+ this only if there is not more than one new line (which
+ implies that we completely overwrite the old visible line)
+ and the new line is shorter than the old. Make sure we are
+ at the end of the new line before clearing. */
+ if (linenum == 0 &&
+ inv_botlin == 0 && _rl_last_c_pos == out &&
+ (wrap_offset > visible_wrap_offset) &&
+ (_rl_last_c_pos < visible_first_line_len))
+ {
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ nleft = _rl_screenwidth - _rl_last_c_pos;
+ else
+ nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos;
+ if (nleft)
+ _rl_clear_to_eol (nleft);
+ }
+#if 0
+ /* This segment is intended to handle the case where the prompt
+ has invisible characters on the second line and the new line
+ to be displayed needs to clear the rest of the old characters
+ out (e.g., when printing the i-search prompt). In general,
+ the case of the new line being shorter than the old.
+ Incomplete */
+ else if (linenum == prompt_last_screen_line &&
+ prompt_physical_chars > _rl_screenwidth &&
+ wrap_offset != prompt_invis_chars_first_line &&
+ _rl_last_c_pos == out &&
+#endif
+
+
+ /* Since the new first line is now visible, save its length. */
+ if (linenum == 0)
+ visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset;
+ }
+
+ /* We may have deleted some lines. If so, clear the left over
+ blank ones at the bottom out. */
+ if (_rl_vis_botlin > inv_botlin)
+ {
+ char *tt;
+ for (; linenum <= _rl_vis_botlin; linenum++)
+ {
+ tt = VIS_CHARS (linenum);
+ _rl_move_vert (linenum);
+ _rl_move_cursor_relative (0, tt);
+ _rl_clear_to_eol
+ ((linenum == _rl_vis_botlin) ? strlen (tt) : _rl_screenwidth);
+ }
+ }
+ _rl_vis_botlin = inv_botlin;
+
+ /* CHANGED_SCREEN_LINE is set to 1 if we have moved to a
+ different screen line during this redisplay. */
+ changed_screen_line = _rl_last_v_pos != cursor_linenum;
+ if (changed_screen_line)
+ {
+ _rl_move_vert (cursor_linenum);
+ /* If we moved up to the line with the prompt using _rl_term_up,
+ the physical cursor position on the screen stays the same,
+ but the buffer position needs to be adjusted to account
+ for invisible characters. */
+ if ((MB_CUR_MAX == 1 || rl_byte_oriented) && cursor_linenum == 0 && wrap_offset)
+ _rl_last_c_pos += wrap_offset;
+ }
+
+ /* We have to reprint the prompt if it contains invisible
+ characters, since it's not generally OK to just reprint
+ the characters from the current cursor position. But we
+ only need to reprint it if the cursor is before the last
+ invisible character in the prompt string. */
+ nleft = prompt_visible_length + wrap_offset;
+ if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&
+#if 0
+ _rl_last_c_pos <= PROMPT_ENDING_INDEX && local_prompt)
+#else
+ _rl_last_c_pos < PROMPT_ENDING_INDEX && local_prompt)
+#endif
+ {
+#if defined (__MSDOS__)
+ putc ('\r', rl_outstream);
+#else
+ if (_rl_term_cr)
+ tputs (_rl_term_cr, 1, _rl_output_character_function);
+#endif
+ if (modmark)
+ _rl_output_some_chars ("*", 1);
+
+ _rl_output_some_chars (local_prompt, nleft);
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ _rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft) - wrap_offset + modmark;
+ else
+ _rl_last_c_pos = nleft + modmark;
+ }
+
+ /* Where on that line? And where does that line start
+ in the buffer? */
+ pos = inv_lbreaks[cursor_linenum];
+ /* nleft == number of characters in the line buffer between the
+ start of the line and the desired cursor position. */
+ nleft = cpos_buffer_position - pos;
+
+ /* NLEFT is now a number of characters in a buffer. When in a
+ multibyte locale, however, _rl_last_c_pos is an absolute cursor
+ position that doesn't take invisible characters in the prompt
+ into account. We use a fudge factor to compensate. */
+
+ /* Since _rl_backspace() doesn't know about invisible characters in the
+ prompt, and there's no good way to tell it, we compensate for
+ those characters here and call _rl_backspace() directly. */
+ if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
+ {
+ /* TX == new physical cursor position in multibyte locale. */
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ tx = _rl_col_width (&visible_line[pos], 0, nleft) - visible_wrap_offset;
+ else
+ tx = nleft;
+ if (tx >= 0 && _rl_last_c_pos > tx)
+ {
+ _rl_backspace (_rl_last_c_pos - tx); /* XXX */
+ _rl_last_c_pos = tx;
+ }
+ }
+
+ /* We need to note that in a multibyte locale we are dealing with
+ _rl_last_c_pos as an absolute cursor position, but moving to a
+ point specified by a buffer position (NLEFT) that doesn't take
+ invisible characters into account. */
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ _rl_move_cursor_relative (nleft, &invisible_line[pos]);
+ else if (nleft != _rl_last_c_pos)
+ _rl_move_cursor_relative (nleft, &invisible_line[pos]);
+ }
+ }
+ else /* Do horizontal scrolling. */
+ {
+#define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0)
+ int lmargin, ndisp, nleft, phys_c_pos, t;
+
+ /* Always at top line. */
+ _rl_last_v_pos = 0;
+
+ /* Compute where in the buffer the displayed line should start. This
+ will be LMARGIN. */
+
+ /* The number of characters that will be displayed before the cursor. */
+ ndisp = cpos_buffer_position - wrap_offset;
+ nleft = prompt_visible_length + wrap_offset;
+ /* Where the new cursor position will be on the screen. This can be
+ longer than SCREENWIDTH; if it is, lmargin will be adjusted. */
+ phys_c_pos = cpos_buffer_position - (last_lmargin ? last_lmargin : wrap_offset);
+ t = _rl_screenwidth / 3;
+
+ /* If the number of characters had already exceeded the screenwidth,
+ last_lmargin will be > 0. */
+
+ /* If the number of characters to be displayed is more than the screen
+ width, compute the starting offset so that the cursor is about
+ two-thirds of the way across the screen. */
+ if (phys_c_pos > _rl_screenwidth - 2)
+ {
+ lmargin = cpos_buffer_position - (2 * t);
+ if (lmargin < 0)
+ lmargin = 0;
+ /* If the left margin would be in the middle of a prompt with
+ invisible characters, don't display the prompt at all. */
+ if (wrap_offset && lmargin > 0 && lmargin < nleft)
+ lmargin = nleft;
+ }
+ else if (ndisp < _rl_screenwidth - 2) /* XXX - was -1 */
+ lmargin = 0;
+ else if (phys_c_pos < 1)
+ {
+ /* If we are moving back towards the beginning of the line and
+ the last margin is no longer correct, compute a new one. */
+ lmargin = ((cpos_buffer_position - 1) / t) * t; /* XXX */
+ if (wrap_offset && lmargin > 0 && lmargin < nleft)
+ lmargin = nleft;
+ }
+ else
+ lmargin = last_lmargin;
+
+ /* If the first character on the screen isn't the first character
+ in the display line, indicate this with a special character. */
+ if (lmargin > 0)
+ line[lmargin] = '<';
+
+ /* If SCREENWIDTH characters starting at LMARGIN do not encompass
+ the whole line, indicate that with a special character at the
+ right edge of the screen. If LMARGIN is 0, we need to take the
+ wrap offset into account. */
+ t = lmargin + M_OFFSET (lmargin, wrap_offset) + _rl_screenwidth;
+ if (t < out)
+ line[t - 1] = '>';
+
+ if (rl_display_fixed == 0 || forced_display || lmargin != last_lmargin)
+ {
+ forced_display = 0;
+ o_cpos = _rl_last_c_pos;
+ cpos_adjusted = 0;
+ update_line (&visible_line[last_lmargin],
+ &invisible_line[lmargin],
+ 0,
+ _rl_screenwidth + visible_wrap_offset,
+ _rl_screenwidth + (lmargin ? 0 : wrap_offset),
+ 0);
+
+ if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && OLD_CPOS_IN_PROMPT())
+ _rl_last_c_pos -= prompt_invis_chars_first_line; /* XXX - was wrap_offset */
+
+ /* If the visible new line is shorter than the old, but the number
+ of invisible characters is greater, and we are at the end of
+ the new line, we need to clear to eol. */
+ t = _rl_last_c_pos - M_OFFSET (lmargin, wrap_offset);
+ if ((M_OFFSET (lmargin, wrap_offset) > visible_wrap_offset) &&
+ (_rl_last_c_pos == out) &&
+ t < visible_first_line_len)
+ {
+ nleft = _rl_screenwidth - t;
+ _rl_clear_to_eol (nleft);
+ }
+ visible_first_line_len = out - lmargin - M_OFFSET (lmargin, wrap_offset);
+ if (visible_first_line_len > _rl_screenwidth)
+ visible_first_line_len = _rl_screenwidth;
+
+ _rl_move_cursor_relative (cpos_buffer_position - lmargin, &invisible_line[lmargin]);
+ last_lmargin = lmargin;
+ }
+ }
+ fflush (rl_outstream);
+
+ /* Swap visible and non-visible lines. */
+ {
+ struct line_state *vtemp = line_state_visible;
+
+ line_state_visible = line_state_invisible;
+ line_state_invisible = vtemp;
+
+ rl_display_fixed = 0;
+ /* If we are displaying on a single line, and last_lmargin is > 0, we
+ are not displaying any invisible characters, so set visible_wrap_offset
+ to 0. */
+ if (_rl_horizontal_scroll_mode && last_lmargin)
+ visible_wrap_offset = 0;
+ else
+ visible_wrap_offset = wrap_offset;
+ }
+
+ RL_UNSETSTATE (RL_STATE_REDISPLAYING);
+ _rl_release_sigint ();
+}
+
+/* PWP: update_line() is based on finding the middle difference of each
+ line on the screen; vis:
+
+ /old first difference
+ /beginning of line | /old last same /old EOL
+ v v v v
+old: eddie> Oh, my little gruntle-buggy is to me, as lurgid as
+new: eddie> Oh, my little buggy says to me, as lurgid as
+ ^ ^ ^ ^
+ \beginning of line | \new last same \new end of line
+ \new first difference
+
+ All are character pointers for the sake of speed. Special cases for
+ no differences, as well as for end of line additions must be handled.
+
+ Could be made even smarter, but this works well enough */
+static void
+update_line (old, new, current_line, omax, nmax, inv_botlin)
+ register char *old, *new;
+ int current_line, omax, nmax, inv_botlin;
+{
+ register char *ofd, *ols, *oe, *nfd, *nls, *ne;
+ int temp, lendiff, wsatend, od, nd, twidth, o_cpos;
+ int current_invis_chars;
+ int col_lendiff, col_temp;
+#if defined (HANDLE_MULTIBYTE)
+ mbstate_t ps_new, ps_old;
+ int new_offset, old_offset;
+#endif
+
+ /* If we're at the right edge of a terminal that supports xn, we're
+ ready to wrap around, so do so. This fixes problems with knowing
+ the exact cursor position and cut-and-paste with certain terminal
+ emulators. In this calculation, TEMP is the physical screen
+ position of the cursor. */
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ temp = _rl_last_c_pos;
+ else
+ temp = _rl_last_c_pos - WRAP_OFFSET (_rl_last_v_pos, visible_wrap_offset);
+ if (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode
+ && _rl_last_v_pos == current_line - 1)
+ {
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ wchar_t wc;
+ mbstate_t ps;
+ int tempwidth, bytes;
+ size_t ret;
+
+ /* This fixes only double-column characters, but if the wrapped
+ character comsumes more than three columns, spaces will be
+ inserted in the string buffer. */
+ if (current_line < line_state_visible->wbsize && line_state_visible->wrapped_line[current_line] > 0)
+ _rl_clear_to_eol (line_state_visible->wrapped_line[current_line]);
+
+ memset (&ps, 0, sizeof (mbstate_t));
+ ret = mbrtowc (&wc, new, MB_CUR_MAX, &ps);
+ if (MB_INVALIDCH (ret))
+ {
+ tempwidth = 1;
+ ret = 1;
+ }
+ else if (MB_NULLWCH (ret))
+ tempwidth = 0;
+ else
+ tempwidth = wcwidth (wc);
+
+ if (tempwidth > 0)
+ {
+ int count, i;
+ bytes = ret;
+ for (count = 0; count < bytes; count++)
+ putc (new[count], rl_outstream);
+ _rl_last_c_pos = tempwidth;
+ _rl_last_v_pos++;
+ memset (&ps, 0, sizeof (mbstate_t));
+ ret = mbrtowc (&wc, old, MB_CUR_MAX, &ps);
+ if (ret != 0 && bytes != 0)
+ {
+ if (MB_INVALIDCH (ret))
+ ret = 1;
+ memmove (old+bytes, old+ret, strlen (old+ret));
+ memcpy (old, new, bytes);
+ /* Fix up indices if we copy data from one line to another */
+ omax += bytes - ret;
+ for (i = current_line+1; i < inv_botlin+1; i++)
+ vis_lbreaks[i] += bytes - ret;
+ }
+ }
+ else
+ {
+ putc (' ', rl_outstream);
+ _rl_last_c_pos = 1;
+ _rl_last_v_pos++;
+ if (old[0] && new[0])
+ old[0] = new[0];
+ }
+ }
+ else
+#endif
+ {
+ if (new[0])
+ putc (new[0], rl_outstream);
+ else
+ putc (' ', rl_outstream);
+ _rl_last_c_pos = 1;
+ _rl_last_v_pos++;
+ if (old[0] && new[0])
+ old[0] = new[0];
+ }
+ }
+
+
+ /* Find first difference. */
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ /* See if the old line is a subset of the new line, so that the
+ only change is adding characters. */
+ temp = (omax < nmax) ? omax : nmax;
+ if (memcmp (old, new, temp) == 0) /* adding at the end */
+ {
+ ofd = old + temp;
+ nfd = new + temp;
+ }
+ else
+ {
+ memset (&ps_new, 0, sizeof(mbstate_t));
+ memset (&ps_old, 0, sizeof(mbstate_t));
+
+ if (omax == nmax && STREQN (new, old, omax))
+ {
+ ofd = old + omax;
+ nfd = new + nmax;
+ }
+ else
+ {
+ new_offset = old_offset = 0;
+ for (ofd = old, nfd = new;
+ (ofd - old < omax) && *ofd &&
+ _rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new); )
+ {
+ old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY);
+ new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY);
+ ofd = old + old_offset;
+ nfd = new + new_offset;
+ }
+ }
+ }
+ }
+ else
+#endif
+ for (ofd = old, nfd = new;
+ (ofd - old < omax) && *ofd && (*ofd == *nfd);
+ ofd++, nfd++)
+ ;
+
+ /* Move to the end of the screen line. ND and OD are used to keep track
+ of the distance between ne and new and oe and old, respectively, to
+ move a subtraction out of each loop. */
+ for (od = ofd - old, oe = ofd; od < omax && *oe; oe++, od++);
+ for (nd = nfd - new, ne = nfd; nd < nmax && *ne; ne++, nd++);
+
+ /* If no difference, continue to next line. */
+ if (ofd == oe && nfd == ne)
+ return;
+
+ wsatend = 1; /* flag for trailing whitespace */
+
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ ols = old + _rl_find_prev_mbchar (old, oe - old, MB_FIND_ANY);
+ nls = new + _rl_find_prev_mbchar (new, ne - new, MB_FIND_ANY);
+ while ((ols > ofd) && (nls > nfd))
+ {
+ memset (&ps_old, 0, sizeof (mbstate_t));
+ memset (&ps_new, 0, sizeof (mbstate_t));
+
+#if 0
+ /* On advice from jir@yamato.ibm.com */
+ _rl_adjust_point (old, ols - old, &ps_old);
+ _rl_adjust_point (new, nls - new, &ps_new);
+#endif
+
+ if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0)
+ break;
+
+ if (*ols == ' ')
+ wsatend = 0;
+
+ ols = old + _rl_find_prev_mbchar (old, ols - old, MB_FIND_ANY);
+ nls = new + _rl_find_prev_mbchar (new, nls - new, MB_FIND_ANY);
+ }
+ }
+ else
+ {
+#endif /* HANDLE_MULTIBYTE */
+ ols = oe - 1; /* find last same */
+ nls = ne - 1;
+ while ((ols > ofd) && (nls > nfd) && (*ols == *nls))
+ {
+ if (*ols != ' ')
+ wsatend = 0;
+ ols--;
+ nls--;
+ }
+#if defined (HANDLE_MULTIBYTE)
+ }
+#endif
+
+ if (wsatend)
+ {
+ ols = oe;
+ nls = ne;
+ }
+#if defined (HANDLE_MULTIBYTE)
+ /* This may not work for stateful encoding, but who cares? To handle
+ stateful encoding properly, we have to scan each string from the
+ beginning and compare. */
+ else if (_rl_compare_chars (ols, 0, NULL, nls, 0, NULL) == 0)
+#else
+ else if (*ols != *nls)
+#endif
+ {
+ if (*ols) /* don't step past the NUL */
+ {
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ ols = old + _rl_find_next_mbchar (old, ols - old, 1, MB_FIND_ANY);
+ else
+ ols++;
+ }
+ if (*nls)
+ {
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ nls = new + _rl_find_next_mbchar (new, nls - new, 1, MB_FIND_ANY);
+ else
+ nls++;
+ }
+ }
+
+ /* count of invisible characters in the current invisible line. */
+ current_invis_chars = W_OFFSET (current_line, wrap_offset);
+ if (_rl_last_v_pos != current_line)
+ {
+ _rl_move_vert (current_line);
+ if ((MB_CUR_MAX == 1 || rl_byte_oriented) && current_line == 0 && visible_wrap_offset)
+ _rl_last_c_pos += visible_wrap_offset;
+ }
+
+ /* If this is the first line and there are invisible characters in the
+ prompt string, and the prompt string has not changed, and the current
+ cursor position is before the last invisible character in the prompt,
+ and the index of the character to move to is past the end of the prompt
+ string, then redraw the entire prompt string. We can only do this
+ reliably if the terminal supports a `cr' capability.
+
+ This is not an efficiency hack -- there is a problem with redrawing
+ portions of the prompt string if they contain terminal escape
+ sequences (like drawing the `unbold' sequence without a corresponding
+ `bold') that manifests itself on certain terminals. */
+
+ lendiff = local_prompt_len;
+ od = ofd - old; /* index of first difference in visible line */
+ if (current_line == 0 && !_rl_horizontal_scroll_mode &&
+ _rl_term_cr && lendiff > prompt_visible_length && _rl_last_c_pos > 0 &&
+ od >= lendiff && _rl_last_c_pos < PROMPT_ENDING_INDEX)
+ {
+#if defined (__MSDOS__)
+ putc ('\r', rl_outstream);
+#else
+ tputs (_rl_term_cr, 1, _rl_output_character_function);
+#endif
+ if (modmark)
+ _rl_output_some_chars ("*", 1);
+ _rl_output_some_chars (local_prompt, lendiff);
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ /* We take wrap_offset into account here so we can pass correct
+ information to _rl_move_cursor_relative. */
+ _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff) - wrap_offset + modmark;
+ cpos_adjusted = 1;
+ }
+ else
+ _rl_last_c_pos = lendiff + modmark;
+ }
+
+ o_cpos = _rl_last_c_pos;
+
+ /* When this function returns, _rl_last_c_pos is correct, and an absolute
+ cursor postion in multibyte mode, but a buffer index when not in a
+ multibyte locale. */
+ _rl_move_cursor_relative (od, old);
+#if 1
+#if defined (HANDLE_MULTIBYTE)
+ /* We need to indicate that the cursor position is correct in the presence of
+ invisible characters in the prompt string. Let's see if setting this when
+ we make sure we're at the end of the drawn prompt string works. */
+ if (current_line == 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0 &&
+ (_rl_last_c_pos > 0 || o_cpos > 0) &&
+ _rl_last_c_pos == prompt_physical_chars)
+ cpos_adjusted = 1;
+#endif
+#endif
+
+ /* if (len (new) > len (old))
+ lendiff == difference in buffer
+ col_lendiff == difference on screen
+ When not using multibyte characters, these are equal */
+ lendiff = (nls - nfd) - (ols - ofd);
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ col_lendiff = _rl_col_width (new, nfd - new, nls - new) - _rl_col_width (old, ofd - old, ols - old);
+ else
+ col_lendiff = lendiff;
+
+ /* If we are changing the number of invisible characters in a line, and
+ the spot of first difference is before the end of the invisible chars,
+ lendiff needs to be adjusted. */
+ if (current_line == 0 && !_rl_horizontal_scroll_mode &&
+ current_invis_chars != visible_wrap_offset)
+ {
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ lendiff += visible_wrap_offset - current_invis_chars;
+ col_lendiff += visible_wrap_offset - current_invis_chars;
+ }
+ else
+ {
+ lendiff += visible_wrap_offset - current_invis_chars;
+ col_lendiff = lendiff;
+ }
+ }
+
+ /* Insert (diff (len (old), len (new)) ch. */
+ temp = ne - nfd;
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ col_temp = _rl_col_width (new, nfd - new, ne - new);
+ else
+ col_temp = temp;
+
+ if (col_lendiff > 0) /* XXX - was lendiff */
+ {
+ /* Non-zero if we're increasing the number of lines. */
+ int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
+ /* If col_lendiff is > 0, implying that the new string takes up more
+ screen real estate than the old, but lendiff is < 0, meaning that it
+ takes fewer bytes, we need to just output the characters starting
+ from the first difference. These will overwrite what is on the
+ display, so there's no reason to do a smart update. This can really
+ only happen in a multibyte environment. */
+ if (lendiff < 0)
+ {
+ _rl_output_some_chars (nfd, temp);
+ _rl_last_c_pos += _rl_col_width (nfd, 0, temp);
+ /* If nfd begins before any invisible characters in the prompt,
+ adjust _rl_last_c_pos to account for wrap_offset and set
+ cpos_adjusted to let the caller know. */
+ if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
+ {
+ _rl_last_c_pos -= wrap_offset;
+ cpos_adjusted = 1;
+ }
+ return;
+ }
+ /* Sometimes it is cheaper to print the characters rather than
+ use the terminal's capabilities. If we're growing the number
+ of lines, make sure we actually cause the new line to wrap
+ around on auto-wrapping terminals. */
+ else if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
+ {
+ /* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and
+ _rl_horizontal_scroll_mode == 1, inserting the characters with
+ _rl_term_IC or _rl_term_ic will screw up the screen because of the
+ invisible characters. We need to just draw them. */
+ /* The same thing happens if we're trying to draw before the last
+ invisible character in the prompt string or we're increasing the
+ number of invisible characters in the line and we're not drawing
+ the entire prompt string. */
+ if (*ols && ((_rl_horizontal_scroll_mode &&
+ _rl_last_c_pos == 0 &&
+ lendiff > prompt_visible_length &&
+ current_invis_chars > 0) == 0) &&
+ (((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
+ current_line == 0 && wrap_offset &&
+ ((nfd - new) <= prompt_last_invisible) &&
+ (col_lendiff < prompt_visible_length)) == 0) &&
+ (visible_wrap_offset >= current_invis_chars))
+ {
+ insert_some_chars (nfd, lendiff, col_lendiff);
+ _rl_last_c_pos += col_lendiff;
+ }
+#if 0 /* XXX - for now */
+ else if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && _rl_last_c_pos == 0 && wrap_offset && (nfd-new) <= prompt_last_invisible && col_lendiff < prompt_visible_length && visible_wrap_offset >= current_invis_chars)
+ {
+ _rl_output_some_chars (nfd, lendiff);
+ _rl_last_c_pos += col_lendiff;
+ }
+#endif
+ else if ((MB_CUR_MAX == 1 || rl_byte_oriented != 0) && *ols == 0 && lendiff > 0)
+ {
+ /* At the end of a line the characters do not have to
+ be "inserted". They can just be placed on the screen. */
+ /* However, this screws up the rest of this block, which
+ assumes you've done the insert because you can. */
+ _rl_output_some_chars (nfd, lendiff);
+ _rl_last_c_pos += col_lendiff;
+ }
+ else
+ {
+ _rl_output_some_chars (nfd, temp);
+ _rl_last_c_pos += col_temp;
+ /* If nfd begins before the last invisible character in the
+ prompt, adjust _rl_last_c_pos to account for wrap_offset
+ and set cpos_adjusted to let the caller know. */
+ if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
+ {
+ _rl_last_c_pos -= wrap_offset;
+ cpos_adjusted = 1;
+ }
+ return;
+ }
+ /* Copy (new) chars to screen from first diff to last match. */
+ temp = nls - nfd;
+ if ((temp - lendiff) > 0)
+ {
+ _rl_output_some_chars (nfd + lendiff, temp - lendiff);
+ /* XXX -- this bears closer inspection. Fixes a redisplay bug
+ reported against bash-3.0-alpha by Andreas Schwab involving
+ multibyte characters and prompt strings with invisible
+ characters, but was previously disabled. */
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ twidth = _rl_col_width (nfd+lendiff, 0, temp-col_lendiff);
+ else
+ twidth = temp - lendiff;
+ _rl_last_c_pos += twidth;
+ /* If nfd begins before the last invisible character in the
+ prompt, adjust _rl_last_c_pos to account for wrap_offset
+ and set cpos_adjusted to let the caller know. */
+ if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
+ {
+ _rl_last_c_pos -= wrap_offset;
+ cpos_adjusted = 1;
+ }
+ }
+ }
+ else
+ {
+ /* cannot insert chars, write to EOL */
+ _rl_output_some_chars (nfd, temp);
+ _rl_last_c_pos += col_temp;
+ /* If we're in a multibyte locale and were before the last invisible
+ char in the current line (which implies we just output some invisible
+ characters) we need to adjust _rl_last_c_pos, since it represents
+ a physical character position. */
+ if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
+ current_line == prompt_last_screen_line && wrap_offset &&
+ wrap_offset != prompt_invis_chars_first_line &&
+ ((nfd-new) < (prompt_last_invisible-(current_line*_rl_screenwidth))))
+ {
+ _rl_last_c_pos -= wrap_offset - prompt_invis_chars_first_line;
+ cpos_adjusted = 1;
+ }
+ }
+ }
+ else /* Delete characters from line. */
+ {
+ /* If possible and inexpensive to use terminal deletion, then do so. */
+ if (_rl_term_dc && (2 * col_temp) >= -col_lendiff)
+ {
+ /* If all we're doing is erasing the invisible characters in the
+ prompt string, don't bother. It screws up the assumptions
+ about what's on the screen. */
+ if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 &&
+ -lendiff == visible_wrap_offset)
+ col_lendiff = 0;
+
+ if (col_lendiff)
+ delete_chars (-col_lendiff); /* delete (diff) characters */
+
+ /* Copy (new) chars to screen from first diff to last match */
+ temp = nls - nfd;
+ if (temp > 0)
+ {
+ /* If nfd begins at the prompt, or before the invisible
+ characters in the prompt, we need to adjust _rl_last_c_pos
+ in a multibyte locale to account for the wrap offset and
+ set cpos_adjusted accordingly. */
+ _rl_output_some_chars (nfd, temp);
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ _rl_last_c_pos += _rl_col_width (nfd, 0, temp);
+ if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
+ {
+ _rl_last_c_pos -= wrap_offset;
+ cpos_adjusted = 1;
+ }
+ }
+ else
+ _rl_last_c_pos += temp;
+ }
+ }
+ /* Otherwise, print over the existing material. */
+ else
+ {
+ if (temp > 0)
+ {
+ /* If nfd begins at the prompt, or before the invisible
+ characters in the prompt, we need to adjust _rl_last_c_pos
+ in a multibyte locale to account for the wrap offset and
+ set cpos_adjusted accordingly. */
+ _rl_output_some_chars (nfd, temp);
+ _rl_last_c_pos += col_temp; /* XXX */
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
+ {
+ _rl_last_c_pos -= wrap_offset;
+ cpos_adjusted = 1;
+ }
+ }
+ }
+ lendiff = (oe - old) - (ne - new);
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ col_lendiff = _rl_col_width (old, 0, oe - old) - _rl_col_width (new, 0, ne - new);
+ else
+ col_lendiff = lendiff;
+
+#if 0
+ if (col_lendiff)
+#else
+ /* If we've already printed over the entire width of the screen,
+ including the old material, then col_lendiff doesn't matter and
+ space_to_eol will insert too many spaces. XXX - maybe we should
+ adjust col_lendiff based on the difference between _rl_last_c_pos
+ and _rl_screenwidth */
+ if (col_lendiff && ((MB_CUR_MAX == 1 || rl_byte_oriented) || (_rl_last_c_pos < _rl_screenwidth)))
+#endif
+ {
+ if (_rl_term_autowrap && current_line < inv_botlin)
+ space_to_eol (col_lendiff);
+ else
+ _rl_clear_to_eol (col_lendiff);
+ }
+ }
+ }
+}
+
+/* Tell the update routines that we have moved onto a new (empty) line. */
+int
+rl_on_new_line ()
+{
+ if (visible_line)
+ visible_line[0] = '\0';
+
+ _rl_last_c_pos = _rl_last_v_pos = 0;
+ _rl_vis_botlin = last_lmargin = 0;
+ if (vis_lbreaks)
+ vis_lbreaks[0] = vis_lbreaks[1] = 0;
+ visible_wrap_offset = 0;
+ return 0;
+}
+
+/* Tell the update routines that we have moved onto a new line with the
+ prompt already displayed. Code originally from the version of readline
+ distributed with CLISP. rl_expand_prompt must have already been called
+ (explicitly or implicitly). This still doesn't work exactly right. */
+int
+rl_on_new_line_with_prompt ()
+{
+ int prompt_size, i, l, real_screenwidth, newlines;
+ char *prompt_last_line, *lprompt;
+
+ /* Initialize visible_line and invisible_line to ensure that they can hold
+ the already-displayed prompt. */
+ prompt_size = strlen (rl_prompt) + 1;
+ init_line_structures (prompt_size);
+
+ /* Make sure the line structures hold the already-displayed prompt for
+ redisplay. */
+ lprompt = local_prompt ? local_prompt : rl_prompt;
+ strcpy (visible_line, lprompt);
+ strcpy (invisible_line, lprompt);
+
+ /* If the prompt contains newlines, take the last tail. */
+ prompt_last_line = strrchr (rl_prompt, '\n');
+ if (!prompt_last_line)
+ prompt_last_line = rl_prompt;
+
+ l = strlen (prompt_last_line);
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ _rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l); /* XXX */
+ else
+ _rl_last_c_pos = l;
+
+ /* Dissect prompt_last_line into screen lines. Note that here we have
+ to use the real screenwidth. Readline's notion of screenwidth might be
+ one less, see terminal.c. */
+ real_screenwidth = _rl_screenwidth + (_rl_term_autowrap ? 0 : 1);
+ _rl_last_v_pos = l / real_screenwidth;
+ /* If the prompt length is a multiple of real_screenwidth, we don't know
+ whether the cursor is at the end of the last line, or already at the
+ beginning of the next line. Output a newline just to be safe. */
+ if (l > 0 && (l % real_screenwidth) == 0)
+ _rl_output_some_chars ("\n", 1);
+ last_lmargin = 0;
+
+ newlines = 0; i = 0;
+ while (i <= l)
+ {
+ _rl_vis_botlin = newlines;
+ vis_lbreaks[newlines++] = i;
+ i += real_screenwidth;
+ }
+ vis_lbreaks[newlines] = l;
+ visible_wrap_offset = 0;
+
+ rl_display_prompt = rl_prompt; /* XXX - make sure it's set */
+
+ return 0;
+}
+
+/* Actually update the display, period. */
+int
+rl_forced_update_display ()
+{
+ register char *temp;
+
+ if (visible_line)
+ {
+ temp = visible_line;
+ while (*temp)
+ *temp++ = '\0';
+ }
+ rl_on_new_line ();
+ forced_display++;
+ (*rl_redisplay_function) ();
+ return 0;
+}
+
+/* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices.
+ (Well, when we don't have multibyte characters, _rl_last_c_pos is a
+ buffer index.)
+ DATA is the contents of the screen line of interest; i.e., where
+ the movement is being done. */
+void
+_rl_move_cursor_relative (new, data)
+ int new;
+ const char *data;
+{
+ register int i;
+ int woff; /* number of invisible chars on current line */
+ int cpos, dpos; /* current and desired cursor positions */
+ int adjust;
+
+ woff = WRAP_OFFSET (_rl_last_v_pos, wrap_offset);
+ cpos = _rl_last_c_pos;
+
+ if (cpos == 0 && cpos == new)
+ return;
+
+#if defined (HANDLE_MULTIBYTE)
+ /* If we have multibyte characters, NEW is indexed by the buffer point in
+ a multibyte string, but _rl_last_c_pos is the display position. In
+ this case, NEW's display position is not obvious and must be
+ calculated. We need to account for invisible characters in this line,
+ as long as we are past them and they are counted by _rl_col_width. */
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ adjust = 1;
+ /* Try to short-circuit common cases and eliminate a bunch of multibyte
+ character function calls. */
+ /* 1. prompt string */
+ if (new == local_prompt_len && memcmp (data, local_prompt, new) == 0)
+ {
+ dpos = prompt_visible_length;
+ cpos_adjusted = 1;
+ adjust = 0;
+ }
+ /* 2. prompt_string + line contents */
+ else if (new > local_prompt_len && local_prompt && memcmp (data, local_prompt, local_prompt_len) == 0)
+ {
+ dpos = prompt_visible_length + _rl_col_width (data, local_prompt_len, new);
+ cpos_adjusted = 1;
+ adjust = 0;
+ }
+ else
+ dpos = _rl_col_width (data, 0, new);
+
+ /* Use NEW when comparing against the last invisible character in the
+ prompt string, since they're both buffer indices and DPOS is a
+ desired display position. */
+ if (adjust && ((new > prompt_last_invisible) || /* XXX - don't use woff here */
+ (prompt_physical_chars >= _rl_screenwidth &&
+ _rl_last_v_pos == prompt_last_screen_line &&
+ wrap_offset >= woff && dpos >= woff &&
+ new > (prompt_last_invisible-(_rl_screenwidth*_rl_last_v_pos)-wrap_offset))))
+ /* XXX last comparison might need to be >= */
+ {
+ dpos -= woff;
+ /* Since this will be assigned to _rl_last_c_pos at the end (more
+ precisely, _rl_last_c_pos == dpos when this function returns),
+ let the caller know. */
+ cpos_adjusted = 1;
+ }
+ }
+ else
+#endif
+ dpos = new;
+
+ /* If we don't have to do anything, then return. */
+ if (cpos == dpos)
+ return;
+
+ /* It may be faster to output a CR, and then move forwards instead
+ of moving backwards. */
+ /* i == current physical cursor position. */
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ i = _rl_last_c_pos;
+ else
+#endif
+ i = _rl_last_c_pos - woff;
+ if (dpos == 0 || CR_FASTER (dpos, _rl_last_c_pos) ||
+ (_rl_term_autowrap && i == _rl_screenwidth))
+ {
+#if defined (__MSDOS__)
+ putc ('\r', rl_outstream);
+#else
+ tputs (_rl_term_cr, 1, _rl_output_character_function);
+#endif /* !__MSDOS__ */
+ cpos = _rl_last_c_pos = 0;
+ }
+
+ if (cpos < dpos)
+ {
+ /* Move the cursor forward. We do it by printing the command
+ to move the cursor forward if there is one, else print that
+ portion of the output buffer again. Which is cheaper? */
+
+ /* The above comment is left here for posterity. It is faster
+ to print one character (non-control) than to print a control
+ sequence telling the terminal to move forward one character.
+ That kind of control is for people who don't know what the
+ data is underneath the cursor. */
+
+ /* However, we need a handle on where the current display position is
+ in the buffer for the immediately preceding comment to be true.
+ In multibyte locales, we don't currently have that info available.
+ Without it, we don't know where the data we have to display begins
+ in the buffer and we have to go back to the beginning of the screen
+ line. In this case, we can use the terminal sequence to move forward
+ if it's available. */
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ if (_rl_term_forward_char)
+ {
+ for (i = cpos; i < dpos; i++)
+ tputs (_rl_term_forward_char, 1, _rl_output_character_function);
+ }
+ else
+ {
+ tputs (_rl_term_cr, 1, _rl_output_character_function);
+ for (i = 0; i < new; i++)
+ putc (data[i], rl_outstream);
+ }
+ }
+ else
+ for (i = cpos; i < new; i++)
+ putc (data[i], rl_outstream);
+ }
+
+#if defined (HANDLE_MULTIBYTE)
+ /* NEW points to the buffer point, but _rl_last_c_pos is the display point.
+ The byte length of the string is probably bigger than the column width
+ of the string, which means that if NEW == _rl_last_c_pos, then NEW's
+ display point is less than _rl_last_c_pos. */
+#endif
+ else if (cpos > dpos)
+ _rl_backspace (cpos - dpos);
+
+ _rl_last_c_pos = dpos;
+}
+
+/* PWP: move the cursor up or down. */
+void
+_rl_move_vert (to)
+ int to;
+{
+ register int delta, i;
+
+ if (_rl_last_v_pos == to || to > _rl_screenheight)
+ return;
+
+ if ((delta = to - _rl_last_v_pos) > 0)
+ {
+ for (i = 0; i < delta; i++)
+ putc ('\n', rl_outstream);
+#if defined (__MSDOS__)
+ putc ('\r', rl_outstream);
+#else
+ tputs (_rl_term_cr, 1, _rl_output_character_function);
+#endif
+ _rl_last_c_pos = 0;
+ }
+ else
+ { /* delta < 0 */
+ if (_rl_term_up && *_rl_term_up)
+ for (i = 0; i < -delta; i++)
+ tputs (_rl_term_up, 1, _rl_output_character_function);
+ }
+
+ _rl_last_v_pos = to; /* Now TO is here */
+}
+
+/* Physically print C on rl_outstream. This is for functions which know
+ how to optimize the display. Return the number of characters output. */
+int
+rl_show_char (c)
+ int c;
+{
+ int n = 1;
+ if (META_CHAR (c) && (_rl_output_meta_chars == 0))
+ {
+ fprintf (rl_outstream, "M-");
+ n += 2;
+ c = UNMETA (c);
+ }
+
+#if defined (DISPLAY_TABS)
+ if ((CTRL_CHAR (c) && c != '\t') || c == RUBOUT)
+#else
+ if (CTRL_CHAR (c) || c == RUBOUT)
+#endif /* !DISPLAY_TABS */
+ {
+ fprintf (rl_outstream, "C-");
+ n += 2;
+ c = CTRL_CHAR (c) ? UNCTRL (c) : '?';
+ }
+
+ putc (c, rl_outstream);
+ fflush (rl_outstream);
+ return n;
+}
+
+int
+rl_character_len (c, pos)
+ register int c, pos;
+{
+ unsigned char uc;
+
+ uc = (unsigned char)c;
+
+ if (META_CHAR (uc))
+ return ((_rl_output_meta_chars == 0) ? 4 : 1);
+
+ if (uc == '\t')
+ {
+#if defined (DISPLAY_TABS)
+ return (((pos | 7) + 1) - pos);
+#else
+ return (2);
+#endif /* !DISPLAY_TABS */
+ }
+
+ if (CTRL_CHAR (c) || c == RUBOUT)
+ return (2);
+
+ return ((ISPRINT (uc)) ? 1 : 2);
+}
+/* How to print things in the "echo-area". The prompt is treated as a
+ mini-modeline. */
+static int msg_saved_prompt = 0;
+
+#if defined (USE_VARARGS)
+int
+#if defined (PREFER_STDARG)
+rl_message (const char *format, ...)
+#else
+rl_message (va_alist)
+ va_dcl
+#endif
+{
+ va_list args;
+#if defined (PREFER_VARARGS)
+ char *format;
+#endif
+
+#if defined (PREFER_STDARG)
+ va_start (args, format);
+#else
+ va_start (args);
+ format = va_arg (args, char *);
+#endif
+
+#if defined (HAVE_VSNPRINTF)
+ vsnprintf (msg_buf, sizeof (msg_buf) - 1, format, args);
+#else
+ vsprintf (msg_buf, format, args);
+ msg_buf[sizeof(msg_buf) - 1] = '\0'; /* overflow? */
+#endif
+ va_end (args);
+
+ if (saved_local_prompt == 0)
+ {
+ rl_save_prompt ();
+ msg_saved_prompt = 1;
+ }
+ rl_display_prompt = msg_buf;
+ local_prompt = expand_prompt (msg_buf, &prompt_visible_length,
+ &prompt_last_invisible,
+ &prompt_invis_chars_first_line,
+ &prompt_physical_chars);
+ local_prompt_prefix = (char *)NULL;
+ local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
+ (*rl_redisplay_function) ();
+
+ return 0;
+}
+#else /* !USE_VARARGS */
+int
+rl_message (format, arg1, arg2)
+ char *format;
+{
+ sprintf (msg_buf, format, arg1, arg2);
+ msg_buf[sizeof(msg_buf) - 1] = '\0'; /* overflow? */
+
+ rl_display_prompt = msg_buf;
+ if (saved_local_prompt == 0)
+ {
+ rl_save_prompt ();
+ msg_saved_prompt = 1;
+ }
+ local_prompt = expand_prompt (msg_buf, &prompt_visible_length,
+ &prompt_last_invisible,
+ &prompt_invis_chars_first_line,
+ &prompt_physical_chars);
+ local_prompt_prefix = (char *)NULL;
+ local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
+ (*rl_redisplay_function) ();
+
+ return 0;
+}
+#endif /* !USE_VARARGS */
+
+/* How to clear things from the "echo-area". */
+int
+rl_clear_message ()
+{
+ rl_display_prompt = rl_prompt;
+ if (msg_saved_prompt)
+ {
+ rl_restore_prompt ();
+ msg_saved_prompt = 0;
+ }
+ (*rl_redisplay_function) ();
+ return 0;
+}
+
+int
+rl_reset_line_state ()
+{
+ rl_on_new_line ();
+
+ rl_display_prompt = rl_prompt ? rl_prompt : "";
+ forced_display = 1;
+ return 0;
+}
+
+void
+rl_save_prompt ()
+{
+ saved_local_prompt = local_prompt;
+ saved_local_prefix = local_prompt_prefix;
+ saved_prefix_length = prompt_prefix_length;
+ saved_local_length = local_prompt_len;
+ saved_last_invisible = prompt_last_invisible;
+ saved_visible_length = prompt_visible_length;
+ saved_invis_chars_first_line = prompt_invis_chars_first_line;
+ saved_physical_chars = prompt_physical_chars;
+
+ local_prompt = local_prompt_prefix = (char *)0;
+ local_prompt_len = 0;
+ prompt_last_invisible = prompt_visible_length = prompt_prefix_length = 0;
+ prompt_invis_chars_first_line = prompt_physical_chars = 0;
+}
+
+void
+rl_restore_prompt ()
+{
+ FREE (local_prompt);
+ FREE (local_prompt_prefix);
+
+ local_prompt = saved_local_prompt;
+ local_prompt_prefix = saved_local_prefix;
+ local_prompt_len = saved_local_length;
+ prompt_prefix_length = saved_prefix_length;
+ prompt_last_invisible = saved_last_invisible;
+ prompt_visible_length = saved_visible_length;
+ prompt_invis_chars_first_line = saved_invis_chars_first_line;
+ prompt_physical_chars = saved_physical_chars;
+
+ /* can test saved_local_prompt to see if prompt info has been saved. */
+ saved_local_prompt = saved_local_prefix = (char *)0;
+ saved_local_length = 0;
+ saved_last_invisible = saved_visible_length = saved_prefix_length = 0;
+ saved_invis_chars_first_line = saved_physical_chars = 0;
+}
+
+char *
+_rl_make_prompt_for_search (pchar)
+ int pchar;
+{
+ int len;
+ char *pmt, *p;
+
+ rl_save_prompt ();
+
+ /* We've saved the prompt, and can do anything with the various prompt
+ strings we need before they're restored. We want the unexpanded
+ portion of the prompt string after any final newline. */
+ p = rl_prompt ? strrchr (rl_prompt, '\n') : 0;
+ if (p == 0)
+ {
+ len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
+ pmt = (char *)xmalloc (len + 2);
+ if (len)
+ strcpy (pmt, rl_prompt);
+ pmt[len] = pchar;
+ pmt[len+1] = '\0';
+ }
+ else
+ {
+ p++;
+ len = strlen (p);
+ pmt = (char *)xmalloc (len + 2);
+ if (len)
+ strcpy (pmt, p);
+ pmt[len] = pchar;
+ pmt[len+1] = '\0';
+ }
+
+ /* will be overwritten by expand_prompt, called from rl_message */
+ prompt_physical_chars = saved_physical_chars + 1;
+ return pmt;
+}
+
+/* Quick redisplay hack when erasing characters at the end of the line. */
+void
+_rl_erase_at_end_of_line (l)
+ int l;
+{
+ register int i;
+
+ _rl_backspace (l);
+ for (i = 0; i < l; i++)
+ putc (' ', rl_outstream);
+ _rl_backspace (l);
+ for (i = 0; i < l; i++)
+ visible_line[--_rl_last_c_pos] = '\0';
+ rl_display_fixed++;
+}
+
+/* Clear to the end of the line. COUNT is the minimum
+ number of character spaces to clear, */
+void
+_rl_clear_to_eol (count)
+ int count;
+{
+ if (_rl_term_clreol)
+ tputs (_rl_term_clreol, 1, _rl_output_character_function);
+ else if (count)
+ space_to_eol (count);
+}
+
+/* Clear to the end of the line using spaces. COUNT is the minimum
+ number of character spaces to clear, */
+static void
+space_to_eol (count)
+ int count;
+{
+ register int i;
+
+ for (i = 0; i < count; i++)
+ putc (' ', rl_outstream);
+
+ _rl_last_c_pos += count;
+}
+
+void
+_rl_clear_screen ()
+{
+ if (_rl_term_clrpag)
+ tputs (_rl_term_clrpag, 1, _rl_output_character_function);
+ else
+ rl_crlf ();
+}
+
+/* Insert COUNT characters from STRING to the output stream at column COL. */
+static void
+insert_some_chars (string, count, col)
+ char *string;
+ int count, col;
+{
+#if defined (__MSDOS__) || defined (__MINGW32__)
+ _rl_output_some_chars (string, count);
+#else
+ /* DEBUGGING */
+ if (MB_CUR_MAX == 1 || rl_byte_oriented)
+ if (count != col)
+ _rl_ttymsg ("debug: insert_some_chars: count (%d) != col (%d)", count, col);
+
+ /* If IC is defined, then we do not have to "enter" insert mode. */
+ if (_rl_term_IC)
+ {
+ char *buffer;
+
+ buffer = tgoto (_rl_term_IC, 0, col);
+ tputs (buffer, 1, _rl_output_character_function);
+ _rl_output_some_chars (string, count);
+ }
+ else
+ {
+ register int i;
+
+ /* If we have to turn on insert-mode, then do so. */
+ if (_rl_term_im && *_rl_term_im)
+ tputs (_rl_term_im, 1, _rl_output_character_function);
+
+ /* If there is a special command for inserting characters, then
+ use that first to open up the space. */
+ if (_rl_term_ic && *_rl_term_ic)
+ {
+ for (i = col; i--; )
+ tputs (_rl_term_ic, 1, _rl_output_character_function);
+ }
+
+ /* Print the text. */
+ _rl_output_some_chars (string, count);
+
+ /* If there is a string to turn off insert mode, we had best use
+ it now. */
+ if (_rl_term_ei && *_rl_term_ei)
+ tputs (_rl_term_ei, 1, _rl_output_character_function);
+ }
+#endif /* __MSDOS__ || __MINGW32__ */
+}
+
+/* Delete COUNT characters from the display line. */
+static void
+delete_chars (count)
+ int count;
+{
+ if (count > _rl_screenwidth) /* XXX */
+ return;
+
+#if !defined (__MSDOS__) && !defined (__MINGW32__)
+ if (_rl_term_DC && *_rl_term_DC)
+ {
+ char *buffer;
+ buffer = tgoto (_rl_term_DC, count, count);
+ tputs (buffer, count, _rl_output_character_function);
+ }
+ else
+ {
+ if (_rl_term_dc && *_rl_term_dc)
+ while (count--)
+ tputs (_rl_term_dc, 1, _rl_output_character_function);
+ }
+#endif /* !__MSDOS__ && !__MINGW32__ */
+}
+
+void
+_rl_update_final ()
+{
+ int full_lines;
+
+ full_lines = 0;
+ /* If the cursor is the only thing on an otherwise-blank last line,
+ compensate so we don't print an extra CRLF. */
+ if (_rl_vis_botlin && _rl_last_c_pos == 0 &&
+ visible_line[vis_lbreaks[_rl_vis_botlin]] == 0)
+ {
+ _rl_vis_botlin--;
+ full_lines = 1;
+ }
+ _rl_move_vert (_rl_vis_botlin);
+ /* If we've wrapped lines, remove the final xterm line-wrap flag. */
+ if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == _rl_screenwidth))
+ {
+ char *last_line;
+
+ last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]];
+ cpos_buffer_position = -1; /* don't know where we are in buffer */
+ _rl_move_cursor_relative (_rl_screenwidth - 1, last_line); /* XXX */
+ _rl_clear_to_eol (0);
+ putc (last_line[_rl_screenwidth - 1], rl_outstream);
+ }
+ _rl_vis_botlin = 0;
+ rl_crlf ();
+ fflush (rl_outstream);
+ rl_display_fixed++;
+}
+
+/* Move to the start of the current line. */
+static void
+cr ()
+{
+ if (_rl_term_cr)
+ {
+#if defined (__MSDOS__)
+ putc ('\r', rl_outstream);
+#else
+ tputs (_rl_term_cr, 1, _rl_output_character_function);
+#endif
+ _rl_last_c_pos = 0;
+ }
+}
+
+/* Redraw the last line of a multi-line prompt that may possibly contain
+ terminal escape sequences. Called with the cursor at column 0 of the
+ line to draw the prompt on. */
+static void
+redraw_prompt (t)
+ char *t;
+{
+ char *oldp;
+
+ oldp = rl_display_prompt;
+ rl_save_prompt ();
+
+ rl_display_prompt = t;
+ local_prompt = expand_prompt (t, &prompt_visible_length,
+ &prompt_last_invisible,
+ &prompt_invis_chars_first_line,
+ &prompt_physical_chars);
+ local_prompt_prefix = (char *)NULL;
+ local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
+
+ rl_forced_update_display ();
+
+ rl_display_prompt = oldp;
+ rl_restore_prompt();
+}
+
+/* Redisplay the current line after a SIGWINCH is received. */
+void
+_rl_redisplay_after_sigwinch ()
+{
+ char *t;
+
+ /* Clear the last line (assuming that the screen size change will result in
+ either more or fewer characters on that line only) and put the cursor at
+ column 0. Make sure the right thing happens if we have wrapped to a new
+ screen line. */
+ if (_rl_term_cr)
+ {
+ _rl_move_vert (_rl_vis_botlin);
+
+#if defined (__MSDOS__)
+ putc ('\r', rl_outstream);
+#else
+ tputs (_rl_term_cr, 1, _rl_output_character_function);
+#endif
+ _rl_last_c_pos = 0;
+#if defined (__MSDOS__)
+ space_to_eol (_rl_screenwidth);
+ putc ('\r', rl_outstream);
+#else
+ if (_rl_term_clreol)
+ tputs (_rl_term_clreol, 1, _rl_output_character_function);
+ else
+ {
+ space_to_eol (_rl_screenwidth);
+ tputs (_rl_term_cr, 1, _rl_output_character_function);
+ }
+#endif
+ if (_rl_last_v_pos > 0)
+ _rl_move_vert (0);
+ }
+ else
+ rl_crlf ();
+
+ /* Redraw only the last line of a multi-line prompt. */
+ t = strrchr (rl_display_prompt, '\n');
+ if (t)
+ redraw_prompt (++t);
+ else
+ rl_forced_update_display ();
+}
+
+void
+_rl_clean_up_for_exit ()
+{
+ if (_rl_echoing_p)
+ {
+ _rl_move_vert (_rl_vis_botlin);
+ _rl_vis_botlin = 0;
+ fflush (rl_outstream);
+ rl_restart_output (1, 0);
+ }
+}
+
+void
+_rl_erase_entire_line ()
+{
+ cr ();
+ _rl_clear_to_eol (0);
+ cr ();
+ fflush (rl_outstream);
+}
+
+/* return the `current display line' of the cursor -- the number of lines to
+ move up to get to the first screen line of the current readline line. */
+int
+_rl_current_display_line ()
+{
+ int ret, nleft;
+
+ /* Find out whether or not there might be invisible characters in the
+ editing buffer. */
+ if (rl_display_prompt == rl_prompt)
+ nleft = _rl_last_c_pos - _rl_screenwidth - rl_visible_prompt_length;
+ else
+ nleft = _rl_last_c_pos - _rl_screenwidth;
+
+ if (nleft > 0)
+ ret = 1 + nleft / _rl_screenwidth;
+ else
+ ret = 0;
+
+ return ret;
+}
+
+#if defined (HANDLE_MULTIBYTE)
+/* Calculate the number of screen columns occupied by STR from START to END.
+ In the case of multibyte characters with stateful encoding, we have to
+ scan from the beginning of the string to take the state into account. */
+static int
+_rl_col_width (str, start, end)
+ const char *str;
+ int start, end;
+{
+ wchar_t wc;
+ mbstate_t ps;
+ int tmp, point, width, max;
+
+ if (end <= start)
+ return 0;
+ if (MB_CUR_MAX == 1 || rl_byte_oriented)
+{
+_rl_ttymsg ("_rl_col_width: called with MB_CUR_MAX == 1");
+ return (end - start);
+}
+
+ memset (&ps, 0, sizeof (mbstate_t));
+
+ point = 0;
+ max = end;
+
+ /* Try to short-circuit common cases. The adjustment to remove wrap_offset
+ is done by the caller. */
+ /* 1. prompt string */
+ if (start == 0 && end == local_prompt_len && memcmp (str, local_prompt, local_prompt_len) == 0)
+ return (prompt_visible_length + wrap_offset);
+ /* 2. prompt string + line contents */
+ else if (start == 0 && end > local_prompt_len && local_prompt && memcmp (str, local_prompt, local_prompt_len) == 0)
+ {
+ tmp = prompt_visible_length + wrap_offset;
+ /* XXX - try to call ourselves recursively with non-prompt portion */
+ if (local_prompt_len > start)
+ tmp += _rl_col_width (str, local_prompt_len, end);
+ return (tmp);
+ }
+
+ while (point < start)
+ {
+ tmp = mbrlen (str + point, max, &ps);
+ if (MB_INVALIDCH ((size_t)tmp))
+ {
+ /* In this case, the bytes are invalid or too short to compose a
+ multibyte character, so we assume that the first byte represents
+ a single character. */
+ point++;
+ max--;
+
+ /* Clear the state of the byte sequence, because in this case the
+ effect of mbstate is undefined. */
+ memset (&ps, 0, sizeof (mbstate_t));
+ }
+ else if (MB_NULLWCH (tmp))
+ break; /* Found '\0' */
+ else
+ {
+ point += tmp;
+ max -= tmp;
+ }
+ }
+
+ /* If START is not a byte that starts a character, then POINT will be
+ greater than START. In this case, assume that (POINT - START) gives
+ a byte count that is the number of columns of difference. */
+ width = point - start;
+
+ while (point < end)
+ {
+ tmp = mbrtowc (&wc, str + point, max, &ps);
+ if (MB_INVALIDCH ((size_t)tmp))
+ {
+ /* In this case, the bytes are invalid or too short to compose a
+ multibyte character, so we assume that the first byte represents
+ a single character. */
+ point++;
+ max--;
+
+ /* and assume that the byte occupies a single column. */
+ width++;
+
+ /* Clear the state of the byte sequence, because in this case the
+ effect of mbstate is undefined. */
+ memset (&ps, 0, sizeof (mbstate_t));
+ }
+ else if (MB_NULLWCH (tmp))
+ break; /* Found '\0' */
+ else
+ {
+ point += tmp;
+ max -= tmp;
+ tmp = wcwidth(wc);
+ width += (tmp >= 0) ? tmp : 1;
+ }
+ }
+
+ width += point - end;
+
+ return width;
+}
+#endif /* HANDLE_MULTIBYTE */
#define invisible_line (line_state_invisible->line)
#if defined (HANDLE_MULTIBYTE)
-static int _rl_col_width PARAMS((const char *, int, int));
+static int _rl_col_width PARAMS((const char *, int, int, int));
#else
-# define _rl_col_width(l, s, e) (((e) <= (s)) ? 0 : (e) - (s))
+# define _rl_col_width(l, s, e, f) (((e) <= (s)) ? 0 : (e) - (s))
#endif
/* Heuristic used to decide whether it is faster to move from CUR to NEW
not be the same as the number of physical characters
on the screen in the presence of multibyte characters */
rl += ind - pind;
- physchars += _rl_col_width (pmt, pind, ind);
+ physchars += _rl_col_width (pmt, pind, ind, 0);
}
else
ninvis += ind - pind;
temp = local_prompt_len;
while (num < temp)
{
- z = _rl_col_width (local_prompt, n0, num);
+ z = _rl_col_width (local_prompt, n0, num, 1);
if (z > _rl_screenwidth)
{
num = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY);
inv_lbreaks[++newlines] = temp;
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0)
- lpos -= _rl_col_width (local_prompt, n0, num);
+ lpos -= _rl_col_width (local_prompt, n0, num, 1);
else
#endif
lpos -= _rl_screenwidth;
_rl_output_some_chars (local_prompt, nleft);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- _rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft) - wrap_offset + modmark;
+ _rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft, 1) - wrap_offset + modmark;
else
_rl_last_c_pos = nleft + modmark;
}
{
/* TX == new physical cursor position in multibyte locale. */
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- tx = _rl_col_width (&visible_line[pos], 0, nleft) - visible_wrap_offset;
+ tx = _rl_col_width (&visible_line[pos], 0, nleft, 1) - visible_wrap_offset;
else
tx = nleft;
if (tx >= 0 && _rl_last_c_pos > tx)
ret = 1;
memmove (old+bytes, old+ret, strlen (old+ret));
memcpy (old, new, bytes);
-#if 0
/* Fix up indices if we copy data from one line to another */
omax += bytes - ret;
for (i = current_line+1; i < inv_botlin+1; i++)
vis_lbreaks[i] += bytes - ret;
-#endif
}
}
else
{
/* We take wrap_offset into account here so we can pass correct
information to _rl_move_cursor_relative. */
- _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff) - wrap_offset + modmark;
+ _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff, 1) - wrap_offset + modmark;
cpos_adjusted = 1;
}
else
When not using multibyte characters, these are equal */
lendiff = (nls - nfd) - (ols - ofd);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- col_lendiff = _rl_col_width (new, nfd - new, nls - new) - _rl_col_width (old, ofd - old, ols - old);
+ col_lendiff = _rl_col_width (new, nfd - new, nls - new, 1) - _rl_col_width (old, ofd - old, ols - old, 1);
else
col_lendiff = lendiff;
/* Insert (diff (len (old), len (new)) ch. */
temp = ne - nfd;
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- col_temp = _rl_col_width (new, nfd - new, ne - new);
+ col_temp = _rl_col_width (new, nfd - new, ne - new, 1);
else
col_temp = temp;
if (lendiff < 0)
{
_rl_output_some_chars (nfd, temp);
- _rl_last_c_pos += _rl_col_width (nfd, 0, temp);
+ _rl_last_c_pos += _rl_col_width (nfd, 0, temp, 1);
/* If nfd begins before any invisible characters in the prompt,
adjust _rl_last_c_pos to account for wrap_offset and set
cpos_adjusted to let the caller know. */
multibyte characters and prompt strings with invisible
characters, but was previously disabled. */
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- twidth = _rl_col_width (nfd+lendiff, 0, temp-col_lendiff);
+ twidth = _rl_col_width (nfd+lendiff, 0, temp-col_lendiff, 1);
else
twidth = temp - lendiff;
_rl_last_c_pos += twidth;
_rl_output_some_chars (nfd, temp);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
- _rl_last_c_pos += _rl_col_width (nfd, 0, temp);
+ _rl_last_c_pos += _rl_col_width (nfd, 0, temp, 1);
if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
{
_rl_last_c_pos -= wrap_offset;
}
lendiff = (oe - old) - (ne - new);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- col_lendiff = _rl_col_width (old, 0, oe - old) - _rl_col_width (new, 0, ne - new);
+ col_lendiff = _rl_col_width (old, 0, oe - old, 1) - _rl_col_width (new, 0, ne - new, 1);
else
col_lendiff = lendiff;
l = strlen (prompt_last_line);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- _rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l); /* XXX */
+ _rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l, 1); /* XXX */
else
_rl_last_c_pos = l;
/* 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);
+ dpos = prompt_visible_length + _rl_col_width (data, local_prompt_len, new, 1);
cpos_adjusted = 1;
adjust = 0;
}
else
- dpos = _rl_col_width (data, 0, new);
+ dpos = _rl_col_width (data, 0, new, 1);
/* Use NEW when comparing against the last invisible character in the
prompt string, since they're both buffer indices and DPOS is a
In the case of multibyte characters with stateful encoding, we have to
scan from the beginning of the string to take the state into account. */
static int
-_rl_col_width (str, start, end)
+_rl_col_width (str, start, end, flags)
const char *str;
- int start, end;
+ int start, end, flags;
{
wchar_t wc;
mbstate_t ps;
/* 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)
+ if (flags && start == 0 && end == local_prompt_len && memcmp (str, local_prompt, local_prompt_len) == 0)
return (prompt_visible_length + wrap_offset);
/* 2. prompt string + line contents */
- else if (start == 0 && end > local_prompt_len && local_prompt && memcmp (str, local_prompt, local_prompt_len) == 0)
+ else if (flags && start == 0 && local_prompt_len > 0 && end > local_prompt_len && local_prompt && memcmp (str, local_prompt, local_prompt_len) == 0)
{
tmp = prompt_visible_length + wrap_offset;
/* XXX - try to call ourselves recursively with non-prompt portion */
- tmp += _rl_col_width (str, local_prompt_len, end);
+ tmp += _rl_col_width (str, local_prompt_len, end, flags);
return (tmp);
}
#ifdef MACOSX
ICONV_CONST char *inbuf;
char *tempbuf;
+ size_t templen;
if (conv_tofs == (iconv_t)-1)
init_tofs ();
outbuf = outbuf ? xrealloc (outbuf, outlen + 1) : xmalloc (outlen + 1);
}
tempbuf = outbuf;
+ templen = outlen;
iconv (conv_tofs, NULL, NULL, NULL, NULL);
- if (iconv (conv_tofs, &inbuf, &len, &tempbuf, &outlen) == (size_t)-1)
+ if (iconv (conv_tofs, &inbuf, &len, &tempbuf, &templen) == (size_t)-1)
return string;
*tempbuf = '\0';
#ifdef MACOSX
ICONV_CONST char *inbuf;
char *tempbuf;
+ size_t templen;
if (conv_fromfs == (iconv_t)-1)
init_fromfs ();
}
inbuf = string;
- if (outbuf == 0 || outlen < len + 8)
+ if (outbuf == 0 || outlen < (len + 8))
{
outlen = len + 8;
outbuf = outbuf ? xrealloc (outbuf, outlen + 1) : xmalloc (outlen + 1);
}
tempbuf = outbuf;
+ templen = outlen;
iconv (conv_fromfs, NULL, NULL, NULL, NULL);
- if (iconv (conv_fromfs, &inbuf, &len, &tempbuf, &outlen) == (size_t)-1)
+ if (iconv (conv_fromfs, &inbuf, &len, &tempbuf, &templen) == (size_t)-1)
return string;
*tempbuf = '\0';
fnx_tofs (string)
char *string;
{
+bar
return string;
}
static iconv_t conv_fromfs = (iconv_t)-1;
static iconv_t conv_tofs = (iconv_t)-1;
+#define OUTLEN_MAX 4096
+
static char *outbuf = 0;
static size_t outlen = 0;
#ifdef MACOSX
ICONV_CONST char *inbuf;
char *tempbuf;
+ size_t templen;
if (conv_tofs == (iconv_t)-1)
init_tofs ();
if (conv_tofs == (iconv_t)-1)
return string;
+ /* Free and reallocate outbuf if it's *too* big */
+ if (outlen >= OUTLEN_MAX && len < OUTLEN_MAX - 8)
+ {
+ free (outbuf);
+ outbuf = 0;
+ outlen = 0;
+ }
+
inbuf = string;
if (outbuf == 0 || outlen < len + 8)
{
outbuf = outbuf ? xrealloc (outbuf, outlen + 1) : xmalloc (outlen + 1);
}
tempbuf = outbuf;
+ templen = outlen;
iconv (conv_tofs, NULL, NULL, NULL, NULL);
- if (iconv (conv_tofs, &inbuf, &len, &tempbuf, &outlen) == (size_t)-1)
+ if (iconv (conv_tofs, &inbuf, &len, &tempbuf, &templen) == (size_t)-1)
return string;
*tempbuf = '\0';
#ifdef MACOSX
ICONV_CONST char *inbuf;
char *tempbuf;
+ size_t templen;
if (conv_fromfs == (iconv_t)-1)
init_fromfs ();
if (conv_fromfs == (iconv_t)-1)
return string;
+itrace("fnx_fromfs: outlen = %d after init_fromfs", outlen);
+ /* Free and reallocate outbuf if it's *too* big */
+ if (outlen >= OUTLEN_MAX && len < OUTLEN_MAX - 8)
+ {
+ free (outbuf);
+ outbuf = 0;
+ outlen = 0;
+ }
+
inbuf = string;
- if (outbuf == 0 || outlen < len + 8)
+ if (outbuf == 0 || outlen < (len + 8))
{
outlen = len + 8;
outbuf = outbuf ? xrealloc (outbuf, outlen + 1) : xmalloc (outlen + 1);
+itrace("fnx_fromfs: increased outlen to %d", outlen);
}
tempbuf = outbuf;
+ templen = outlen;
iconv (conv_fromfs, NULL, NULL, NULL, NULL);
- if (iconv (conv_fromfs, &inbuf, &len, &tempbuf, &outlen) == (size_t)-1)
+ if (iconv (conv_fromfs, &inbuf, &len, &tempbuf, &templen) == (size_t)-1)
return string;
*tempbuf = '\0';
fnx_tofs (string)
char *string;
{
+bar
return string;
}
# include <config.h>
#endif
-#if defined(DEBUG)
+/* GCC 4.2 on Snow Leopard doesn't like the snprintf prototype */
+#if defined(DEBUG) && !defined (MACOSX)
# undef HAVE_SNPRINTF
# undef HAVE_ASPRINTF
#endif
--- /dev/null
+/* snprintf - formatted output to strings, with bounds checking and allocation */
+
+/*
+ build a test version with
+ gcc -g -DDRIVER -I../.. -I../../include -o test-snprintf snprintf.c fmtu*long.o
+*/
+
+/*
+ Unix snprintf implementation.
+ derived from inetutils/libinetutils/snprintf.c Version 1.1
+
+ Copyright (C) 2001,2006 Free Software Foundation, Inc.
+
+ This file is part of GNU Bash, the Bourne Again SHell.
+
+ Bash is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Bash is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Bash. If not, see <http://www.gnu.org/licenses/>.
+
+ Revision History:
+
+ 1.1:
+ * added changes from Miles Bader
+ * corrected a bug with %f
+ * added support for %#g
+ * added more comments :-)
+ 1.0:
+ * supporting must ANSI syntaxic_sugars
+ 0.0:
+ * support %s %c %d
+
+ THANKS(for the patches and ideas):
+ Miles Bader
+ Cyrille Rustom
+ Jacek Slabocewiz
+ Mike Parker(mouse)
+
+*/
+
+/*
+ * Currently doesn't handle (and bash/readline doesn't use):
+ * * *M$ width, precision specifications
+ * * %N$ numbered argument conversions
+ * * inf, nan floating values imperfect (if isinf(), isnan() not in libc)
+ * * support for `F' is imperfect with ldfallback(), since underlying
+ * printf may not handle it -- should ideally have another autoconf test
+ */
+
+#define FLOATING_POINT
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* GCC 4.2 on Snow Leopard doesn't like the snprintf prototype */
+#if defined(DEBUG) /* && !defined (MACOSX) */
+# undef HAVE_SNPRINTF
+# undef HAVE_ASPRINTF
+#endif
+
+#if defined(DRIVER) && !defined(HAVE_CONFIG_H)
+#define HAVE_LONG_LONG
+#define HAVE_LONG_DOUBLE
+#ifdef __linux__
+#define HAVE_PRINTF_A_FORMAT
+#endif
+#define HAVE_ISINF_IN_LIBC
+#define HAVE_ISNAN_IN_LIBC
+#define PREFER_STDARG
+#define HAVE_STRINGIZE
+#define HAVE_LIMITS_H
+#define HAVE_STDDEF_H
+#define HAVE_LOCALE_H
+#define intmax_t long
+#endif
+
+#if !defined (HAVE_SNPRINTF) || !defined (HAVE_ASPRINTF)
+
+#include <bashtypes.h>
+
+#if defined(PREFER_STDARG)
+# include <stdarg.h>
+#else
+# include <varargs.h>
+#endif
+
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+#include <bashansi.h>
+#ifdef HAVE_STDDEF_H
+# include <stddef.h>
+#endif
+#include <chartypes.h>
+
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+#ifdef FLOATING_POINT
+# include <float.h> /* for manifest constants */
+# include <stdio.h> /* for sprintf */
+#endif
+
+#include <typemax.h>
+
+#ifdef HAVE_LOCALE_H
+# include <locale.h>
+#endif
+
+#include "stdc.h"
+#include <shmbutil.h>
+
+#ifndef DRIVER
+# include "shell.h"
+#else
+# define FL_PREFIX 0x01 /* add 0x, 0X, or 0 prefix as appropriate */
+# define FL_ADDBASE 0x02 /* add base# prefix to converted value */
+# define FL_HEXUPPER 0x04 /* use uppercase when converting to hex */
+# define FL_UNSIGNED 0x08 /* don't add any sign */
+extern char *fmtulong __P((unsigned long int, int, char *, size_t, int));
+extern char *fmtullong __P((unsigned long long int, int, char *, size_t, int));
+#endif
+
+#ifndef FREE
+# define FREE(x) if (x) free (x)
+#endif
+
+/* Bound on length of the string representing an integer value of type T.
+ Subtract one for the sign bit if T is signed;
+ 302 / 1000 is log10 (2) rounded up;
+ add one for integer division truncation;
+ add one more for a minus sign if t is signed. */
+#define INT_STRLEN_BOUND(t) \
+ ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 \
+ + 1 + TYPE_SIGNED (t))
+
+/* conversion flags */
+#define PF_ALTFORM 0x00001 /* # */
+#define PF_HEXPREFIX 0x00002 /* 0[Xx] */
+#define PF_LADJUST 0x00004 /* - */
+#define PF_ZEROPAD 0x00008 /* 0 */
+#define PF_PLUS 0x00010 /* + */
+#define PF_SPACE 0x00020 /* ' ' */
+#define PF_THOUSANDS 0x00040 /* ' */
+
+#define PF_DOT 0x00080 /* `.precision' */
+#define PF_STAR_P 0x00100 /* `*' after precision */
+#define PF_STAR_W 0x00200 /* `*' before or without precision */
+
+/* length modifiers */
+#define PF_SIGNEDCHAR 0x00400 /* hh */
+#define PF_SHORTINT 0x00800 /* h */
+#define PF_LONGINT 0x01000 /* l */
+#define PF_LONGLONG 0x02000 /* ll */
+#define PF_LONGDBL 0x04000 /* L */
+#define PF_INTMAX_T 0x08000 /* j */
+#define PF_SIZE_T 0x10000 /* z */
+#define PF_PTRDIFF_T 0x20000 /* t */
+
+#define PF_ALLOCBUF 0x40000 /* for asprintf, vasprintf */
+
+#define PFM_SN 0x01 /* snprintf, vsnprintf */
+#define PFM_AS 0x02 /* asprintf, vasprintf */
+
+#define ASBUFSIZE 128
+
+#define x_digs "0123456789abcdef"
+#define X_digs "0123456789ABCDEF"
+
+static char intbuf[INT_STRLEN_BOUND(unsigned long) + 1];
+
+static int decpoint;
+static int thoussep;
+static char *grouping;
+
+/*
+ * For the FLOATING POINT FORMAT :
+ * the challenge was finding a way to
+ * manipulate the Real numbers without having
+ * to resort to mathematical function(it
+ * would require to link with -lm) and not
+ * going down to the bit pattern(not portable)
+ *
+ * so a number, a real is:
+
+ real = integral + fraction
+
+ integral = ... + a(2)*10^2 + a(1)*10^1 + a(0)*10^0
+ fraction = b(1)*10^-1 + b(2)*10^-2 + ...
+
+ where:
+ 0 <= a(i) => 9
+ 0 <= b(i) => 9
+
+ from then it was simple math
+ */
+
+/*
+ * size of the buffer for the integral part
+ * and the fraction part
+ */
+#define MAX_INT 99 + 1 /* 1 for the null */
+#define MAX_FRACT 307 + 1
+
+/*
+ * These functions use static buffers to store the results,
+ * and so are not reentrant
+ */
+#define itoa(n) fmtulong(n, 10, intbuf, sizeof(intbuf), 0);
+#define dtoa(n, p, f) numtoa(n, 10, p, f)
+
+#define SWAP_INT(a,b) {int t; t = (a); (a) = (b); (b) = t;}
+
+#define GETARG(type) (va_arg(args, type))
+
+/* Macros that do proper sign extension and handle length modifiers. Used
+ for the integer conversion specifiers. */
+#define GETSIGNED(p) \
+ (((p)->flags & PF_LONGINT) \
+ ? GETARG (long) \
+ : (((p)->flags & PF_SHORTINT) ? (long)(short)GETARG (int) \
+ : (long)GETARG (int)))
+
+#define GETUNSIGNED(p) \
+ (((p)->flags & PF_LONGINT) \
+ ? GETARG (unsigned long) \
+ : (((p)->flags & PF_SHORTINT) ? (unsigned long)(unsigned short)GETARG (int) \
+ : (unsigned long)GETARG (unsigned int)))
+
+
+#ifdef HAVE_LONG_DOUBLE
+#define GETLDOUBLE(p) GETARG (long double)
+#endif
+#define GETDOUBLE(p) GETARG (double)
+
+#define SET_SIZE_FLAGS(p, type) \
+ if (sizeof (type) > sizeof (int)) \
+ (p)->flags |= PF_LONGINT; \
+ if (sizeof (type) > sizeof (long)) \
+ (p)->flags |= PF_LONGLONG;
+
+/* this struct holds everything we need */
+struct DATA
+{
+ int length;
+ char *base; /* needed for [v]asprintf */
+ char *holder;
+ int counter;
+ const char *pf;
+
+/* FLAGS */
+ int flags;
+ int justify;
+ int width, precision;
+ char pad;
+};
+
+/* the floating point stuff */
+#ifdef FLOATING_POINT
+static double pow_10 __P((int));
+static int log_10 __P((double));
+static double integral __P((double, double *));
+static char *numtoa __P((double, int, int, char **));
+#endif
+
+static void init_data __P((struct DATA *, char *, size_t, const char *, int));
+static void init_conv_flag __P((struct DATA *));
+
+/* for the format */
+#ifdef FLOATING_POINT
+static void floating __P((struct DATA *, double));
+static void exponent __P((struct DATA *, double));
+#endif
+static void number __P((struct DATA *, unsigned long, int));
+#ifdef HAVE_LONG_LONG
+static void lnumber __P((struct DATA *, unsigned long long, int));
+#endif
+static void pointer __P((struct DATA *, unsigned long));
+static void strings __P((struct DATA *, char *));
+
+#ifdef FLOATING_POINT
+# define FALLBACK_FMTSIZE 32
+# define FALLBACK_BASE 4096
+# define LFALLBACK_BASE 5120
+# ifdef HAVE_LONG_DOUBLE
+static void ldfallback __P((struct DATA *, const char *, const char *, long double));
+# endif
+static void dfallback __P((struct DATA *, const char *, const char *, double));
+#endif
+
+static char *groupnum __P((char *));
+
+#ifdef DRIVER
+static void memory_error_and_abort ();
+static void *xmalloc __P((size_t));
+static void *xrealloc __P((void *, size_t));
+static void xfree __P((void *));
+#else
+# include <xmalloc.h>
+#endif
+
+/* those are defines specific to snprintf to hopefully
+ * make the code clearer :-)
+ */
+#define RIGHT 1
+#define LEFT 0
+#define NOT_FOUND -1
+#define FOUND 1
+#define MAX_FIELD 15
+
+/* round off to the precision */
+#define ROUND(d, p) \
+ (d < 0.) ? \
+ d - pow_10(-(p)->precision) * 0.5 : \
+ d + pow_10(-(p)->precision) * 0.5
+
+/* set default precision */
+#define DEF_PREC(p) \
+ if ((p)->precision == NOT_FOUND) \
+ (p)->precision = 6
+
+/* put a char. increment the number of chars written even if we've exceeded
+ the vsnprintf/snprintf buffer size (for the return value) */
+#define PUT_CHAR(c, p) \
+ do \
+ { \
+ if (((p)->flags & PF_ALLOCBUF) && ((p)->counter >= (p)->length - 1)) \
+ { \
+ (p)->length += ASBUFSIZE; \
+ (p)->base = (char *)xrealloc((p)->base, (p)->length); \
+ (p)->holder = (p)->base + (p)->counter; /* in case reallocated */ \
+ } \
+ if ((p)->counter < (p)->length) \
+ *(p)->holder++ = (c); \
+ (p)->counter++; \
+ } \
+ while (0)
+
+/* Output a string. P->WIDTH has already been adjusted for padding. */
+#define PUT_STRING(string, len, p) \
+ do \
+ { \
+ PAD_RIGHT (p); \
+ while ((len)-- > 0) \
+ { \
+ PUT_CHAR (*(string), (p)); \
+ (string)++; \
+ } \
+ PAD_LEFT (p); \
+ } \
+ while (0)
+
+#define PUT_PLUS(d, p, zero) \
+ if ((d) > zero && (p)->justify == RIGHT) \
+ PUT_CHAR('+', p)
+
+#define PUT_SPACE(d, p, zero) \
+ if (((p)->flags & PF_SPACE) && (d) > zero) \
+ PUT_CHAR(' ', p)
+
+/* pad right */
+#define PAD_RIGHT(p) \
+ if ((p)->width > 0 && (p)->justify != LEFT) \
+ for (; (p)->width > 0; (p)->width--) \
+ PUT_CHAR((p)->pad, p)
+
+/* pad left */
+#define PAD_LEFT(p) \
+ if ((p)->width > 0 && (p)->justify == LEFT) \
+ for (; (p)->width > 0; (p)->width--) \
+ PUT_CHAR((p)->pad, p)
+
+/* pad with zeros from decimal precision */
+#define PAD_ZERO(p) \
+ if ((p)->precision > 0) \
+ for (; (p)->precision > 0; (p)->precision--) \
+ PUT_CHAR('0', p)
+
+/* if width and prec. in the args */
+#define STAR_ARGS(p) \
+ do { \
+ if ((p)->flags & PF_STAR_W) \
+ { \
+ (p)->width = GETARG (int); \
+ if ((p)->width < 0) \
+ { \
+ (p)->flags |= PF_LADJUST; \
+ (p)->justify = LEFT; \
+ (p)->width = -(p)->width; \
+ } \
+ } \
+ if ((p)->flags & PF_STAR_P) \
+ { \
+ (p)->precision = GETARG (int); \
+ if ((p)->precision < 0) \
+ { \
+ (p)->flags &= ~PF_STAR_P; \
+ (p)->precision = NOT_FOUND; \
+ } \
+ } \
+ } while (0)
+
+#if defined (HAVE_LOCALE_H) && defined (HAVE_LOCALECONV)
+# define GETLOCALEDATA(d, t, g) \
+ do \
+ { \
+ struct lconv *lv; \
+ if ((d) == 0) { \
+ (d) = '.'; (t) = -1; (g) = 0; /* defaults */ \
+ lv = localeconv(); \
+ if (lv) \
+ { \
+ if (lv->decimal_point && lv->decimal_point[0]) \
+ (d) = lv->decimal_point[0]; \
+ if (lv->thousands_sep && lv->thousands_sep[0]) \
+ (t) = lv->thousands_sep[0]; \
+ (g) = lv->grouping ? lv->grouping : ""; \
+ if (*(g) == '\0' || *(g) == CHAR_MAX || (t) == -1) (g) = 0; \
+ } \
+ } \
+ } \
+ while (0);
+#else
+# define GETLOCALEDATA(d, t, g) \
+ ( (d) = '.', (t) = ',', g = "\003" )
+#endif
+
+#ifdef FLOATING_POINT
+/*
+ * Find the nth power of 10
+ */
+static double
+pow_10(n)
+ int n;
+{
+ double P;
+
+ /* handle common cases with fast switch statement. */
+ switch (n)
+ {
+ case -3: return .001;
+ case -2: return .01;
+ case -1: return .1;
+ case 0: return 1.;
+ case 1: return 10.;
+ case 2: return 100.;
+ case 3: return 1000.;
+ }
+
+ if (n < 0)
+ {
+ P = .0001;
+ for (n += 4; n < 0; n++)
+ P /= 10.;
+ }
+ else
+ {
+ P = 10000.;
+ for (n -= 4; n > 0; n--)
+ P *= 10.;
+ }
+
+ return P;
+}
+
+/*
+ * Find the integral part of the log in base 10
+ * Note: this not a real log10()
+ I just need and approximation(integerpart) of x in:
+ 10^x ~= r
+ * log_10(200) = 2;
+ * log_10(250) = 2;
+ *
+ * NOTE: do not call this with r == 0 -- an infinite loop results.
+ */
+static int
+log_10(r)
+ double r;
+{
+ int i = 0;
+ double result = 1.;
+
+ if (r < 0.)
+ r = -r;
+
+ if (r < 1.)
+ {
+ while (result >= r)
+ {
+ result /= 10.;
+ i++;
+ }
+ return (-i);
+ }
+ else
+ {
+ while (result <= r)
+ {
+ result *= 10.;
+ i++;
+ }
+ return (i - 1);
+ }
+}
+
+/*
+ * This function return the fraction part of a double
+ * and set in ip the integral part.
+ * In many ways it resemble the modf() found on most Un*x
+ */
+static double
+integral(real, ip)
+ double real;
+ double *ip;
+{
+ int j;
+ double i, s, p;
+ double real_integral = 0.;
+
+ /* take care of the obvious */
+ /* equal to zero ? */
+ if (real == 0.)
+ {
+ *ip = 0.;
+ return (0.);
+ }
+
+ /* negative number ? */
+ if (real < 0.)
+ real = -real;
+
+ /* a fraction ? */
+ if ( real < 1.)
+ {
+ *ip = 0.;
+ return real;
+ }
+
+ /* the real work :-) */
+ for (j = log_10(real); j >= 0; j--)
+ {
+ p = pow_10(j);
+ s = (real - real_integral)/p;
+ i = 0.;
+ while (i + 1. <= s)
+ i++;
+ real_integral += i*p;
+ }
+ *ip = real_integral;
+ return (real - real_integral);
+}
+
+#define PRECISION 1.e-6
+/*
+ * return an ascii representation of the integral part of the number
+ * and set fract to be an ascii representation of the fraction part
+ * the container for the fraction and the integral part or staticly
+ * declare with fix size
+ */
+static char *
+numtoa(number, base, precision, fract)
+ double number;
+ int base, precision;
+ char **fract;
+{
+ register int i, j;
+ double ip, fp; /* integer and fraction part */
+ double fraction;
+ int digits = MAX_INT - 1;
+ static char integral_part[MAX_INT];
+ static char fraction_part[MAX_FRACT];
+ double sign;
+ int ch;
+
+ /* taking care of the obvious case: 0.0 */
+ if (number == 0.)
+ {
+ integral_part[0] = '0';
+ integral_part[1] = '\0';
+ /* The fractional part has to take the precision into account */
+ for (ch = 0; ch < precision-1; ch++)
+ fraction_part[ch] = '0';
+ fraction_part[ch] = '0';
+ fraction_part[ch+1] = '\0';
+ if (fract)
+ *fract = fraction_part;
+ return integral_part;
+ }
+
+ /* for negative numbers */
+ if ((sign = number) < 0.)
+ {
+ number = -number;
+ digits--; /* sign consume one digit */
+ }
+
+ fraction = integral(number, &ip);
+ number = ip;
+
+ /* do the integral part */
+ if (ip == 0.)
+ {
+ integral_part[0] = '0';
+ i = 1;
+ }
+ else
+ {
+ for ( i = 0; i < digits && number != 0.; ++i)
+ {
+ number /= base;
+ fp = integral(number, &ip);
+ ch = (int)((fp + PRECISION)*base); /* force to round */
+ integral_part[i] = (ch <= 9) ? ch + '0' : ch + 'a' - 10;
+ if (! ISXDIGIT((unsigned char)integral_part[i]))
+ break; /* bail out overflow !! */
+ number = ip;
+ }
+ }
+
+ /* Oh No !! out of bound, ho well fill it up ! */
+ if (number != 0.)
+ for (i = 0; i < digits; ++i)
+ integral_part[i] = '9';
+
+ /* put the sign ? */
+ if (sign < 0.)
+ integral_part[i++] = '-';
+
+ integral_part[i] = '\0';
+
+ /* reverse every thing */
+ for ( i--, j = 0; j < i; j++, i--)
+ SWAP_INT(integral_part[i], integral_part[j]);
+
+ /* the fractional part */
+ for (i=0, fp=fraction; precision > 0 && i < MAX_FRACT ; i++, precision--)
+ {
+ fraction_part[i] = (int)((fp + PRECISION)*10. + '0');
+ if (! DIGIT(fraction_part[i])) /* underflow ? */
+ break;
+ fp = (fp*10.0) - (double)(long)((fp + PRECISION)*10.);
+ }
+ fraction_part[i] = '\0';
+
+ if (fract != (char **)0)
+ *fract = fraction_part;
+
+ return integral_part;
+}
+#endif
+
+/* for %d and friends, it puts in holder
+ * the representation with the right padding
+ */
+static void
+number(p, d, base)
+ struct DATA *p;
+ unsigned long d;
+ int base;
+{
+ char *tmp, *t;
+ long sd;
+ int flags;
+
+ /* An explicit precision turns off the zero-padding flag. */
+ if ((p->flags & PF_ZEROPAD) && p->precision >= 0 && (p->flags & PF_DOT))
+ p->flags &= ~PF_ZEROPAD;
+
+ sd = d; /* signed for ' ' padding in base 10 */
+ flags = 0;
+ flags = (*p->pf == 'x' || *p->pf == 'X' || *p->pf == 'o' || *p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0;
+ if (*p->pf == 'X')
+ flags |= FL_HEXUPPER;
+
+ tmp = fmtulong (d, base, intbuf, sizeof(intbuf), flags);
+ t = 0;
+ if ((p->flags & PF_THOUSANDS))
+ {
+ GETLOCALEDATA(decpoint, thoussep, grouping);
+ if (grouping && (t = groupnum (tmp)))
+ tmp = t;
+ }
+
+ p->width -= strlen(tmp);
+ PAD_RIGHT(p);
+
+ if ((p->flags & PF_DOT) && p->precision > 0)
+ {
+ p->precision -= strlen(tmp);
+ PAD_ZERO(p);
+ }
+
+ switch (base)
+ {
+ case 10:
+ PUT_PLUS(sd, p, 0);
+ PUT_SPACE(sd, p, 0);
+ break;
+ case 8:
+ if (p->flags & PF_ALTFORM)
+ PUT_CHAR('0', p);
+ break;
+ case 16:
+ if (p->flags & PF_ALTFORM)
+ {
+ PUT_CHAR('0', p);
+ PUT_CHAR(*p->pf, p);
+ }
+ break;
+ }
+
+ while (*tmp)
+ {
+ PUT_CHAR(*tmp, p);
+ tmp++;
+ }
+
+ PAD_LEFT(p);
+ FREE (t);
+}
+
+#ifdef HAVE_LONG_LONG
+/*
+ * identical to number() but works for `long long'
+ */
+static void
+lnumber(p, d, base)
+ struct DATA *p;
+ unsigned long long d;
+ int base;
+{
+ char *tmp, *t;
+ long long sd;
+ int flags;
+
+ /* An explicit precision turns off the zero-padding flag. */
+ if ((p->flags & PF_ZEROPAD) && p->precision >= 0 && (p->flags & PF_DOT))
+ p->flags &= ~PF_ZEROPAD;
+
+ sd = d; /* signed for ' ' padding in base 10 */
+ flags = (*p->pf == 'x' || *p->pf == 'X' || *p->pf == 'o' || *p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0;
+ if (*p->pf == 'X')
+ flags |= FL_HEXUPPER;
+
+ tmp = fmtullong (d, base, intbuf, sizeof(intbuf), flags);
+ t = 0;
+ if ((p->flags & PF_THOUSANDS))
+ {
+ GETLOCALEDATA(decpoint, thoussep, grouping);
+ if (grouping && (t = groupnum (tmp)))
+ tmp = t;
+ }
+
+ p->width -= strlen(tmp);
+ PAD_RIGHT(p);
+
+ if ((p->flags & PF_DOT) && p->precision > 0)
+ {
+ p->precision -= strlen(tmp);
+ PAD_ZERO(p);
+ }
+
+ switch (base)
+ {
+ case 10:
+ PUT_PLUS(sd, p, 0);
+ PUT_SPACE(sd, p, 0);
+ break;
+ case 8:
+ if (p->flags & PF_ALTFORM)
+ PUT_CHAR('0', p);
+ break;
+ case 16:
+ if (p->flags & PF_ALTFORM)
+ {
+ PUT_CHAR('0', p);
+ PUT_CHAR(*p->pf, p);
+ }
+ break;
+ }
+
+ while (*tmp)
+ {
+ PUT_CHAR(*tmp, p);
+ tmp++;
+ }
+
+ PAD_LEFT(p);
+ FREE (t);
+}
+#endif
+
+static void
+pointer(p, d)
+ struct DATA *p;
+ unsigned long d;
+{
+ char *tmp;
+
+ tmp = fmtulong(d, 16, intbuf, sizeof(intbuf), 0);
+ p->width -= strlen(tmp);
+ PAD_RIGHT(p);
+
+ /* prefix '0x' for pointers */
+ PUT_CHAR('0', p);
+ PUT_CHAR('x', p);
+
+ while (*tmp)
+ {
+ PUT_CHAR(*tmp, p);
+ tmp++;
+ }
+
+ PAD_LEFT(p);
+}
+
+/* %s strings */
+static void
+strings(p, tmp)
+ struct DATA *p;
+ char *tmp;
+{
+ size_t len;
+
+ len = strlen(tmp);
+ if (p->precision != NOT_FOUND) /* the smallest number */
+ len = (len < p->precision ? len : p->precision);
+ p->width -= len;
+
+ PUT_STRING (tmp, len, p);
+}
+
+#if HANDLE_MULTIBYTE
+/* %ls wide-character strings */
+static void
+wstrings(p, tmp)
+ struct DATA *p;
+ wchar_t *tmp;
+{
+ size_t len;
+ mbstate_t mbs;
+ char *os;
+ const wchar_t *ws;
+
+ memset (&mbs, '\0', sizeof (mbstate_t));
+ ws = (const wchar_t *)tmp;
+
+ os = (char *)NULL;
+ if (p->precision != NOT_FOUND)
+ {
+ os = (char *)xmalloc (p->precision + 1);
+ len = wcsrtombs (os, &ws, p->precision, &mbs);
+ }
+ else
+ {
+ len = wcsrtombs (NULL, &ws, 0, &mbs);
+ if (len != (size_t)-1)
+ {
+ memset (&mbs, '\0', sizeof (mbstate_t));
+ os = (char *)xmalloc (len + 1);
+ (void)wcsrtombs (os, &ws, len + 1, &mbs);
+ }
+ }
+ if (len == (size_t)-1)
+ {
+ /* invalid multibyte sequence; bail now. */
+ FREE (os);
+ return;
+ }
+
+ p->width -= len;
+ PUT_STRING (os, len, p);
+ free (os);
+}
+
+static void
+wchars (p, wc)
+ struct DATA *p;
+ wint_t wc;
+{
+ char *lbuf, *l;
+ mbstate_t mbs;
+ size_t len;
+
+ lbuf = (char *)malloc (MB_CUR_MAX+1);
+ if (lbuf == 0)
+ return;
+ memset (&mbs, '\0', sizeof (mbstate_t));
+ len = wcrtomb (lbuf, wc, &mbs);
+ if (len == (size_t)-1)
+ /* conversion failed; bail now. */
+ return;
+ p->width -= len;
+ l = lbuf;
+ PUT_STRING (l, len, p);
+ free (lbuf);
+}
+#endif /* HANDLE_MULTIBYTE */
+
+#ifdef FLOATING_POINT
+
+#ifndef HAVE_ISINF_IN_LIBC
+/* Half-assed versions, since we don't want to link with libm. */
+static int
+isinf(d)
+ double d;
+{
+#ifdef DBL_MAX
+ if (d < DBL_MIN)
+ return -1;
+ else if (d > DBL_MAX)
+ return 1;
+ else
+#endif
+ return 0;
+}
+#endif
+
+#ifndef HAVE_ISNAN_IN_LIBC
+static int
+isnan(d)
+ double d;
+{
+ return 0;
+}
+#endif
+
+/* Check for [+-]infinity and NaN. If MODE == 1, we check for Infinity, else
+ (mode == 2) we check for NaN. This does the necessary printing. Returns
+ 1 if Inf or Nan, 0 if not. */
+static int
+chkinfnan(p, d, mode)
+ struct DATA *p;
+ double d;
+ int mode; /* == 1 for inf, == 2 for nan */
+{
+ int i;
+ char *tmp;
+ char *big, *small;
+
+ i = (mode == 1) ? isinf(d) : isnan(d);
+ if (i == 0)
+ return 0;
+ big = (mode == 1) ? "INF" : "NAN";
+ small = (mode == 1) ? "inf" : "nan";
+
+ tmp = (*p->pf == 'F' || *p->pf == 'G' || *p->pf == 'E') ? big : small;
+
+ if (i < 0)
+ PUT_CHAR('-', p);
+
+ while (*tmp)
+ {
+ PUT_CHAR (*tmp, p);
+ tmp++;
+ }
+
+ return 1;
+}
+
+/* %f %F %g %G floating point representation */
+static void
+floating(p, d)
+ struct DATA *p;
+ double d;
+{
+ char *tmp, *tmp2, *t;
+ int i;
+
+ if (d != 0 && (chkinfnan(p, d, 1) || chkinfnan(p, d, 2)))
+ return; /* already printed nan or inf */
+
+ GETLOCALEDATA(decpoint, thoussep, grouping);
+ DEF_PREC(p);
+ d = ROUND(d, p);
+ tmp = dtoa(d, p->precision, &tmp2);
+ t = 0;
+ if ((p->flags & PF_THOUSANDS) && grouping && (t = groupnum (tmp)))
+ tmp = t;
+
+ if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0)
+ {
+ /* smash the trailing zeros unless altform */
+ for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--)
+ tmp2[i] = '\0';
+ if (tmp2[0] == '\0')
+ p->precision = 0;
+ }
+
+ /* calculate the padding. 1 for the dot */
+ p->width = p->width -
+ ((d > 0. && p->justify == RIGHT) ? 1:0) -
+ ((p->flags & PF_SPACE) ? 1:0) -
+ strlen(tmp) - p->precision -
+ ((p->precision != 0 || (p->flags & PF_ALTFORM)) ? 1 : 0); /* radix char */
+ PAD_RIGHT(p);
+ PUT_PLUS(d, p, 0.);
+ PUT_SPACE(d, p, 0.);
+
+ while (*tmp)
+ {
+ PUT_CHAR(*tmp, p); /* the integral */
+ tmp++;
+ }
+ FREE (t);
+
+ if (p->precision != 0 || (p->flags & PF_ALTFORM))
+ PUT_CHAR(decpoint, p); /* put the '.' */
+
+ for (; *tmp2; tmp2++)
+ PUT_CHAR(*tmp2, p); /* the fraction */
+
+ PAD_LEFT(p);
+}
+
+/* %e %E %g %G exponent representation */
+static void
+exponent(p, d)
+ struct DATA *p;
+ double d;
+{
+ char *tmp, *tmp2;
+ int j, i;
+
+ if (d != 0 && (chkinfnan(p, d, 1) || chkinfnan(p, d, 2)))
+ return; /* already printed nan or inf */
+
+ GETLOCALEDATA(decpoint, thoussep, grouping);
+ DEF_PREC(p);
+ if (d == 0.)
+ j = 0;
+ else
+ {
+ j = log_10(d);
+ d = d / pow_10(j); /* get the Mantissa */
+ d = ROUND(d, p);
+ }
+ tmp = dtoa(d, p->precision, &tmp2);
+
+ /* 1 for unit, 1 for the '.', 1 for 'e|E',
+ * 1 for '+|-', 2 for 'exp' */
+ /* calculate how much padding need */
+ p->width = p->width -
+ ((d > 0. && p->justify == RIGHT) ? 1:0) -
+ ((p->flags & PF_SPACE) ? 1:0) - p->precision - 6;
+
+ PAD_RIGHT(p);
+ PUT_PLUS(d, p, 0.);
+ PUT_SPACE(d, p, 0.);
+
+ while (*tmp)
+ {
+ PUT_CHAR(*tmp, p);
+ tmp++;
+ }
+
+ if (p->precision != 0 || (p->flags & PF_ALTFORM))
+ PUT_CHAR(decpoint, p); /* the '.' */
+
+ if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0)
+ /* smash the trailing zeros unless altform */
+ for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--)
+ tmp2[i] = '\0';
+
+ for (; *tmp2; tmp2++)
+ PUT_CHAR(*tmp2, p); /* the fraction */
+
+ /* the exponent put the 'e|E' */
+ if (*p->pf == 'g' || *p->pf == 'e')
+ PUT_CHAR('e', p);
+ else
+ PUT_CHAR('E', p);
+
+ /* the sign of the exp */
+ if (j >= 0)
+ PUT_CHAR('+', p);
+ else
+ {
+ PUT_CHAR('-', p);
+ j = -j;
+ }
+
+ tmp = itoa(j);
+ /* pad out to at least two spaces. pad with `0' if the exponent is a
+ single digit. */
+ if (j <= 9)
+ PUT_CHAR('0', p);
+
+ /* the exponent */
+ while (*tmp)
+ {
+ PUT_CHAR(*tmp, p);
+ tmp++;
+ }
+
+ PAD_LEFT(p);
+}
+#endif
+
+/* Return a new string with the digits in S grouped according to the locale's
+ grouping info and thousands separator. If no grouping should be performed,
+ this returns NULL; the caller needs to check for it. */
+static char *
+groupnum (s)
+ char *s;
+{
+ char *se, *ret, *re, *g;
+ int len, slen;
+
+ if (grouping == 0 || *grouping <= 0 || *grouping == CHAR_MAX)
+ return ((char *)NULL);
+
+ /* find min grouping to size returned string */
+ for (len = *grouping, g = grouping; *g; g++)
+ if (*g > 0 && *g < len)
+ len = *g;
+
+ slen = strlen (s);
+ len = slen / len + 1;
+ ret = (char *)xmalloc (slen + len + 1);
+ re = ret + slen + len;
+ *re = '\0';
+
+ g = grouping;
+ se = s + slen;
+ len = *g;
+
+ while (se > s)
+ {
+ *--re = *--se;
+
+ /* handle `-' inserted by numtoa() and the fmtu* family here. */
+ if (se > s && se[-1] == '-')
+ continue;
+
+ /* begin new group. */
+ if (--len == 0 && se > s)
+ {
+ *--re = thoussep;
+ len = *++g; /* was g++, but that uses first char twice (glibc bug, too) */
+ if (*g == '\0')
+ len = *--g; /* use previous grouping */
+ else if (*g == CHAR_MAX)
+ {
+ do
+ *--re = *--se;
+ while (se > s);
+ break;
+ }
+ }
+ }
+
+ if (re > ret)
+#ifdef HAVE_MEMMOVE
+ memmove (ret, re, strlen (re) + 1);
+#else
+ strcpy (ret, re);
+#endif
+
+ return ret;
+}
+
+/* initialize the conversion specifiers */
+static void
+init_conv_flag (p)
+ struct DATA *p;
+{
+ p->flags &= PF_ALLOCBUF; /* preserve PF_ALLOCBUF flag */
+ p->precision = p->width = NOT_FOUND;
+ p->justify = NOT_FOUND;
+ p->pad = ' ';
+}
+
+static void
+init_data (p, string, length, format, mode)
+ struct DATA *p;
+ char *string;
+ size_t length;
+ const char *format;
+ int mode;
+{
+ p->length = length - 1; /* leave room for '\0' */
+ p->holder = p->base = string;
+ p->pf = format;
+ p->counter = 0;
+ p->flags = (mode == PFM_AS) ? PF_ALLOCBUF : 0;
+}
+
+static int
+#if defined (__STDC__)
+vsnprintf_internal(struct DATA *data, char *string, size_t length, const char *format, va_list args)
+#else
+vsnprintf_internal(data, string, length, format, args)
+ struct DATA *data;
+ char *string;
+ size_t length;
+ const char *format;
+ va_list args;
+#endif
+{
+ double d; /* temporary holder */
+#ifdef HAVE_LONG_DOUBLE
+ long double ld; /* for later */
+#endif
+ unsigned long ul;
+#ifdef HAVE_LONG_LONG
+ unsigned long long ull;
+#endif
+ int state, i, c, n;
+ char *s;
+#if HANDLE_MULTIBYTE
+ wchar_t *ws;
+ wint_t wc;
+#endif
+ const char *convstart;
+ int negprec;
+
+ /* Sanity check, the string length must be >= 0. C99 actually says that
+ LENGTH can be zero here, in the case of snprintf/vsnprintf (it's never
+ 0 in the case of asprintf/vasprintf), and the return value is the number
+ of characters that would have been written. */
+ if (length < 0)
+ return -1;
+
+ if (format == 0)
+ return 0;
+
+ /* Reset these for each call because the locale might have changed. */
+ decpoint = thoussep = 0;
+ grouping = 0;
+
+ negprec = 0;
+ for (; c = *(data->pf); data->pf++)
+ {
+ if (c != '%')
+ {
+ PUT_CHAR (c, data);
+ continue;
+ }
+
+ convstart = data->pf;
+ init_conv_flag (data); /* initialise format flags */
+
+ state = 1;
+ for (state = 1; state && *data->pf; )
+ {
+ c = *(++data->pf);
+ /* fmtend = data->pf */
+#if defined (FLOATING_POINT) && defined (HAVE_LONG_DOUBLE)
+ if (data->flags & PF_LONGDBL)
+ {
+ switch (c)
+ {
+ case 'f': case 'F':
+ case 'e': case 'E':
+ case 'g': case 'G':
+# ifdef HAVE_PRINTF_A_FORMAT
+ case 'a': case 'A':
+# endif
+ STAR_ARGS (data);
+ ld = GETLDOUBLE (data);
+ ldfallback (data, convstart, data->pf, ld);
+ goto conv_break;
+ }
+ }
+#endif /* FLOATING_POINT && HAVE_LONG_DOUBLE */
+
+ switch (c)
+ {
+ /* Parse format flags */
+ case '\0': /* a NULL here ? ? bail out */
+ *data->holder = '\0';
+ return data->counter;
+ break;
+ case '#':
+ data->flags |= PF_ALTFORM;
+ continue;
+ case '0':
+ data->flags |= PF_ZEROPAD;
+ data->pad = '0';
+ continue;
+ case '*':
+ if (data->flags & PF_DOT)
+ data->flags |= PF_STAR_P;
+ else
+ data->flags |= PF_STAR_W;
+ continue;
+ case '-':
+ if ((data->flags & PF_DOT) == 0)
+ {
+ data->flags |= PF_LADJUST;
+ data->justify = LEFT;
+ }
+ else
+ negprec = 1;
+ continue;
+ case ' ':
+ if ((data->flags & PF_PLUS) == 0)
+ data->flags |= PF_SPACE;
+ continue;
+ case '+':
+ if ((data->flags & PF_DOT) == 0)
+ {
+ data->flags |= PF_PLUS;
+ data->justify = RIGHT;
+ }
+ continue;
+ case '\'':
+ data->flags |= PF_THOUSANDS;
+ continue;
+
+ case '1': case '2': case '3':
+ case '4': case '5': case '6':
+ case '7': case '8': case '9':
+ n = 0;
+ do
+ {
+ n = n * 10 + TODIGIT(c);
+ c = *(++data->pf);
+ }
+ while (DIGIT(c));
+ data->pf--; /* went too far */
+ if (n < 0)
+ n = 0;
+ if (data->flags & PF_DOT)
+ data->precision = negprec ? NOT_FOUND : n;
+ else
+ data->width = n;
+ continue;
+
+ /* optional precision */
+ case '.':
+ data->flags |= PF_DOT;
+ data->precision = 0;
+ continue;
+
+ /* length modifiers */
+ case 'h':
+ data->flags |= (data->flags & PF_SHORTINT) ? PF_SIGNEDCHAR : PF_SHORTINT;
+ continue;
+ case 'l':
+ data->flags |= (data->flags & PF_LONGINT) ? PF_LONGLONG : PF_LONGINT;
+ continue;
+ case 'L':
+ data->flags |= PF_LONGDBL;
+ continue;
+ case 'q':
+ data->flags |= PF_LONGLONG;
+ continue;
+ case 'j':
+ data->flags |= PF_INTMAX_T;
+ SET_SIZE_FLAGS(data, intmax_t);
+ continue;
+ case 'z':
+ data->flags |= PF_SIZE_T;
+ SET_SIZE_FLAGS(data, size_t);
+ continue;
+ case 't':
+ data->flags |= PF_PTRDIFF_T;
+ SET_SIZE_FLAGS(data, ptrdiff_t);
+ continue;
+
+ /* Conversion specifiers */
+#ifdef FLOATING_POINT
+ case 'f': /* float, double */
+ case 'F':
+ STAR_ARGS(data);
+ d = GETDOUBLE(data);
+ floating(data, d);
+conv_break:
+ state = 0;
+ break;
+ case 'g':
+ case 'G':
+ STAR_ARGS(data);
+ DEF_PREC(data);
+ d = GETDOUBLE(data);
+ i = (d != 0.) ? log_10(d) : -1;
+ /*
+ * for '%g|%G' ANSI: use f if exponent
+ * is in the range or [-4,p] exclusively
+ * else use %e|%E
+ */
+ if (-4 < i && i < data->precision)
+ {
+ /* reset precision */
+ data->precision -= i + 1;
+ floating(data, d);
+ }
+ else
+ {
+ /* reduce precision by 1 because of leading digit before
+ decimal point in e format. */
+ data->precision--;
+ exponent(data, d);
+ }
+ state = 0;
+ break;
+ case 'e':
+ case 'E': /* Exponent double */
+ STAR_ARGS(data);
+ d = GETDOUBLE(data);
+ exponent(data, d);
+ state = 0;
+ break;
+# ifdef HAVE_PRINTF_A_FORMAT
+ case 'a':
+ case 'A':
+ STAR_ARGS(data);
+ d = GETDOUBLE(data);
+ dfallback(data, convstart, data->pf, d);
+ state = 0;
+ break;
+# endif /* HAVE_PRINTF_A_FORMAT */
+#endif /* FLOATING_POINT */
+ case 'U':
+ data->flags |= PF_LONGINT;
+ /* FALLTHROUGH */
+ case 'u':
+ STAR_ARGS(data);
+#ifdef HAVE_LONG_LONG
+ if (data->flags & PF_LONGLONG)
+ {
+ ull = GETARG (unsigned long long);
+ lnumber(data, ull, 10);
+ }
+ else
+#endif
+ {
+ ul = GETUNSIGNED(data);
+ number(data, ul, 10);
+ }
+ state = 0;
+ break;
+ case 'D':
+ data->flags |= PF_LONGINT;
+ /* FALLTHROUGH */
+ case 'd': /* decimal */
+ case 'i':
+ STAR_ARGS(data);
+#ifdef HAVE_LONG_LONG
+ if (data->flags & PF_LONGLONG)
+ {
+ ull = GETARG (long long);
+ lnumber(data, ull, 10);
+ }
+ else
+#endif
+ {
+ ul = GETSIGNED(data);
+ number(data, ul, 10);
+ }
+ state = 0;
+ break;
+ case 'o': /* octal */
+ STAR_ARGS(data);
+#ifdef HAVE_LONG_LONG
+ if (data->flags & PF_LONGLONG)
+ {
+ ull = GETARG (unsigned long long);
+ lnumber(data, ull, 8);
+ }
+ else
+#endif
+ {
+ ul = GETUNSIGNED(data);
+ number(data, ul, 8);
+ }
+ state = 0;
+ break;
+ case 'x':
+ case 'X': /* hexadecimal */
+ STAR_ARGS(data);
+#ifdef HAVE_LONG_LONG
+ if (data->flags & PF_LONGLONG)
+ {
+ ull = GETARG (unsigned long long);
+ lnumber(data, ull, 16);
+ }
+ else
+#endif
+ {
+ ul = GETUNSIGNED(data);
+ number(data, ul, 16);
+ }
+ state = 0;
+ break;
+ case 'p':
+ STAR_ARGS(data);
+ ul = (unsigned long)GETARG (void *);
+ pointer(data, ul);
+ state = 0;
+ break;
+#if HANDLE_MULTIBYTE
+ case 'C':
+ data->flags |= PF_LONGINT;
+ /* FALLTHROUGH */
+#endif
+ case 'c': /* character */
+ STAR_ARGS(data);
+#if HANDLE_MULTIBYTE
+ if (data->flags & PF_LONGINT)
+ {
+ wc = GETARG (wint_t);
+ wchars (data, wc);
+ }
+ else
+#endif
+ {
+ ul = GETARG (int);
+ PUT_CHAR(ul, data);
+ }
+ state = 0;
+ break;
+#if HANDLE_MULTIBYTE
+ case 'S':
+ data->flags |= PF_LONGINT;
+ /* FALLTHROUGH */
+#endif
+ case 's': /* string */
+ STAR_ARGS(data);
+#if HANDLE_MULTIBYTE
+ if (data->flags & PF_LONGINT)
+ {
+ ws = GETARG (wchar_t *);
+ wstrings (data, ws);
+ }
+ else
+#endif
+ {
+ s = GETARG (char *);
+ strings(data, s);
+ }
+ state = 0;
+ break;
+ case 'n':
+#ifdef HAVE_LONG_LONG
+ if (data->flags & PF_LONGLONG)
+ *(GETARG (long long *)) = data->counter;
+ else
+#endif
+ if (data->flags & PF_LONGINT)
+ *(GETARG (long *)) = data->counter;
+ else if (data->flags & PF_SHORTINT)
+ *(GETARG (short *)) = data->counter;
+ else
+ *(GETARG (int *)) = data->counter;
+ state = 0;
+ break;
+ case '%': /* nothing just % */
+ PUT_CHAR('%', data);
+ state = 0;
+ break;
+ default:
+ /* is this an error ? maybe bail out */
+ state = 0;
+ break;
+ } /* end switch */
+ } /* end of `%' for loop */
+ } /* end of format string for loop */
+
+ if (data->length >= 0)
+ *data->holder = '\0'; /* the end ye ! */
+
+ return data->counter;
+}
+
+#if defined (FLOATING_POINT) && defined (HAVE_LONG_DOUBLE)
+/*
+ * Printing floating point numbers accurately is an art. I'm not good
+ * at it. Fall back to sprintf for long double formats.
+ */
+static void
+ldfallback (data, fs, fe, ld)
+ struct DATA *data;
+ const char *fs, *fe;
+ long double ld;
+{
+ register char *x;
+ char fmtbuf[FALLBACK_FMTSIZE], *obuf;
+ int fl;
+
+ fl = LFALLBACK_BASE + (data->precision < 6 ? 6 : data->precision) + 2;
+ obuf = (char *)xmalloc (fl);
+ fl = fe - fs + 1;
+ strncpy (fmtbuf, fs, fl);
+ fmtbuf[fl] = '\0';
+
+ if ((data->flags & PF_STAR_W) && (data->flags & PF_STAR_P))
+ sprintf (obuf, fmtbuf, data->width, data->precision, ld);
+ else if (data->flags & PF_STAR_W)
+ sprintf (obuf, fmtbuf, data->width, ld);
+ else if (data->flags & PF_STAR_P)
+ sprintf (obuf, fmtbuf, data->precision, ld);
+ else
+ sprintf (obuf, fmtbuf, ld);
+
+ for (x = obuf; *x; x++)
+ PUT_CHAR (*x, data);
+ xfree (obuf);
+}
+#endif /* FLOATING_POINT && HAVE_LONG_DOUBLE */
+
+#ifdef FLOATING_POINT
+/* Used for %a, %A if the libc printf supports them. */
+static void
+dfallback (data, fs, fe, d)
+ struct DATA *data;
+ const char *fs, *fe;
+ double d;
+{
+ register char *x;
+ char fmtbuf[FALLBACK_FMTSIZE], obuf[FALLBACK_BASE];
+ int fl;
+
+ fl = fe - fs + 1;
+ strncpy (fmtbuf, fs, fl);
+ fmtbuf[fl] = '\0';
+
+ if ((data->flags & PF_STAR_W) && (data->flags & PF_STAR_P))
+ sprintf (obuf, fmtbuf, data->width, data->precision, d);
+ else if (data->flags & PF_STAR_W)
+ sprintf (obuf, fmtbuf, data->width, d);
+ else if (data->flags & PF_STAR_P)
+ sprintf (obuf, fmtbuf, data->precision, d);
+ else
+ sprintf (obuf, fmtbuf, d);
+
+ for (x = obuf; *x; x++)
+ PUT_CHAR (*x, data);
+}
+#endif /* FLOATING_POINT */
+
+#ifndef HAVE_SNPRINTF
+
+int
+#if defined (__STDC__)
+vsnprintf(char *string, size_t length, const char *format, va_list args)
+#else
+vsnprintf(string, length, format, args)
+ char *string;
+ size_t length;
+ const char *format;
+ va_list args;
+#endif
+{
+ struct DATA data;
+
+ if (string == 0 && length != 0)
+ return 0;
+ init_data (&data, string, length, format, PFM_SN);
+ return (vsnprintf_internal(&data, string, length, format, args));
+}
+
+int
+#if defined(PREFER_STDARG)
+snprintf(char *string, size_t length, const char * format, ...)
+#else
+snprintf(string, length, format, va_alist)
+ char *string;
+ size_t length;
+ const char *format;
+ va_dcl
+#endif
+{
+ struct DATA data;
+ int rval;
+ va_list args;
+
+ SH_VA_START(args, format);
+
+ if (string == 0 && length != 0)
+ return 0;
+ init_data (&data, string, length, format, PFM_SN);
+ rval = vsnprintf_internal (&data, string, length, format, args);
+
+ va_end(args);
+
+ return rval;
+}
+
+#endif /* HAVE_SNPRINTF */
+
+#ifndef HAVE_ASPRINTF
+
+int
+#if defined (__STDC__)
+vasprintf(char **stringp, const char *format, va_list args)
+#else
+vasprintf(stringp, format, args)
+ char **stringp;
+ const char *format;
+ va_list args;
+#endif
+{
+ struct DATA data;
+ char *string;
+ int r;
+
+ string = (char *)xmalloc(ASBUFSIZE);
+ init_data (&data, string, ASBUFSIZE, format, PFM_AS);
+ r = vsnprintf_internal(&data, string, ASBUFSIZE, format, args);
+ *stringp = data.base; /* not string in case reallocated */
+ return r;
+}
+
+int
+#if defined(PREFER_STDARG)
+asprintf(char **stringp, const char * format, ...)
+#else
+asprintf(stringp, format, va_alist)
+ char **stringp;
+ const char *format;
+ va_dcl
+#endif
+{
+ int rval;
+ va_list args;
+
+ SH_VA_START(args, format);
+
+ rval = vasprintf (stringp, format, args);
+
+ va_end(args);
+
+ return rval;
+}
+
+#endif
+
+#endif
+
+#ifdef DRIVER
+
+static void
+memory_error_and_abort ()
+{
+ write (2, "out of virtual memory\n", 22);
+ abort ();
+}
+
+static void *
+xmalloc(bytes)
+ size_t bytes;
+{
+ void *ret;
+
+ ret = malloc(bytes);
+ if (ret == 0)
+ memory_error_and_abort ();
+ return ret;
+}
+
+static void *
+xrealloc (pointer, bytes)
+ void *pointer;
+ size_t bytes;
+{
+ void *ret;
+
+ ret = pointer ? realloc(pointer, bytes) : malloc(bytes);
+ if (ret == 0)
+ memory_error_and_abort ();
+ return ret;
+}
+
+static void
+xfree(x)
+ void *x;
+{
+ if (x)
+ free (x);
+}
+
+/* set of small tests for snprintf() */
+main()
+{
+ char holder[100];
+ char *h;
+ int i, si, ai;
+
+#ifdef HAVE_LOCALE_H
+ setlocale(LC_ALL, "");
+#endif
+
+#if 1
+ si = snprintf((char *)NULL, 0, "abcde\n");
+ printf("snprintf returns %d with NULL first argument and size of 0\n", si);
+ si = snprintf(holder, 0, "abcde\n");
+ printf("snprintf returns %d with non-NULL first argument and size of 0\n", si);
+ si = snprintf((char *)NULL, 16, "abcde\n");
+ printf("snprintf returns %d with NULL first argument and non-zero size\n", si);
+
+/*
+ printf("Suite of test for snprintf:\n");
+ printf("a_format\n");
+ printf("printf() format\n");
+ printf("snprintf() format\n\n");
+*/
+/* Checking the field widths */
+
+ printf("/%%ld %%ld/, 336, 336\n");
+ snprintf(holder, sizeof holder, "/%ld %ld/\n", 336, 336);
+ asprintf(&h, "/%ld %ld/\n", 336, 336);
+ printf("/%ld %ld/\n", 336, 336);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%d/, 336\n");
+ snprintf(holder, sizeof holder, "/%d/\n", 336);
+ asprintf(&h, "/%d/\n", 336);
+ printf("/%d/\n", 336);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%2d/, 336\n");
+ snprintf(holder, sizeof holder, "/%2d/\n", 336);
+ asprintf(&h, "/%2d/\n", 336);
+ printf("/%2d/\n", 336);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%10d/, 336\n");
+ snprintf(holder, sizeof holder, "/%10d/\n", 336);
+ asprintf(&h, "/%10d/\n", 336);
+ printf("/%10d/\n", 336);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%-10d/, 336\n");
+ snprintf(holder, sizeof holder, "/%-10d/\n", 336);
+ asprintf(&h, "/%-10d/\n", 336);
+ printf("/%-10d/\n", 336);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+
+/* floating points */
+
+ printf("/%%f/, 1234.56\n");
+ snprintf(holder, sizeof holder, "/%f/\n", 1234.56);
+ asprintf(&h, "/%f/\n", 1234.56);
+ printf("/%f/\n", 1234.56);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%e/, 1234.56\n");
+ snprintf(holder, sizeof holder, "/%e/\n", 1234.56);
+ asprintf(&h, "/%e/\n", 1234.56);
+ printf("/%e/\n", 1234.56);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%4.2f/, 1234.56\n");
+ snprintf(holder, sizeof holder, "/%4.2f/\n", 1234.56);
+ asprintf(&h, "/%4.2f/\n", 1234.56);
+ printf("/%4.2f/\n", 1234.56);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%3.1f/, 1234.56\n");
+ snprintf(holder, sizeof holder, "/%3.1f/\n", 1234.56);
+ asprintf(&h, "/%3.1f/\n", 1234.56);
+ printf("/%3.1f/\n", 1234.56);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%10.3f/, 1234.56\n");
+ snprintf(holder, sizeof holder, "/%10.3f/\n", 1234.56);
+ asprintf(&h, "/%10.3f/\n", 1234.56);
+ printf("/%10.3f/\n", 1234.56);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%10.3e/, 1234.56\n");
+ snprintf(holder, sizeof holder, "/%10.3e/\n", 1234.56);
+ asprintf(&h, "/%10.3e/\n", 1234.56);
+ printf("/%10.3e/\n", 1234.56);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%+4.2f/, 1234.56\n");
+ snprintf(holder, sizeof holder, "/%+4.2f/\n", 1234.56);
+ asprintf(&h, "/%+4.2f/\n", 1234.56);
+ printf("/%+4.2f/\n", 1234.56);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%010.2f/, 1234.56\n");
+ snprintf(holder, sizeof holder, "/%010.2f/\n", 1234.56);
+ asprintf(&h, "/%010.2f/\n", 1234.56);
+ printf("/%010.2f/\n", 1234.56);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+#define BLURB "Outstanding acting !"
+/* strings precisions */
+
+ printf("/%%2s/, \"%s\"\n", BLURB);
+ snprintf(holder, sizeof holder, "/%2s/\n", BLURB);
+ asprintf(&h, "/%2s/\n", BLURB);
+ printf("/%2s/\n", BLURB);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%22s/ %s\n", BLURB);
+ snprintf(holder, sizeof holder, "/%22s/\n", BLURB);
+ asprintf(&h, "/%22s/\n", BLURB);
+ printf("/%22s/\n", BLURB);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%22.5s/ %s\n", BLURB);
+ snprintf(holder, sizeof holder, "/%22.5s/\n", BLURB);
+ asprintf(&h, "/%22.5s/\n", BLURB);
+ printf("/%22.5s/\n", BLURB);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%-22.5s/ %s\n", BLURB);
+ snprintf(holder, sizeof holder, "/%-22.5s/\n", BLURB);
+ asprintf(&h, "/%-22.5s/\n", BLURB);
+ printf("/%-22.5s/\n", BLURB);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+/* see some flags */
+
+ printf("%%x %%X %%#x, 31, 31, 31\n");
+ snprintf(holder, sizeof holder, "%x %X %#x\n", 31, 31, 31);
+ asprintf(&h, "%x %X %#x\n", 31, 31, 31);
+ printf("%x %X %#x\n", 31, 31, 31);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("**%%d**%% d**%% d**, 42, 42, -42\n");
+ snprintf(holder, sizeof holder, "**%d**% d**% d**\n", 42, 42, -42);
+ asprintf(&h, "**%d**% d**% d**\n", 42, 42, -42);
+ printf("**%d**% d**% d**\n", 42, 42, -42);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+/* other flags */
+
+ printf("/%%g/, 31.4\n");
+ snprintf(holder, sizeof holder, "/%g/\n", 31.4);
+ asprintf(&h, "/%g/\n", 31.4);
+ printf("/%g/\n", 31.4);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%.6g/, 31.4\n");
+ snprintf(holder, sizeof holder, "/%.6g/\n", 31.4);
+ asprintf(&h, "/%.6g/\n", 31.4);
+ printf("/%.6g/\n", 31.4);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%.1G/, 31.4\n");
+ snprintf(holder, sizeof holder, "/%.1G/\n", 31.4);
+ asprintf(&h, "/%.1G/\n", 31.4);
+ printf("/%.1G/\n", 31.4);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%.1G/, 3100000000.4\n");
+ snprintf(holder, sizeof holder, "/%.1G/\n", 3100000000.4);
+ asprintf(&h, "/%.1G/\n", 3100000000.4);
+ printf("/%.1G/\n", 3100000000.4);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("abc%%n\n");
+ printf("abc%n", &i); printf("%d\n", i);
+ snprintf(holder, sizeof holder, "abc%n", &i);
+ printf("%s", holder); printf("%d\n\n", i);
+ asprintf(&h, "abc%n", &i);
+ printf("%s", h); printf("%d\n\n", i);
+
+ printf("%%*.*s --> 10.10\n");
+ snprintf(holder, sizeof holder, "%*.*s\n", 10, 10, BLURB);
+ asprintf(&h, "%*.*s\n", 10, 10, BLURB);
+ printf("%*.*s\n", 10, 10, BLURB);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("%%%%%%%%\n");
+ snprintf(holder, sizeof holder, "%%%%\n");
+ asprintf(&h, "%%%%\n");
+ printf("%%%%\n");
+ printf("%s", holder);
+ printf("%s\n", h);
+
+#define BIG "Hello this is a too big string for the buffer"
+/* printf("A buffer to small of 10, trying to put this:\n");*/
+ printf("<%%>, %s\n", BIG);
+ i = snprintf(holder, 10, "%s\n", BIG);
+ i = asprintf(&h, "%s", BIG);
+ printf("<%s>\n", BIG);
+ printf("<%s>\n", holder);
+ printf("<%s>\n\n", h);
+
+ printf ("<%%p> vsnprintf\n");
+ i = snprintf(holder, 100, "%p", vsnprintf);
+ i = asprintf(&h, "%p", vsnprintf);
+ printf("<%p>\n", vsnprintf);
+ printf("<%s>\n", holder);
+ printf("<%s>\n\n", h);
+
+ printf ("<%%lu> LONG_MAX+1\n");
+ i = snprintf(holder, 100, "%lu", (unsigned long)(LONG_MAX)+1);
+ i = asprintf(&h, "%lu", (unsigned long)(LONG_MAX)+1);
+ printf("<%lu>\n", (unsigned long)(LONG_MAX)+1);
+ printf("<%s>\n", holder);
+ printf("<%s>\n\n", h);
+
+#ifdef HAVE_LONG_LONG
+ printf ("<%%llu> LLONG_MAX+1\n");
+ i = snprintf(holder, 100, "%llu", (unsigned long long)(LLONG_MAX)+1);
+ i = asprintf(&h, "%llu", (unsigned long long)(LLONG_MAX)+1);
+ printf("<%llu>\n", (unsigned long long)(LLONG_MAX)+1);
+ printf("<%s>\n", holder);
+ printf("<%s>\n\n", h);
+#endif
+
+#ifdef HAVE_LONG_DOUBLE
+ printf ("<%%6.2LE> 42.42\n");
+ i = snprintf(holder, 100, "%6.2LE", (long double)42.42);
+ i = asprintf(&h, "%6.2LE", (long double)42.42);
+ printf ("<%6.2LE>\n", (long double)42.42);
+ printf ("<%s>\n", holder);
+ printf ("<%s>\n\n", h);
+#endif
+
+#ifdef HAVE_PRINTF_A_FORMAT
+ printf ("<%%6.2A> 42.42\n");
+ i = snprintf(holder, 100, "%6.2A", 42.42);
+ i = asprintf(&h, "%6.2A", 42.42);
+ printf ("<%6.2A>\n", 42.42);
+ printf ("<%s>\n", holder);
+ printf ("<%s>\n\n", h);
+
+ printf ("<%%6.2LA> 42.42\n");
+ i = snprintf(holder, 100, "%6.2LA", (long double)42.42);
+ i = asprintf(&h, "%6.2LA", (long double)42.42);
+ printf ("<%6.2LA>\n", (long double)42.42);
+ printf ("<%s>\n", holder);
+ printf ("<%s>\n\n", h);
+#endif
+
+ printf ("<%%.10240f> DBL_MAX\n");
+ si = snprintf(holder, 100, "%.10240f", DBL_MAX);
+ ai = asprintf(&h, "%.10240f", DBL_MAX);
+ printf ("<%.10240f>\n", DBL_MAX);
+ printf ("<%d> <%s>\n", si, holder);
+ printf ("<%d> <%s>\n\n", ai, h);
+
+ printf ("<%%.10240Lf> LDBL_MAX\n");
+ si = snprintf(holder, 100, "%.10240Lf", (long double)LDBL_MAX);
+ ai = asprintf(&h, "%.10240Lf", (long double)LDBL_MAX);
+ printf ("<%.10240Lf>\n", (long double)LDBL_MAX);
+ printf ("<%d> <%s>\n", si, holder);
+ printf ("<%d> <%s>\n\n", ai, h);
+
+ /* huh? */
+ printf("/%%g/, 421.2345\n");
+ snprintf(holder, sizeof holder, "/%g/\n", 421.2345);
+ asprintf(&h, "/%g/\n", 421.2345);
+ printf("/%g/\n", 421.2345);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%g/, 4214.2345\n");
+ snprintf(holder, sizeof holder, "/%g/\n", 4214.2345);
+ asprintf(&h, "/%g/\n", 4214.2345);
+ printf("/%g/\n", 4214.2345);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%.5g/, 4214.2345\n");
+ snprintf(holder, sizeof holder, "/%.5g/\n", 4214.2345);
+ asprintf(&h, "/%.5g/\n", 4214.2345);
+ printf("/%.5g/\n", 4214.2345);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%.4g/, 4214.2345\n");
+ snprintf(holder, sizeof holder, "/%.4g/\n", 4214.2345);
+ asprintf(&h, "/%.4g/\n", 4214.2345);
+ printf("/%.4g/\n", 4214.2345);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%'ld %%'ld/, 12345, 1234567\n");
+ snprintf(holder, sizeof holder, "/%'ld %'ld/\n", 12345, 1234567);
+ asprintf(&h, "/%'ld %'ld/\n", 12345, 1234567);
+ printf("/%'ld %'ld/\n", 12345, 1234567);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%'ld %%'ld/, 336, 3336\n");
+ snprintf(holder, sizeof holder, "/%'ld %'ld/\n", 336, 3336);
+ asprintf(&h, "/%'ld %'ld/\n", 336, 3336);
+ printf("/%'ld %'ld/\n", 336, 3336);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%'ld %%'ld/, -42786, -142786\n");
+ snprintf(holder, sizeof holder, "/%'ld %'ld/\n", -42786, -142786);
+ asprintf(&h, "/%'ld %'ld/\n", -42786, -142786);
+ printf("/%'ld %'ld/\n", -42786, -142786);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%'f %%'f/, 421.2345, 421234.56789\n");
+ snprintf(holder, sizeof holder, "/%'f %'f/\n", 421.2345, 421234.56789);
+ asprintf(&h, "/%'f %'f/\n", 421.2345, 421234.56789);
+ printf("/%'f %'f/\n", 421.2345, 421234.56789);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%'f %%'f/, -421.2345, -421234.56789\n");
+ snprintf(holder, sizeof holder, "/%'f %'f/\n", -421.2345, -421234.56789);
+ asprintf(&h, "/%'f %'f/\n", -421.2345, -421234.56789);
+ printf("/%'f %'f/\n", -421.2345, -421234.56789);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%'g %%'g/, 421.2345, 421234.56789\n");
+ snprintf(holder, sizeof holder, "/%'g %'g/\n", 421.2345, 421234.56789);
+ asprintf(&h, "/%'g %'g/\n", 421.2345, 421234.56789);
+ printf("/%'g %'g/\n", 421.2345, 421234.56789);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ printf("/%%'g %%'g/, -421.2345, -421234.56789\n");
+ snprintf(holder, sizeof holder, "/%'g %'g/\n", -421.2345, -421234.56789);
+ asprintf(&h, "/%'g %'g/\n", -421.2345, -421234.56789);
+ printf("/%'g %'g/\n", -421.2345, -421234.56789);
+ printf("%s", holder);
+ printf("%s\n", h);
+#endif
+
+ printf("/%%'g/, 4213455.8392\n");
+ snprintf(holder, sizeof holder, "/%'g/\n", 4213455.8392);
+ asprintf(&h, "/%'g/\n", 4213455.8392);
+ printf("/%'g/\n", 4213455.8392);
+ printf("%s", holder);
+ printf("%s\n", h);
+
+ exit (0);
+}
+#endif
}
t_string[tlen] = '\0';
+#if defined (MACOSX)
+ /* Convert from "fs" format to "input" format */
+ temp = fnx_fromfs (t_string, strlen (t_string));
+ if (temp != t_string)
+ strcpy (t_string, temp);
+#endif
+
#define ROOT_PATH(x) ((x)[0] == '/' && (x)[1] == 0)
#define DOUBLE_SLASH_ROOT(x) ((x)[0] == '/' && (x)[1] == '/' && (x)[2] == 0)
/* Abbreviate \W as ~ if $PWD == $HOME */
%token IN BANG TIME TIMEOPT
/* More general tokens. yylex () knows how to make these. */
-%token <word> WORD ASSIGNMENT_WORD
+%token <word> WORD ASSIGNMENT_WORD REDIR_WORD
%token <number> NUMBER
%token <word_list> ARITH_CMD ARITH_FOR_EXPRS
%token <command> COND_CMD
redir.filename = $3;
$$ = make_redirection (source, r_input_direction, redir, 0);
}
+ | REDIR_WORD '>' WORD
+ {
+ source.filename = $1;
+ redir.filename = $3;
+ $$ = make_redirection (source, r_output_direction, redir, REDIR_VARASSIGN);
+ }
+ | REDIR_WORD '<' WORD
+ {
+ source.filename = $1;
+ redir.filename = $3;
+ $$ = make_redirection (source, r_input_direction, redir, REDIR_VARASSIGN);
+ }
| GREATER_GREATER WORD
{
source.dest = 1;
redir.filename = $3;
$$ = make_redirection (source, r_appending_to, redir, 0);
}
+ | REDIR_WORD GREATER_GREATER WORD
+ {
+ source.filename = $1;
+ redir.filename = $3;
+ $$ = make_redirection (source, r_appending_to, redir, REDIR_VARASSIGN);
+ }
+ | GREATER_BAR WORD
+ {
+ source.dest = 1;
+ redir.filename = $2;
+ $$ = make_redirection (source, r_output_force, redir, 0);
+ }
+ | NUMBER GREATER_BAR WORD
+ {
+ source.dest = $1;
+ redir.filename = $3;
+ $$ = make_redirection (source, r_output_force, redir, 0);
+ }
+ | REDIR_WORD GREATER_BAR WORD
+ {
+ source.filename = $1;
+ redir.filename = $3;
+ $$ = make_redirection (source, r_output_force, redir, REDIR_VARASSIGN);
+ }
+ | LESS_GREATER WORD
+ {
+ source.dest = 0;
+ redir.filename = $2;
+ $$ = make_redirection (source, r_input_output, redir, 0);
+ }
+ | NUMBER LESS_GREATER WORD
+ {
+ source.dest = $1;
+ redir.filename = $3;
+ $$ = make_redirection (source, r_input_output, redir, 0);
+ }
+ | REDIR_WORD LESS_GREATER WORD
+ {
+ source.filename = $1;
+ redir.filename = $3;
+ $$ = make_redirection (source, r_input_output, redir, REDIR_VARASSIGN);
+ }
| LESS_LESS WORD
{
source.dest = 0;
$$ = make_redirection (source, r_reading_until, redir, 0);
redir_stack[need_here_doc++] = $$;
}
+ | REDIR_WORD LESS_LESS WORD
+ {
+ source.filename = $1;
+ redir.filename = $3;
+ $$ = make_redirection (source, r_reading_until, redir, REDIR_VARASSIGN);
+ redir_stack[need_here_doc++] = $$;
+ }
+ | LESS_LESS_MINUS WORD
+ {
+ source.dest = 0;
+ redir.filename = $2;
+ $$ = make_redirection (source, r_deblank_reading_until, redir, 0);
+ redir_stack[need_here_doc++] = $$;
+ }
+ | NUMBER LESS_LESS_MINUS WORD
+ {
+ source.dest = $1;
+ redir.filename = $3;
+ $$ = make_redirection (source, r_deblank_reading_until, redir, 0);
+ redir_stack[need_here_doc++] = $$;
+ }
+ | REDIR_WORD LESS_LESS_MINUS WORD
+ {
+ source.filename = $1;
+ redir.filename = $3;
+ $$ = make_redirection (source, r_deblank_reading_until, redir, REDIR_VARASSIGN);
+ redir_stack[need_here_doc++] = $$;
+ }
| LESS_LESS_LESS WORD
{
source.dest = 0;
redir.filename = $3;
$$ = make_redirection (source, r_reading_string, redir, 0);
}
+ | REDIR_WORD LESS_LESS_LESS WORD
+ {
+ source.filename = $1;
+ redir.filename = $3;
+ $$ = make_redirection (source, r_reading_string, redir, REDIR_VARASSIGN);
+ }
| LESS_AND NUMBER
{
source.dest = 0;
redir.dest = $3;
$$ = make_redirection (source, r_duplicating_input, redir, 0);
}
+ | REDIR_WORD LESS_AND NUMBER
+ {
+ source.filename = $1;
+ redir.dest = $3;
+ $$ = make_redirection (source, r_duplicating_input, redir, REDIR_VARASSIGN);
+ }
| GREATER_AND NUMBER
{
source.dest = 1;
redir.dest = $3;
$$ = make_redirection (source, r_duplicating_output, redir, 0);
}
+ | REDIR_WORD GREATER_AND NUMBER
+ {
+ source.filename = $1;
+ redir.dest = $3;
+ $$ = make_redirection (source, r_duplicating_output, redir, REDIR_VARASSIGN);
+ }
| LESS_AND WORD
{
source.dest = 0;
redir.filename = $3;
$$ = make_redirection (source, r_duplicating_input_word, redir, 0);
}
+ | REDIR_WORD LESS_AND WORD
+ {
+ source.filename = $1;
+ redir.filename = $3;
+ $$ = make_redirection (source, r_duplicating_input_word, redir, REDIR_VARASSIGN);
+ }
| GREATER_AND WORD
{
source.dest = 1;
redir.filename = $3;
$$ = make_redirection (source, r_duplicating_output_word, redir, 0);
}
- | LESS_LESS_MINUS WORD
- {
- source.dest = 0;
- redir.filename = $2;
- $$ = make_redirection (source, r_deblank_reading_until, redir, 0);
- redir_stack[need_here_doc++] = $$;
- }
- | NUMBER LESS_LESS_MINUS WORD
+ | REDIR_WORD GREATER_AND WORD
{
- source.dest = $1;
+ source.filename = $1;
redir.filename = $3;
- $$ = make_redirection (source, r_deblank_reading_until, redir, 0);
- redir_stack[need_here_doc++] = $$;
+ $$ = make_redirection (source, r_duplicating_output_word, redir, REDIR_VARASSIGN);
}
| GREATER_AND '-'
{
redir.dest = 0;
$$ = make_redirection (source, r_close_this, redir, 0);
}
+ | REDIR_WORD GREATER_AND '-'
+ {
+ source.filename = $1;
+ redir.dest = 0;
+ $$ = make_redirection (source, r_close_this, redir, REDIR_VARASSIGN);
+ }
| LESS_AND '-'
{
source.dest = 0;
redir.dest = 0;
$$ = make_redirection (source, r_close_this, redir, 0);
}
+ | REDIR_WORD LESS_AND '-'
+ {
+ source.filename = $1;
+ redir.dest = 0;
+ $$ = make_redirection (source, r_close_this, redir, REDIR_VARASSIGN);
+ }
| AND_GREATER WORD
{
source.dest = 1;
redir.filename = $2;
$$ = make_redirection (source, r_append_err_and_out, redir, 0);
}
- | NUMBER LESS_GREATER WORD
- {
- source.dest = $1;
- redir.filename = $3;
- $$ = make_redirection (source, r_input_output, redir, 0);
- }
- | LESS_GREATER WORD
- {
- source.dest = 0;
- redir.filename = $2;
- $$ = make_redirection (source, r_input_output, redir, 0);
- }
- | GREATER_BAR WORD
- {
- source.dest = 1;
- redir.filename = $2;
- $$ = make_redirection (source, r_output_force, redir, 0);
- }
- | NUMBER GREATER_BAR WORD
- {
- source.dest = $1;
- redir.filename = $3;
- $$ = make_redirection (source, r_output_force, redir, 0);
- }
;
simple_command_element: WORD
yylval.word = the_word;
+ if (token[0] == '{' && token[token_index-1] == '}' &&
+ (character == '<' || character == '>'))
+ {
+ /* can use token; already copied to the_word */
+ token[token_index-1] = '\0';
+ if (legal_identifier (token+1))
+ {
+ strcpy (the_word->word, token+1);
+/*itrace("read_token_word: returning REDIR_WORD for %s", the_word->word);*/
+ return (REDIR_WORD);
+ }
+ }
+
result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT))
? ASSIGNMENT_WORD : WORD;
}
t_string[tlen] = '\0';
+#if defined (MACOSX)
+temp = fnx_fromfs (t_string, tlen);
+if (temp != t_string)
+ strcpy (t_string, temp);
+#endif
#define ROOT_PATH(x) ((x)[0] == '/' && (x)[1] == 0)
#define DOUBLE_SLASH_ROOT(x) ((x)[0] == '/' && (x)[1] == '/' && (x)[2] == 0)
/* Abbreviate \W as ~ if $PWD == $HOME */
# Set of available languages.
-en@quot en@boldquot af bg ca cs de eo es et fi fr hu id ja lt nl pl pt_BR ro ru sk sv tr vi zh_TW
+en@quot en@boldquot af bg ca cs de eo es et fi fr ga hu id ja lt nl pl pt_BR ro ru sk sv tr vi zh_TW
# Set of available languages.
-en@quot en@boldquot af bg ca cs de eo es et fr hu id ja lt nl pl pt_BR ro ru sk sv tr vi zh_TW
+en@quot en@boldquot af bg ca cs de eo es et fi fr hu id ja lt nl pl pt_BR ro ru sk sv tr vi zh_TW
"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: 2009-03-19 09:21+0100\n"
+"PO-Revision-Date: 2009-09-23 14:23+0200\n"
"Last-Translator: Petr Pisar <petr.pisar@atlas.cz>\n"
"Language-Team: Czech <translation-team-cs@lists.sourceforge.net>\n"
"MIME-Version: 1.0\n"
msgid "Signal %d"
msgstr "Signál %d"
-# FIXME: rod a zkontrolovat následující
+# XXX: (úloha) dokončna. Používat ženský rod i unásledujících. Jedná se
+# o výpis úloh.
#: jobs.c:1430 jobs.c:1455
msgid "Done"
-msgstr "Dokonán"
+msgstr "Dokončena"
#: jobs.c:1435 siglist.c:122
msgid "Stopped"
-msgstr "Pozastaven"
+msgstr "Pozastavena"
#: jobs.c:1439
#, c-format
msgid "Stopped(%s)"
-msgstr "Pozastaven (%s)"
+msgstr "Pozastavena (%s)"
#: jobs.c:1443
msgid "Running"
#: jobs.c:1457
#, c-format
msgid "Done(%d)"
-msgstr "Dokonán (%d)"
+msgstr "Dokončena (%d)"
#: jobs.c:1459
#, c-format
msgid "Exit %d"
-msgstr "Ukončen %d"
+msgstr "Ukončena %d"
#: jobs.c:1462
msgid "Unknown status"
--- /dev/null
+# translation of bash4.po to Irish
+# Copyright (C) 2009 Free Software Foundation, Inc.
+# This file is distributed under the same license as the bash package.
+#
+# Séamus Ó Ciardhuáin <seoc(at)iolfree.ie>, 2009.
+msgid ""
+msgstr ""
+"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: 2009-09-24 23:08+0100\n"
+"Last-Translator: Séamus Ó Ciardhuáin <seoc@iolfree.ie>\n"
+"Language-Team: Irish <gaeilge-gnulinux@lists.sourceforge.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2;\n"
+
+#: arrayfunc.c:50
+msgid "bad array subscript"
+msgstr "droch-fhoscript eagair"
+
+#: arrayfunc.c:313 builtins/declare.def:474
+#, c-format
+msgid "%s: cannot convert indexed to associative array"
+msgstr ""
+
+#: arrayfunc.c:479
+#, c-format
+msgid "%s: invalid associative array key"
+msgstr ""
+
+#: arrayfunc.c:481
+#, c-format
+msgid "%s: cannot assign to non-numeric index"
+msgstr "%s: ní féidir sannadh go hinnéacs neamhuimhriúil."
+
+#: arrayfunc.c:517
+#, c-format
+msgid "%s: %s: must use subscript when assigning associative array"
+msgstr ""
+
+#: bashhist.c:379
+#, c-format
+msgid "%s: cannot create: %s"
+msgstr "%s: ní féidir cruthú: %s"
+
+#: bashline.c:3413
+msgid "bash_execute_unix_command: cannot find keymap for command"
+msgstr "bash_execute_unix_command: ní féidir mapa eochrach an ordaithe a aimsiú"
+
+#: bashline.c:3491
+#, c-format
+msgid "%s: first non-whitespace character is not `\"'"
+msgstr "%s: ní \" é an chéad charachtar nach spás bán é."
+
+#: bashline.c:3520
+#, c-format
+msgid "no closing `%c' in %s"
+msgstr "Níl \"%c\" dúnta i %s"
+
+#: bashline.c:3554
+#, c-format
+msgid "%s: missing colon separator"
+msgstr "%s: deighilteoir idirstaid ar iarraidh"
+
+#: builtins/bind.def:120 builtins/bind.def:123
+msgid "line editing not enabled"
+msgstr "níl eagarthóireacht líne cumasaithe"
+
+#: builtins/bind.def:206
+#, c-format
+msgid "`%s': invalid keymap name"
+msgstr "\"%s\": ainm neamhbhailí ar mhapa eochrach "
+
+#: builtins/bind.def:245
+#, c-format
+msgid "%s: cannot read: %s"
+msgstr "%s: ní féidir léamh: %s"
+
+#: builtins/bind.def:260
+#, c-format
+msgid "`%s': cannot unbind"
+msgstr "\"%s\": ní féidir dícheangail"
+
+#: builtins/bind.def:295 builtins/bind.def:325
+#, c-format
+msgid "`%s': unknown function name"
+msgstr "\"%s\": ainm feidhme anaithnid"
+
+#: builtins/bind.def:303
+#, c-format
+msgid "%s is not bound to any keys.\n"
+msgstr "Níl %s ceangailte le heochair ar bith.\n"
+
+#: builtins/bind.def:307
+#, c-format
+msgid "%s can be invoked via "
+msgstr "Is féidir %s a ghlaoigh trí "
+
+#: builtins/break.def:77 builtins/break.def:117
+msgid "loop count"
+msgstr "comhaireamh lúibe"
+
+#: builtins/break.def:137
+msgid "only meaningful in a `for', `while', or `until' loop"
+msgstr "Gan chiall ach i lúb \"for\", \"while\" nó \"until\""
+
+#: builtins/caller.def:133
+msgid ""
+"Returns the context of the current subroutine call.\n"
+" \n"
+" Without EXPR, returns "
+msgstr ""
+
+#: builtins/cd.def:215
+msgid "HOME not set"
+msgstr "Níl HOME socruithe"
+
+#: builtins/cd.def:227
+msgid "OLDPWD not set"
+msgstr "Níl OLDPWD socruithe"
+
+#: builtins/common.c:101
+#, c-format
+msgid "line %d: "
+msgstr "líne %d: "
+
+#: builtins/common.c:139 error.c:260
+#, c-format
+msgid "warning: "
+msgstr "rabhadh: "
+
+#: builtins/common.c:153
+#, c-format
+msgid "%s: usage: "
+msgstr "%s: úsáid: "
+
+#: builtins/common.c:166 test.c:822
+msgid "too many arguments"
+msgstr "An iomarca argóintí"
+
+#: builtins/common.c:191 shell.c:493 shell.c:774
+#, c-format
+msgid "%s: option requires an argument"
+msgstr "%s: tá argóint riachtanach don rogha"
+
+#: builtins/common.c:198
+#, c-format
+msgid "%s: numeric argument required"
+msgstr "%s: argóint uimhriúil de dhíth"
+
+#: builtins/common.c:205
+#, c-format
+msgid "%s: not found"
+msgstr "%s: gan aimsiú"
+
+#: builtins/common.c:214 shell.c:787
+#, c-format
+msgid "%s: invalid option"
+msgstr "%s: rogha neamhbhailí"
+
+#: builtins/common.c:221
+#, c-format
+msgid "%s: invalid option name"
+msgstr "%s: ainm neamhbhailí rogha"
+
+#: builtins/common.c:228 general.c:231 general.c:236
+#, c-format
+msgid "`%s': not a valid identifier"
+msgstr "\"%s\": ní aitheantóir bailí é"
+
+#: builtins/common.c:238
+msgid "invalid octal number"
+msgstr "uimhir ochtnártha neamhbhailí"
+
+#: builtins/common.c:240
+msgid "invalid hex number"
+msgstr "uimhir heicsidheachúlach neamhbhailí"
+
+#: builtins/common.c:242 expr.c:1255
+msgid "invalid number"
+msgstr "uimhir neamhbhailí"
+
+#: builtins/common.c:250
+#, c-format
+msgid "%s: invalid signal specification"
+msgstr "%s: sonrú neamhbhailí comhartha"
+
+#: builtins/common.c:257
+#, c-format
+msgid "`%s': not a pid or valid job spec"
+msgstr "\"%s\": ní aitheantas próisis nó sonrú jab bailí é"
+
+#: builtins/common.c:264 error.c:453
+#, c-format
+msgid "%s: readonly variable"
+msgstr "%s: athróg inléite amháin"
+
+#: builtins/common.c:272
+#, c-format
+msgid "%s: %s out of range"
+msgstr "%s: %s as raon"
+
+#: builtins/common.c:272 builtins/common.c:274
+msgid "argument"
+msgstr "argóint"
+
+#: builtins/common.c:274
+#, c-format
+msgid "%s out of range"
+msgstr "%s as raon"
+
+#: builtins/common.c:282
+#, c-format
+msgid "%s: no such job"
+msgstr "%s: níl a léithéid de jab ann."
+
+#: builtins/common.c:290
+#, c-format
+msgid "%s: no job control"
+msgstr "%s: gan rialú jabanna."
+
+#: builtins/common.c:292
+msgid "no job control"
+msgstr "Gan rialú jabanna."
+
+#: builtins/common.c:302
+#, c-format
+msgid "%s: restricted"
+msgstr "%s: srianta"
+
+#: builtins/common.c:304
+msgid "restricted"
+msgstr "srianta"
+
+#: builtins/common.c:312
+#, c-format
+msgid "%s: not a shell builtin"
+msgstr "%s: ní ordú ionsuite blaoisce é."
+
+#: builtins/common.c:321
+#, c-format
+msgid "write error: %s"
+msgstr "earráid scríofa: %s"
+
+#: builtins/common.c:329
+#, c-format
+msgid "error setting terminal attributes: %s"
+msgstr "earráid agus airíonna teirminéil á socrú: %s"
+
+#: builtins/common.c:331
+#, c-format
+msgid "error getting terminal attributes: %s"
+msgstr "earráid agus airíonna teirminéil á fáil: %s"
+
+#: builtins/common.c:563
+#, c-format
+msgid "%s: error retrieving current directory: %s: %s\n"
+msgstr "%s: earráid ag fáil na comhadlainne reatha: %s: %s\n"
+
+#: builtins/common.c:629 builtins/common.c:631
+#, c-format
+msgid "%s: ambiguous job spec"
+msgstr "%s: sonrú jab athbhríoch"
+
+#: builtins/complete.def:270
+#, c-format
+msgid "%s: invalid action name"
+msgstr "%s: ainm neamhbhailí gnímh"
+
+#: builtins/complete.def:430 builtins/complete.def:615
+#: builtins/complete.def:813
+#, c-format
+msgid "%s: no completion specification"
+msgstr "%s: níl sonrú iomlánaithe ann."
+
+#: builtins/complete.def:667
+msgid "warning: -F option may not work as you expect"
+msgstr "Rabhadh: b'fhéidir nach n-oibríonn an rogha -F mar a bheifeá ag súil leis."
+
+#: builtins/complete.def:669
+msgid "warning: -C option may not work as you expect"
+msgstr "Rabhadh: b'fhéidir nach n-oibríonn an rogha -C mar a bheifeá ag súil leis."
+
+#: builtins/complete.def:786
+msgid "not currently executing completion function"
+msgstr ""
+
+#: builtins/declare.def:122
+msgid "can only be used in a function"
+msgstr "Inúsáidte i bhfeidhmeanna amháin. "
+
+#: builtins/declare.def:353
+msgid "cannot use `-f' to make functions"
+msgstr "Ní féidir \"-f\" a úsáid chun feidhmeanna a dhéanamh"
+
+#: builtins/declare.def:365 execute_cmd.c:4818
+#, c-format
+msgid "%s: readonly function"
+msgstr "%s: feidhm inléite amháin"
+
+#: builtins/declare.def:461
+#, c-format
+msgid "%s: cannot destroy array variables in this way"
+msgstr "%s: ní féidir athróga eagair a scrios mar seo."
+
+#: builtins/declare.def:468
+#, c-format
+msgid "%s: cannot convert associative to indexed array"
+msgstr ""
+
+#: builtins/enable.def:137 builtins/enable.def:145
+msgid "dynamic loading not available"
+msgstr "Níl luchtú dinimiciúil ar fáil"
+
+#: builtins/enable.def:312
+#, c-format
+msgid "cannot open shared object %s: %s"
+msgstr "Ní féidir an réad comhroinnte %s a oscailt: %s"
+
+#: builtins/enable.def:335
+#, c-format
+msgid "cannot find %s in shared object %s: %s"
+msgstr "Ní féidir %s a aimsiú sa réad comhroinnte %s: %s"
+
+#: builtins/enable.def:459
+#, c-format
+msgid "%s: not dynamically loaded"
+msgstr "%s: níl sé luchtaithe go dinimiciúil"
+
+#: builtins/enable.def:474
+#, c-format
+msgid "%s: cannot delete: %s"
+msgstr "%s: ní féidir scrios: %s"
+
+#: builtins/evalfile.c:134 builtins/hash.def:169 execute_cmd.c:4675
+#: shell.c:1439
+#, c-format
+msgid "%s: is a directory"
+msgstr "%s: is comhadlann é"
+
+#: builtins/evalfile.c:139
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: ní gnáthchomhad é"
+
+#: builtins/evalfile.c:147
+#, c-format
+msgid "%s: file is too large"
+msgstr "%s: tá an comhad ró-mhór"
+
+#: builtins/evalfile.c:185 execute_cmd.c:4745 shell.c:1449
+#, c-format
+msgid "%s: cannot execute binary file"
+msgstr "%s: ní féidir comhad dénártha a rith"
+
+#: builtins/exec.def:212
+#, c-format
+msgid "%s: cannot execute: %s"
+msgstr "%s: ní féidir rith: %s"
+
+#: builtins/exit.def:65
+#, c-format
+msgid "logout\n"
+msgstr "logout\n"
+
+#: builtins/exit.def:88
+msgid "not login shell: use `exit'"
+msgstr "Ní blaosc logála isteach é seo: úsáid \"exit\""
+
+#: builtins/exit.def:120
+#, c-format
+msgid "There are stopped jobs.\n"
+msgstr "Tá jabanna stoptha ann.\n"
+
+#: builtins/exit.def:122
+#, c-format
+msgid "There are running jobs.\n"
+msgstr "Tá jabanna ag rith.\n"
+
+#: builtins/fc.def:261
+msgid "no command found"
+msgstr "Níor aimsíodh ordú"
+
+#: builtins/fc.def:341
+msgid "history specification"
+msgstr "Sonrú staire"
+
+#: builtins/fc.def:362
+#, c-format
+msgid "%s: cannot open temp file: %s"
+msgstr "%s: ní féidir comhad sealadach a oscailt: %s"
+
+#: builtins/fg_bg.def:149 builtins/jobs.def:282
+msgid "current"
+msgstr "reatha"
+
+#: builtins/fg_bg.def:158
+#, c-format
+msgid "job %d started without job control"
+msgstr "Thosaigh jab %d gan rialú jabanna."
+
+#: builtins/getopt.c:110
+#, c-format
+msgid "%s: illegal option -- %c\n"
+msgstr "%s: rogha neamhdhleathach -- %c\n"
+
+#: builtins/getopt.c:111
+#, c-format
+msgid "%s: option requires an argument -- %c\n"
+msgstr "%s: tá argóint riachtanach don rogha -- %c\n"
+
+#: builtins/hash.def:92
+msgid "hashing disabled"
+msgstr "Tá haiseáil díchumasaithe."
+
+#: builtins/hash.def:138
+#, c-format
+msgid "%s: hash table empty\n"
+msgstr "%s: tá an tábla haiseála folamh.\n"
+
+#: builtins/hash.def:244
+#, c-format
+msgid "hits\tcommand\n"
+msgstr "amais\tordú\n"
+
+#: builtins/help.def:130
+#, c-format
+msgid "Shell commands matching keyword `"
+msgid_plural "Shell commands matching keywords `"
+msgstr[0] "Ordaithe blaoisce a mheaitseálann an lorgfhocal '"
+msgstr[1] "Ordaithe blaoisce a mheaitseálann na lorgfhocail '"
+msgstr[2] "Ordaithe blaoisce a mheaitseálann na lorgfhocail '"
+
+#: builtins/help.def:168
+#, c-format
+msgid "no help topics match `%s'. Try `help help' or `man -k %s' or `info %s'."
+msgstr "Ní mheaitseálann ábhar cabhrach ar bith \"%s\". Bain triail as \"help help\" nó \"man -k %s\" nó \"info %s\"."
+
+#: builtins/help.def:185
+#, c-format
+msgid "%s: cannot open: %s"
+msgstr "%s: ní féidir oscailt: %s"
+
+#: builtins/help.def:337
+#, c-format
+msgid ""
+"These shell commands are defined internally. Type `help' to see this list.\n"
+"Type `help name' to find out more about the function `name'.\n"
+"Use `info bash' to find out more about the shell in general.\n"
+"Use `man -k' or `info' to find out more about commands not in this list.\n"
+"\n"
+"A star (*) next to a name means that the command is disabled.\n"
+"\n"
+msgstr ""
+"Tá na horduithe blaoisce seo sainmhínithe go hinmheánach.\n"
+"Usáid \"help\" leis an liosta seo a thaispeáint.\n"
+"Úsáid \"help ainm\" chun tuilleadh eolais a fháil faoin bhfeidhm \"ainm\".\n"
+"Úsáid \"info bash\" chun tuilleadh eolais a fháil faoin mblaosc féin.\n"
+"Úsáid \"man -k\" nó \"info\" chun tuilleadh eolais a fháil faoi ordaithe nach bhfuil sa liosta seo.\n"
+"Ciallaíonn réalt (*) ar ainm go bhfuil an t-ordú díchumasaithe.\n"
+"\n"
+
+#: builtins/history.def:154
+msgid "cannot use more than one of -anrw"
+msgstr "Ní féidir níos mó ná ceann amháin as -anrw a úsáid."
+
+#: builtins/history.def:186
+msgid "history position"
+msgstr "suíomh staire"
+
+#: builtins/history.def:365
+#, c-format
+msgid "%s: history expansion failed"
+msgstr "%s: theip ar fhairsingiú staire."
+
+#: builtins/inlib.def:71
+#, c-format
+msgid "%s: inlib failed"
+msgstr "%s: theip ar inlib"
+
+#: builtins/jobs.def:109
+msgid "no other options allowed with `-x'"
+msgstr "Níl roghanna eile ceadaithe le \"-x\""
+
+#: builtins/kill.def:197
+#, c-format
+msgid "%s: arguments must be process or job IDs"
+msgstr "%s: is gá le argóintí bheith ina aitheantais phróisis nó jab"
+
+#: builtins/kill.def:260
+msgid "Unknown error"
+msgstr "Earráid anaithnid"
+
+#: builtins/let.def:95 builtins/let.def:120 expr.c:501 expr.c:516
+msgid "expression expected"
+msgstr "Ag súil le slonn"
+
+#: builtins/mapfile.def:241 builtins/read.def:272
+#, c-format
+msgid "%s: invalid file descriptor specification"
+msgstr "%s: sonrú neamhbhailí tuairisceora comhaid"
+
+#: builtins/mapfile.def:249 builtins/read.def:279
+#, c-format
+msgid "%d: invalid file descriptor: %s"
+msgstr "%d: tuairisceoir comhaid neamhbhailí: %s"
+
+#: builtins/mapfile.def:258 builtins/mapfile.def:296
+#, c-format
+msgid "%s: invalid line count"
+msgstr "%s: comhaireamh neamhbhailí línte"
+
+#: builtins/mapfile.def:269
+#, c-format
+msgid "%s: invalid array origin"
+msgstr ""
+
+#: builtins/mapfile.def:286
+#, c-format
+msgid "%s: invalid callback quantum"
+msgstr ""
+
+#: builtins/mapfile.def:318
+msgid "empty array variable name"
+msgstr "ainm folamh athróga eagair"
+
+#: builtins/mapfile.def:339
+msgid "array variable support required"
+msgstr "tacaíocht le hathróga eagair de dhíth"
+
+#: builtins/printf.def:367
+#, c-format
+msgid "`%s': missing format character"
+msgstr "\"%s\": carachtar formáide ar iarraidh."
+
+#: builtins/printf.def:544
+#, c-format
+msgid "`%c': invalid format character"
+msgstr "\"%c\": carachtar formáide neamhbhailí."
+
+#: builtins/printf.def:571
+#, c-format
+msgid "warning: %s: %s"
+msgstr "rabhadh: %s: %s"
+
+#: builtins/printf.def:750
+msgid "missing hex digit for \\x"
+msgstr "digit heicsidheachúlach ar iarraidh le haghaidh \\x"
+
+#: builtins/pushd.def:195
+msgid "no other directory"
+msgstr "Níl comhadlann eile ann"
+
+#: builtins/pushd.def:462
+msgid "<no current directory>"
+msgstr "<níl comhadlann reatha ann>"
+
+#: builtins/pushd.def:506
+msgid "directory stack empty"
+msgstr "cruach fholamh chomhadlainne"
+
+#: builtins/pushd.def:508
+msgid "directory stack index"
+msgstr "innéacs cruaiche comhadlainne"
+
+#: builtins/pushd.def:683
+msgid ""
+"Display the list of currently remembered directories. Directories\n"
+" find their way onto the list with the `pushd' command; you can get\n"
+" back up through the list with the `popd' command.\n"
+" \n"
+" Options:\n"
+" -c\tclear the directory stack by deleting all of the elements\n"
+" -l\tdo not print tilde-prefixed versions of directories relative\n"
+" \tto your home directory\n"
+" -p\tprint the directory stack with one entry per line\n"
+" -v\tprint the directory stack with one entry per line prefixed\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"
+" \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"
+"\tdirs when invoked without options, starting with zero."
+msgstr ""
+
+#: builtins/pushd.def:705
+msgid ""
+"Adds a directory to the top of the directory stack, or rotates\n"
+" the stack, making the new top of the stack the current working\n"
+" directory. With no arguments, exchanges the top two directories.\n"
+" \n"
+" Options:\n"
+" -n\tSuppresses the normal change of directory when adding\n"
+" \tdirectories to the stack, so only the stack is manipulated.\n"
+" \n"
+" Arguments:\n"
+" +N\tRotates the stack so that the Nth directory (counting\n"
+" \tfrom the left of the list shown by `dirs', starting with\n"
+" \tzero) is at the top.\n"
+" \n"
+" -N\tRotates the stack so that the Nth directory (counting\n"
+" \tfrom the right of the list shown by `dirs', starting with\n"
+" \tzero) is at the top.\n"
+" \n"
+" dir\tAdds DIR to the directory stack at the top, making it the\n"
+" \tnew current working directory.\n"
+" \n"
+" The `dirs' builtin displays the directory stack."
+msgstr ""
+
+#: builtins/pushd.def:730
+msgid ""
+"Removes entries from the directory stack. With no arguments, removes\n"
+" the top directory from the stack, and changes to the new top directory.\n"
+" \n"
+" Options:\n"
+" -n\tSuppresses the normal change of directory when removing\n"
+" \tdirectories from the stack, so only the stack is manipulated.\n"
+" \n"
+" Arguments:\n"
+" +N\tRemoves the Nth entry counting from the left of the list\n"
+" \tshown by `dirs', starting with zero. For example: `popd +0'\n"
+" \tremoves the first directory, `popd +1' the second.\n"
+" \n"
+" -N\tRemoves the Nth entry counting from the right of the list\n"
+" \tshown by `dirs', starting with zero. For example: `popd -0'\n"
+" \tremoves the last directory, `popd -1' the next to last.\n"
+" \n"
+" The `dirs' builtin displays the directory stack."
+msgstr ""
+
+#: builtins/read.def:248
+#, c-format
+msgid "%s: invalid timeout specification"
+msgstr "%s: sonrú neamhbhailí teorann ama"
+
+#: builtins/read.def:574
+#, c-format
+msgid "read error: %d: %s"
+msgstr "earráid léite: %d: %s"
+
+#: builtins/return.def:73
+msgid "can only `return' from a function or sourced script"
+msgstr "ní féidir \"return\" a dhéanamh ach ó fheidhm nó ó script rite le \"source\""
+
+#: builtins/set.def:768
+msgid "cannot simultaneously unset a function and a variable"
+msgstr "Ní féidir feidhm agus athróg a dhíshocrú ag an am céanna."
+
+#: builtins/set.def:805
+#, c-format
+msgid "%s: cannot unset"
+msgstr "%s: ní féidir díshocrú"
+
+#: builtins/set.def:812
+#, c-format
+msgid "%s: cannot unset: readonly %s"
+msgstr "%s: ní féidir díshocrú: %s inléite amháin"
+
+#: builtins/set.def:823
+#, c-format
+msgid "%s: not an array variable"
+msgstr "%s: ní athróg eagair é"
+
+#: builtins/setattr.def:186
+#, c-format
+msgid "%s: not a function"
+msgstr "%s: ní feidhm é."
+
+#: builtins/shift.def:71 builtins/shift.def:77
+msgid "shift count"
+msgstr "comhaireamh iomlaoide"
+
+#: builtins/shopt.def:254
+msgid "cannot set and unset shell options simultaneously"
+msgstr "Ní féidir roghanna blaoisce a shocrú agus a dhíshocrú ag an am céanna."
+
+#: builtins/shopt.def:319
+#, c-format
+msgid "%s: invalid shell option name"
+msgstr "%s: ainm neamhbhailí ar rogha blaoisce"
+
+#: builtins/source.def:128
+msgid "filename argument required"
+msgstr "Is gá don argóint bheith ina ainm comhaid."
+
+#: builtins/source.def:153
+#, c-format
+msgid "%s: file not found"
+msgstr "%s: níor aimsíodh an comhad"
+
+#: builtins/suspend.def:101
+msgid "cannot suspend"
+msgstr "Ní féidir cur ar fionraí."
+
+#: builtins/suspend.def:111
+msgid "cannot suspend a login shell"
+msgstr "Ní féidir blaosc logála isteach a chur ar fionraí."
+
+#: builtins/type.def:234
+#, c-format
+msgid "%s is aliased to `%s'\n"
+msgstr "Tá %s ailiasáilte go \"%s\".\n"
+
+#: builtins/type.def:255
+#, c-format
+msgid "%s is a shell keyword\n"
+msgstr "Is eochairfhocal blaoisce é %s.\n"
+
+#: builtins/type.def:274
+#, c-format
+msgid "%s is a function\n"
+msgstr "Is feidhm é %s.\n"
+
+#: builtins/type.def:296
+#, c-format
+msgid "%s is a shell builtin\n"
+msgstr "Is ordú ionsuite blaoisce é %s\n"
+
+#: builtins/type.def:317 builtins/type.def:391
+#, c-format
+msgid "%s is %s\n"
+msgstr "Tá %s %s\n"
+
+#: builtins/type.def:337
+#, c-format
+msgid "%s is hashed (%s)\n"
+msgstr "Tá %s haiseáilte (%s)\n"
+
+#: builtins/ulimit.def:372
+#, c-format
+msgid "%s: invalid limit argument"
+msgstr "%s: argóint teorann neamhbhailí"
+
+#: builtins/ulimit.def:398
+#, c-format
+msgid "`%c': bad command"
+msgstr "\"%c\": droch-ordú"
+
+#: builtins/ulimit.def:427
+#, c-format
+msgid "%s: cannot get limit: %s"
+msgstr "%s: ní féidir teorainn a fháil: %s"
+
+#: builtins/ulimit.def:453
+msgid "limit"
+msgstr "teorainn"
+
+#: builtins/ulimit.def:465 builtins/ulimit.def:765
+#, c-format
+msgid "%s: cannot modify limit: %s"
+msgstr "%s: ní féidir teorainn a athrú: %s"
+
+#: builtins/umask.def:118
+msgid "octal number"
+msgstr "uimhir ochtnártha"
+
+#: builtins/umask.def:231
+#, c-format
+msgid "`%c': invalid symbolic mode operator"
+msgstr "\"%c\": oibreoir neamhbhailí móid shiombalaigh"
+
+#: builtins/umask.def:286
+#, c-format
+msgid "`%c': invalid symbolic mode character"
+msgstr "\"%c\": carachtar neamhbhailí móid shiombalaigh"
+
+#: error.c:89 error.c:320 error.c:322 error.c:324
+msgid " line "
+msgstr " líne "
+
+#: error.c:164
+#, c-format
+msgid "last command: %s\n"
+msgstr "Ordú deireanach: %s\n"
+
+#: error.c:172
+#, c-format
+msgid "Aborting..."
+msgstr "Ag tobscor..."
+
+#: error.c:405
+msgid "unknown command error"
+msgstr "earráid ordaithe anaithnid"
+
+#: error.c:406
+msgid "bad command type"
+msgstr "droch-chineál ordaithe"
+
+#: error.c:407
+msgid "bad connector"
+msgstr "drochnascóir"
+
+#: error.c:408
+msgid "bad jump"
+msgstr "drochléim"
+
+#: error.c:446
+#, c-format
+msgid "%s: unbound variable"
+msgstr "%s: athróg neamhcheangailte"
+
+#: eval.c:181
+#, c-format
+msgid "\atimed out waiting for input: auto-logout\n"
+msgstr "\aimithe thar am ag feitheamh le hionchur: logáil amach uathoibríoch\n"
+
+#: execute_cmd.c:491
+#, c-format
+msgid "cannot redirect standard input from /dev/null: %s"
+msgstr "Ní féidir an ionchur caighdeánach a atreorú ó /dev/null: %s"
+
+#: execute_cmd.c:1112
+#, c-format
+msgid "TIMEFORMAT: `%c': invalid format character"
+msgstr "FORMÁID_AMA: \"%c\": carachtar formáide neamhbhaií."
+
+#: execute_cmd.c:2011
+msgid "pipe error"
+msgstr "earráid phíopa"
+
+#: execute_cmd.c:4363
+#, c-format
+msgid "%s: restricted: cannot specify `/' in command names"
+msgstr "%s: srianta: ní féidir \"/\" a shonrú in ainmneacha ordaithe"
+
+#: execute_cmd.c:4454
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: níor aimsíodh an t-ordú"
+
+#: execute_cmd.c:4708
+#, c-format
+msgid "%s: %s: bad interpreter"
+msgstr "%s: %s: drochléirmhínitheoir"
+
+#: execute_cmd.c:4857
+#, c-format
+msgid "cannot duplicate fd %d to fd %d"
+msgstr "Ní féidir an tuairisceoir comhaid %d a dhúbailt mar thuairisceoir comhaid %d."
+
+#: expr.c:241
+msgid "expression recursion level exceeded"
+msgstr ""
+
+#: expr.c:265
+msgid "recursion stack underflow"
+msgstr "gannsreabhadh na cruaiche athchúrsála"
+
+#: expr.c:379
+msgid "syntax error in expression"
+msgstr "Earráid chomhréire sa slonn."
+
+#: expr.c:419
+msgid "attempted assignment to non-variable"
+msgstr "Deineadh iarracht sannadh go rud nach athróg é."
+
+#: expr.c:440 expr.c:445 expr.c:756
+msgid "division by 0"
+msgstr "roinnt ar 0"
+
+#: expr.c:471
+msgid "bug: bad expassign token"
+msgstr "fabht: droch-chomhartha expassign"
+
+#: expr.c:513
+msgid "`:' expected for conditional expression"
+msgstr "Bhíothas ag súil le \":\" le haghaidh sloinn choinníollaigh."
+
+#: expr.c:781
+msgid "exponent less than 0"
+msgstr "Easpónant níos lú ná 0."
+
+#: expr.c:826
+msgid "identifier expected after pre-increment or pre-decrement"
+msgstr "ag súil le aitheantóir tar éis réamhincriminte nó réamhdeicriminte"
+
+#: expr.c:854
+msgid "missing `)'"
+msgstr "\")\" ar iarraidh"
+
+#: expr.c:897 expr.c:1175
+msgid "syntax error: operand expected"
+msgstr "Earráid chomhréire: bhíothas ag súil le hoibreann."
+
+#: expr.c:1177
+msgid "syntax error: invalid arithmetic operator"
+msgstr "earráid chomhréire: oibreoir neamhbhailí uimhríochta"
+
+#: expr.c:1201
+#, c-format
+msgid "%s%s%s: %s (error token is \"%s\")"
+msgstr "%s%s%s: %s (comhartha earráide \"%s\")"
+
+#: expr.c:1259
+msgid "invalid arithmetic base"
+msgstr "Bonnuimhir uimhríochtúil neamhbhailí."
+
+#: expr.c:1279
+msgid "value too great for base"
+msgstr "Tá an luach rómhór don bhonnuimhir."
+
+#: expr.c:1328
+#, c-format
+msgid "%s: expression error\n"
+msgstr "%s: earráid sloinn\n"
+
+#: general.c:61
+msgid "getcwd: cannot access parent directories"
+msgstr "getcwd: ní féidir na máthairchomhadlanna a rochtain."
+
+#: input.c:94 subst.c:4559
+#, c-format
+msgid "cannot reset nodelay mode for fd %d"
+msgstr ""
+
+#: input.c:258
+#, c-format
+msgid "cannot allocate new file descriptor for bash input from fd %d"
+msgstr "Ní féidir tuairisceoir comhaid nua a leithdháileadh le haghaidh ionchur bash ón tuairisceoir comhaid %d."
+
+#: input.c:266
+#, c-format
+msgid "save_bash_input: buffer already exists for new fd %d"
+msgstr "save_bash_input: tá an maolán ann cheana le haghaidh an tuairisceoir comhaid nua %d"
+
+#: jobs.c:466
+msgid "start_pipeline: pgrp pipe"
+msgstr ""
+
+#: jobs.c:887
+#, c-format
+msgid "forked pid %d appears in running job %d"
+msgstr ""
+
+#: jobs.c:1005
+#, c-format
+msgid "deleting stopped job %d with process group %ld"
+msgstr "Tá an jab stoptha %d leis an ngrúpa próisis %ld á scrios."
+
+#: jobs.c:1110
+#, c-format
+msgid "add_process: process %5ld (%s) in the_pipeline"
+msgstr ""
+
+#: jobs.c:1113
+#, c-format
+msgid "add_process: pid %5ld (%s) marked as still alive"
+msgstr "add_process: próiseas %5ld (%s) marcáilte mar fós beo"
+
+#: jobs.c:1401
+#, c-format
+msgid "describe_pid: %ld: no such pid"
+msgstr "describe_pid: %ld: níl an aitheantóir próisis sin ann."
+
+#: jobs.c:1416
+#, c-format
+msgid "Signal %d"
+msgstr "Comhartha %d"
+
+#: jobs.c:1430 jobs.c:1455
+msgid "Done"
+msgstr "Déanta"
+
+#: jobs.c:1435 siglist.c:122
+msgid "Stopped"
+msgstr "Stoptha"
+
+#: jobs.c:1439
+#, c-format
+msgid "Stopped(%s)"
+msgstr "Stoptha(%s)"
+
+#: jobs.c:1443
+msgid "Running"
+msgstr "Ag Rith"
+
+#: jobs.c:1457
+#, c-format
+msgid "Done(%d)"
+msgstr "Déanta(%d)"
+
+#: jobs.c:1459
+#, c-format
+msgid "Exit %d"
+msgstr "Scoir %d"
+
+#: jobs.c:1462
+msgid "Unknown status"
+msgstr "Stádas neamhaithnid"
+
+#: jobs.c:1549
+#, c-format
+msgid "(core dumped) "
+msgstr "(cuimhne dumpáilte)"
+
+#: jobs.c:1568
+#, c-format
+msgid " (wd: %s)"
+msgstr ""
+
+#: jobs.c:1771
+#, c-format
+msgid "child setpgid (%ld to %ld)"
+msgstr ""
+
+#: jobs.c:2099 nojobs.c:585
+#, c-format
+msgid "wait: pid %ld is not a child of this shell"
+msgstr "wait: níl an próiseas %ld ina mhac den bhlaosc seo."
+
+#: jobs.c:2326
+#, c-format
+msgid "wait_for: No record of process %ld"
+msgstr "wait_for: níl taifead den phróiseas %ld"
+
+#: jobs.c:2598
+#, c-format
+msgid "wait_for_job: job %d is stopped"
+msgstr "wait_for_job: tá an jab %d stoptha."
+
+#: jobs.c:2820
+#, c-format
+msgid "%s: job has terminated"
+msgstr "%s: tá an jab críochnaithe."
+
+#: jobs.c:2829
+#, c-format
+msgid "%s: job %d already in background"
+msgstr "%s: tá an jab %d sa chúlra cheana."
+
+#: jobs.c:3492
+#, c-format
+msgid "%s: line %d: "
+msgstr "%s: líne %d: "
+
+#: jobs.c:3506 nojobs.c:814
+#, c-format
+msgid " (core dumped)"
+msgstr " (cuimhne dumpáilte)"
+
+#: jobs.c:3518 jobs.c:3531
+#, c-format
+msgid "(wd now: %s)\n"
+msgstr ""
+
+#: jobs.c:3563
+msgid "initialize_job_control: getpgrp failed"
+msgstr ""
+
+#: jobs.c:3623
+msgid "initialize_job_control: line discipline"
+msgstr ""
+
+#: jobs.c:3633
+msgid "initialize_job_control: setpgid"
+msgstr ""
+
+#: jobs.c:3661
+#, c-format
+msgid "cannot set terminal process group (%d)"
+msgstr "ní féidir grúpa próisis teirminéil a shocrú (%d)"
+
+#: jobs.c:3666
+msgid "no job control in this shell"
+msgstr "Níl rialú jabanna sa bhlaosc seo."
+
+#: lib/malloc/malloc.c:296
+#, c-format
+msgid "malloc: failed assertion: %s\n"
+msgstr "malloc: dearbhú teipthe: %s\n"
+
+#: lib/malloc/malloc.c:312
+#, c-format
+msgid ""
+"\r\n"
+"malloc: %s:%d: assertion botched\r\n"
+msgstr ""
+"\r\n"
+"malloc: %s:%d: dearbhú ina phraiseach\r\n"
+
+#: lib/malloc/malloc.c:313
+msgid "unknown"
+msgstr "neamhaithnid"
+
+#: lib/malloc/malloc.c:797
+msgid "malloc: block on free list clobbered"
+msgstr "malloc: bloc ar an liosta saor scriosta"
+
+#: lib/malloc/malloc.c:874
+msgid "free: called with already freed block argument"
+msgstr "free: glaoite le argóint bhloic á saoradh cheana"
+
+#: lib/malloc/malloc.c:877
+msgid "free: called with unallocated block argument"
+msgstr "free: glaoite le argóint bhloic nár leithdháileadh"
+
+#: lib/malloc/malloc.c:896
+msgid "free: underflow detected; mh_nbytes out of range"
+msgstr "free: gannsreabhadh; tá mh_nbytes as raon"
+
+#: lib/malloc/malloc.c:902
+msgid "free: start and end chunk sizes differ"
+msgstr "free: ní ionann méid na smután túis agus deiridh"
+
+#: lib/malloc/malloc.c:1001
+msgid "realloc: called with unallocated block argument"
+msgstr "realloc: glaoite le argóint bhloic nár leithdháileadh"
+
+#: lib/malloc/malloc.c:1016
+msgid "realloc: underflow detected; mh_nbytes out of range"
+msgstr "realloc: gannsreabhadh; tá mh_nbytes as raon"
+
+#: lib/malloc/malloc.c:1022
+msgid "realloc: start and end chunk sizes differ"
+msgstr "realloc: ní ionann méideanna na smután túis agus deiridh"
+
+#: lib/malloc/table.c:177
+#, c-format
+msgid "register_alloc: alloc table is full with FIND_ALLOC?\n"
+msgstr "register_alloc: an bhfuil an tábla leithdháilte lán le FIND_ALLOC?\n"
+
+#: lib/malloc/table.c:184
+#, c-format
+msgid "register_alloc: %p already in table as allocated?\n"
+msgstr "register_alloc: an bhfuil %p sa tábla mar atá sé leithdháilte cheana?\n"
+
+#: lib/malloc/table.c:220
+#, c-format
+msgid "register_free: %p already in table as free?\n"
+msgstr "register_free: an bhfuil %p sa tábla cheana mar ceann saor?\n"
+
+#: lib/sh/fmtulong.c:101
+msgid "invalid base"
+msgstr "Bonn neamhbhailí"
+
+#: lib/sh/netopen.c:168
+#, c-format
+msgid "%s: host unknown"
+msgstr "%s: óstríomhaire anaithnid"
+
+#: lib/sh/netopen.c:175
+#, c-format
+msgid "%s: invalid service"
+msgstr "%s: seirbhís neamhbhailí"
+
+#: lib/sh/netopen.c:306
+#, c-format
+msgid "%s: bad network path specification"
+msgstr "%s: drochshonrú conaire líonra"
+
+#: lib/sh/netopen.c:346
+msgid "network operations not supported"
+msgstr "Ní thacaítear le oibríochtaí líonra."
+
+#: mailcheck.c:433
+msgid "You have mail in $_"
+msgstr "Tá ríomhphost agat i $_"
+
+#: mailcheck.c:458
+msgid "You have new mail in $_"
+msgstr "Tá ríomhphost nua agat i $_"
+
+#: mailcheck.c:474
+#, c-format
+msgid "The mail in %s has been read\n"
+msgstr "Tá an ríomhphost i %s léite\n"
+
+#: make_cmd.c:322
+msgid "syntax error: arithmetic expression required"
+msgstr "Earráid chomhréire: tá slonn uimhríochtúil de dhith."
+
+#: make_cmd.c:324
+msgid "syntax error: `;' unexpected"
+msgstr "Earráid chomhréire: \";\" gan súil leis."
+
+#: make_cmd.c:325
+#, c-format
+msgid "syntax error: `((%s))'"
+msgstr "Earráid chomhréire: \"((%s))\""
+
+#: make_cmd.c:567
+#, c-format
+msgid "make_here_document: bad instruction type %d"
+msgstr "make_here_document: drochchineál ordaithe %d"
+
+#: make_cmd.c:651
+#, c-format
+msgid "here-document at line %d delimited by end-of-file (wanted `%s')"
+msgstr ""
+
+#: make_cmd.c:746
+#, c-format
+msgid "make_redirection: redirection instruction `%d' out of range"
+msgstr "make_redirection: ordú atreoraithe \"%d\" as raon."
+
+#: parse.y:2986 parse.y:3218
+#, c-format
+msgid "unexpected EOF while looking for matching `%c'"
+msgstr "Deireadh comhaid gan súil leis agus \"%c\" a mheaitseálann á lorg."
+
+#: parse.y:3722
+msgid "unexpected EOF while looking for `]]'"
+msgstr "Deireadh comhaid gan súil leis agus \"]]\" á lorg."
+
+#: parse.y:3727
+#, c-format
+msgid "syntax error in conditional expression: unexpected token `%s'"
+msgstr "Earráid chomhréire i slonn coinníollach: comhartha \"%s\" gan suil leis."
+
+#: parse.y:3731
+msgid "syntax error in conditional expression"
+msgstr "Earráid chomhréire i slonn coinníollach."
+
+#: parse.y:3809
+#, c-format
+msgid "unexpected token `%s', expected `)'"
+msgstr "Comhartha \"%s\" gan súil leis; ag súil le \")\"."
+
+#: parse.y:3813
+msgid "expected `)'"
+msgstr "Ag súil le \")\""
+
+#: parse.y:3841
+#, c-format
+msgid "unexpected argument `%s' to conditional unary operator"
+msgstr "Argóint \"%s\" gan súil lei go hoibreoir aonártha coinníollach."
+
+#: parse.y:3845
+msgid "unexpected argument to conditional unary operator"
+msgstr "Argóint gan súil lei go hoibreoir coinníollach aonártha ."
+
+#: parse.y:3885
+#, c-format
+msgid "unexpected token `%s', conditional binary operator expected"
+msgstr "Comhartha \"%s\" gan súil leis. Bhíothas ag súil le hoibreoir coinníollach dénártha."
+
+#: parse.y:3889
+msgid "conditional binary operator expected"
+msgstr "Bhíothas ag súil le hoibreoir coinníollach dénártha."
+
+#: parse.y:3906
+#, c-format
+msgid "unexpected argument `%s' to conditional binary operator"
+msgstr "Argóint \"%s\" gan súil lei go hoibreoir dénártha coinníollach."
+
+#: parse.y:3910
+msgid "unexpected argument to conditional binary operator"
+msgstr "Argóint gan súil lei go hoibreoir dénártha coinníollach."
+
+#: parse.y:3921
+#, c-format
+msgid "unexpected token `%c' in conditional command"
+msgstr "Comhartha \"%c\" gan súil leis in ordú coinníollach."
+
+#: parse.y:3924
+#, c-format
+msgid "unexpected token `%s' in conditional command"
+msgstr "Comhartha \"%s\" gan súil leis in ordú coinníollach."
+
+#: parse.y:3928
+#, c-format
+msgid "unexpected token %d in conditional command"
+msgstr "Comhartha %d gan súil leis in ordú coinníollach."
+
+#: parse.y:5195
+#, c-format
+msgid "syntax error near unexpected token `%s'"
+msgstr "Earráid chomhréire in aice comhartha \"%s\" nach rabhthas ag súil leis."
+
+#: parse.y:5213
+#, c-format
+msgid "syntax error near `%s'"
+msgstr "Earráid chomhréire in aice \"%s\""
+
+#: parse.y:5223
+msgid "syntax error: unexpected end of file"
+msgstr "Earráid chomhréire: deireadh comhaid gan súil leis."
+
+#: parse.y:5223
+msgid "syntax error"
+msgstr "Earráid chomhréire"
+
+#: parse.y:5285
+#, c-format
+msgid "Use \"%s\" to leave the shell.\n"
+msgstr "Úsáid \"%s\" le scoir den mblaosc.\n"
+
+#: parse.y:5447
+msgid "unexpected EOF while looking for matching `)'"
+msgstr "Deireadh comhaid gan súil leis agus \")\" á lorg le meaitseáil."
+
+#: pcomplete.c:1018
+#, c-format
+msgid "completion: function `%s' not found"
+msgstr "Iomlánú: níor aimsíodh an fheidhm \"%s\"."
+
+#: pcomplib.c:179
+#, c-format
+msgid "progcomp_insert: %s: NULL COMPSPEC"
+msgstr "progcomp_insert: %s: tá COMPSPEC neamhnitheach"
+
+#: print_cmd.c:285
+#, c-format
+msgid "print_command: bad connector `%d'"
+msgstr "print_command: drochnascóir \"%d\""
+
+#: print_cmd.c:1348
+#, c-format
+msgid "cprintf: `%c': invalid format character"
+msgstr "cprintf: \"%c\": carachtar formáide neamhbhailí"
+
+#: redir.c:105
+msgid "file descriptor out of range"
+msgstr "tuairisceoir comhaid as raon"
+
+#: redir.c:148
+#, c-format
+msgid "%s: ambiguous redirect"
+msgstr "%s: atreorú athbhríoch"
+
+#: redir.c:152
+#, c-format
+msgid "%s: cannot overwrite existing file"
+msgstr "%s: ní féidir comhad atá ann cheana a fhorscríobh."
+
+#: redir.c:157
+#, c-format
+msgid "%s: restricted: cannot redirect output"
+msgstr "%s: srianta: ní féidir aschur a atreorú."
+
+#: redir.c:162
+#, c-format
+msgid "cannot create temp file for here-document: %s"
+msgstr ""
+
+#: redir.c:517
+msgid "/dev/(tcp|udp)/host/port not supported without networking"
+msgstr "Ní thacaítear le /dev/(tcp|udp)/óstríomhaire/port gan líonrú."
+
+#: redir.c:1023
+msgid "redirection error: cannot duplicate fd"
+msgstr "Earráid atreoraithe: ní féidir an tuairisceoir comhaid a dhúbailt."
+
+#: shell.c:328
+msgid "could not find /tmp, please create!"
+msgstr "Níorbh fhéidir /tmp a aimsiú. Cruthaigh é le do thoil!"
+
+#: shell.c:332
+msgid "/tmp must be a valid directory name"
+msgstr "Caithfidh /tmp bheith ina ainm comhadlainne bailí."
+
+#: shell.c:876
+#, c-format
+msgid "%c%c: invalid option"
+msgstr "%c%c: rogha neamhbhailí"
+
+#: shell.c:1638
+msgid "I have no name!"
+msgstr "Níl ainm orm!"
+
+#: shell.c:1778
+#, c-format
+msgid "GNU bash, version %s-(%s)\n"
+msgstr "GNU bash, leagan %s-(%s)\n"
+
+#: shell.c:1779
+#, c-format
+msgid ""
+"Usage:\t%s [GNU long option] [option] ...\n"
+"\t%s [GNU long option] [option] script-file ...\n"
+msgstr ""
+"Úsáid:\t%s [rogha fada GNU] [rogha] ...\n"
+"\t%s [rogha fada GNU] [rogha] comhad_scripte ...\n"
+
+#: shell.c:1781
+msgid "GNU long options:\n"
+msgstr "Roghanna fada GNU:\n"
+
+#: shell.c:1785
+msgid "Shell options:\n"
+msgstr "Roghanna blaoisce:\n"
+
+#: shell.c:1786
+msgid "\t-irsD or -c command or -O shopt_option\t\t(invocation only)\n"
+msgstr "\t-irsD nó -c ordú nó -O rogha_shopt\t\t(glaoch amháin)\n"
+
+#: shell.c:1801
+#, c-format
+msgid "\t-%s or -o option\n"
+msgstr "\t-%s nó -o rogha\n"
+
+#: shell.c:1807
+#, c-format
+msgid "Type `%s -c \"help set\"' for more information about shell options.\n"
+msgstr "Úsáid %s -c \"help set\" le haghaidh tuilleadh eolais faoi roghanna blaoisce.\n"
+
+#: shell.c:1808
+#, c-format
+msgid "Type `%s -c help' for more information about shell builtin commands.\n"
+msgstr "Úsáid \"%s -c help\" le haghaidh tuilleadh eolais faoi orduithe ionsuite blaoisce.\n"
+
+#: shell.c:1809
+#, c-format
+msgid "Use the `bashbug' command to report bugs.\n"
+msgstr "Úsáid an t-ordú \"bashbug\" le tuarascáil a sheoladh faoi fhabht.\n"
+
+#: sig.c:583
+#, c-format
+msgid "sigprocmask: %d: invalid operation"
+msgstr "sigprocmask: %d: oibríocht neamhbhailí"
+
+#: siglist.c:47
+msgid "Bogus signal"
+msgstr ""
+
+#: siglist.c:50
+msgid "Hangup"
+msgstr "Crochadh"
+
+#: siglist.c:54
+msgid "Interrupt"
+msgstr "Idirbhriseadh"
+
+#: siglist.c:58
+msgid "Quit"
+msgstr "Scoir"
+
+#: siglist.c:62
+msgid "Illegal instruction"
+msgstr "Treoir mídhleathach"
+
+#: siglist.c:66
+msgid "BPT trace/trap"
+msgstr ""
+
+#: siglist.c:74
+msgid "ABORT instruction"
+msgstr "Treoir ABORT"
+
+#: siglist.c:78
+msgid "EMT instruction"
+msgstr "Treoir EMT"
+
+#: siglist.c:82
+msgid "Floating point exception"
+msgstr ""
+
+#: siglist.c:86
+msgid "Killed"
+msgstr ""
+
+#: siglist.c:90
+msgid "Bus error"
+msgstr "Earráid bhus"
+
+#: siglist.c:94
+msgid "Segmentation fault"
+msgstr ""
+
+#: siglist.c:98
+msgid "Bad system call"
+msgstr "Droch-ghlaoch córais"
+
+#: siglist.c:102
+msgid "Broken pipe"
+msgstr "Píopa briste"
+
+#: siglist.c:106
+msgid "Alarm clock"
+msgstr ""
+
+#: siglist.c:110
+msgid "Terminated"
+msgstr ""
+
+#: siglist.c:114
+msgid "Urgent IO condition"
+msgstr ""
+
+#: siglist.c:118
+msgid "Stopped (signal)"
+msgstr "Stoptha (comhartha)"
+
+#: siglist.c:126
+msgid "Continue"
+msgstr "Lean ar aghaidh"
+
+#: siglist.c:134
+msgid "Child death or stop"
+msgstr ""
+
+#: siglist.c:138
+msgid "Stopped (tty input)"
+msgstr "Stoptha (ionchur teirminéil)"
+
+#: siglist.c:142
+msgid "Stopped (tty output)"
+msgstr "Stoptha (aschur teirminéil)"
+
+#: siglist.c:146
+msgid "I/O ready"
+msgstr "I/A ullamh"
+
+#: siglist.c:150
+msgid "CPU limit"
+msgstr ""
+
+#: siglist.c:154
+msgid "File limit"
+msgstr ""
+
+#: siglist.c:158
+msgid "Alarm (virtual)"
+msgstr ""
+
+#: siglist.c:162
+msgid "Alarm (profile)"
+msgstr ""
+
+#: siglist.c:166
+msgid "Window changed"
+msgstr "Fuinneog athraithe"
+
+#: siglist.c:170
+msgid "Record lock"
+msgstr ""
+
+#: siglist.c:174
+msgid "User signal 1"
+msgstr "Comhartha úsáideora 1"
+
+#: siglist.c:178
+msgid "User signal 2"
+msgstr "Comhartha úsáideora 2"
+
+#: siglist.c:182
+msgid "HFT input data pending"
+msgstr ""
+
+#: siglist.c:186
+msgid "power failure imminent"
+msgstr "teip chumhachta ar tí tarlú"
+
+#: siglist.c:190
+msgid "system crash imminent"
+msgstr "cliseadh córais ar tí tarlú"
+
+#: siglist.c:194
+msgid "migrate process to another CPU"
+msgstr ""
+
+#: siglist.c:198
+msgid "programming error"
+msgstr ""
+
+#: siglist.c:202
+msgid "HFT monitor mode granted"
+msgstr ""
+
+#: siglist.c:206
+msgid "HFT monitor mode retracted"
+msgstr ""
+
+#: siglist.c:210
+msgid "HFT sound sequence has completed"
+msgstr ""
+
+#: siglist.c:214
+msgid "Information request"
+msgstr ""
+
+#: siglist.c:222
+msgid "Unknown Signal #"
+msgstr "Comhartha neamhaithnid #"
+
+#: siglist.c:224
+#, c-format
+msgid "Unknown Signal #%d"
+msgstr "Comhartha neamhaithnid #%d"
+
+#: subst.c:1181 subst.c:1302
+#, c-format
+msgid "bad substitution: no closing `%s' in %s"
+msgstr "Drochionadú: níl \"%s\" dúnta i %s"
+
+#: subst.c:2458
+#, c-format
+msgid "%s: cannot assign list to array member"
+msgstr "%s: ní féidir liosta a shannadh go ball eagair."
+
+#: subst.c:4456 subst.c:4472
+msgid "cannot make pipe for process substitution"
+msgstr "Ní féidir píopa a dhéanamh le haghaidh ionadaíocht próisis."
+
+#: subst.c:4504
+msgid "cannot make child for process substitution"
+msgstr "Ní féidir mac a dhéanamh le haghaidh ionadaíocht próisis."
+
+#: subst.c:4549
+#, c-format
+msgid "cannot open named pipe %s for reading"
+msgstr "Ní féidir píopa ainmnithe %s a oscailt le haghaidh léamh."
+
+#: subst.c:4551
+#, c-format
+msgid "cannot open named pipe %s for writing"
+msgstr "Ní féidir píopa ainmnithe %s a oscailt le haghaidh scríofa."
+
+#: subst.c:4569
+#, c-format
+msgid "cannot duplicate named pipe %s as fd %d"
+msgstr "Ní féidir an píopa ainmnithe %s a dhúbailt mar thuairisceoir comhaid %d."
+
+#: subst.c:4765
+msgid "cannot make pipe for command substitution"
+msgstr "Ní féidir píopa a dhéanamh le haghaidh ionadú ordaithe."
+
+#: subst.c:4799
+msgid "cannot make child for command substitution"
+msgstr "Ní féidir mac a dhéanamh le haghaidh ionadú ordaithe."
+
+#: subst.c:4816
+msgid "command_substitute: cannot duplicate pipe as fd 1"
+msgstr "command_substitute: ní feidir an píopa a dhúbailt mar thuairisceoir comhaid 1."
+
+#: subst.c:5318
+#, c-format
+msgid "%s: parameter null or not set"
+msgstr "%s: paraiméadar neamhnitheach nó gan socrú."
+
+#: subst.c:5608
+#, c-format
+msgid "%s: substring expression < 0"
+msgstr "%s: slonn fotheaghráin < 0"
+
+#: subst.c:6660
+#, c-format
+msgid "%s: bad substitution"
+msgstr "%s: drochionadú"
+
+#: subst.c:6740
+#, c-format
+msgid "$%s: cannot assign in this way"
+msgstr "$%s: ní féidir sannadh mar seo."
+
+#: subst.c:7499
+#, c-format
+msgid "bad substitution: no closing \"`\" in %s"
+msgstr "drochionadú: níl \"`\" dúnta i %s"
+
+#: subst.c:8375
+#, c-format
+msgid "no match: %s"
+msgstr "gan meaitseáil: %s"
+
+#: test.c:145
+msgid "argument expected"
+msgstr "Bhíothas ag súil le hargóint"
+
+#: test.c:154
+#, c-format
+msgid "%s: integer expression expected"
+msgstr "%s: ag súil le slonn slánuimhreach."
+
+#: test.c:262
+msgid "`)' expected"
+msgstr "Ag súil le \")\""
+
+#: test.c:264
+#, c-format
+msgid "`)' expected, found %s"
+msgstr "Ag súil le \")\", ach fuarthas %s"
+
+#: test.c:279 test.c:688 test.c:691
+#, c-format
+msgid "%s: unary operator expected"
+msgstr "%s: ag súil le hoibreoir aonártha."
+
+#: test.c:444 test.c:731
+#, c-format
+msgid "%s: binary operator expected"
+msgstr "%s: ag súil le hoibreoir dénártha."
+
+#: test.c:806
+msgid "missing `]'"
+msgstr "\"]\" ar iarraidh"
+
+#: trap.c:201
+msgid "invalid signal number"
+msgstr "Uimhir chomhartha neamhbhailí"
+
+#: trap.c:324
+#, c-format
+msgid "run_pending_traps: bad value in trap_list[%d]: %p"
+msgstr "run_pending_traps: drochluach sa liosta_gaistí[%d]: %p"
+
+#: trap.c:328
+#, c-format
+msgid "run_pending_traps: signal handler is SIG_DFL, resending %d (%s) to myself"
+msgstr "run_pending_traps: is SIG_DFL an láimhseálaí comharthaí; %d (%s) á athsheoladh chugam féin."
+
+#: trap.c:372
+#, c-format
+msgid "trap_handler: bad signal %d"
+msgstr "trap_handler: droch-chomhartha %d"
+
+#: variables.c:358
+#, c-format
+msgid "error importing function definition for `%s'"
+msgstr "Earráid agus sainmhíniú na feidhme \"%s\" á iompórtáil."
+
+#: variables.c:736
+#, c-format
+msgid "shell level (%d) too high, resetting to 1"
+msgstr "Tá an leibhéal blaoisce (%d) ró-ard; á athshocrú go 1."
+
+#: variables.c:1898
+msgid "make_local_variable: no function context at current scope"
+msgstr "make_local_variable: níl comhthéacs feidhme sa scóip reatha."
+
+#: variables.c:3127
+msgid "all_local_variables: no function context at current scope"
+msgstr "all_local_variables: níl comhthéacs feidhme sa scóip reatha"
+
+#: variables.c:3344 variables.c:3353
+#, c-format
+msgid "invalid character %d in exportstr for %s"
+msgstr "Carachtar neamhbhailí %d sa teaghrán easpórtála le haghaidh %s."
+
+#: variables.c:3359
+#, c-format
+msgid "no `=' in exportstr for %s"
+msgstr "Níl \"=\" sa teaghrán easpórtála le haghaidh %s."
+
+#: variables.c:3794
+msgid "pop_var_context: head of shell_variables not a function context"
+msgstr ""
+
+#: variables.c:3807
+msgid "pop_var_context: no global_variables context"
+msgstr "pop_var_context: níl comhthéacs global_variables ann"
+
+#: variables.c:3881
+msgid "pop_scope: head of shell_variables not a temporary environment scope"
+msgstr ""
+
+#: version.c:46
+msgid "Copyright (C) 2009 Free Software Foundation, Inc."
+msgstr "Cóipcheart © 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 "Ceadúnas GPLv3+: GNU GPL leagan 3 nó níos déanaí <http://gnu.org/licenses/gpl.html>\n"
+
+#: version.c:86
+#, c-format
+msgid "GNU bash, version %s (%s)\n"
+msgstr "GNU bash, leagan %s (%s)\n"
+
+#: version.c:91
+#, c-format
+msgid "This is free software; you are free to change and redistribute it.\n"
+msgstr "Is saorbhogearra é seo; tá cead agat é a athrú agus a dháileadh.\n"
+
+#: version.c:92
+#, c-format
+msgid "There is NO WARRANTY, to the extent permitted by law.\n"
+msgstr "Ní ghabhann baránta ar bith leis, sa mhéid is atá sin ceadaithe de réir dlí.\n"
+
+#: xmalloc.c:92
+#, c-format
+msgid "xmalloc: cannot allocate %lu bytes (%lu bytes allocated)"
+msgstr "xmalloc: ní féidir %lu beart a leithdháileadh (%lu beart leithdháilte)"
+
+#: xmalloc.c:94
+#, c-format
+msgid "xmalloc: cannot allocate %lu bytes"
+msgstr "xmalloc: ní féidir %lu beart a leithdháileadh"
+
+#: xmalloc.c:114
+#, c-format
+msgid "xrealloc: cannot reallocate %lu bytes (%lu bytes allocated)"
+msgstr "xrealloc: ní féidir %lu beart a athleithdháileadh (%lu beart leithdháilte)"
+
+#: xmalloc.c:116
+#, c-format
+msgid "xrealloc: cannot allocate %lu bytes"
+msgstr "xrealloc: ní féidir %lu beart a leithdháileadh"
+
+#: xmalloc.c:150
+#, c-format
+msgid "xmalloc: %s:%d: cannot allocate %lu bytes (%lu bytes allocated)"
+msgstr "xmalloc: %s:%d: ní féidir %lu beart a leithdháileadh (%lu beart leithdháilte)"
+
+#: xmalloc.c:152
+#, c-format
+msgid "xmalloc: %s:%d: cannot allocate %lu bytes"
+msgstr "xmalloc: %s:%d: ní féidir %lu beart a leithdháileadh"
+
+#: xmalloc.c:174
+#, c-format
+msgid "xrealloc: %s:%d: cannot reallocate %lu bytes (%lu bytes allocated)"
+msgstr "xrealloc: %s:%d: ní féidir %lu beart a athleithdháileadh (%lu beart leithdháilte)"
+
+#: xmalloc.c:176
+#, c-format
+msgid "xrealloc: %s:%d: cannot allocate %lu bytes"
+msgstr "xrealloc: %s:%d: ní féidir %lu beart a leithdháileadh"
+
+#: builtins.c:43
+msgid "alias [-p] [name[=value] ... ]"
+msgstr "alias [-p] [ainm[=luach] ... ]"
+
+#: builtins.c:47
+msgid "unalias [-a] name [name ...]"
+msgstr "unalias [-a] ainm [ainm ...]"
+
+#: 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 ""
+
+#: builtins.c:54
+msgid "break [n]"
+msgstr "break [n]"
+
+#: builtins.c:56
+msgid "continue [n]"
+msgstr "continue [n]"
+
+#: builtins.c:58
+msgid "builtin [shell-builtin [arg ...]]"
+msgstr ""
+
+#: builtins.c:61
+msgid "caller [expr]"
+msgstr "caller [slonn]"
+
+#: builtins.c:64
+msgid "cd [-L|-P] [dir]"
+msgstr "cd [-L|-P] [comhadlann]"
+
+#: builtins.c:66
+msgid "pwd [-LP]"
+msgstr "pwd [-LP]"
+
+#: builtins.c:68
+msgid ":"
+msgstr ":"
+
+#: builtins.c:70
+msgid "true"
+msgstr "true"
+
+#: builtins.c:72
+msgid "false"
+msgstr "false"
+
+#: builtins.c:74
+msgid "command [-pVv] command [arg ...]"
+msgstr "command [-pVv] ordú [argóint ...]"
+
+#: builtins.c:76
+msgid "declare [-aAfFilrtux] [-p] [name[=value] ...]"
+msgstr "declare [-aAfFilrtux] [-p] [ainm[=luach] ...]"
+
+#: builtins.c:78
+msgid "typeset [-aAfFilrtux] [-p] name[=value] ..."
+msgstr "typeset [-aAfFilrtux] [-p] ainm[=luach] ..."
+
+#: builtins.c:80
+msgid "local [option] name[=value] ..."
+msgstr "local [rogha] ainm[=luach] ..."
+
+#: builtins.c:83
+msgid "echo [-neE] [arg ...]"
+msgstr "echo [-neE] [argóint ...]"
+
+#: builtins.c:87
+msgid "echo [-n] [arg ...]"
+msgstr "echo [-n] [argóint ...]"
+
+#: builtins.c:90
+msgid "enable [-a] [-dnps] [-f filename] [name ...]"
+msgstr "enable [-a] [-dnps] [-f comhadainm] [ainm ...]"
+
+#: builtins.c:92
+msgid "eval [arg ...]"
+msgstr "eval [argóint ...]"
+
+#: builtins.c:94
+msgid "getopts optstring name [arg]"
+msgstr "getopts teaghrán_roghanna ainm [argóint]"
+
+#: builtins.c:96
+msgid "exec [-cl] [-a name] [command [arguments ...]] [redirection ...]"
+msgstr "exec [-cl] [-a ainm] [ordú [argóintí ...]] [atreorú ...]"
+
+#: builtins.c:98
+msgid "exit [n]"
+msgstr "exit [n]"
+
+#: builtins.c:100
+msgid "logout [n]"
+msgstr "logout [n]"
+
+#: builtins.c:103
+msgid "fc [-e ename] [-lnr] [first] [last] or fc -s [pat=rep] [command]"
+msgstr ""
+
+#: builtins.c:107
+msgid "fg [job_spec]"
+msgstr "fg [sonrú_jab]"
+
+#: builtins.c:111
+msgid "bg [job_spec ...]"
+msgstr "bg [sonrú_jab ...]"
+
+#: builtins.c:114
+msgid "hash [-lr] [-p pathname] [-dt] [name ...]"
+msgstr "hash [-lr] [-p conair] [-dt] [ainm ...]"
+
+#: builtins.c:117
+msgid "help [-ds] [pattern ...]"
+msgstr "help [-ds] [patrún ...]"
+
+#: builtins.c:121
+msgid "history [-c] [-d offset] [n] or history -anrw [filename] or history -ps arg [arg...]"
+msgstr "history [-c] [-d seach-chur] [n] nó history -anrw [comhadainm] nó history -ps argóint [argóint...]"
+
+#: builtins.c:125
+msgid "jobs [-lnprs] [jobspec ...] or jobs -x command [args]"
+msgstr "jobs [-lnprs] [sonrú_jab ...] nó jobs -x ordú [argóintí]"
+
+#: builtins.c:129
+msgid "disown [-h] [-ar] [jobspec ...]"
+msgstr "disown [-h] [-ar] [sonrú_jab ...]"
+
+#: builtins.c:132
+msgid "kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]"
+msgstr ""
+
+#: builtins.c:134
+msgid "let arg [arg ...]"
+msgstr "let argóint [argóint ...]"
+
+#: builtins.c:136
+msgid "read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-p prompt] [-t timeout] [-u fd] [name ...]"
+msgstr ""
+
+#: builtins.c:138
+msgid "return [n]"
+msgstr "return [n]"
+
+#: builtins.c:140
+msgid "set [--abefhkmnptuvxBCHP] [-o option-name] [arg ...]"
+msgstr "set [--abefhkmnptuvxBCHP] [-o ainm-rogha] [argóint ...]"
+
+#: builtins.c:142
+msgid "unset [-f] [-v] [name ...]"
+msgstr "unset [-f] [-v] [ainm ...]"
+
+#: builtins.c:144
+msgid "export [-fn] [name[=value] ...] or export -p"
+msgstr "export [-fn] [ainm[=luach] ...] nó export -p"
+
+#: builtins.c:146
+msgid "readonly [-af] [name[=value] ...] or readonly -p"
+msgstr "readonly [-af] [ainm[=luach] ...] nó readonly -p"
+
+#: builtins.c:148
+msgid "shift [n]"
+msgstr "shift [n]"
+
+#: builtins.c:150
+msgid "source filename [arguments]"
+msgstr "source comhadainm [argóintí]"
+
+#: builtins.c:152
+msgid ". filename [arguments]"
+msgstr ". comhadainm [argóintí]"
+
+#: builtins.c:155
+msgid "suspend [-f]"
+msgstr "suspend [-f]"
+
+#: builtins.c:158
+msgid "test [expr]"
+msgstr "test [slonn]"
+
+#: builtins.c:160
+msgid "[ arg... ]"
+msgstr "[ argóint... ]"
+
+#: builtins.c:162
+msgid "times"
+msgstr "times"
+
+#: builtins.c:164
+msgid "trap [-lp] [[arg] signal_spec ...]"
+msgstr "trap [-lp] [[argóint] sonrú_comhartha ...]"
+
+#: builtins.c:166
+msgid "type [-afptP] name [name ...]"
+msgstr "type [-afptP] ainm [ainm ...]"
+
+#: builtins.c:169
+msgid "ulimit [-SHacdefilmnpqrstuvx] [limit]"
+msgstr "ulimit [-SHacdefilmnpqrstuvx] [teorainn]"
+
+#: builtins.c:172
+msgid "umask [-p] [-S] [mode]"
+msgstr "umask [-p] [-S] [mód]"
+
+#: builtins.c:175
+msgid "wait [id]"
+msgstr "wait [aitheantas]"
+
+#: builtins.c:179
+msgid "wait [pid]"
+msgstr "wait [aitheantas_próisis]"
+
+#: builtins.c:182
+msgid "for NAME [in WORDS ... ] ; do COMMANDS; done"
+msgstr "for AINM [in FOCAIL ... ] ; do ORDUITHE; done"
+
+#: builtins.c:184
+msgid "for (( exp1; exp2; exp3 )); do COMMANDS; done"
+msgstr "for (( slonn1; slonn2; slonn3 )); do ORDUITHE; done"
+
+#: builtins.c:186
+msgid "select NAME [in WORDS ... ;] do COMMANDS; done"
+msgstr "select AINM [in FOCAIL ... ;] do ORDUITHE; done"
+
+#: builtins.c:188
+msgid "time [-p] pipeline"
+msgstr "time [-p] píblíne"
+
+#: builtins.c:190
+msgid "case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac"
+msgstr "case FOCAL in [PATRÚN [| PATRÚN]...) ORDUITHE ;;]... esac"
+
+#: builtins.c:192
+msgid "if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi"
+msgstr "if ORDUITHE; then ORDUITHE; [ elif ORDUITHE; then ORDUITHE; ]... [ else ORDUITHE; ] fi"
+
+#: builtins.c:194
+msgid "while COMMANDS; do COMMANDS; done"
+msgstr "while ORDUITHE; do ORDUITHE; done"
+
+#: builtins.c:196
+msgid "until COMMANDS; do COMMANDS; done"
+msgstr "until ORDUITHE; do ORDUITHE; done"
+
+#: builtins.c:198
+msgid "coproc [NAME] command [redirections]"
+msgstr "coproc [AINM] ordú [atreoruithe]"
+
+#: builtins.c:200
+msgid "function name { COMMANDS ; } or name () { COMMANDS ; }"
+msgstr "function ainm { ORDUITHE ; } or ainm () { ORDUITHE ; }"
+
+#: builtins.c:202
+msgid "{ COMMANDS ; }"
+msgstr "{ ORDUITHE ; }"
+
+#: builtins.c:204
+msgid "job_spec [&]"
+msgstr "sonrú_jab [&]"
+
+#: builtins.c:206
+msgid "(( expression ))"
+msgstr "(( slonn ))"
+
+#: builtins.c:208
+msgid "[[ expression ]]"
+msgstr "[[ slonn ]]"
+
+#: builtins.c:210
+msgid "variables - Names and meanings of some shell variables"
+msgstr "variables - Ainmneacha agus mínithe d'athróga áirithe blaoisce"
+
+#: builtins.c:213
+msgid "pushd [-n] [+N | -N | dir]"
+msgstr "pushd [-n] [+N | -N | comhadlann]"
+
+#: builtins.c:217
+msgid "popd [-n] [+N | -N]"
+msgstr "popd [-n] [+N | -N]"
+
+#: builtins.c:221
+msgid "dirs [-clpv] [+N] [-N]"
+msgstr "dirs [-clpv] [+N] [-N]"
+
+#: builtins.c:224
+msgid "shopt [-pqsu] [-o] [optname ...]"
+msgstr "shopt [-pqsu] [-o] [ainm_rogha ...]"
+
+#: builtins.c:226
+msgid "printf [-v var] format [arguments]"
+msgstr "printf [-v athróg] formáid [argóintí]"
+
+#: 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 ""
+
+#: 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 ""
+
+#: builtins.c:237
+msgid "compopt [-o|+o option] [name ...]"
+msgstr "compopt [-o|+o rogha] [ainm ...]"
+
+#: builtins.c:240
+msgid "mapfile [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]"
+msgstr "a"
+
+#: builtins.c:242
+msgid "readarray [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]"
+msgstr "t"
+
+#: builtins.c:254
+msgid ""
+"Define or display aliases.\n"
+" \n"
+" Without arguments, `alias' prints the list of aliases in the reusable\n"
+" form `alias NAME=VALUE' on standard output.\n"
+" \n"
+" Otherwise, an alias is defined for each NAME whose VALUE is given.\n"
+" A trailing space in VALUE causes the next word to be checked for\n"
+" alias substitution when the alias is expanded.\n"
+" \n"
+" Options:\n"
+" -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"
+" defined."
+msgstr ""
+"Sainigh nó taispeáin ailiasanna.\n"
+" \n"
+" Gan argóintí, priontálann \"alias\" an liosta ailiasanna san fhoirm\n"
+" \"alias LUACH=VALUE\" ar an ngnáth-aschur.\n"
+" \n"
+" I ngach cás eile, sainítear ailias do gach AINM a thugtar LUACH dó.\n"
+" Má tá spás chun deiridh LUACH, déantar an chéad fhocal eile a sheiceáil\n"
+" le haghaidh ionadú ailias nuair a fhairsingítear an ailias.\n"
+" \n"
+" Roghanna:\n"
+" -p\tPriontáil gach ailias sainithe i bhfoirm inathúsáidte.\n"
+" \n"
+" Stádas Scortha:\n"
+" Cuireann alias an luach true ar ais mura thugtar AINM nach bhfuil\n"
+" ailias sainithe dó."
+
+#: builtins.c:276
+msgid ""
+"Remove each NAME from the list of defined aliases.\n"
+" \n"
+" Options:\n"
+" -a\tremove all alias definitions.\n"
+" \n"
+" Return success unless a NAME is not an existing alias."
+msgstr ""
+
+#: builtins.c:289
+msgid ""
+"Set Readline key bindings and variables.\n"
+" \n"
+" Bind a key sequence to a Readline function or a macro, or set a\n"
+" Readline variable. The non-option argument syntax is equivalent to\n"
+" that found in ~/.inputrc, but must be passed as a single argument:\n"
+" e.g., bind '\"\\C-x\\C-r\": re-read-init-file'.\n"
+" \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"
+" 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"
+" 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"
+" -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"
+" \t\t\t\tKEYSEQ is entered.\n"
+" \n"
+" Exit Status:\n"
+" bind returns 0 unless an unrecognized option is given or an error occurs."
+msgstr ""
+
+#: builtins.c:326
+msgid ""
+"Exit for, while, or until loops.\n"
+" \n"
+" Exit a FOR, WHILE or UNTIL loop. If N is specified, break N enclosing\n"
+" loops.\n"
+" \n"
+" Exit Status:\n"
+" The exit status is 0 unless N is not greater than or equal to 1."
+msgstr ""
+
+#: builtins.c:338
+msgid ""
+"Resume for, while, or until loops.\n"
+" \n"
+" Resumes the next iteration of the enclosing FOR, WHILE or UNTIL loop.\n"
+" If N is specified, resumes the Nth enclosing loop.\n"
+" \n"
+" Exit Status:\n"
+" The exit status is 0 unless N is not greater than or equal to 1."
+msgstr ""
+
+#: builtins.c:350
+msgid ""
+"Execute shell builtins.\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"
+" \n"
+" Exit Status:\n"
+" Returns the exit status of SHELL-BUILTIN, or false if SHELL-BUILTIN is\n"
+" not a shell builtin.."
+msgstr ""
+
+#: builtins.c:365
+msgid ""
+"Return the context of the current subroutine call.\n"
+" \n"
+" Without EXPR, returns \"$line $filename\". With EXPR, returns\n"
+" \"$line $subroutine $filename\"; this extra information can be used to\n"
+" provide a stack trace.\n"
+" \n"
+" The value of EXPR indicates how many call frames to go back before the\n"
+" current one; the top frame is frame 0.\n"
+" \n"
+" Exit Status:\n"
+" Returns 0 unless the shell is not executing a shell function or EXPR\n"
+" is invalid."
+msgstr ""
+
+#: builtins.c:383
+msgid ""
+"Change the shell working directory.\n"
+" \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"
+" 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"
+" its value is used for DIR.\n"
+" \n"
+" Options:\n"
+" -L\tforce symbolic links to be followed\n"
+" -P\tuse the physical directory structure without following symbolic\n"
+" \tlinks\n"
+" \n"
+" The default is to follow symbolic links, as if `-L' were specified.\n"
+" \n"
+" Exit Status:\n"
+" Returns 0 if the directory is changed; non-zero otherwise."
+msgstr ""
+
+#: builtins.c:411
+msgid ""
+"Print the name of the current working directory.\n"
+" \n"
+" Options:\n"
+" -L\tprint the value of $PWD if it names the current working\n"
+" \tdirectory\n"
+" -P\tprint the physical directory, without any symbolic links\n"
+" \n"
+" By default, `pwd' behaves as if `-L' were specified.\n"
+" \n"
+" Exit Status:\n"
+" Returns 0 unless an invalid option is given or the current directory\n"
+" cannot be read."
+msgstr ""
+"Priontáil ainm na comhadlainne oibre reatha.\n"
+" \n"
+" Roghanna:\n"
+" -L\tpriontáil luach $PWD má thugann sé ainm na comhadlainne\n"
+" \toibre reatha. -P\tpriontáil an chomhadlann fhisiciúil, gan naisc shiombalacha\n"
+" \n"
+" Mar réamhshocrú, oibríonn \"pwd\" faoi mar a bheadh \"-L\" sonraithe.\n"
+" \n"
+" Stádas Scortha:\n"
+" Aischuireann luach de 0 mura thugtar rogha neamhbhailí nó mura féidir\n"
+" an chomhadlann reatha a léamh."
+
+#: builtins.c:428
+msgid ""
+"Null command.\n"
+" \n"
+" No effect; the command does nothing.\n"
+" \n"
+" Exit Status:\n"
+" Always succeeds."
+msgstr ""
+"Ordú neamhnitheach.\n"
+" \n"
+" Gan éifeacht. Ní dhéanann an t-ordú faic.\n"
+" \n"
+" Stadas Scortha:\n"
+" Éiríonn leis i gcónaí."
+
+#: builtins.c:439
+msgid ""
+"Return a successful result.\n"
+" \n"
+" Exit Status:\n"
+" Always succeeds."
+msgstr ""
+
+#: builtins.c:448
+msgid ""
+"Return an unsuccessful result.\n"
+" \n"
+" Exit Status:\n"
+" Always fails."
+msgstr ""
+
+#: builtins.c:457
+msgid ""
+"Execute a simple command or display information about commands.\n"
+" \n"
+" Runs COMMAND with ARGS suppressing shell function lookup, or display\n"
+" information about the specified COMMANDs. Can be used to invoke commands\n"
+" on disk when a function with the same name exists.\n"
+" \n"
+" Options:\n"
+" -p\tuse a default value for PATH that is guaranteed to find all of\n"
+" \tthe standard utilities\n"
+" -v\tprint a description of COMMAND similar to the `type' builtin\n"
+" -V\tprint a more verbose description of each COMMAND\n"
+" \n"
+" Exit Status:\n"
+" Returns exit status of COMMAND, or failure if COMMAND is not found."
+msgstr ""
+
+#: builtins.c:476
+msgid ""
+"Set variable values and attributes.\n"
+" \n"
+" Declare variables and give them attributes. If no NAMEs are given,\n"
+" display the attributes and values of all variables.\n"
+" \n"
+" Options:\n"
+" -f\trestrict action or display to function names and definitions\n"
+" -F\trestrict display to function names only (plus line number and\n"
+" \tsource file when debugging)\n"
+" -p\tdisplay the attributes and value of each NAME\n"
+" \n"
+" Options which set attributes:\n"
+" -a\tto make NAMEs indexed arrays (if supported)\n"
+" -A\tto make NAMEs associative arrays (if supported)\n"
+" -i\tto make NAMEs have the `integer' attribute\n"
+" -l\tto convert NAMEs to lower case on assignment\n"
+" -r\tto make NAMEs readonly\n"
+" -t\tto make NAMEs have the `trace' attribute\n"
+" -u\tto convert NAMEs to upper case on assignment\n"
+" -x\tto make NAMEs export\n"
+" \n"
+" Using `+' instead of `-' turns off the given attribute.\n"
+" \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"
+" command.\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless an invalid option is supplied or an error occurs."
+msgstr ""
+
+#: builtins.c:512
+msgid ""
+"Set variable values and attributes.\n"
+" \n"
+" Obsolete. See `help declare'."
+msgstr ""
+"Socraigh luachanna agus airíonna athróg.\n"
+" \n"
+" Imithe i léig. Feic 'help declare'."
+
+#: builtins.c:520
+msgid ""
+"Define local variables.\n"
+" \n"
+" Create a local variable called NAME, and give it VALUE. OPTION can\n"
+" be any option accepted by `declare'.\n"
+" \n"
+" Local variables can only be used within a function; they are visible\n"
+" only to the function where they are defined and its children.\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless an invalid option is supplied, an error occurs,\n"
+" or the shell is not executing a function."
+msgstr ""
+
+#: builtins.c:537
+msgid ""
+"Write arguments to the standard output.\n"
+" \n"
+" Display the ARGs on the standard output followed by a newline.\n"
+" \n"
+" Options:\n"
+" -n\tdo not append a newline\n"
+" -e\tenable interpretation of the following backslash escapes\n"
+" -E\texplicitly suppress interpretation of backslash escapes\n"
+" \n"
+" `echo' interprets the following backslash-escaped characters:\n"
+" \\a\talert (bell)\n"
+" \\b\tbackspace\n"
+" \\c\tsuppress further output\n"
+" \\e\tescape character\n"
+" \\f\tform feed\n"
+" \\n\tnew line\n"
+" \\r\tcarriage return\n"
+" \\t\thorizontal tab\n"
+" \\v\tvertical tab\n"
+" \\\\\tbackslash\n"
+" \\0nnn\tthe character whose ASCII code is NNN (octal). NNN can be\n"
+" \t0 to 3 octal digits\n"
+" \\xHH\tthe eight-bit character whose value is HH (hexadecimal). HH\n"
+" \tcan be one or two hex digits\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless a write error occurs."
+msgstr ""
+
+#: builtins.c:571
+msgid ""
+"Write arguments to the standard output.\n"
+" \n"
+" Display the ARGs on the standard output followed by a newline.\n"
+" \n"
+" Options:\n"
+" -n\tdo not append a newline\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless a write error occurs."
+msgstr ""
+
+#: builtins.c:586
+msgid ""
+"Enable and disable shell builtins.\n"
+" \n"
+" Enables and disables builtin shell commands. Disabling allows you to\n"
+" execute a disk command which has the same name as a shell builtin\n"
+" without using a full pathname.\n"
+" \n"
+" Options:\n"
+" -a\tprint a list of builtins showing whether or not each is enabled\n"
+" -n\tdisable each NAME or display a list of disabled builtins\n"
+" -p\tprint the list of builtins in a reusable format\n"
+" -s\tprint only the names of Posix `special' builtins\n"
+" \n"
+" Options controlling dynamic loading:\n"
+" -f\tLoad builtin NAME from shared object FILENAME\n"
+" -d\tRemove a builtin loaded with -f\n"
+" \n"
+" Without options, each NAME is enabled.\n"
+" \n"
+" To use the `test' found in $PATH instead of the shell builtin\n"
+" version, type `enable -n test'.\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless NAME is not a shell builtin or an error occurs."
+msgstr ""
+
+#: builtins.c:614
+msgid ""
+"Execute arguments as a shell command.\n"
+" \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"
+" Returns exit status of command or success if command is null."
+msgstr ""
+
+#: builtins.c:626
+msgid ""
+"Parse option arguments.\n"
+" \n"
+" Getopts is used by shell procedures to parse positional parameters\n"
+" as options.\n"
+" \n"
+" OPTSTRING contains the option letters to be recognized; if a letter\n"
+" is followed by a colon, the option is expected to have an argument,\n"
+" which should be separated from it by white space.\n"
+" \n"
+" Each time it is invoked, getopts will place the next option in the\n"
+" shell variable $name, initializing name if it does not exist, and\n"
+" the index of the next argument to be processed into the shell\n"
+" variable OPTIND. OPTIND is initialized to 1 each time the shell or\n"
+" a shell script is invoked. When an option requires an argument,\n"
+" getopts places that argument into the shell variable OPTARG.\n"
+" \n"
+" getopts reports errors in one of two ways. If the first character\n"
+" of OPTSTRING is a colon, getopts uses silent error reporting. In\n"
+" this mode, no error messages are printed. If an invalid option is\n"
+" seen, getopts places the option character found into OPTARG. If a\n"
+" required argument is not found, getopts places a ':' into NAME and\n"
+" sets OPTARG to the option character found. If getopts is not in\n"
+" silent mode, and an invalid option is seen, getopts places '?' into\n"
+" NAME and unsets OPTARG. If a required argument is not found, a '?'\n"
+" is placed in NAME, OPTARG is unset, and a diagnostic message is\n"
+" printed.\n"
+" \n"
+" If the shell variable OPTERR has the value 0, getopts disables the\n"
+" printing of error messages, even if the first character of\n"
+" OPTSTRING is not a colon. OPTERR has the value 1 by default.\n"
+" \n"
+" Getopts normally parses the positional parameters ($0 - $9), but if\n"
+" more arguments are given, they are parsed instead.\n"
+" \n"
+" Exit Status:\n"
+" Returns success if an option is found; fails if the end of options is\n"
+" encountered or an error occurs."
+msgstr ""
+
+#: builtins.c:668
+msgid ""
+"Replace the shell with the given command.\n"
+" \n"
+" Execute COMMAND, replacing this shell with the specified program.\n"
+" ARGUMENTS become the arguments to COMMAND. If COMMAND is not specified,\n"
+" any redirections take effect in the current shell.\n"
+" \n"
+" Options:\n"
+" -a name\tpass NAME as the zeroth argument to COMMAND\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"
+" the shell option `execfail' is set.\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless COMMAND is not found or a redirection error occurs."
+msgstr ""
+
+#: builtins.c:689
+msgid ""
+"Exit the shell.\n"
+" \n"
+" Exits the shell with a status of N. If N is omitted, the exit status\n"
+" is that of the last command executed."
+msgstr ""
+"Scoir den bhlaosc.\n"
+" \n"
+" Scoireann den bhlaosc le stádas N. Má fhágtar N ar lár, is é stádas\n"
+" an chéad ordaithe deireanaigh an stádas scortha."
+
+#: 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"
+" in a login shell."
+msgstr ""
+
+#: builtins.c:708
+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"
+" 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"
+" \t\tthen vi\n"
+" -l \tlist lines instead of editing\n"
+" -n\tomit line numbers when listing\n"
+" -r\treverse the order of the lines (newest listed first)\n"
+" \n"
+" With the `fc -s [pat=rep ...] [command]' format, COMMAND is\n"
+" re-executed after the substitution OLD=NEW is performed.\n"
+" \n"
+" A useful alias to use with this is r='fc -s', so that typing `r cc'\n"
+" runs the last command beginning with `cc' and typing `r' re-executes\n"
+" the last command.\n"
+" \n"
+" Exit Status:\n"
+" Returns success or status of executed command; non-zero if an error occurs."
+msgstr ""
+
+#: builtins.c:738
+msgid ""
+"Move job to the foreground.\n"
+" \n"
+" Place the job identified by JOB_SPEC in the foreground, making it the\n"
+" current job. If JOB_SPEC is not present, the shell's notion of the\n"
+" current job is used.\n"
+" \n"
+" Exit Status:\n"
+" Status of command placed in foreground, or failure if an error occurs."
+msgstr ""
+
+#: builtins.c:753
+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"
+" of the current job is used.\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless job control is not enabled or an error occurs."
+msgstr ""
+
+#: builtins.c:767
+msgid ""
+"Remember or display program locations.\n"
+" \n"
+" Determine and remember the full pathname of each command NAME. If\n"
+" no arguments are given, information about remembered commands is displayed.\n"
+" \n"
+" Options:\n"
+" -d\t\tforget the remembered location of each NAME\n"
+" -l\t\tdisplay in a format that may be reused as input\n"
+" -p pathname\tuse PATHNAME is the full pathname of NAME\n"
+" -r\t\tforget all remembered locations\n"
+" -t\t\tprint the remembered location of each NAME, preceding\n"
+" \t\teach location with the corresponding NAME if multiple\n"
+" \t\tNAMEs are given\n"
+" Arguments:\n"
+" NAME\t\tEach NAME is searched for in $PATH and added to the list\n"
+" \t\tof remembered commands.\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless NAME is not found or an invalid option is given."
+msgstr ""
+
+#: builtins.c:792
+msgid ""
+"Display information about builtin commands.\n"
+" \n"
+" Displays brief summaries of builtin commands. If PATTERN is\n"
+" specified, gives detailed help on all commands matching PATTERN,\n"
+" otherwise the list of help topics is printed.\n"
+" \n"
+" Options:\n"
+" -d\toutput short description for each topic\n"
+" -m\tdisplay usage in pseudo-manpage format\n"
+" -s\toutput only a short usage synopsis for each topic matching\n"
+" \tPATTERN\n"
+" \n"
+" Arguments:\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."
+msgstr ""
+
+#: builtins.c:816
+msgid ""
+"Display or manipulate the history list.\n"
+" \n"
+" Display the history list with line numbers, prefixing each modified\n"
+" entry with a `*'. An argument of N lists only the last N entries.\n"
+" \n"
+" Options:\n"
+" -c\tclear the history list by deleting all of the entries\n"
+" -d offset\tdelete the history entry at offset OFFSET.\n"
+" \n"
+" -a\tappend history lines from this session to the history file\n"
+" -n\tread all history lines not already read from the history file\n"
+" -r\tread the history file and append the contents to the history\n"
+" \tlist\n"
+" -w\twrite the current history to the history file\n"
+" \tand append them to the history list\n"
+" \n"
+" -p\tperform history expansion on each ARG and display the result\n"
+" \twithout storing it in the history list\n"
+" -s\tappend the ARGs to the history list as a single entry\n"
+" \n"
+" If FILENAME is given, it is used as the history file. Otherwise,\n"
+" if $HISTFILE has a value, that is used, else ~/.bash_history.\n"
+" \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"
+" \n"
+" Exit Status:\n"
+" Returns success unless an invalid option is given or an error occurs."
+msgstr ""
+
+#: builtins.c:852
+msgid ""
+"Display status of jobs.\n"
+" \n"
+" Lists the active jobs. JOBSPEC restricts output to that job.\n"
+" Without options, the status of all active jobs is displayed.\n"
+" \n"
+" Options:\n"
+" -l\tlists process IDs in addition to the normal information\n"
+" -n\tlist only processes that have changed status since the last\n"
+" \tnotification\n"
+" -p\tlists process IDs only\n"
+" -r\trestrict output to running jobs\n"
+" -s\trestrict output to stopped jobs\n"
+" \n"
+" If -x is supplied, COMMAND is run after all job specifications that\n"
+" appear in ARGS have been replaced with the process ID of that job's\n"
+" process group leader.\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless an invalid option is given or an error occurs.\n"
+" If -x is used, returns the exit status of COMMAND."
+msgstr ""
+
+#: builtins.c:879
+msgid ""
+"Remove jobs from current shell.\n"
+" \n"
+" Removes each JOBSPEC argument from the table of active jobs. Without\n"
+" any JOBSPECs, the shell uses its notion of the current job.\n"
+" \n"
+" Options:\n"
+" -a\tremove all jobs if JOBSPEC is not supplied\n"
+" -h\tmark each JOBSPEC so that SIGHUP is not sent to the job if the\n"
+" \tshell receives a SIGHUP\n"
+" -r\tremove only running jobs\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless an invalid option or JOBSPEC is given."
+msgstr ""
+
+#: builtins.c:898
+msgid ""
+"Send a signal to a job.\n"
+" \n"
+" Send the processes identified by PID or JOBSPEC the signal named by\n"
+" SIGSPEC or SIGNUM. If neither SIGSPEC nor SIGNUM is present, then\n"
+" SIGTERM is assumed.\n"
+" \n"
+" Options:\n"
+" -s sig\tSIG is a signal name\n"
+" -n sig\tSIG is a signal number\n"
+" -l\tlist the signal names; if arguments follow `-l' they are\n"
+" \tassumed to be signal numbers for which names should be listed\n"
+" \n"
+" Kill is a shell builtin for two reasons: it allows job IDs to be used\n"
+" instead of process IDs, and allows processes to be killed if the limit\n"
+" on processes that you can create is reached.\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless an invalid option is given or an error occurs."
+msgstr ""
+
+#: builtins.c:921
+msgid ""
+"Evaluate arithmetic expressions.\n"
+" \n"
+" 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"
+" in order of decreasing precedence.\n"
+" \n"
+" \tid++, id--\tvariable post-increment, post-decrement\n"
+" \t++id, --id\tvariable pre-increment, pre-decrement\n"
+" \t-, +\t\tunary minus, plus\n"
+" \t!, ~\t\tlogical and bitwise negation\n"
+" \t**\t\texponentiation\n"
+" \t*, /, %\t\tmultiplication, division, remainder\n"
+" \t+, -\t\taddition, subtraction\n"
+" \t<<, >>\t\tleft and right bitwise shifts\n"
+" \t<=, >=, <, >\tcomparison\n"
+" \t==, !=\t\tequality, inequality\n"
+" \t&\t\tbitwise AND\n"
+" \t^\t\tbitwise XOR\n"
+" \t|\t\tbitwise OR\n"
+" \t&&\t\tlogical AND\n"
+" \t||\t\tlogical OR\n"
+" \texpr ? expr : expr\n"
+" \t\t\tconditional operator\n"
+" \t=, *=, /=, %=,\n"
+" \t+=, -=, <<=, >>=,\n"
+" \t&=, ^=, |=\tassignment\n"
+" \n"
+" Shell variables are allowed as operands. The name of the variable\n"
+" is replaced by its value (coerced to a fixed-width integer) within\n"
+" an expression. The variable need not have its integer attribute\n"
+" turned on to be used in an expression.\n"
+" \n"
+" Operators are evaluated in order of precedence. Sub-expressions in\n"
+" parentheses are evaluated first and may override the precedence\n"
+" rules above.\n"
+" \n"
+" Exit Status:\n"
+" If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise.."
+msgstr ""
+
+#: builtins.c:966
+msgid ""
+"Read a line from the standard input and split it into fields.\n"
+" \n"
+" Reads a single line from the standard input, or from file descriptor FD\n"
+" if the -u option is supplied. The line is split into fields as with word\n"
+" 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"
+" delimiters.\n"
+" \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\tvariable ARRAY, starting at zero\n"
+" -d delim\tcontinue until the first character of DELIM is read, rather\n"
+" \t\tthan newline\n"
+" -e\t\tuse Readline to obtain the line in an interactive shell\n"
+" -i text\tUse TEXT as the initial text for Readline\n"
+" -n nchars\treturn after reading NCHARS characters rather than waiting\n"
+" \t\tfor a newline\n"
+" -p prompt\toutput the string PROMPT without a trailing newline before\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\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"
+" \t\tif input is available on the specified file descriptor. The\n"
+" \t\texit status is greater than 128 if the timeout is exceeded\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"
+" or an invalid file descriptor is supplied as the argument to -u."
+msgstr ""
+
+#: builtins.c:1006
+msgid ""
+"Return from a shell function.\n"
+" \n"
+" Causes a function or sourced script to exit with the return value\n"
+" specified by N. If N is omitted, the return status is that of the\n"
+" last command executed within the function or script.\n"
+" \n"
+" Exit Status:\n"
+" Returns N, or failure if the shell is not executing a function or script."
+msgstr ""
+
+#: builtins.c:1019
+msgid ""
+"Set or unset values of shell options and positional parameters.\n"
+" \n"
+" Change the value of shell attributes and positional parameters, or\n"
+" display the names and values of shell variables.\n"
+" \n"
+" Options:\n"
+" -a Mark variables which are modified or created for export.\n"
+" -b Notify of job termination immediately.\n"
+" -e Exit immediately if a command exits with a non-zero status.\n"
+" -f Disable file name generation (globbing).\n"
+" -h Remember the location of commands as they are looked up.\n"
+" -k All assignment arguments are placed in the environment for a\n"
+" command, not just those that precede the command name.\n"
+" -m Job control is enabled.\n"
+" -n Read commands but do not execute them.\n"
+" -o option-name\n"
+" Set the variable corresponding to option-name:\n"
+" allexport same as -a\n"
+" braceexpand same as -B\n"
+" emacs use an emacs-style line editing interface\n"
+" errexit same as -e\n"
+" errtrace same as -E\n"
+" functrace same as -T\n"
+" hashall same as -h\n"
+" histexpand same as -H\n"
+" history enable command history\n"
+" ignoreeof the shell will not exit upon reading EOF\n"
+" interactive-comments\n"
+" allow comments to appear in interactive commands\n"
+" keyword same as -k\n"
+" monitor same as -m\n"
+" noclobber same as -C\n"
+" noexec same as -n\n"
+" noglob same as -f\n"
+" nolog currently accepted but ignored\n"
+" notify same as -b\n"
+" nounset same as -u\n"
+" onecmd same as -t\n"
+" 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"
+" posix change the behavior of bash where the default\n"
+" operation differs from the Posix standard to\n"
+" match the standard\n"
+" privileged same as -p\n"
+" verbose same as -v\n"
+" vi use a vi-style line editing interface\n"
+" xtrace same as -x\n"
+" -p Turned on whenever the real and effective user ids do not match.\n"
+" Disables processing of the $ENV file and importing of shell\n"
+" functions. Turning this option off causes the effective uid and\n"
+" gid to be set to the real uid and gid.\n"
+" -t Exit after reading and executing one command.\n"
+" -u Treat unset variables as an error when substituting.\n"
+" -v Print shell input lines as they are read.\n"
+" -x Print commands and their arguments as they are executed.\n"
+" -B the shell will perform brace expansion\n"
+" -C If set, disallow existing regular files to be overwritten\n"
+" by redirection of output.\n"
+" -E If set, the ERR trap is inherited by shell functions.\n"
+" -H Enable ! style history substitution. This flag is on\n"
+" by default when the shell is interactive.\n"
+" -P If set, do not follow symbolic links when executing commands\n"
+" such as cd which change the current directory.\n"
+" -T If set, the DEBUG trap is inherited by shell functions.\n"
+" - Assign any remaining arguments to the positional parameters.\n"
+" The -x and -v options are turned off.\n"
+" \n"
+" Using + rather than - causes these flags to be turned off. The\n"
+" flags can also be used upon invocation of the shell. The current\n"
+" set of flags may be found in $-. The remaining n ARGs are positional\n"
+" parameters and are assigned, in order, to $1, $2, .. $n. If no\n"
+" ARGs are given, all shell variables are printed.\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless an invalid option is given."
+msgstr ""
+
+#: builtins.c:1101
+msgid ""
+"Unset values and attributes of shell variables and functions.\n"
+" \n"
+" For each NAME, remove the corresponding variable or function.\n"
+" \n"
+" Options:\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"
+" tries to unset a function.\n"
+" \n"
+" Some variables cannot be unset; also see `readonly'.\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless an invalid option is given or a NAME is read-only."
+msgstr ""
+
+#: builtins.c:1121
+msgid ""
+"Set export attribute for shell variables.\n"
+" \n"
+" Marks each NAME for automatic export to the environment of subsequently\n"
+" executed commands. If VALUE is supplied, assign VALUE before exporting.\n"
+" \n"
+" Options:\n"
+" -f\trefer to shell functions\n"
+" -n\tremove the export property from each NAME\n"
+" -p\tdisplay a list of all exported variables and functions\n"
+" \n"
+" An argument of `--' disables further option processing.\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless an invalid option is given or NAME is invalid."
+msgstr ""
+
+#: builtins.c:1140
+msgid ""
+"Mark shell variables as unchangeable.\n"
+" \n"
+" Mark each NAME as read-only; the values of these NAMEs may not be\n"
+" changed by subsequent assignment. If VALUE is supplied, assign VALUE\n"
+" before marking as read-only.\n"
+" \n"
+" Options:\n"
+" -a\trefer to indexed array variables\n"
+" -A\trefer to associative array variables\n"
+" -f\trefer to shell functions\n"
+" -p\tdisplay a list of all readonly variables and functions\n"
+" \n"
+" An argument of `--' disables further option processing.\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless an invalid option is given or NAME is invalid."
+msgstr ""
+
+#: builtins.c:1161
+msgid ""
+"Shift positional parameters.\n"
+" \n"
+" Rename the positional parameters $N+1,$N+2 ... to $1,$2 ... If N is\n"
+" not given, it is assumed to be 1.\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless N is negative or greater than $#."
+msgstr ""
+
+#: builtins.c:1173 builtins.c:1188
+msgid ""
+"Execute commands from a file in the current shell.\n"
+" \n"
+" Read and execute commands from FILENAME in the current shell. The\n"
+" entries in $PATH are used to find the directory containing FILENAME.\n"
+" If any ARGUMENTS are supplied, they become the positional parameters\n"
+" when FILENAME is executed.\n"
+" \n"
+" Exit Status:\n"
+" Returns the status of the last command executed in FILENAME; fails if\n"
+" FILENAME cannot be read."
+msgstr ""
+
+#: builtins.c:1204
+msgid ""
+"Suspend shell execution.\n"
+" \n"
+" Suspend the execution of this shell until it receives a SIGCONT signal.\n"
+" Unless forced, login shells cannot be suspended.\n"
+" \n"
+" Options:\n"
+" -f\tforce the suspend, even if the shell is a login shell\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless job control is not enabled or an error occurs."
+msgstr ""
+
+#: builtins.c:1220
+msgid ""
+"Evaluate conditional expression.\n"
+" \n"
+" Exits with a status of 0 (true) or 1 (false) depending on\n"
+" the evaluation of EXPR. Expressions may be unary or binary. Unary\n"
+" expressions are often used to examine the status of a file. There\n"
+" are string operators as well, and numeric comparison operators.\n"
+" \n"
+" File operators:\n"
+" \n"
+" -a FILE True if file exists.\n"
+" -b FILE True if file is block special.\n"
+" -c FILE True if file is character special.\n"
+" -d FILE True if file is a directory.\n"
+" -e FILE True if file exists.\n"
+" -f FILE True if file exists and is a regular file.\n"
+" -g FILE True if file is set-group-id.\n"
+" -h FILE True if file is a symbolic link.\n"
+" -L FILE True if file is a symbolic link.\n"
+" -k FILE True if file has its `sticky' bit set.\n"
+" -p FILE True if file is a named pipe.\n"
+" -r FILE True if file is readable by you.\n"
+" -s FILE True if file exists and is not empty.\n"
+" -S FILE True if file is a socket.\n"
+" -t FD True if FD is opened on a terminal.\n"
+" -u FILE True if the file is set-user-id.\n"
+" -w FILE True if the file is writable by you.\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"
+" FILE1 -nt FILE2 True if file1 is newer than file2 (according to\n"
+" modification date).\n"
+" \n"
+" FILE1 -ot FILE2 True if file1 is older than file2.\n"
+" \n"
+" FILE1 -ef FILE2 True if file1 is a hard link to file2.\n"
+" \n"
+" String operators:\n"
+" \n"
+" -z STRING True if string is empty.\n"
+" \n"
+" -n STRING\n"
+" STRING True if string is not empty.\n"
+" \n"
+" STRING1 = STRING2\n"
+" True if the strings are equal.\n"
+" STRING1 != STRING2\n"
+" True if the strings are not equal.\n"
+" STRING1 < STRING2\n"
+" True if STRING1 sorts before STRING2 lexicographically.\n"
+" STRING1 > STRING2\n"
+" True if STRING1 sorts after STRING2 lexicographically.\n"
+" \n"
+" Other operators:\n"
+" \n"
+" -o OPTION True if the shell option OPTION is enabled.\n"
+" ! EXPR True if expr is false.\n"
+" EXPR1 -a EXPR2 True if both expr1 AND expr2 are true.\n"
+" EXPR1 -o EXPR2 True if either expr1 OR expr2 is true.\n"
+" \n"
+" arg1 OP arg2 Arithmetic tests. OP is one of -eq, -ne,\n"
+" -lt, -le, -gt, or -ge.\n"
+" \n"
+" Arithmetic binary operators return true if ARG1 is equal, not-equal,\n"
+" less-than, less-than-or-equal, greater-than, or greater-than-or-equal\n"
+" than ARG2.\n"
+" \n"
+" Exit Status:\n"
+" Returns success if EXPR evaluates to true; fails if EXPR evaluates to\n"
+" false or an invalid argument is given."
+msgstr ""
+
+#: builtins.c:1296
+msgid ""
+"Evaluate conditional expression.\n"
+" \n"
+" This is a synonym for the \"test\" builtin, but the last argument must\n"
+" be a literal `]', to match the opening `['."
+msgstr ""
+
+#: builtins.c:1305
+msgid ""
+"Display process times.\n"
+" \n"
+" Prints the accumulated user and system times for the shell and all of its\n"
+" child processes.\n"
+" \n"
+" Exit Status:\n"
+" Always succeeds."
+msgstr ""
+
+#: builtins.c:1317
+msgid ""
+"Trap signals and other events.\n"
+" \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"
+" signal(s) SIGNAL_SPEC. If ARG is absent (and a single SIGNAL_SPEC\n"
+" is supplied) or `-', each specified signal is reset to its original\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"
+" 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"
+" 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"
+" 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."
+msgstr ""
+
+#: builtins.c:1349
+msgid ""
+"Display information about command type.\n"
+" \n"
+" For each NAME, indicate how it would be interpreted if used as a\n"
+" command name.\n"
+" \n"
+" Options:\n"
+" -a\tdisplay all locations containing an executable named NAME;\n"
+" \tincludes aliases, builtins, and functions, if and only if\n"
+" \tthe `-p' option is not also used\n"
+" -f\tsuppress shell function lookup\n"
+" -P\tforce a PATH search for each NAME, even if it is an alias,\n"
+" \tbuiltin, or function, and returns the name of the disk file\n"
+" \tthat would be executed\n"
+" -p\treturns either the name of the disk file that would be executed,\n"
+" \tor nothing if `type -t NAME' would not return `file'.\n"
+" -t\toutput a single word which is one of `alias', `keyword',\n"
+" \t`function', `builtin', `file' or `', if NAME is an alias, shell\n"
+" \treserved word, shell function, shell builtin, disk file, or not\n"
+" \tfound, respectively\n"
+" \n"
+" Arguments:\n"
+" 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."
+msgstr ""
+
+#: builtins.c:1380
+msgid ""
+"Modify shell resource limits.\n"
+" \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"
+" -S\tuse the `soft' resource limit\n"
+" -H\tuse the `hard' resource limit\n"
+" -a\tall current limits are reported\n"
+" -b\tthe socket buffer size\n"
+" -c\tthe maximum size of core files created\n"
+" -d\tthe maximum size of a process's data segment\n"
+" -e\tthe maximum scheduling priority (`nice')\n"
+" -f\tthe maximum size of files written by the shell and its children\n"
+" -i\tthe maximum number of pending signals\n"
+" -l\tthe maximum size a process may lock into memory\n"
+" -m\tthe maximum resident set size\n"
+" -n\tthe maximum number of open file descriptors\n"
+" -p\tthe pipe buffer size\n"
+" -q\tthe maximum number of bytes in POSIX message queues\n"
+" -r\tthe maximum real-time scheduling priority\n"
+" -s\tthe maximum stack size\n"
+" -t\tthe maximum amount of cpu time in seconds\n"
+" -u\tthe maximum number of user processes\n"
+" -v\tthe size of virtual memory\n"
+" -x\tthe maximum number of file locks\n"
+" \n"
+" If LIMIT is given, it is the new value of the specified resource; the\n"
+" special LIMIT values `soft', `hard', and `unlimited' stand for the\n"
+" current soft limit, the current hard limit, and no limit, respectively.\n"
+" Otherwise, the current value of the specified resource is printed. If\n"
+" no option is given, then -f is assumed.\n"
+" \n"
+" Values are in 1024-byte increments, except for -t, which is in seconds,\n"
+" -p, which is in increments of 512 bytes, and -u, which is an unscaled\n"
+" number of processes.\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless an invalid option is supplied or an error occurs."
+msgstr ""
+
+#: builtins.c:1425
+msgid ""
+"Display or set file mode mask.\n"
+" \n"
+" Sets the user file-creation mask to MODE. If MODE is omitted, prints\n"
+" the current value of the mask.\n"
+" \n"
+" If MODE begins with a digit, it is interpreted as an octal number;\n"
+" otherwise it is a symbolic mode string like that accepted by chmod(1).\n"
+" \n"
+" Options:\n"
+" -p\tif MODE is omitted, output in a form that may be reused as input\n"
+" -S\tmakes the output symbolic; otherwise an octal number is output\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless MODE is invalid or an invalid option is given."
+msgstr ""
+
+#: builtins.c:1445
+msgid ""
+"Wait for job completion and return exit status.\n"
+" \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"
+" 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"
+" given."
+msgstr ""
+
+#: builtins.c:1463
+msgid ""
+"Wait for process completion and return exit status.\n"
+" \n"
+" Waits for the specified process and reports its termination status. If\n"
+" PID is not given, all currently active child processes are waited for,\n"
+" 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"
+" given."
+msgstr ""
+
+#: builtins.c:1478
+msgid ""
+"Execute commands for each member in a list.\n"
+" \n"
+" The `for' loop executes a sequence of commands for each member in a\n"
+" list of items. If `in WORDS ...;' is not present, then `in \"$@\"' is\n"
+" assumed. For each element in WORDS, NAME is set to that element, and\n"
+" the COMMANDS are executed.\n"
+" \n"
+" Exit Status:\n"
+" Returns the status of the last command executed."
+msgstr ""
+
+#: builtins.c:1492
+msgid ""
+"Arithmetic for loop.\n"
+" \n"
+" Equivalent to\n"
+" \t(( EXP1 ))\n"
+" \twhile (( EXP2 )); do\n"
+" \t\tCOMMANDS\n"
+" \t\t(( EXP3 ))\n"
+" \tdone\n"
+" EXP1, EXP2, and EXP3 are arithmetic expressions. If any expression is\n"
+" omitted, it behaves as if it evaluates to 1.\n"
+" \n"
+" Exit Status:\n"
+" Returns the status of the last command executed."
+msgstr ""
+
+#: builtins.c:1510
+msgid ""
+"Select words from a list and execute commands.\n"
+" \n"
+" The WORDS are expanded, generating a list of words. The\n"
+" set of expanded words is printed on the standard error, each\n"
+" preceded by a number. If `in WORDS' is not present, `in \"$@\"'\n"
+" is assumed. The PS3 prompt is then displayed and a line read\n"
+" from the standard input. If the line consists of the number\n"
+" corresponding to one of the displayed words, then NAME is set\n"
+" to that word. If the line is empty, WORDS and the prompt are\n"
+" redisplayed. If EOF is read, the command completes. Any other\n"
+" value read causes NAME to be set to null. The line read is saved\n"
+" in the variable REPLY. COMMANDS are executed after each selection\n"
+" until a break command is executed.\n"
+" \n"
+" Exit Status:\n"
+" Returns the status of the last command executed."
+msgstr ""
+
+#: builtins.c:1531
+msgid ""
+"Report time consumed by pipeline's execution.\n"
+" \n"
+" Execute PIPELINE and print a summary of the real time, user CPU time,\n"
+" and system CPU time spent executing PIPELINE when it terminates.\n"
+" \n"
+" Options:\n"
+" -p\tprint the timing summary in the portable Posix format\n"
+" \n"
+" The value of the TIMEFORMAT variable is used as the output format.\n"
+" \n"
+" Exit Status:\n"
+" The return status is the return status of PIPELINE."
+msgstr ""
+
+#: builtins.c:1548
+msgid ""
+"Execute commands based on pattern matching.\n"
+" \n"
+" Selectively execute COMMANDS based upon WORD matching PATTERN. The\n"
+" `|' is used to separate multiple patterns.\n"
+" \n"
+" Exit Status:\n"
+" Returns the status of the last command executed."
+msgstr ""
+
+#: builtins.c:1560
+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"
+" 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"
+" if no condition tested true.\n"
+" \n"
+" Exit Status:\n"
+" Returns the status of the last command executed."
+msgstr ""
+
+#: builtins.c:1577
+msgid ""
+"Execute commands as long as a test succeeds.\n"
+" \n"
+" Expand and execute COMMANDS as long as the final command in the\n"
+" `while' COMMANDS has an exit status of zero.\n"
+" \n"
+" Exit Status:\n"
+" Returns the status of the last command executed."
+msgstr ""
+
+#: builtins.c:1589
+msgid ""
+"Execute commands as long as a test does not succeed.\n"
+" \n"
+" Expand and execute COMMANDS as long as the final command in the\n"
+" `until' COMMANDS has an exit status which is not zero.\n"
+" \n"
+" Exit Status:\n"
+" Returns the status of the last command executed."
+msgstr ""
+
+#: builtins.c:1601
+msgid ""
+"Create a coprocess named NAME.\n"
+" \n"
+" Execute COMMAND asynchronously, with the standard output and standard\n"
+" input of the command connected via a pipe to file descriptors assigned\n"
+" to indices 0 and 1 of an array variable NAME in the executing shell.\n"
+" The default NAME is \"COPROC\".\n"
+" \n"
+" Exit Status:\n"
+" Returns the exit status of COMMAND."
+msgstr ""
+
+#: builtins.c:1615
+msgid ""
+"Define shell function.\n"
+" \n"
+" Create a shell function named NAME. When invoked as a simple command,\n"
+" NAME runs COMMANDs in the calling shell's context. When NAME is invoked,\n"
+" the arguments are passed to the function as $1...$n, and the function's\n"
+" name is in $FUNCNAME.\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless NAME is readonly."
+msgstr ""
+
+#: builtins.c:1629
+msgid ""
+"Group commands as a unit.\n"
+" \n"
+" Run a set of commands in a group. This is one way to redirect an\n"
+" entire set of commands.\n"
+" \n"
+" Exit Status:\n"
+" Returns the status of the last command executed."
+msgstr ""
+
+#: builtins.c:1641
+msgid ""
+"Resume job in foreground.\n"
+" \n"
+" Equivalent to the JOB_SPEC argument to the `fg' command. Resume a\n"
+" stopped or background job. JOB_SPEC can specify either a job name\n"
+" or a job number. Following JOB_SPEC with a `&' places the job in\n"
+" the background, as if the job specification had been supplied as an\n"
+" argument to `bg'.\n"
+" \n"
+" Exit Status:\n"
+" Returns the status of the resumed job."
+msgstr ""
+
+#: builtins.c:1656
+msgid ""
+"Evaluate arithmetic expression.\n"
+" \n"
+" The EXPRESSION is evaluated according to the rules for arithmetic\n"
+" evaluation. Equivalent to \"let EXPRESSION\".\n"
+" \n"
+" Exit Status:\n"
+" Returns 1 if EXPRESSION evaluates to 0; returns 0 otherwise."
+msgstr ""
+
+#: builtins.c:1668
+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"
+" \n"
+" ( EXPRESSION )\tReturns the value of EXPRESSION\n"
+" ! EXPRESSION\t\tTrue if EXPRESSION is false; else false\n"
+" EXPR1 && EXPR2\tTrue if both EXPR1 and EXPR2 are true; else false\n"
+" EXPR1 || EXPR2\tTrue if either EXPR1 or EXPR2 is true; else false\n"
+" \n"
+" When the `==' and `!=' operators are used, the string to the right of\n"
+" the operator is used as a pattern and pattern matching is performed.\n"
+" When the `=~' operator is used, the string to the right of the operator\n"
+" is matched as a regular expression.\n"
+" \n"
+" The && and || operators do not evaluate EXPR2 if EXPR1 is sufficient to\n"
+" determine the expression's value.\n"
+" \n"
+" Exit Status:\n"
+" 0 or 1 depending on value of EXPRESSION."
+msgstr ""
+
+#: builtins.c:1694
+msgid ""
+"Common shell variable names and usage.\n"
+" \n"
+" BASH_VERSION\tVersion information for this Bash.\n"
+" CDPATH\tA colon-separated list of directories to search\n"
+" \t\tfor directories given as arguments to `cd'.\n"
+" GLOBIGNORE\tA colon-separated list of patterns describing filenames to\n"
+" \t\tbe ignored by pathname expansion.\n"
+" HISTFILE\tThe name of the file where your command history is stored.\n"
+" HISTFILESIZE\tThe maximum number of lines this file can contain.\n"
+" HISTSIZE\tThe maximum number of history lines that a running\n"
+" \t\tshell can access.\n"
+" HOME\tThe complete pathname to your login directory.\n"
+" HOSTNAME\tThe name of the current host.\n"
+" HOSTTYPE\tThe type of CPU this version of Bash is running under.\n"
+" IGNOREEOF\tControls the action of the shell on receipt of an EOF\n"
+" \t\tcharacter as the sole input. If set, then the value\n"
+" \t\tof it is the number of EOF characters that can be seen\n"
+" \t\tin a row on an empty line before the shell will exit\n"
+" \t\t(default 10). When unset, EOF signifies the end of input.\n"
+" MACHTYPE\tA string describing the current system Bash is running on.\n"
+" MAILCHECK\tHow often, in seconds, Bash checks for new mail.\n"
+" MAILPATH\tA colon-separated list of filenames which Bash checks\n"
+" \t\tfor new mail.\n"
+" OSTYPE\tThe version of Unix this version of Bash is running on.\n"
+" PATH\tA colon-separated list of directories to search when\n"
+" \t\tlooking for commands.\n"
+" PROMPT_COMMAND\tA command to be executed before the printing of each\n"
+" \t\tprimary prompt.\n"
+" PS1\t\tThe primary prompt string.\n"
+" PS2\t\tThe secondary prompt string.\n"
+" PWD\t\tThe full pathname of the current directory.\n"
+" SHELLOPTS\tA colon-separated list of enabled shell options.\n"
+" TERM\tThe name of the current terminal type.\n"
+" TIMEFORMAT\tThe output format for timing statistics displayed by the\n"
+" \t\t`time' reserved word.\n"
+" auto_resume\tNon-null means a command word appearing on a line by\n"
+" \t\titself is first looked for in the list of currently\n"
+" \t\tstopped jobs. If found there, that job is foregrounded.\n"
+" \t\tA value of `exact' means that the command word must\n"
+" \t\texactly match a command in the list of stopped jobs. A\n"
+" \t\tvalue of `substring' means that the command word must\n"
+" \t\tmatch a substring of the job. Any other value means that\n"
+" \t\tthe command must be a prefix of a stopped job.\n"
+" histchars\tCharacters controlling history expansion and quick\n"
+" \t\tsubstitution. The first character is the history\n"
+" \t\tsubstitution character, usually `!'. The second is\n"
+" \t\tthe `quick substitution' character, usually `^'. The\n"
+" \t\tthird is the `history comment' character, usually `#'.\n"
+" HISTIGNORE\tA colon-separated list of patterns used to decide which\n"
+" \t\tcommands should be saved on the history list.\n"
+msgstr ""
+
+#: builtins.c:1751
+msgid ""
+"Add directories to stack.\n"
+" \n"
+" Adds a directory to the top of the directory stack, or rotates\n"
+" the stack, making the new top of the stack the current working\n"
+" directory. With no arguments, exchanges the top two directories.\n"
+" \n"
+" Options:\n"
+" -n\tSuppresses the normal change of directory when adding\n"
+" \tdirectories to the stack, so only the stack is manipulated.\n"
+" \n"
+" Arguments:\n"
+" +N\tRotates the stack so that the Nth directory (counting\n"
+" \tfrom the left of the list shown by `dirs', starting with\n"
+" \tzero) is at the top.\n"
+" \n"
+" -N\tRotates the stack so that the Nth directory (counting\n"
+" \tfrom the right of the list shown by `dirs', starting with\n"
+" \tzero) is at the top.\n"
+" \n"
+" dir\tAdds DIR to the directory stack at the top, making it the\n"
+" \tnew current working directory.\n"
+" \n"
+" The `dirs' builtin displays the directory stack.\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless an invalid argument is supplied or the directory\n"
+" change fails."
+msgstr ""
+
+#: builtins.c:1785
+msgid ""
+"Remove directories from stack.\n"
+" \n"
+" Removes entries from the directory stack. With no arguments, removes\n"
+" the top directory from the stack, and changes to the new top directory.\n"
+" \n"
+" Options:\n"
+" -n\tSuppresses the normal change of directory when removing\n"
+" \tdirectories from the stack, so only the stack is manipulated.\n"
+" \n"
+" Arguments:\n"
+" +N\tRemoves the Nth entry counting from the left of the list\n"
+" \tshown by `dirs', starting with zero. For example: `popd +0'\n"
+" \tremoves the first directory, `popd +1' the second.\n"
+" \n"
+" -N\tRemoves the Nth entry counting from the right of the list\n"
+" \tshown by `dirs', starting with zero. For example: `popd -0'\n"
+" \tremoves the last directory, `popd -1' the next to last.\n"
+" \n"
+" The `dirs' builtin displays the directory stack.\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless an invalid argument is supplied or the directory\n"
+" change fails."
+msgstr ""
+
+#: builtins.c:1815
+msgid ""
+"Display directory stack.\n"
+" \n"
+" Display the list of currently remembered directories. Directories\n"
+" find their way onto the list with the `pushd' command; you can get\n"
+" back up through the list with the `popd' command.\n"
+" \n"
+" Options:\n"
+" -c\tclear the directory stack by deleting all of the elements\n"
+" -l\tdo not print tilde-prefixed versions of directories relative\n"
+" \tto your home directory\n"
+" -p\tprint the directory stack with one entry per line\n"
+" -v\tprint the directory stack with one entry per line prefixed\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"
+" \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"
+" \tdirs when invoked without options, starting with zero.\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless an invalid option is supplied or an error occurs."
+msgstr ""
+
+#: builtins.c:1844
+msgid ""
+"Set and unset shell options.\n"
+" \n"
+" Change the setting of each shell option OPTNAME. Without any option\n"
+" arguments, list all shell options with an indication of whether or not each\n"
+" is set.\n"
+" \n"
+" Options:\n"
+" -o\trestrict OPTNAMEs to those defined for use with `set -o'\n"
+" -p\tprint each shell option with an indication of its status\n"
+" -q\tsuppress output\n"
+" -s\tenable (set) each OPTNAME\n"
+" -u\tdisable (unset) each OPTNAME\n"
+" \n"
+" Exit Status:\n"
+" Returns success if OPTNAME is enabled; fails if an invalid option is\n"
+" given or OPTNAME is disabled."
+msgstr ""
+
+#: builtins.c:1865
+msgid ""
+"Formats and prints ARGUMENTS under control of the FORMAT.\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"
+" sequences, which are converted and copied to the standard output; and\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"
+" 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"
+" error occurs."
+msgstr ""
+
+#: builtins.c:1892
+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"
+" allows them to be reused as input.\n"
+" \n"
+" Options:\n"
+" -p\tprint existing completion specifications in a reusable format\n"
+" -r\tremove a completion specification for each NAME, or, if no\n"
+" \tNAMEs are supplied, all completion specifications\n"
+" \n"
+" When completion is attempted, the actions are applied in the order the\n"
+" uppercase-letter options are listed above.\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless an invalid option is supplied or an error occurs."
+msgstr ""
+
+#: builtins.c:1915
+msgid ""
+"Display possible completions depending on the options.\n"
+" \n"
+" Intended to be used from within a shell function generating possible\n"
+" completions. If the optional WORD argument is supplied, matches against\n"
+" WORD are generated.\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless an invalid option is supplied or an error occurs."
+msgstr ""
+
+#: builtins.c:1930
+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"
+" \n"
+" Options:\n"
+" \t-o option\tSet completion option OPTION for each NAME\n"
+" \n"
+" Using `+o' instead of `-o' turns off the specified option.\n"
+" \n"
+" Arguments:\n"
+" \n"
+" Each NAME refers to a command for which a completion specification must\n"
+" have previously been defined using the `complete' builtin. If no NAMEs\n"
+" are supplied, compopt must be called by a function currently generating\n"
+" completions, and the options for that currently-executing completion\n"
+" generator are modified.\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless an invalid option is supplied or NAME does not\n"
+" have a completion specification defined."
+msgstr ""
+
+#: builtins.c:1958
+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"
+" 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"
+" -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"
+" -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"
+" \n"
+" Arguments:\n"
+" ARRAY\t\tArray variable name to use for file data.\n"
+" \n"
+" If -C is supplied without -c, the default quantum is 5000. When\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"
+" assigning to it.\n"
+" \n"
+" Exit Status:\n"
+" Returns success unless an invalid option is given or ARRAY is readonly."
+msgstr ""
+
+#: builtins.c:1990
+msgid ""
+"Read lines from a file into an array variable.\n"
+" \n"
+" A synonym for `mapfile'."
+msgstr ""
+"Léigh línte ó chomhad agus cuir in athróg eagair iad.\n"
+" \n"
+" Comhchiallach le 'mapfile'."
-BUILD_DIR=/usr/local/build/bash/bash-current
+BUILD_DIR=/usr/local/build/chet/bash/bash-current
THIS_SH=$BUILD_DIR/bash
PATH=$PATH:$BUILD_DIR
+ x=i
+ case x in
+ x=i
++ set +x
+1
+2
+3
+4
++ for f in a b c d e
++ echo a
+a
++ for f in a b c d e
++ echo b
+b
++ for f in a b c d e
++ echo c
+c
++ for f in a b c d e
++ echo d
+d
++ for f in a b c d e
++ echo e
+e
++ set +x
+TRACEFILE:
++ echo 1
++ echo 2
++ echo 3
++ echo 4
++ unset BASH_XTRACEFD
+=====
0) x=i ;;
*) x=i ;;
esac
+set +x
-#;;; Local Variables: ***
-#;;; mode:shell-script ***
-#;;; eval: (sh-set-shell "bash") ***
-#;;; End: ***
+# test BASH_XTRACEFD
+${THIS_SH} ./set-x1.sub
--- /dev/null
+: ${TMPDIR:=/var/tmp}
+TRACEFILE=$TMPDIR/bash-trace-$$
+trap 'rm -f $TRACEFILE' 0 1 2 3 6 15
+
+exec 4>$TRACEFILE
+BASH_XTRACEFD=4
+
+set -x
+
+echo 1
+echo 2
+echo 3
+echo 4
+
+unset BASH_XTRACEFD
+
+for f in a b c d e; do echo $f ; done
+
+set +x
+
+echo TRACEFILE:
+cat $TRACEFILE
+echo =====
+
+exit 0