aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorSebastian Schmidt <yath@yath.de>2012-04-17 11:23:35 +0200
committerSebastian Schmidt <yath@yath.de>2012-04-17 11:24:20 +0200
commitf4b417c62a4f272c4cf9a074d0f7a3a97201f9db (patch)
treee2196f3b6361e2377c43ab47a3abf17d8f6afd77 /lib
parent791237e44695d2ee123c8a6f665ef074f5fadfbb (diff)
downloadexternal_bash-f4b417c62a4f272c4cf9a074d0f7a3a97201f9db.zip
external_bash-f4b417c62a4f272c4cf9a074d0f7a3a97201f9db.tar.gz
external_bash-f4b417c62a4f272c4cf9a074d0f7a3a97201f9db.tar.bz2
Update to upstream bash 4.2
This upgrades bash to from 4.1-rc to 4.2-release. See CWRU/changelog for changes. Change-Id: I926269c300cf44fa25964b5b375a148fcf11c4b7
Diffstat (limited to 'lib')
-rw-r--r--lib/glob/Android.mk3
-rw-r--r--lib/glob/Makefile.in11
-rw-r--r--lib/glob/gmisc.c314
-rw-r--r--lib/glob/smatch.c16
-rw-r--r--lib/glob/xmbsrtowcs.c106
-rw-r--r--lib/malloc/Makefile.in1
-rw-r--r--lib/readline/Makefile.in11
-rw-r--r--lib/readline/bind.c28
-rw-r--r--lib/readline/callback.c9
-rw-r--r--lib/readline/complete.c260
-rw-r--r--lib/readline/doc/history.texi2
-rw-r--r--lib/readline/doc/hstech.texi6
-rw-r--r--lib/readline/doc/hsuser.texi13
-rw-r--r--lib/readline/doc/rlman.texi2
-rw-r--r--lib/readline/doc/rltech.texi21
-rw-r--r--lib/readline/doc/rluser.texi86
-rw-r--r--lib/readline/doc/rluserman.texi2
-rw-r--r--lib/readline/doc/version.texi12
-rw-r--r--lib/readline/funmap.c7
-rw-r--r--lib/readline/histexpand.c121
-rw-r--r--lib/readline/histfile.c17
-rw-r--r--lib/readline/history.c2
-rw-r--r--lib/readline/input.c14
-rw-r--r--lib/readline/isearch.c35
-rw-r--r--lib/readline/keymaps.c6
-rw-r--r--lib/readline/keymaps.h5
-rw-r--r--lib/readline/kill.c6
-rw-r--r--lib/readline/misc.c8
-rw-r--r--lib/readline/nls.c2
-rw-r--r--lib/readline/readline.c6
-rw-r--r--lib/readline/readline.h70
-rw-r--r--lib/readline/rlprivate.h35
-rw-r--r--lib/readline/rltty.c4
-rw-r--r--lib/readline/savestring.c6
-rw-r--r--lib/readline/search.c2
-rw-r--r--lib/readline/shell.c4
-rw-r--r--lib/readline/signals.c1
-rw-r--r--lib/readline/terminal.c6
-rw-r--r--lib/readline/text.c65
-rw-r--r--lib/readline/tilde.c4
-rw-r--r--lib/readline/util.c51
-rw-r--r--lib/readline/vi_mode.c558
-rw-r--r--lib/readline/xfree.c50
-rw-r--r--lib/readline/xmalloc.c10
-rw-r--r--lib/sh/Android.mk3
-rw-r--r--lib/sh/Makefile.in26
-rw-r--r--lib/sh/casemod.c7
-rw-r--r--lib/sh/dprintf.c70
-rw-r--r--lib/sh/eaccess.c25
-rw-r--r--lib/sh/fnxform.c4
-rw-r--r--lib/sh/fpurge.c96
-rw-r--r--lib/sh/oslib.c9
-rw-r--r--lib/sh/shmatch.c2
-rw-r--r--lib/sh/shmbchar.c92
-rw-r--r--lib/sh/shquote.c10
-rw-r--r--lib/sh/snprintf.c2
-rw-r--r--lib/sh/strchrnul.c144
-rw-r--r--lib/sh/strftime.c49
-rw-r--r--lib/sh/strtrans.c34
-rw-r--r--lib/sh/tmpfile.c2
-rw-r--r--lib/sh/unicode.c235
-rw-r--r--lib/sh/wcswidth.c46
-rw-r--r--lib/tilde/tilde.c4
63 files changed, 2348 insertions, 510 deletions
diff --git a/lib/glob/Android.mk b/lib/glob/Android.mk
index b7d31bf..b22b8b5 100644
--- a/lib/glob/Android.mk
+++ b/lib/glob/Android.mk
@@ -9,7 +9,8 @@ LOCAL_SRC_FILES:= \
glob.c \
smatch.c \
strmatch.c \
- xmbsrtowcs.c
+ xmbsrtowcs.c \
+ gmisc.c
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/../.. \
diff --git a/lib/glob/Makefile.in b/lib/glob/Makefile.in
index 1ccae68..12cbb61 100644
--- a/lib/glob/Makefile.in
+++ b/lib/glob/Makefile.in
@@ -71,7 +71,7 @@ CSOURCES = $(srcdir)/glob.c $(srcdir)/strmatch.c $(srcdir)/smatch.c \
# The header files for this library.
HSOURCES = $(srcdir)/strmatch.h
-OBJECTS = glob.o strmatch.o smatch.o xmbsrtowcs.o
+OBJECTS = glob.o strmatch.o smatch.o xmbsrtowcs.o gmisc.o
# The texinfo files which document this library.
DOCSOURCE = doc/glob.texi
@@ -119,6 +119,9 @@ realclean distclean maintainer-clean: clean
mostlyclean: clean
-( cd doc && $(MAKE) $(MFLAGS) $@ )
+${BUILD_DIR}/pathnames.h: ${BUILD_DIR}/config.h ${BUILD_DIR}/Makefile Makefile
+ -( cd ${BUILD_DIR} && ${MAKE} ${MFLAGS} pathnames.h )
+
######################################################################
# #
# Dependencies for the object files which make up this library. #
@@ -137,18 +140,24 @@ strmatch.o: $(BUILD_DIR)/config.h
strmatch.o: $(BASHINCDIR)/stdc.h
glob.o: $(BUILD_DIR)/config.h
+glob.o: $(topdir)/shell.h $(BUILD_DIR)/pathnames.h
glob.o: $(topdir)/bashtypes.h $(BASHINCDIR)/ansi_stdlib.h $(topdir)/bashansi.h
glob.o: $(BASHINCDIR)/posixstat.h $(BASHINCDIR)/memalloc.h
glob.o: strmatch.h glob.h
glob.o: $(BASHINCDIR)/shmbutil.h
glob.o: $(topdir)/xmalloc.h
+gmisc.o: $(BUILD_DIR)/config.h
+gmisc.o: $(topdir)/bashtypes.h $(BASHINCDIR)/ansi_stdlib.h $(topdir)/bashansi.h
+gmisc.o: $(BASHINCDIR)/shmbutil.h
+
xmbsrtowcs.o: ${BUILD_DIR}/config.h
xmbsrtowcs.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
xmbsrtowcs.o: ${BASHINCDIR}/shmbutil.h
# Rules for deficient makes, like SunOS and Solaris
glob.o: glob.c
+gmisc.o: gmisc.c
strmatch.o: strmatch.c
smatch.o: smatch.c
xmbsrtowcs.o: xmbsrtowcs.c
diff --git a/lib/glob/gmisc.c b/lib/glob/gmisc.c
new file mode 100644
index 0000000..84794cd
--- /dev/null
+++ b/lib/glob/gmisc.c
@@ -0,0 +1,314 @@
+/* gmisc.c -- miscellaneous pattern matching utility functions for Bash.
+
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This file is part of GNU Bash, the Bourne-Again SHell.
+
+ Bash is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Bash is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Bash. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <config.h>
+
+#include "bashtypes.h"
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
+
+#include "bashansi.h"
+#include "shmbutil.h"
+
+#include "stdc.h"
+
+#ifndef LPAREN
+# define LPAREN '('
+#endif
+#ifndef RPAREN
+# define RPAREN ')'
+#endif
+
+#if defined (HANDLE_MULTIBYTE)
+#define WLPAREN L'('
+#define WRPAREN L')'
+
+/* Return 1 of the first character of WSTRING could match the first
+ character of pattern WPAT. Wide character version. */
+int
+match_pattern_wchar (wpat, wstring)
+ wchar_t *wpat, *wstring;
+{
+ wchar_t wc;
+
+ if (*wstring == 0)
+ return (0);
+
+ switch (wc = *wpat++)
+ {
+ default:
+ return (*wstring == wc);
+ case L'\\':
+ return (*wstring == *wpat);
+ case L'?':
+ return (*wpat == WLPAREN ? 1 : (*wstring != L'\0'));
+ case L'*':
+ return (1);
+ case L'+':
+ case L'!':
+ case L'@':
+ return (*wpat == WLPAREN ? 1 : (*wstring == wc));
+ case L'[':
+ return (*wstring != L'\0');
+ }
+}
+
+int
+wmatchlen (wpat, wmax)
+ wchar_t *wpat;
+ size_t wmax;
+{
+ wchar_t wc, *wbrack;
+ int matlen, t, in_cclass, in_collsym, in_equiv;
+
+ if (*wpat == 0)
+ return (0);
+
+ matlen = in_cclass = in_collsym = in_equiv = 0;
+ while (wc = *wpat++)
+ {
+ switch (wc)
+ {
+ default:
+ matlen++;
+ break;
+ case L'\\':
+ if (*wpat == 0)
+ return ++matlen;
+ else
+ {
+ matlen++;
+ wpat++;
+ }
+ break;
+ case L'?':
+ if (*wpat == WLPAREN)
+ return (matlen = -1); /* XXX for now */
+ else
+ matlen++;
+ break;
+ case L'*':
+ return (matlen = -1);
+ case L'+':
+ case L'!':
+ case L'@':
+ if (*wpat == WLPAREN)
+ return (matlen = -1); /* XXX for now */
+ else
+ matlen++;
+ break;
+ case L'[':
+ /* scan for ending `]', skipping over embedded [:...:] */
+ wbrack = wpat;
+ wc = *wpat++;
+ do
+ {
+ if (wc == 0)
+ {
+ matlen += wpat - wbrack - 1; /* incremented below */
+ break;
+ }
+ else if (wc == L'\\')
+ {
+ wc = *wpat++;
+ if (*wpat == 0)
+ break;
+ }
+ else if (wc == L'[' && *wpat == L':') /* character class */
+ {
+ wpat++;
+ in_cclass = 1;
+ }
+ else if (in_cclass && wc == L':' && *wpat == L']')
+ {
+ wpat++;
+ in_cclass = 0;
+ }
+ else if (wc == L'[' && *wpat == L'.') /* collating symbol */
+ {
+ wpat++;
+ if (*wpat == L']') /* right bracket can appear as collating symbol */
+ wpat++;
+ in_collsym = 1;
+ }
+ else if (in_collsym && wc == L'.' && *wpat == L']')
+ {
+ wpat++;
+ in_collsym = 0;
+ }
+ else if (wc == L'[' && *wpat == L'=') /* equivalence class */
+ {
+ wpat++;
+ if (*wpat == L']') /* right bracket can appear as equivalence class */
+ wpat++;
+ in_equiv = 1;
+ }
+ else if (in_equiv && wc == L'=' && *wpat == L']')
+ {
+ wpat++;
+ in_equiv = 0;
+ }
+ }
+ while ((wc = *wpat++) != L']');
+ matlen++; /* bracket expression can only match one char */
+ break;
+ }
+ }
+
+ return matlen;
+}
+#endif
+
+/* Return 1 of the first character of STRING could match the first
+ character of pattern PAT. Used to avoid n2 calls to strmatch(). */
+int
+match_pattern_char (pat, string)
+ char *pat, *string;
+{
+ char c;
+
+ if (*string == 0)
+ return (0);
+
+ switch (c = *pat++)
+ {
+ default:
+ return (*string == c);
+ case '\\':
+ return (*string == *pat);
+ case '?':
+ return (*pat == LPAREN ? 1 : (*string != '\0'));
+ case '*':
+ return (1);
+ case '+':
+ case '!':
+ case '@':
+ return (*pat == LPAREN ? 1 : (*string == c));
+ case '[':
+ return (*string != '\0');
+ }
+}
+
+int
+umatchlen (pat, max)
+ char *pat;
+ size_t max;
+{
+ char c, *brack;
+ int matlen, t, in_cclass, in_collsym, in_equiv;
+
+ if (*pat == 0)
+ return (0);
+
+ matlen = in_cclass = in_collsym = in_equiv = 0;
+ while (c = *pat++)
+ {
+ switch (c)
+ {
+ default:
+ matlen++;
+ break;
+ case '\\':
+ if (*pat == 0)
+ return ++matlen;
+ else
+ {
+ matlen++;
+ pat++;
+ }
+ break;
+ case '?':
+ if (*pat == LPAREN)
+ return (matlen = -1); /* XXX for now */
+ else
+ matlen++;
+ break;
+ case '*':
+ return (matlen = -1);
+ case '+':
+ case '!':
+ case '@':
+ if (*pat == LPAREN)
+ return (matlen = -1); /* XXX for now */
+ else
+ matlen++;
+ break;
+ case '[':
+ /* scan for ending `]', skipping over embedded [:...:] */
+ brack = pat;
+ c = *pat++;
+ do
+ {
+ if (c == 0)
+ {
+ matlen += pat - brack - 1; /* incremented below */
+ break;
+ }
+ else if (c == '\\')
+ {
+ c = *pat++;
+ if (*pat == 0)
+ break;
+ }
+ else if (c == '[' && *pat == ':') /* character class */
+ {
+ pat++;
+ in_cclass = 1;
+ }
+ else if (in_cclass && c == ':' && *pat == ']')
+ {
+ pat++;
+ in_cclass = 0;
+ }
+ else if (c == '[' && *pat == '.') /* collating symbol */
+ {
+ pat++;
+ if (*pat == ']') /* right bracket can appear as collating symbol */
+ pat++;
+ in_collsym = 1;
+ }
+ else if (in_collsym && c == '.' && *pat == ']')
+ {
+ pat++;
+ in_collsym = 0;
+ }
+ else if (c == '[' && *pat == '=') /* equivalence class */
+ {
+ pat++;
+ if (*pat == ']') /* right bracket can appear as equivalence class */
+ pat++;
+ in_equiv = 1;
+ }
+ else if (in_equiv && c == '=' && *pat == ']')
+ {
+ pat++;
+ in_equiv = 0;
+ }
+ }
+ while ((c = *pat++) != ']');
+ matlen++; /* bracket expression can only match one char */
+ break;
+ }
+ }
+
+ return matlen;
+}
diff --git a/lib/glob/smatch.c b/lib/glob/smatch.c
index 11d86b0..061142b 100644
--- a/lib/glob/smatch.c
+++ b/lib/glob/smatch.c
@@ -1,7 +1,7 @@
/* strmatch.c -- ksh-like extended pattern matching for the shell and filename
globbing. */
-/* Copyright (C) 1991-2005 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2011 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -241,6 +241,8 @@ is_cclass (c, name)
# define STREQ(s1, s2) ((wcscmp (s1, s2) == 0))
# define STREQN(a, b, n) ((a)[0] == (b)[0] && wcsncmp(a, b, n) == 0)
+extern char *mbsmbchar __P((const char *));
+
static int
rangecmp_wc (c1, c2)
wint_t c1, c2;
@@ -314,7 +316,7 @@ is_wcclass (wc, name)
memset (&state, '\0', sizeof (mbstate_t));
mbs = (char *) malloc (wcslen(name) * MB_CUR_MAX + 1);
- mbslength = wcsrtombs(mbs, (const wchar_t **)&name, (wcslen(name) * MB_CUR_MAX + 1), &state);
+ mbslength = wcsrtombs (mbs, (const wchar_t **)&name, (wcslen(name) * MB_CUR_MAX + 1), &state);
if (mbslength == (size_t)-1 || mbslength == (size_t)-2)
{
@@ -365,6 +367,16 @@ xstrmatch (pattern, string, flags)
int ret;
size_t n;
wchar_t *wpattern, *wstring;
+ size_t plen, slen, mplen, mslen;
+
+#if 0
+ plen = strlen (pattern);
+ mplen = mbstrlen (pattern);
+ if (plen == mplen && strlen (string) == mbstrlen (string))
+#else
+ if (mbsmbchar (string) == 0 && mbsmbchar (pattern) == 0)
+#endif
+ return (internal_strmatch ((unsigned char *)pattern, (unsigned char *)string, flags));
if (MB_CUR_MAX == 1)
return (internal_strmatch ((unsigned char *)pattern, (unsigned char *)string, flags));
diff --git a/lib/glob/xmbsrtowcs.c b/lib/glob/xmbsrtowcs.c
index 23fcd8e..7abf727 100644
--- a/lib/glob/xmbsrtowcs.c
+++ b/lib/glob/xmbsrtowcs.c
@@ -1,6 +1,6 @@
/* xmbsrtowcs.c -- replacement function for mbsrtowcs */
-/* Copyright (C) 2002-2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -18,6 +18,12 @@
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
+/* Ask for GNU extensions to get extern declaration for mbsnrtowcs if
+ available via glibc. */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+
#include <config.h>
#include <bashansi.h>
@@ -32,6 +38,11 @@
#ifndef FREE
# define FREE(x) do { if (x) free (x); } while (0)
#endif
+
+#if ! HAVE_STRCHRNUL
+extern char *strchrnul __P((const char *, int));
+#endif
+
/* On some locales (ex. ja_JP.sjis), mbsrtowc doesn't convert 0x5c to U<0x5c>.
So, this function is made for converting 0x5c to U<0x5c>. */
@@ -120,6 +131,94 @@ xmbsrtowcs (dest, src, len, pstate)
return (wclength);
}
+#if HAVE_MBSNRTOWCS
+/* Convert a multibyte string to a wide character string. Memory for the
+ new wide character string is obtained with malloc.
+
+ Fast multiple-character version of xdupmbstowcs used when the indices are
+ not required and mbsnrtowcs is available. */
+
+static size_t
+xdupmbstowcs2 (destp, src)
+ wchar_t **destp; /* Store the pointer to the wide character string */
+ const char *src; /* Multibyte character string */
+{
+ const char *p; /* Conversion start position of src */
+ wchar_t *wsbuf; /* Buffer for wide characters. */
+ size_t wsbuf_size; /* Size of WSBUF */
+ size_t wcnum; /* Number of wide characters in WSBUF */
+ mbstate_t state; /* Conversion State */
+ size_t wcslength; /* Number of wide characters produced by the conversion. */
+ const char *end_or_backslash;
+ size_t nms; /* Number of multibyte characters to convert at one time. */
+ mbstate_t tmp_state;
+ const char *tmp_p;
+
+ memset (&state, '\0', sizeof(mbstate_t));
+
+ wsbuf_size = 0;
+ wsbuf = NULL;
+
+ p = src;
+ wcnum = 0;
+ do
+ {
+ end_or_backslash = strchrnul(p, '\\');
+ nms = (end_or_backslash - p);
+ if (*end_or_backslash == '\0')
+ nms++;
+
+ /* Compute the number of produced wide-characters. */
+ tmp_p = p;
+ tmp_state = state;
+ wcslength = mbsnrtowcs(NULL, &tmp_p, nms, 0, &tmp_state);
+
+ /* Conversion failed. */
+ if (wcslength == (size_t)-1)
+ {
+ free (wsbuf);
+ *destp = NULL;
+ return (size_t)-1;
+ }
+
+ /* Resize the buffer if it is not large enough. */
+ if (wsbuf_size < wcnum+wcslength+1) /* 1 for the L'\0' or the potential L'\\' */
+ {
+ wchar_t *wstmp;
+
+ wsbuf_size = wcnum+wcslength+1; /* 1 for the L'\0' or the potential L'\\' */
+
+ wstmp = (wchar_t *) realloc (wsbuf, wsbuf_size * sizeof (wchar_t));
+ if (wstmp == NULL)
+ {
+ free (wsbuf);
+ *destp = NULL;
+ return (size_t)-1;
+ }
+ wsbuf = wstmp;
+ }
+
+ /* Perform the conversion. This is assumed to return 'wcslength'.
+ * It may set 'p' to NULL. */
+ mbsnrtowcs(wsbuf+wcnum, &p, nms, wsbuf_size-wcnum, &state);
+
+ wcnum += wcslength;
+
+ if (mbsinit (&state) && (p != NULL) && (*p == '\\'))
+ {
+ wsbuf[wcnum++] = L'\\';
+ p++;
+ }
+ }
+ while (p != NULL);
+
+ *destp = wsbuf;
+
+ /* Return the length of the wide character string, not including `\0'. */
+ return wcnum;
+}
+#endif /* HAVE_MBSNRTOWCS */
+
/* Convert a multibyte string to a wide character string. Memory for the
new wide character string is obtained with malloc.
@@ -155,6 +254,11 @@ xdupmbstowcs (destp, indicesp, src)
return (size_t)-1;
}
+#if HAVE_MBSNRTOWCS
+ if (indicesp == NULL)
+ return (xdupmbstowcs2 (destp, src));
+#endif
+
memset (&state, '\0', sizeof(mbstate_t));
wsbuf_size = WSBUF_INC;
diff --git a/lib/malloc/Makefile.in b/lib/malloc/Makefile.in
index e40f00a..abe0eca 100644
--- a/lib/malloc/Makefile.in
+++ b/lib/malloc/Makefile.in
@@ -112,6 +112,7 @@ alloca.o: $(BUILD_DIR)/config.h
malloc.o: $(BUILD_DIR)/config.h $(topdir)/bashtypes.h getpagesize.h
xmalloc.o: $(BUILD_DIR)/config.h $(BASHINCDIR)/ansi_stdlib.h
trace.o: ${BUILD_DIR}/config.h
+stats.o: ${BUILD_DIR}/config.h
table.o: ${BUILD_DIR}/config.h
watch.o: ${BUILD_DIR}/config.h
diff --git a/lib/readline/Makefile.in b/lib/readline/Makefile.in
index 2204628..4387a54 100644
--- a/lib/readline/Makefile.in
+++ b/lib/readline/Makefile.in
@@ -83,7 +83,7 @@ CSOURCES = $(srcdir)/readline.c $(srcdir)/funmap.c $(srcdir)/keymaps.c \
$(srcdir)/histfile.c $(srcdir)/nls.c $(srcdir)/search.c \
$(srcdir)/shell.c $(srcdir)/tilde.c $(srcdir)/savestring.c \
$(srcdir)/text.c $(srcdir)/misc.c $(srcdir)/compat.c \
- $(srcdir)/mbutil.c
+ $(srcdir)/mbutil.c $(srcdir)/xfree.c
# The header files for this library.
HSOURCES = readline.h rldefs.h chardefs.h keymaps.h history.h histlib.h \
@@ -97,7 +97,7 @@ TILDEOBJ = tilde.o
OBJECTS = readline.o vi_mode.o funmap.o keymaps.o parens.o search.o \
rltty.o complete.o bind.o isearch.o display.o signals.o \
util.o kill.o undo.o macro.o input.o callback.o terminal.o \
- text.o nls.o misc.o $(HISTOBJ) $(TILDEOBJ) xmalloc.o compat.o
+ text.o nls.o misc.o $(HISTOBJ) $(TILDEOBJ) xmalloc.o xfree.o compat.o
# The texinfo files which document this library.
DOCSOURCE = doc/rlman.texinfo doc/rltech.texinfo doc/rluser.texinfo
@@ -123,9 +123,9 @@ libreadline.a: $(OBJECTS)
$(AR) $(ARFLAGS) $@ $(OBJECTS)
-test -n "$(RANLIB)" && $(RANLIB) $@
-libhistory.a: $(HISTOBJ) xmalloc.o
+libhistory.a: $(HISTOBJ) xmalloc.o xfree.o
$(RM) $@
- $(AR) $(ARFLAGS) $@ $(HISTOBJ) xmalloc.o
+ $(AR) $(ARFLAGS) $@ $(HISTOBJ) xmalloc.o xfree.o
-test -n "$(RANLIB)" && $(RANLIB) $@
documentation: force
@@ -262,6 +262,7 @@ vi_mode.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
vi_mode.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
vi_mode.o: history.h ansi_stdlib.h rlstdc.h
xmalloc.o: ${BUILD_DIR}/config.h ansi_stdlib.h
+xfree.o: ${BUILD_DIR}/config.h ansi_stdlib.h
bind.o: rlshell.h
histfile.o: rlshell.h
@@ -317,6 +318,7 @@ tilde.o: xmalloc.h
undo.o: xmalloc.h
util.o: xmalloc.h
vi_mode.o: xmalloc.h
+xfree.o: xmalloc.h
xmalloc.o: xmalloc.h
complete.o: rlmbutil.h
@@ -359,6 +361,7 @@ tilde.o: tilde.c
undo.o: undo.c
util.o: util.c
vi_mode.o: vi_mode.c
+xfree.o: xfree.c
xmalloc.o: xmalloc.c
histexpand.o: histexpand.c
diff --git a/lib/readline/bind.c b/lib/readline/bind.c
index fc8c2a2..59e7964 100644
--- a/lib/readline/bind.c
+++ b/lib/readline/bind.c
@@ -1,6 +1,6 @@
/* bind.c -- key binding and startup file support for the readline library. */
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2010 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.
@@ -1424,6 +1424,7 @@ static const struct {
{ "blink-matching-paren", &rl_blink_matching_paren, V_SPECIAL },
{ "byte-oriented", &rl_byte_oriented, 0 },
{ "completion-ignore-case", &_rl_completion_case_fold, 0 },
+ { "completion-map-case", &_rl_completion_case_map, 0 },
{ "convert-meta", &_rl_convert_meta_chars_to_ascii, 0 },
{ "disable-completion", &rl_inhibit_completion, 0 },
{ "echo-control-characters", &_rl_echo_control_chars, 0 },
@@ -1437,6 +1438,7 @@ static const struct {
{ "mark-modified-lines", &_rl_mark_modified_lines, 0 },
{ "mark-symlinked-directories", &_rl_complete_mark_symlink_dirs, 0 },
{ "match-hidden-files", &_rl_match_hidden_files, 0 },
+ { "menu-complete-display-prefix", &_rl_menu_complete_prefix_first, 0 },
{ "meta-flag", &_rl_meta_flag, 0 },
{ "output-meta", &_rl_output_meta_chars, 0 },
{ "page-completions", &_rl_page_completions, 0 },
@@ -1449,7 +1451,7 @@ static const struct {
#if defined (VISIBLE_STATS)
{ "visible-stats", &rl_visible_stats, 0 },
#endif /* VISIBLE_STATS */
- { (char *)NULL, (int *)NULL }
+ { (char *)NULL, (int *)NULL, 0 }
};
static int
@@ -1504,6 +1506,7 @@ static int sv_bell_style PARAMS((const char *));
static int sv_combegin PARAMS((const char *));
static int sv_dispprefix PARAMS((const char *));
static int sv_compquery PARAMS((const char *));
+static int sv_compwidth PARAMS((const char *));
static int sv_editmode PARAMS((const char *));
static int sv_histsize PARAMS((const char *));
static int sv_isrchterm PARAMS((const char *));
@@ -1516,13 +1519,14 @@ static const struct {
} string_varlist[] = {
{ "bell-style", V_STRING, sv_bell_style },
{ "comment-begin", V_STRING, sv_combegin },
+ { "completion-display-width", V_INT, sv_compwidth },
{ "completion-prefix-display-length", V_INT, sv_dispprefix },
{ "completion-query-items", V_INT, sv_compquery },
{ "editing-mode", V_STRING, sv_editmode },
{ "history-size", V_INT, sv_histsize },
{ "isearch-terminators", V_STRING, sv_isrchterm },
{ "keymap", V_STRING, sv_keymap },
- { (char *)NULL, 0 }
+ { (char *)NULL, 0, (_rl_sv_func_t *)0 }
};
static int
@@ -1663,6 +1667,19 @@ sv_compquery (value)
}
static int
+sv_compwidth (value)
+ const char *value;
+{
+ int nval = -1;
+
+ if (value && *value)
+ nval = atoi (value);
+
+ _rl_completion_columns = nval;
+ return 0;
+}
+
+static int
sv_histsize (value)
const char *value;
{
@@ -2268,6 +2285,11 @@ _rl_get_string_variable_value (name)
}
else if (_rl_stricmp (name, "comment-begin") == 0)
return (_rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT);
+ else if (_rl_stricmp (name, "completion-display-width") == 0)
+ {
+ sprintf (numbuf, "%d", _rl_completion_columns);
+ return (numbuf);
+ }
else if (_rl_stricmp (name, "completion-prefix-display-length") == 0)
{
sprintf (numbuf, "%d", _rl_completion_prefix_display_length);
diff --git a/lib/readline/callback.c b/lib/readline/callback.c
index 6c52ac0..4ee6361 100644
--- a/lib/readline/callback.c
+++ b/lib/readline/callback.c
@@ -142,6 +142,15 @@ rl_callback_read_char ()
eof = _rl_nsearch_callback (_rl_nscxt);
return;
}
+#if defined (VI_MODE)
+ else if (RL_ISSTATE (RL_STATE_VIMOTION))
+ {
+ eof = _rl_vi_domove_callback (_rl_vimvcxt);
+ /* Should handle everything, including cleanup, numeric arguments,
+ and turning off RL_STATE_VIMOTION */
+ return;
+ }
+#endif
else if (RL_ISSTATE (RL_STATE_NUMERICARG))
{
eof = _rl_arg_callback (_rl_argcxt);
diff --git a/lib/readline/complete.c b/lib/readline/complete.c
index 2c7e696..6e5b4f8 100644
--- a/lib/readline/complete.c
+++ b/lib/readline/complete.c
@@ -1,6 +1,6 @@
/* complete.c -- filename completion for readline. */
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2011 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.
@@ -119,9 +119,11 @@ static char **remove_duplicate_matches PARAMS((char **));
static void insert_match PARAMS((char *, int, int, char *));
static int append_to_match PARAMS((char *, int, int, int));
static void insert_all_matches PARAMS((char **, int, char *));
+static int complete_fncmp PARAMS((const char *, int, const char *, int));
static void display_matches PARAMS((char **));
static int compute_lcd_of_matches PARAMS((char **, int, const char *));
static int postprocess_matches PARAMS((char ***, int));
+static int complete_get_screenwidth PARAMS((void));
static char *make_quoted_replacement PARAMS((char *, int, char *));
@@ -157,10 +159,14 @@ int _rl_print_completions_horizontally;
#if defined (__MSDOS__) && !defined (__DJGPP__)
int _rl_completion_case_fold = 1;
#else
-int _rl_completion_case_fold;
+int _rl_completion_case_fold = 0;
#endif
-/* If non-zero, don't match hidden files (filenames beginning with a `.' on
+/* Non-zero means that `-' and `_' are equivalent when comparing filenames
+ for completion. */
+int _rl_completion_case_map = 0;
+
+/* If zero, don't match hidden files (filenames beginning with a `.' on
Unix) when doing filename completion. */
int _rl_match_hidden_files = 1;
@@ -170,6 +176,10 @@ int _rl_match_hidden_files = 1;
display prefix replaced with an ellipsis. */
int _rl_completion_prefix_display_length = 0;
+/* The readline-private number of screen columns to use when displaying
+ matches. If < 0 or > _rl_screenwidth, it is ignored. */
+int _rl_completion_columns = -1;
+
/* Global variables available to applications using readline. */
#if defined (VISIBLE_STATS)
@@ -185,6 +195,10 @@ int rl_visible_stats = 0;
after the `e' in `Makefile' won't result in `Makefilefile'. */
int _rl_skip_completed_text = 0;
+/* If non-zero, menu completion displays the common prefix first in the
+ cycle of possible completions instead of the last. */
+int _rl_menu_complete_prefix_first = 0;
+
/* If non-zero, then this is the address of a function to call when
completing on a directory name. The function is called with
the address of a string (the current directory name) as an arg. */
@@ -467,6 +481,14 @@ get_y_or_n (for_pager)
{
int c;
+ /* For now, disable pager in callback mode, until we later convert to state
+ driven functions. Have to wait until next major version to add new
+ state definition, since it will change value of RL_STATE_DONE. */
+#if defined (READLINE_CALLBACKS)
+ if (RL_ISSTATE (RL_STATE_CALLBACK))
+ return 1;
+#endif
+
for (;;)
{
RL_SETSTATE(RL_STATE_MOREINPUT);
@@ -829,7 +851,7 @@ print_filename (to_print, full_pathname, prefix_bytes)
if (path_isdir (new_full_pathname))
extension_char = '/';
- free (new_full_pathname);
+ xfree (new_full_pathname);
to_print[-1] = c;
}
else
@@ -844,7 +866,7 @@ print_filename (to_print, full_pathname, prefix_bytes)
extension_char = '/';
}
- free (s);
+ xfree (s);
if (extension_char)
{
putc (extension_char, rl_outstream);
@@ -1081,7 +1103,7 @@ remove_duplicate_matches (matches)
{
if (strcmp (matches[i], matches[i + 1]) == 0)
{
- free (matches[i]);
+ xfree (matches[i]);
matches[i] = (char *)&dead_slot;
}
else
@@ -1099,7 +1121,7 @@ remove_duplicate_matches (matches)
temp_array[j] = (char *)NULL;
if (matches[0] != (char *)&dead_slot)
- free (matches[0]);
+ xfree (matches[0]);
/* Place the lowest common denominator back in [0]. */
temp_array[0] = lowest_common;
@@ -1109,7 +1131,7 @@ remove_duplicate_matches (matches)
insert. */
if (j == 2 && strcmp (temp_array[0], temp_array[1]) == 0)
{
- free (temp_array[1]);
+ xfree (temp_array[1]);
temp_array[1] = (char *)NULL;
}
return (temp_array);
@@ -1288,7 +1310,7 @@ postprocess_matches (matchesp, matching_filenames)
if (rl_ignore_completion_duplicates)
{
temp_matches = remove_duplicate_matches (matches);
- free (matches);
+ xfree (matches);
matches = temp_matches;
}
@@ -1325,6 +1347,23 @@ postprocess_matches (matchesp, matching_filenames)
return (1);
}
+static int
+complete_get_screenwidth ()
+{
+ int cols;
+ char *envcols;
+
+ cols = _rl_completion_columns;
+ if (cols >= 0 && cols <= _rl_screenwidth)
+ return cols;
+ envcols = getenv ("COLUMNS");
+ if (envcols && *envcols)
+ cols = atoi (envcols);
+ if (cols >= 0 && cols <= _rl_screenwidth)
+ return cols;
+ return _rl_screenwidth;
+}
+
/* A convenience function for displaying a list of strings in
columnar format on readline's output stream. MATCHES is the list
of strings, in argv format, LEN is the number of strings in MATCHES,
@@ -1334,7 +1373,7 @@ rl_display_match_list (matches, len, max)
char **matches;
int len, max;
{
- int count, limit, printed_len, lines;
+ int count, limit, printed_len, lines, cols;
int i, j, k, l, common_length, sind;
char *temp, *t;
@@ -1355,12 +1394,17 @@ rl_display_match_list (matches, len, max)
}
/* How many items of MAX length can we fit in the screen window? */
+ cols = complete_get_screenwidth ();
max += 2;
- limit = _rl_screenwidth / max;
- if (limit != 1 && (limit * max == _rl_screenwidth))
+ limit = cols / max;
+ if (limit != 1 && (limit * max == cols))
limit--;
- /* Avoid a possible floating exception. If max > _rl_screenwidth,
+ /* If cols == 0, limit will end up -1 */
+ if (cols < _rl_screenwidth && limit < 0)
+ limit = 1;
+
+ /* Avoid a possible floating exception. If max > cols,
limit will be 0 and a divide-by-zero fault will result. */
if (limit == 0)
limit = 1;
@@ -1608,7 +1652,7 @@ insert_match (match, start, mtype, qc)
else
_rl_replace_text (replacement, start, end);
if (replacement != match)
- free (replacement);
+ xfree (replacement);
}
}
@@ -1675,7 +1719,7 @@ append_to_match (text, delimiter, quote_char, nontrivial_match)
if (rl_point == rl_end && temp_string_index)
rl_insert_text (temp_string);
}
- free (filename);
+ xfree (filename);
}
else
{
@@ -1711,7 +1755,7 @@ insert_all_matches (matches, point, qc)
rl_insert_text (rp);
rl_insert_text (" ");
if (rp != matches[i])
- free (rp);
+ xfree (rp);
}
}
else
@@ -1720,7 +1764,7 @@ insert_all_matches (matches, point, qc)
rl_insert_text (rp);
rl_insert_text (" ");
if (rp != matches[0])
- free (rp);
+ xfree (rp);
}
rl_end_undo_group ();
}
@@ -1735,8 +1779,8 @@ _rl_free_match_list (matches)
return;
for (i = 0; matches[i]; i++)
- free (matches[i]);
- free (matches);
+ xfree (matches[i]);
+ xfree (matches);
}
/* Complete the word at or before point.
@@ -1757,6 +1801,9 @@ rl_complete_internal (what_to_do)
int start, end, delimiter, found_quote, i, nontrivial_lcd;
char *text, *saved_line_buffer;
char quote_char;
+#if 1
+ int tlen, mlen;
+#endif
RL_SETSTATE(RL_STATE_COMPLETING);
@@ -1784,7 +1831,11 @@ rl_complete_internal (what_to_do)
/* nontrivial_lcd is set if the common prefix adds something to the word
being completed. */
nontrivial_lcd = matches && strcmp (text, matches[0]) != 0;
- free (text);
+#if 1
+ if (what_to_do == '!' || what_to_do == '@')
+ tlen = strlen (text);
+#endif
+ xfree (text);
if (matches == 0)
{
@@ -1817,8 +1868,25 @@ rl_complete_internal (what_to_do)
case '!':
case '@':
/* Insert the first match with proper quoting. */
+#if 0
if (*matches[0])
insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
+#else
+ if (what_to_do == TAB)
+ {
+ if (*matches[0])
+ insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
+ }
+ else if (*matches[0] && matches[1] == 0)
+ /* should we perform the check only if there are multiple matches? */
+ insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
+ else if (*matches[0]) /* what_to_do != TAB && multiple matches */
+ {
+ mlen = *matches[0] ? strlen (matches[0]) : 0;
+ if (mlen >= tlen)
+ insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
+ }
+#endif
/* If there are more matches, ring the bell to indicate.
If we are in vi mode, Posix.2 says to not ring the bell.
@@ -1872,7 +1940,7 @@ rl_complete_internal (what_to_do)
if (saved_line_buffer)
{
completion_changed_buffer = strcmp (rl_line_buffer, saved_line_buffer) != 0;
- free (saved_line_buffer);
+ xfree (saved_line_buffer);
}
RL_UNSETSTATE(RL_STATE_COMPLETING);
@@ -1939,7 +2007,7 @@ rl_completion_matches (text, entry_function)
compute_lcd_of_matches (match_list, matches, text);
else /* There were no matches. */
{
- free (match_list);
+ xfree (match_list);
match_list = (char **)NULL;
}
return (match_list);
@@ -2005,6 +2073,62 @@ rl_username_completion_function (text, state)
#endif /* !__WIN32__ && !__OPENNT */
}
+/* Return non-zero if CONVFN matches FILENAME up to the length of FILENAME
+ (FILENAME_LEN). If _rl_completion_case_fold is set, compare without
+ regard to the alphabetic case of characters. CONVFN is the possibly-
+ converted directory entry; FILENAME is what the user typed. */
+static int
+complete_fncmp (convfn, convlen, filename, filename_len)
+ const char *convfn;
+ int convlen;
+ const char *filename;
+ int filename_len;
+{
+ register char *s1, *s2;
+ int d, len;
+
+ /* Otherwise, if these match up to the length of filename, then
+ it is a match. */
+ if (_rl_completion_case_fold && _rl_completion_case_map)
+ {
+ /* Case-insensitive comparison treating _ and - as equivalent */
+ if (filename_len == 0)
+ return 1;
+ if (convlen < filename_len)
+ return 0;
+ s1 = (char *)convfn;
+ s2 = (char *)filename;
+ len = filename_len;
+ do
+ {
+ d = _rl_to_lower (*s1) - _rl_to_lower (*s2);
+ /* *s1 == [-_] && *s2 == [-_] */
+ if ((*s1 == '-' || *s1 == '_') && (*s2 == '-' || *s2 == '_'))
+ d = 0;
+ if (d != 0)
+ return 0;
+ s1++; s2++; /* already checked convlen >= filename_len */
+ }
+ while (--len != 0);
+ return 1;
+ }
+ else if (_rl_completion_case_fold)
+ {
+ if ((_rl_to_lower (convfn[0]) == _rl_to_lower (filename[0])) &&
+ (convlen >= filename_len) &&
+ (_rl_strnicmp (filename, convfn, filename_len) == 0))
+ return 1;
+ }
+ else
+ {
+ if ((convfn[0] == filename[0]) &&
+ (convlen >= filename_len) &&
+ (strncmp (filename, convfn, filename_len) == 0))
+ return 1;
+ }
+ return 0;
+}
+
/* Okay, now we write the entry_function for filename completion. In the
general case. Note that completion in the shell is a little different
because of all the pathnames that must be followed when looking up the
@@ -2071,32 +2195,41 @@ rl_filename_completion_function (text, state)
/* We aren't done yet. We also support the "~user" syntax. */
- /* Save the version of the directory that the user typed. */
- users_dirname = savestring (dirname);
+ /* Save the version of the directory that the user typed, dequoting
+ it if necessary. */
+ if (rl_completion_found_quote && rl_filename_dequoting_function)
+ users_dirname = (*rl_filename_dequoting_function) (dirname, rl_completion_quote_character);
+ else
+ users_dirname = savestring (dirname);
if (*dirname == '~')
{
temp = tilde_expand (dirname);
- free (dirname);
+ xfree (dirname);
dirname = temp;
}
+ /* We have saved the possibly-dequoted version of the directory name
+ the user typed. Now transform the directory name we're going to
+ pass to opendir(2). The directory rewrite hook modifies only the
+ directory name; the directory completion hook modifies both the
+ directory name passed to opendir(2) and the version the user
+ typed. Both the directory completion and rewrite hooks should perform
+ any necessary dequoting. The hook functions return 1 if they modify
+ the directory name argument. If either hook returns 0, it should
+ not modify the directory name pointer passed as an argument. */
if (rl_directory_rewrite_hook)
(*rl_directory_rewrite_hook) (&dirname);
-
- /* The directory completion hook should perform any necessary
- dequoting. */
- if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&dirname))
+ else if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&dirname))
{
- free (users_dirname);
+ xfree (users_dirname);
users_dirname = savestring (dirname);
}
else if (rl_completion_found_quote && rl_filename_dequoting_function)
{
/* delete single and double quotes */
- temp = (*rl_filename_dequoting_function) (users_dirname, rl_completion_quote_character);
- free (users_dirname);
- users_dirname = temp;
+ xfree (dirname);
+ dirname = savestring (users_dirname);
}
directory = opendir (dirname);
@@ -2105,7 +2238,7 @@ rl_filename_completion_function (text, state)
{
/* delete single and double quotes */
temp = (*rl_filename_dequoting_function) (filename, rl_completion_quote_character);
- free (filename);
+ xfree (filename);
filename = temp;
}
filename_len = strlen (filename);
@@ -2147,22 +2280,8 @@ rl_filename_completion_function (text, state)
}
else
{
- /* Otherwise, if these match up to the length of filename, then
- it is a match. */
- if (_rl_completion_case_fold)
- {
- if ((_rl_to_lower (convfn[0]) == _rl_to_lower (filename[0])) &&
- (convlen >= filename_len) &&
- (_rl_strnicmp (filename, convfn, filename_len) == 0))
- break;
- }
- else
- {
- if ((convfn[0] == filename[0]) &&
- (convlen >= filename_len) &&
- (strncmp (filename, convfn, filename_len) == 0))
- break;
- }
+ if (complete_fncmp (convfn, convlen, filename, filename_len))
+ break;
}
}
@@ -2175,17 +2294,17 @@ rl_filename_completion_function (text, state)
}
if (dirname)
{
- free (dirname);
+ xfree (dirname);
dirname = (char *)NULL;
}
if (filename)
{
- free (filename);
+ xfree (filename);
filename = (char *)NULL;
}
if (users_dirname)
{
- free (users_dirname);
+ xfree (users_dirname);
users_dirname = (char *)NULL;
}
@@ -2225,7 +2344,7 @@ rl_filename_completion_function (text, state)
temp = savestring (convfn);
if (convfn != dentry)
- free (convfn);
+ xfree (convfn);
return (temp);
}
@@ -2304,14 +2423,14 @@ rl_old_menu_complete (count, invoking_key)
if (matches == 0 || postprocess_matches (&matches, matching_filenames) == 0)
{
- rl_ding ();
+ rl_ding ();
FREE (matches);
matches = (char **)0;
FREE (orig_text);
orig_text = (char *)0;
- completion_changed_buffer = 0;
- RL_UNSETSTATE(RL_STATE_COMPLETING);
- return (0);
+ completion_changed_buffer = 0;
+ RL_UNSETSTATE(RL_STATE_COMPLETING);
+ return (0);
}
RL_UNSETSTATE(RL_STATE_COMPLETING);
@@ -2340,7 +2459,10 @@ rl_old_menu_complete (count, invoking_key)
match_list_index += count;
if (match_list_index < 0)
- match_list_index += match_list_size;
+ {
+ while (match_list_index < 0)
+ match_list_index += match_list_size;
+ }
else
match_list_index %= match_list_size;
@@ -2375,7 +2497,7 @@ rl_menu_complete (count, ignore)
static int full_completion = 0; /* set to 1 if menu completion should reinitialize on next call */
static int orig_start, orig_end;
static char quote_char;
- static int delimiter;
+ static int delimiter, cstate;
/* The first time through, we generate the list of matches and set things
up to insert them. */
@@ -2428,14 +2550,14 @@ rl_menu_complete (count, ignore)
if (matches == 0 || postprocess_matches (&matches, matching_filenames) == 0)
{
- rl_ding ();
+ rl_ding ();
FREE (matches);
matches = (char **)0;
FREE (orig_text);
orig_text = (char *)0;
- completion_changed_buffer = 0;
- RL_UNSETSTATE(RL_STATE_COMPLETING);
- return (0);
+ completion_changed_buffer = 0;
+ RL_UNSETSTATE(RL_STATE_COMPLETING);
+ return (0);
}
RL_UNSETSTATE(RL_STATE_COMPLETING);
@@ -2483,6 +2605,11 @@ rl_menu_complete (count, ignore)
full_completion = 1;
return (0);
}
+ else if (_rl_menu_complete_prefix_first && match_list_size > 1)
+ {
+ rl_ding ();
+ return (0);
+ }
}
/* Now we have the list of matches. Replace the text between
@@ -2500,7 +2627,10 @@ rl_menu_complete (count, ignore)
match_list_index += count;
if (match_list_index < 0)
- match_list_index += match_list_size;
+ {
+ while (match_list_index < 0)
+ match_list_index += match_list_size;
+ }
else
match_list_index %= match_list_size;
diff --git a/lib/readline/doc/history.texi b/lib/readline/doc/history.texi
index afdb901..64945d8 100644
--- a/lib/readline/doc/history.texi
+++ b/lib/readline/doc/history.texi
@@ -12,7 +12,7 @@ This document describes the GNU History library
a programming tool that provides a consistent user interface for
recalling lines of previously typed input.
-Copyright @copyright{} 1988--2009 Free Software Foundation, Inc.
+Copyright @copyright{} 1988--2011 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
diff --git a/lib/readline/doc/hstech.texi b/lib/readline/doc/hstech.texi
index c4e5a75..4fc9e8e 100644
--- a/lib/readline/doc/hstech.texi
+++ b/lib/readline/doc/hstech.texi
@@ -1,7 +1,7 @@
@ignore
This file documents the user interface to the GNU History library.
-Copyright (C) 1988-2007 Free Software Foundation, Inc.
+Copyright (C) 1988-2011 Free Software Foundation, Inc.
Authored by Brian Fox and Chet Ramey.
Permission is granted to make and distribute verbatim copies of this manual
@@ -426,6 +426,10 @@ The maximum number of history entries. This must be changed using
If non-zero, timestamps are written to the history file, so they can be
preserved between sessions. The default value is 0, meaning that
timestamps are not saved.
+
+The current timestamp format uses the value of @var{history_comment_char}
+to delimit timestamp entries in the history file. If that variable does
+not have a value (the default), timestamps will not be written.
@end deftypevar
@deftypevar char history_expansion_char
diff --git a/lib/readline/doc/hsuser.texi b/lib/readline/doc/hsuser.texi
index 87b3541..75df3ee 100644
--- a/lib/readline/doc/hsuser.texi
+++ b/lib/readline/doc/hsuser.texi
@@ -1,7 +1,7 @@
@ignore
This file documents the user interface to the GNU History library.
-Copyright (C) 1988-2007 Free Software Foundation, Inc.
+Copyright (C) 1988--2011 Free Software Foundation, Inc.
Authored by Brian Fox and Chet Ramey.
Permission is granted to make and distribute verbatim copies of this manual
@@ -299,6 +299,8 @@ writing the history file.
An event designator is a reference to a command line entry in the
history list.
+Unless the reference is absolute, events are relative to the current
+position in the history list.
@cindex history events
@table @asis
@@ -324,10 +326,15 @@ Refer to the command @var{n} lines back.
Refer to the previous command. This is a synonym for @samp{!-1}.
@item @code{!@var{string}}
-Refer to the most recent command starting with @var{string}.
+Refer to the most recent command
+preceding the current position in the history list
+starting with @var{string}.
@item @code{!?@var{string}[?]}
-Refer to the most recent command containing @var{string}. The trailing
+Refer to the most recent command
+preceding the current position in the history list
+containing @var{string}.
+The trailing
@samp{?} may be omitted if the @var{string} is followed immediately by
a newline.
diff --git a/lib/readline/doc/rlman.texi b/lib/readline/doc/rlman.texi
index be24709..1c9ac13 100644
--- a/lib/readline/doc/rlman.texi
+++ b/lib/readline/doc/rlman.texi
@@ -13,7 +13,7 @@ This manual describes the GNU Readline Library
consistency of user interface across discrete programs which provide
a command line interface.
-Copyright @copyright{} 1988--2009 Free Software Foundation, Inc.
+Copyright @copyright{} 1988--2011 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
diff --git a/lib/readline/doc/rltech.texi b/lib/readline/doc/rltech.texi
index 04c8489..dc272a2 100644
--- a/lib/readline/doc/rltech.texi
+++ b/lib/readline/doc/rltech.texi
@@ -7,7 +7,7 @@ This document describes the GNU Readline Library, a utility for aiding
in the consistency of user interface across discrete programs that need
to provide a command line interface.
-Copyright (C) 1988-2007 Free Software Foundation, Inc.
+Copyright (C) 1988--2011 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
@@ -1157,6 +1157,9 @@ of strings, in argv format, such as a list of completion matches.
is the length of the longest string in @code{matches}. This function uses
the setting of @code{print-completions-horizontally} to select how the
matches are displayed (@pxref{Readline Init File Syntax}).
+When displaying completions, this function sets the number of columns used
+for display to the value of @code{completion-display-width}, the value of
+the environment variable @env{COLUMNS}, or the screen width, in that order.
@end deftypefun
The following are implemented as macros, defined in @code{chardefs.h}.
@@ -1714,18 +1717,20 @@ from the array must be freed.
@deftypevar {rl_icppfunc_t *} rl_directory_completion_hook
This function, if defined, is allowed to modify the directory portion
-of filenames Readline completes. It is called with the address of a
-string (the current directory name) as an argument, and may modify that string.
+of filenames Readline completes.
+It could be used to expand symbolic links or shell variables in pathnames.
+It is called with the address of a string (the current directory name) as an
+argument, and may modify that string.
If the string is replaced with a new string, the old value should be freed.
Any modified directory name should have a trailing slash.
-The modified value will be displayed as part of the completion, replacing
+The modified value will be used as part of the completion, replacing
the directory portion of the pathname the user typed.
-It returns an integer that should be non-zero if the function modifies
-its directory argument.
-It could be used to expand symbolic links or shell variables in pathnames.
At the least, even if no other expansion is performed, this function should
remove any quote characters from the directory name, because its result will
be passed directly to @code{opendir()}.
+The directory completion hook returns an integer that should be non-zero if
+the function modifies its directory argument.
+The function should not modify the directory argument if it returns 0.
@end deftypevar
@ignore
@@ -1737,7 +1742,7 @@ it only modifies the directory name used in @code{opendir}, not what is
displayed when the possible completions are printed or inserted. It is
called before rl_directory_completion_hook.
-I'm not happy with how this worksyet, so it's undocumented.
+I'm not happy with how this works yet, so it's undocumented.
@end deftypevar
@end ignore
diff --git a/lib/readline/doc/rluser.texi b/lib/readline/doc/rluser.texi
index 519c0de..8a69c99 100644
--- a/lib/readline/doc/rluser.texi
+++ b/lib/readline/doc/rluser.texi
@@ -9,7 +9,7 @@ use these features. There is a document entitled "readline.texinfo"
which contains both end-user and programmer documentation for the
GNU Readline Library.
-Copyright (C) 1988--2009 Free Software Foundation, Inc.
+Copyright (C) 1988--2011 Free Software Foundation, Inc.
Authored by Brian Fox and Chet Ramey.
@@ -51,7 +51,7 @@ Command line editing is enabled by default when using an interactive shell,
unless the @option{--noediting} option is supplied at shell invocation.
Line editing is also used when using the @option{-e} option to the
@code{read} builtin command (@pxref{Bash Builtins}).
-By default, the line editing commands are similar to those of emacs.
+By default, the line editing commands are similar to those of Emacs.
A vi-style line editing interface is also available.
Line editing can be enabled at any time using the @option{-o emacs} or
@option{-o vi} options to the @code{set} builtin command
@@ -431,11 +431,27 @@ The string to insert at the beginning of the line when the
@code{insert-comment} command is executed. The default value
is @code{"#"}.
+@item completion-display-width
+@vindex completion-display-width
+The number of screen columns used to display possible matches
+when performing completion.
+The value is ignored if it is less than 0 or greater than the terminal
+screen width.
+A value of 0 will cause matches to be displayed one per line.
+The default value is -1.
+
@item completion-ignore-case
+@vindex completion-ignore-case
If set to @samp{on}, Readline performs filename matching and completion
in a case-insensitive fashion.
The default value is @samp{off}.
+@item completion-map-case
+@vindex completion-map-case
+If set to @samp{on}, and @var{completion-ignore-case} is enabled, Readline
+treats hyphens (@samp{-}) and underscores (@samp{_}) as equivalent when
+performing case-insensitive filename matching and completion.
+
@item completion-prefix-display-length
@vindex completion-prefix-display-length
The length in characters of the common prefix of a list of possible
@@ -570,10 +586,17 @@ The default is @samp{off}.
@vindex match-hidden-files
This variable, when set to @samp{on}, causes Readline to match files whose
names begin with a @samp{.} (hidden files) when performing filename
-completion, unless the leading @samp{.} is
+completion.
+If set to @samp{off}, the leading @samp{.} must be
supplied by the user in the filename to be completed.
This variable is @samp{on} by default.
+@item menu-complete-display-prefix
+@vindex menu-complete-display-prefix
+If set to @samp{on}, menu completion displays the common prefix of the
+list of possible completions (which may be empty) before cycling through
+the list. The default is @samp{off}.
+
@item output-meta
@vindex output-meta
If set to @samp{on}, Readline will display characters with the
@@ -1097,10 +1120,14 @@ as if the @samp{!@var{n}} history expansion had been specified.
@item yank-last-arg (M-. or M-_)
Insert last argument to the previous command (the last word of the
-previous history entry). With an
-argument, behave exactly like @code{yank-nth-arg}.
+previous history entry).
+With a numeric argument, behave exactly like @code{yank-nth-arg}.
Successive calls to @code{yank-last-arg} move back through the history
-list, inserting the last argument of each line in turn.
+list, inserting the last word (or the word specified by the argument to
+the first call) of each line in turn.
+Any numeric argument supplied to these successive calls determines
+the direction to move through the history. A negative argument switches
+the direction through the history (back or forward).
The history expansion facilities are used to extract the last argument,
as if the @samp{!$} history expansion had been specified.
@@ -1212,7 +1239,7 @@ Kill from point to the end of the current word, or if between
words, to the end of the next word.
Word boundaries are the same as @code{shell-forward-word}.
-@item backward-kill-word ()
+@item shell-backward-kill-word ()
Kill the word behind point.
Word boundaries are the same as @code{shell-backward-word}.
@end ifset
@@ -1298,6 +1325,9 @@ The default is filename completion.
@item possible-completions (M-?)
List the possible completions of the text before point.
+When displaying completions, Readline sets the number of columns used
+for display to the value of @code{completion-display-width}, the value of
+the environment variable @env{COLUMNS}, or the screen width, in that order.
@item insert-completions (M-*)
Insert all completions of the text before point that would have
@@ -1579,7 +1609,7 @@ editing mode.
While the Readline library does not have a full set of @code{vi}
editing functions, it does contain enough to allow simple editing
of the line. The Readline @code{vi} mode behaves as specified in
-the @sc{posix} 1003.2 standard.
+the @sc{posix} standard.
@ifset BashFeatures
In order to switch interactively between @code{emacs} and @code{vi}
@@ -1733,7 +1763,7 @@ exit status of 124. If a shell function returns 124, and changes
the compspec associated with the command on which completion is being
attempted (supplied as the first argument when the function is executed),
programmable completion restarts from the beginning, with an
-attempt to find a compspec for that command. This allows a set of
+attempt to find a new compspec for that command. This allows a set of
completions to be built dynamically as completion is attempted, rather than
being loaded all at once.
@@ -1933,17 +1963,6 @@ User names. May also be specified as @option{-u}.
Names of all shell variables. May also be specified as @option{-v}.
@end table
-@item -G @var{globpat}
-The filename expansion pattern @var{globpat} is expanded to generate
-the possible completions.
-
-@item -W @var{wordlist}
-The @var{wordlist} is split using the characters in the
-@env{IFS} special variable as delimiters, and each resultant word
-is expanded.
-The possible completions are the members of the resultant list which
-match the word being completed.
-
@item -C @var{command}
@var{command} is executed in a subshell environment, and its output is
used as the possible completions.
@@ -1954,13 +1973,9 @@ environment.
When it finishes, the possible completions are retrieved from the value
of the @env{COMPREPLY} array variable.
-@item -X @var{filterpat}
-@var{filterpat} is a pattern as used for filename expansion.
-It is applied to the list of possible completions generated by the
-preceding options and arguments, and each completion matching
-@var{filterpat} is removed from the list.
-A leading @samp{!} in @var{filterpat} negates the pattern; in this
-case, any completion not matching @var{filterpat} is removed.
+@item -G @var{globpat}
+The filename expansion pattern @var{globpat} is expanded to generate
+the possible completions.
@item -P @var{prefix}
@var{prefix} is added at the beginning of each possible completion
@@ -1969,6 +1984,21 @@ after all other options have been applied.
@item -S @var{suffix}
@var{suffix} is appended to each possible completion
after all other options have been applied.
+
+@item -W @var{wordlist}
+The @var{wordlist} is split using the characters in the
+@env{IFS} special variable as delimiters, and each resultant word
+is expanded.
+The possible completions are the members of the resultant list which
+match the word being completed.
+
+@item -X @var{filterpat}
+@var{filterpat} is a pattern as used for filename expansion.
+It is applied to the list of possible completions generated by the
+preceding options and arguments, and each completion matching
+@var{filterpat} is removed from the list.
+A leading @samp{!} in @var{filterpat} negates the pattern; in this
+case, any completion not matching @var{filterpat} is removed.
@end table
The return value is true unless an invalid option is supplied, an option
@@ -1983,7 +2013,7 @@ an error occurs adding a completion specification.
@code{compopt} [-o @var{option}] [-DE] [+o @var{option}] [@var{name}]
@end example
Modify completion options for each @var{name} according to the
-@var{option}s, or for the currently-execution completion if no @var{name}s
+@var{option}s, or for the currently-executing completion if no @var{name}s
are supplied.
If no @var{option}s are given, display the completion options for each
@var{name} or the current completion.
diff --git a/lib/readline/doc/rluserman.texi b/lib/readline/doc/rluserman.texi
index 49d9a2c..3d54520 100644
--- a/lib/readline/doc/rluserman.texi
+++ b/lib/readline/doc/rluserman.texi
@@ -12,7 +12,7 @@ This manual describes the end user interface of the GNU Readline Library
consistency of user interface across discrete programs which provide
a command line interface.
-Copyright @copyright{} 1988--2009 Free Software Foundation, Inc.
+Copyright @copyright{} 1988--2011 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
diff --git a/lib/readline/doc/version.texi b/lib/readline/doc/version.texi
index 823b3ba..3ee1c10 100644
--- a/lib/readline/doc/version.texi
+++ b/lib/readline/doc/version.texi
@@ -1,10 +1,10 @@
@ignore
-Copyright (C) 1988-2009 Free Software Foundation, Inc.
+Copyright (C) 1988-2011 Free Software Foundation, Inc.
@end ignore
-@set EDITION 6.1
-@set VERSION 6.1
-@set UPDATED 9 October 2009
-@set UPDATED-MONTH October 2009
+@set EDITION 6.2
+@set VERSION 6.2
+@set UPDATED September 6 2010
+@set UPDATED-MONTH September 2010
-@set LASTCHANGE Fri Oct 9 12:57:58 EDT 2009
+@set LASTCHANGE Mon Sep 6 22:07:10 EDT 2010
diff --git a/lib/readline/funmap.c b/lib/readline/funmap.c
index cccddb6..86e375f 100644
--- a/lib/readline/funmap.c
+++ b/lib/readline/funmap.c
@@ -1,6 +1,6 @@
/* funmap.c -- attach names to functions. */
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2010 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.
@@ -148,6 +148,8 @@ static const FUNMAP default_funmap[] = {
{ "vi-append-mode", rl_vi_append_mode },
{ "vi-arg-digit", rl_vi_arg_digit },
{ "vi-back-to-indent", rl_vi_back_to_indent },
+ { "vi-backward-bigword", rl_vi_bWord },
+ { "vi-backward-word", rl_vi_bword },
{ "vi-bWord", rl_vi_bWord },
{ "vi-bword", rl_vi_bword },
{ "vi-change-case", rl_vi_change_case },
@@ -160,12 +162,15 @@ static const FUNMAP default_funmap[] = {
{ "vi-delete-to", rl_vi_delete_to },
{ "vi-eWord", rl_vi_eWord },
{ "vi-editing-mode", rl_vi_editing_mode },
+ { "vi-end-bigword", rl_vi_eWord },
{ "vi-end-word", rl_vi_end_word },
{ "vi-eof-maybe", rl_vi_eof_maybe },
{ "vi-eword", rl_vi_eword },
{ "vi-fWord", rl_vi_fWord },
{ "vi-fetch-history", rl_vi_fetch_history },
{ "vi-first-print", rl_vi_first_print },
+ { "vi-forward-bigword", rl_vi_fWord },
+ { "vi-forward-word", rl_vi_fword },
{ "vi-fword", rl_vi_fword },
{ "vi-goto-mark", rl_vi_goto_mark },
{ "vi-insert-beg", rl_vi_insert_beg },
diff --git a/lib/readline/histexpand.c b/lib/readline/histexpand.c
index 42498d2..8fb3798 100644
--- a/lib/readline/histexpand.c
+++ b/lib/readline/histexpand.c
@@ -1,6 +1,6 @@
/* histexpand.c -- history expansion. */
-/* Copyright (C) 1989-2009 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2010 Free Software Foundation, Inc.
This file contains the GNU History Library (History), a set of
routines for managing the text of previously typed lines.
@@ -245,7 +245,7 @@ get_history_event (string, caller_index, delimiting_quote)
#define FAIL_SEARCH() \
do { \
- history_offset = history_length; free (temp) ; return (char *)NULL; \
+ history_offset = history_length; xfree (temp) ; return (char *)NULL; \
} while (0)
/* If there is no search string, try to use the previous search string,
@@ -254,7 +254,7 @@ get_history_event (string, caller_index, delimiting_quote)
{
if (search_string)
{
- free (temp);
+ xfree (temp);
temp = savestring (search_string);
}
else
@@ -285,7 +285,7 @@ get_history_event (string, caller_index, delimiting_quote)
search_match = history_find_word (entry->line, local_index);
}
else
- free (temp);
+ xfree (temp);
return (entry->line);
}
@@ -508,7 +508,7 @@ postproc_subst_rhs ()
}
}
new[j] = '\0';
- free (subst_rhs);
+ xfree (subst_rhs);
subst_rhs = new;
subst_rhs_len = j;
}
@@ -585,7 +585,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
if (event == 0)
{
*ret_string = hist_error (string, start, i, EVENT_NOT_FOUND);
- free (result);
+ xfree (result);
return (-1);
}
@@ -599,7 +599,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
if (word_spec == (char *)&error_pointer)
{
*ret_string = hist_error (string, starting_index, i, BAD_WORD_SPEC);
- free (result);
+ xfree (result);
return (-1);
}
@@ -632,8 +632,8 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
{
default:
*ret_string = hist_error (string, i+1, i+2, BAD_MODIFIER);
- free (result);
- free (temp);
+ xfree (result);
+ xfree (temp);
return -1;
case 'q':
@@ -658,7 +658,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
{
tstr++;
t = savestring (tstr);
- free (temp);
+ xfree (temp);
temp = t;
}
break;
@@ -683,7 +683,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
if (tstr)
{
t = savestring (tstr);
- free (temp);
+ xfree (temp);
temp = t;
}
break;
@@ -759,8 +759,8 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
if (subst_lhs_len == 0)
{
*ret_string = hist_error (string, starting_index, i, NO_PREV_SUBST);
- free (result);
- free (temp);
+ xfree (result);
+ xfree (temp);
return -1;
}
@@ -769,8 +769,8 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
if (subst_lhs_len > l_temp)
{
*ret_string = hist_error (string, starting_index, i, SUBST_FAILED);
- free (result);
- free (temp);
+ xfree (result);
+ xfree (temp);
return (-1);
}
@@ -811,7 +811,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
temp + si + subst_lhs_len,
l_temp - (si + subst_lhs_len));
new_event[len] = '\0';
- free (temp);
+ xfree (temp);
temp = new_event;
failed = 0;
@@ -847,8 +847,8 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
continue; /* don't want to increment i */
*ret_string = hist_error (string, starting_index, i, SUBST_FAILED);
- free (result);
- free (temp);
+ xfree (result);
+ xfree (temp);
return (-1);
}
}
@@ -869,7 +869,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
else
x = savestring (temp);
- free (temp);
+ xfree (temp);
temp = x;
}
@@ -877,7 +877,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
if (n >= result_len)
result = (char *)xrealloc (result, n + 2);
strcpy (result, temp);
- free (temp);
+ xfree (temp);
*end_index_ptr = i;
*ret_string = result;
@@ -1064,7 +1064,7 @@ history_expand (hstring, output)
if (string[i] != history_expansion_char)
{
- free (result);
+ xfree (result);
*output = savestring (string);
return (0);
}
@@ -1144,7 +1144,7 @@ history_expand (hstring, output)
strncpy (temp, string + quote, slen);
temp[slen - 1] = '\0';
ADD_STRING (temp);
- free (temp);
+ xfree (temp);
}
else
ADD_CHAR (string[i]);
@@ -1157,7 +1157,7 @@ history_expand (hstring, output)
temp = (char *)xmalloc (l - i + 1);
strcpy (temp, string + i);
ADD_STRING (temp);
- free (temp);
+ xfree (temp);
i = l;
}
else
@@ -1190,7 +1190,7 @@ history_expand (hstring, output)
temp = (char *)xmalloc (1 + strlen (result));
strcpy (temp, result);
ADD_STRING (temp);
- free (temp);
+ xfree (temp);
}
i++;
break;
@@ -1201,9 +1201,9 @@ history_expand (hstring, output)
if (r < 0)
{
*output = temp;
- free (result);
+ xfree (result);
if (string != hstring)
- free (string);
+ xfree (string);
return -1;
}
else
@@ -1213,7 +1213,7 @@ history_expand (hstring, output)
modified++;
if (*temp)
ADD_STRING (temp);
- free (temp);
+ xfree (temp);
}
only_printing = r == 1;
i = eindex;
@@ -1224,7 +1224,7 @@ history_expand (hstring, output)
*output = result;
if (string != hstring)
- free (string);
+ xfree (string);
if (only_printing)
{
@@ -1405,8 +1405,8 @@ history_arg_extract (first, last, string)
}
for (i = 0; i < len; i++)
- free (list[i]);
- free (list);
+ xfree (list[i]);
+ xfree (list);
return (result);
}
@@ -1417,10 +1417,10 @@ history_tokenize_word (string, ind)
int ind;
{
register int i;
- int delimiter;
+ int delimiter, nestdelim, delimopen;
i = ind;
- delimiter = 0;
+ delimiter = nestdelim = 0;
if (member (string[i], "()\n"))
{
@@ -1442,13 +1442,21 @@ history_tokenize_word (string, ind)
return i;
}
else if ((peek == '&' && (string[i] == '>' || string[i] == '<')) ||
- (peek == '>' && string[i] == '&') ||
- (peek == '(' && (string[i] == '>' || string[i] == '<')) || /* ) */
- (peek == '(' && string[i] == '$')) /* ) */
+ (peek == '>' && string[i] == '&'))
{
i += 2;
return i;
}
+ /* XXX - separated out for later -- bash-4.2 */
+ else if ((peek == '(' && (string[i] == '>' || string[i] == '<')) || /* ) */
+ (peek == '(' && string[i] == '$')) /*)*/
+ {
+ i += 2;
+ delimopen = '(';
+ delimiter = ')';
+ nestdelim = 1;
+ goto get_word;
+ }
#if 0
else if (peek == '\'' && string[i] == '$')
{
@@ -1464,9 +1472,25 @@ history_tokenize_word (string, ind)
}
}
+ /* same code also used for $(...)/<(...)/>(...) above */
+ if (member (string[i], "!@?+*"))
+ {
+ int peek = string[i + 1];
+
+ if (peek == '(') /*)*/
+ {
+ /* Shell extended globbing patterns */
+ i += 2;
+ delimopen = '(';
+ delimiter = ')'; /* XXX - not perfect */
+ nestdelim = 1;
+ }
+ }
+
+get_word:
/* Get word from string + i; */
- if (member (string[i], HISTORY_QUOTE_CHARACTERS))
+ if (delimiter == 0 && member (string[i], HISTORY_QUOTE_CHARACTERS))
delimiter = string[i++];
for (; string[i]; i++)
@@ -1484,16 +1508,31 @@ history_tokenize_word (string, ind)
continue;
}
+ /* delimiter must be set and set to something other than a quote if
+ nestdelim is set, so these tests are safe. */
+ if (nestdelim && string[i] == delimopen)
+ {
+ nestdelim++;
+ continue;
+ }
+ if (nestdelim && string[i] == delimiter)
+ {
+ nestdelim--;
+ if (nestdelim == 0)
+ delimiter = 0;
+ continue;
+ }
+
if (delimiter && string[i] == delimiter)
{
delimiter = 0;
continue;
}
- if (!delimiter && (member (string[i], history_word_delimiters)))
+ if (delimiter == 0 && (member (string[i], history_word_delimiters)))
break;
- if (!delimiter && member (string[i], HISTORY_QUOTE_CHARACTERS))
+ if (delimiter == 0 && member (string[i], HISTORY_QUOTE_CHARACTERS))
delimiter = string[i];
}
@@ -1590,7 +1629,7 @@ freewords (words, start)
register int i;
for (i = start; words[i]; i++)
- free (words[i]);
+ xfree (words[i]);
}
/* Find and return the word which contains the character at index IND
@@ -1614,8 +1653,8 @@ history_find_word (line, ind)
}
s = words[wind];
for (i = 0; i < wind; i++)
- free (words[i]);
+ xfree (words[i]);
freewords (words, wind + 1);
- free (words);
+ xfree (words);
return s;
}
diff --git a/lib/readline/histfile.c b/lib/readline/histfile.c
index a75fc16..30a6182 100644
--- a/lib/readline/histfile.c
+++ b/lib/readline/histfile.c
@@ -1,6 +1,6 @@
/* histfile.c - functions to manipulate the history file. */
-/* Copyright (C) 1989-2009 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2010 Free Software Foundation, Inc.
This file contains the GNU History Library (History), a set of
routines for managing the text of previously typed lines.
@@ -126,8 +126,12 @@ history_filename (filename)
if (home == 0)
{
+#if 0
home = ".";
home_len = 1;
+#else
+ return (NULL);
+#endif
}
else
home_len = strlen (home);
@@ -179,7 +183,7 @@ read_history_range (filename, from, to)
buffer = last_ts = (char *)NULL;
input = history_filename (filename);
- file = open (input, O_RDONLY|O_BINARY, 0666);
+ file = input ? open (input, O_RDONLY|O_BINARY, 0666) : -1;
if ((file < 0) || (fstat (file, &finfo) == -1))
goto error_and_exit;
@@ -314,7 +318,7 @@ history_truncate_file (fname, lines)
buffer = (char *)NULL;
filename = history_filename (fname);
- file = open (filename, O_RDONLY|O_BINARY, 0666);
+ file = filename ? open (filename, O_RDONLY|O_BINARY, 0666) : -1;
rv = 0;
/* Don't try to truncate non-regular files. */
@@ -413,7 +417,7 @@ history_truncate_file (fname, lines)
FREE (buffer);
- free (filename);
+ xfree (filename);
return rv;
}
@@ -436,9 +440,10 @@ history_do_write (filename, nelements, overwrite)
mode = overwrite ? O_WRONLY|O_CREAT|O_TRUNC|O_BINARY : O_WRONLY|O_APPEND|O_BINARY;
#endif
output = history_filename (filename);
+ file = output ? open (output, mode, 0600) : -1;
rv = 0;
- if ((file = open (output, mode, 0600)) == -1)
+ if (file == -1)
{
FREE (output);
return (errno);
@@ -515,7 +520,7 @@ mmap_error:
#else
if (write (file, buffer, buffer_size) < 0)
rv = errno;
- free (buffer);
+ xfree (buffer);
#endif
}
diff --git a/lib/readline/history.c b/lib/readline/history.c
index 8e613bb..d7894cf 100644
--- a/lib/readline/history.c
+++ b/lib/readline/history.c
@@ -338,7 +338,7 @@ free_history_entry (hist)
FREE (hist->line);
FREE (hist->timestamp);
x = hist->data;
- free (hist);
+ xfree (hist);
return (x);
}
diff --git a/lib/readline/input.c b/lib/readline/input.c
index b5876da..7c74c99 100644
--- a/lib/readline/input.c
+++ b/lib/readline/input.c
@@ -1,6 +1,6 @@
/* input.c -- character input functions for readline. */
-/* Copyright (C) 1994-2009 Free Software Foundation, Inc.
+/* Copyright (C) 1994-2010 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.
@@ -427,17 +427,19 @@ rl_read_key ()
/* If the user has an event function, then call it periodically. */
if (rl_event_hook)
{
- while (rl_event_hook && rl_get_char (&c) == 0)
+ while (rl_event_hook)
{
- (*rl_event_hook) ();
- RL_CHECK_SIGNALS ();
- if (rl_done) /* XXX - experimental */
- return ('\n');
if (rl_gather_tyi () < 0) /* XXX - EIO */
{
rl_done = 1;
return ('\n');
}
+ RL_CHECK_SIGNALS ();
+ if (rl_get_char (&c) != 0)
+ break;
+ if (rl_done) /* XXX - experimental */
+ return ('\n');
+ (*rl_event_hook) ();
}
}
else
diff --git a/lib/readline/isearch.c b/lib/readline/isearch.c
index f3f46a7..712b9ea 100644
--- a/lib/readline/isearch.c
+++ b/lib/readline/isearch.c
@@ -104,6 +104,9 @@ _rl_scxt_alloc (type, flags)
cxt->save_undo_list = 0;
+ cxt->keymap = _rl_keymap;
+ cxt->okeymap = _rl_keymap;
+
cxt->history_pos = 0;
cxt->direction = 0;
@@ -336,10 +339,22 @@ _rl_isearch_dispatch (cxt, c)
return -1;
}
+ /* If we are moving into a new keymap, modify cxt->keymap and go on.
+ This can be a problem if c == ESC and we want to terminate the
+ incremental search, so we check */
+ if (c >= 0 && cxt->keymap[c].type == ISKMAP && strchr (cxt->search_terminators, cxt->lastc) == 0)
+ {
+ cxt->keymap = FUNCTION_TO_KEYMAP (cxt->keymap, c);
+ cxt->sflags |= SF_CHGKMAP;
+ /* XXX - we should probably save this sequence, so we can do
+ something useful if this doesn't end up mapping to a command. */
+ return 1;
+ }
+
/* Translate the keys we do something with to opcodes. */
- if (c >= 0 && _rl_keymap[c].type == ISFUNC)
+ if (c >= 0 && cxt->keymap[c].type == ISFUNC)
{
- f = _rl_keymap[c].function;
+ f = cxt->keymap[c].function;
if (f == rl_reverse_search_history)
cxt->lastc = (cxt->sflags & SF_REVERSE) ? -1 : -2;
@@ -347,19 +362,27 @@ _rl_isearch_dispatch (cxt, c)
cxt->lastc = (cxt->sflags & SF_REVERSE) ? -2 : -1;
else if (f == rl_rubout)
cxt->lastc = -3;
- else if (c == CTRL ('G'))
+ else if (c == CTRL ('G') || f == rl_abort)
cxt->lastc = -4;
- else if (c == CTRL ('W')) /* XXX */
+ else if (c == CTRL ('W') || f == rl_unix_word_rubout) /* XXX */
cxt->lastc = -5;
- else if (c == CTRL ('Y')) /* XXX */
+ else if (c == CTRL ('Y') || f == rl_yank) /* XXX */
cxt->lastc = -6;
}
+ /* If we changed the keymap earlier while translating a key sequence into
+ a command, restore it now that we've succeeded. */
+ if (cxt->sflags & SF_CHGKMAP)
+ {
+ cxt->keymap = cxt->okeymap;
+ cxt->sflags &= ~SF_CHGKMAP;
+ }
+
/* The characters in isearch_terminators (set from the user-settable
variable isearch-terminators) are used to terminate the search but
not subsequently execute the character as a command. The default
value is "\033\012" (ESC and C-J). */
- if (strchr (cxt->search_terminators, cxt->lastc))
+ if (cxt->lastc > 0 && strchr (cxt->search_terminators, cxt->lastc))
{
/* ESC still terminates the search, but if there is pending
input or if input arrives within 0.1 seconds (on systems
diff --git a/lib/readline/keymaps.c b/lib/readline/keymaps.c
index 9379dec..58661e2 100644
--- a/lib/readline/keymaps.c
+++ b/lib/readline/keymaps.c
@@ -142,11 +142,11 @@ rl_discard_keymap (map)
case ISKMAP:
rl_discard_keymap ((Keymap)map[i].function);
- free ((char *)map[i].function);
+ xfree ((char *)map[i].function);
break;
case ISMACR:
- free ((char *)map[i].function);
+ xfree ((char *)map[i].function);
break;
}
}
@@ -158,5 +158,5 @@ rl_free_keymap (map)
Keymap map;
{
rl_discard_keymap (map);
- free ((char *)map);
+ xfree ((char *)map);
}
diff --git a/lib/readline/keymaps.h b/lib/readline/keymaps.h
index 6c4611d..af8d5d9 100644
--- a/lib/readline/keymaps.h
+++ b/lib/readline/keymaps.h
@@ -52,11 +52,6 @@ typedef struct _keymap_entry {
#define KEYMAP_SIZE 257
#define ANYOTHERKEY KEYMAP_SIZE-1
-/* I wanted to make the above structure contain a union of:
- union { rl_command_func_t *function; struct _keymap_entry *keymap; } value;
- but this made it impossible for me to create a static array.
- Maybe I need C lessons. */
-
typedef KEYMAP_ENTRY KEYMAP_ENTRY_ARRAY[KEYMAP_SIZE];
typedef KEYMAP_ENTRY *Keymap;
diff --git a/lib/readline/kill.c b/lib/readline/kill.c
index a4d6d14..1a78783 100644
--- a/lib/readline/kill.c
+++ b/lib/readline/kill.c
@@ -147,7 +147,7 @@ _rl_copy_to_kill_ring (text, append)
strcat (new, old);
}
xfree (old);
- free (text);
+ xfree (text);
rl_kill_ring[slot] = new;
}
else
@@ -601,7 +601,7 @@ rl_yank_nth_arg_internal (count, ignore, history_skip)
#endif /* VI_MODE */
rl_insert_text (arg);
- free (arg);
+ xfree (arg);
rl_end_undo_group ();
return 0;
@@ -640,7 +640,7 @@ rl_yank_last_arg (count, key)
{
if (undo_needed)
rl_do_undo ();
- if (count < 1)
+ if (count < 0) /* XXX - was < 1 */
direction = -direction;
history_skip += direction;
if (history_skip < 0)
diff --git a/lib/readline/misc.c b/lib/readline/misc.c
index 12ae4a5..9f45773 100644
--- a/lib/readline/misc.c
+++ b/lib/readline/misc.c
@@ -328,7 +328,7 @@ _rl_free_history_entry (entry)
FREE (entry->line);
FREE (entry->timestamp);
- free (entry);
+ xfree (entry);
}
/* Perhaps put back the current line if it has changed. */
@@ -342,9 +342,9 @@ rl_maybe_replace_line ()
if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list))
{
temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list);
- free (temp->line);
+ xfree (temp->line);
FREE (temp->timestamp);
- free (temp);
+ xfree (temp);
}
return 0;
}
@@ -480,7 +480,7 @@ _rl_revert_all_lines ()
_rl_set_the_line ();
/* and clean up */
- free (lbuf);
+ xfree (lbuf);
}
/* **************************************************************** */
diff --git a/lib/readline/nls.c b/lib/readline/nls.c
index 7f10f01..e3599eb 100644
--- a/lib/readline/nls.c
+++ b/lib/readline/nls.c
@@ -145,7 +145,7 @@ _rl_init_eightbit ()
_rl_output_meta_chars = 1;
break;
}
- free (t);
+ xfree (t);
return (legal_lang_values[i] ? 1 : 0);
#endif /* !HAVE_SETLOCALE */
diff --git a/lib/readline/readline.c b/lib/readline/readline.c
index c0e78d4..f2e4d93 100644
--- a/lib/readline/readline.c
+++ b/lib/readline/readline.c
@@ -382,7 +382,7 @@ readline_internal_setup ()
nprompt = _rl_strip_prompt (rl_prompt);
fprintf (_rl_out_stream, "%s", nprompt);
fflush (_rl_out_stream);
- free (nprompt);
+ xfree (nprompt);
}
}
else
@@ -426,7 +426,7 @@ readline_internal_teardown (eof)
_rl_free_history_entry (entry);
strcpy (the_line, temp);
- free (temp);
+ xfree (temp);
}
if (_rl_revert_all_at_newline)
@@ -629,7 +629,7 @@ void
_rl_keyseq_cxt_dispose (cxt)
_rl_keyseq_cxt *cxt;
{
- free (cxt);
+ xfree (cxt);
}
void
diff --git a/lib/readline/readline.h b/lib/readline/readline.h
index 7a4ffaa..0de168c 100644
--- a/lib/readline/readline.h
+++ b/lib/readline/readline.h
@@ -1,6 +1,6 @@
/* Readline.h -- the names of functions callable from within readline. */
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2011 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.
@@ -39,9 +39,9 @@ extern "C" {
#endif
/* Hex-encoded Readline version number. */
-#define RL_READLINE_VERSION 0x0600 /* Readline 6.0 */
+#define RL_READLINE_VERSION 0x0602 /* Readline 6.2 */
#define RL_VERSION_MAJOR 6
-#define RL_VERSION_MINOR 0
+#define RL_VERSION_MINOR 2
/* Readline data structures. */
@@ -666,16 +666,24 @@ extern const char *rl_special_prefixes;
completing on a directory name. The function is called with
the address of a string (the current directory name) as an arg. It
changes what is displayed when the possible completions are printed
- or inserted. */
+ or inserted. The directory completion hook should perform
+ any necessary dequoting. This function should return 1 if it modifies
+ the directory name pointer passed as an argument. If the directory
+ completion hook returns 0, it should not modify the directory name
+ pointer passed as an argument. */
extern rl_icppfunc_t *rl_directory_completion_hook;
/* If non-zero, this is the address of a function to call when completing
a directory name. This function takes the address of the directory name
to be modified as an argument. Unlike rl_directory_completion_hook, it
only modifies the directory name used in opendir(2), not what is displayed
- when the possible completions are printed or inserted. It is called
- before rl_directory_completion_hook. I'm not happy with how this works
- yet, so it's undocumented. */
+ when the possible completions are printed or inserted. If set, it takes
+ precedence over rl_directory_completion_hook. The directory rewrite
+ hook should perform any necessary dequoting. This function has the same
+ return value properties as the directory_completion_hook.
+
+ I'm not happy with how this works yet, so it's undocumented. I'm trying
+ it in bash to see how well it goes. */
extern rl_icppfunc_t *rl_directory_rewrite_hook;
/* If non-zero, this is the address of a function to call when reading
@@ -805,30 +813,30 @@ extern int rl_inhibit_completion;
/* Possible state values for rl_readline_state */
#define RL_STATE_NONE 0x000000 /* no state; before first call */
-#define RL_STATE_INITIALIZING 0x000001 /* initializing */
-#define RL_STATE_INITIALIZED 0x000002 /* initialization done */
-#define RL_STATE_TERMPREPPED 0x000004 /* terminal is prepped */
-#define RL_STATE_READCMD 0x000008 /* reading a command key */
-#define RL_STATE_METANEXT 0x000010 /* reading input after ESC */
-#define RL_STATE_DISPATCHING 0x000020 /* dispatching to a command */
-#define RL_STATE_MOREINPUT 0x000040 /* reading more input in a command function */
-#define RL_STATE_ISEARCH 0x000080 /* doing incremental search */
-#define RL_STATE_NSEARCH 0x000100 /* doing non-inc search */
-#define RL_STATE_SEARCH 0x000200 /* doing a history search */
-#define RL_STATE_NUMERICARG 0x000400 /* reading numeric argument */
-#define RL_STATE_MACROINPUT 0x000800 /* getting input from a macro */
-#define RL_STATE_MACRODEF 0x001000 /* defining keyboard macro */
-#define RL_STATE_OVERWRITE 0x002000 /* overwrite mode */
-#define RL_STATE_COMPLETING 0x004000 /* doing completion */
-#define RL_STATE_SIGHANDLER 0x008000 /* in readline sighandler */
-#define RL_STATE_UNDOING 0x010000 /* doing an undo */
-#define RL_STATE_INPUTPENDING 0x020000 /* rl_execute_next called */
-#define RL_STATE_TTYCSAVED 0x040000 /* tty special chars saved */
-#define RL_STATE_CALLBACK 0x080000 /* using the callback interface */
-#define RL_STATE_VIMOTION 0x100000 /* reading vi motion arg */
-#define RL_STATE_MULTIKEY 0x200000 /* reading multiple-key command */
-#define RL_STATE_VICMDONCE 0x400000 /* entered vi command mode at least once */
-#define RL_STATE_REDISPLAYING 0x800000 /* updating terminal display */
+#define RL_STATE_INITIALIZING 0x0000001 /* initializing */
+#define RL_STATE_INITIALIZED 0x0000002 /* initialization done */
+#define RL_STATE_TERMPREPPED 0x0000004 /* terminal is prepped */
+#define RL_STATE_READCMD 0x0000008 /* reading a command key */
+#define RL_STATE_METANEXT 0x0000010 /* reading input after ESC */
+#define RL_STATE_DISPATCHING 0x0000020 /* dispatching to a command */
+#define RL_STATE_MOREINPUT 0x0000040 /* reading more input in a command function */
+#define RL_STATE_ISEARCH 0x0000080 /* doing incremental search */
+#define RL_STATE_NSEARCH 0x0000100 /* doing non-inc search */
+#define RL_STATE_SEARCH 0x0000200 /* doing a history search */
+#define RL_STATE_NUMERICARG 0x0000400 /* reading numeric argument */
+#define RL_STATE_MACROINPUT 0x0000800 /* getting input from a macro */
+#define RL_STATE_MACRODEF 0x0001000 /* defining keyboard macro */
+#define RL_STATE_OVERWRITE 0x0002000 /* overwrite mode */
+#define RL_STATE_COMPLETING 0x0004000 /* doing completion */
+#define RL_STATE_SIGHANDLER 0x0008000 /* in readline sighandler */
+#define RL_STATE_UNDOING 0x0010000 /* doing an undo */
+#define RL_STATE_INPUTPENDING 0x0020000 /* rl_execute_next called */
+#define RL_STATE_TTYCSAVED 0x0040000 /* tty special chars saved */
+#define RL_STATE_CALLBACK 0x0080000 /* using the callback interface */
+#define RL_STATE_VIMOTION 0x0100000 /* reading vi motion arg */
+#define RL_STATE_MULTIKEY 0x0200000 /* reading multiple-key command */
+#define RL_STATE_VICMDONCE 0x0400000 /* entered vi command mode at least once */
+#define RL_STATE_REDISPLAYING 0x0800000 /* updating terminal display */
#define RL_STATE_DONE 0x1000000 /* done; accepted line */
diff --git a/lib/readline/rlprivate.h b/lib/readline/rlprivate.h
index 819f127..384ff67 100644
--- a/lib/readline/rlprivate.h
+++ b/lib/readline/rlprivate.h
@@ -1,7 +1,7 @@
/* rlprivate.h -- functions and variables global to the readline library,
but not intended for use by applications. */
-/* Copyright (C) 1999-2009 Free Software Foundation, Inc.
+/* Copyright (C) 1999-2010 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.
@@ -56,6 +56,7 @@
#define SF_REVERSE 0x01
#define SF_FOUND 0x02
#define SF_FAILED 0x04
+#define SF_CHGKMAP 0x08
typedef struct __rl_search_context
{
@@ -79,6 +80,9 @@ typedef struct __rl_search_context
UNDO_LIST *save_undo_list;
+ Keymap keymap; /* used when dispatching commands in search string */
+ Keymap okeymap; /* original keymap */
+
int history_pos;
int direction;
@@ -120,7 +124,28 @@ typedef struct __rl_keyseq_context
int childval;
} _rl_keyseq_cxt;
- /* fill in more as needed */
+/* vi-mode commands that use result of motion command to define boundaries */
+#define VIM_DELETE 0x01
+#define VIM_CHANGE 0x02
+#define VIM_YANK 0x04
+
+/* various states for vi-mode commands that use motion commands. reflects
+ RL_READLINE_STATE */
+#define VMSTATE_READ 0x01
+#define VMSTATE_NUMARG 0x02
+
+typedef struct __rl_vimotion_context
+{
+ int op;
+ int state;
+ int flags; /* reserved */
+ _rl_arg_cxt ncxt;
+ int numeric_arg;
+ int start, end; /* rl_point, rl_end */
+ int key, motion; /* initial key, motion command */
+} _rl_vimotion_cxt;
+
+/* fill in more as needed */
/* `Generic' callback data and functions */
typedef struct __rl_callback_generic_arg
{
@@ -320,6 +345,7 @@ extern void _rl_set_cursor PARAMS((int, int));
/* text.c */
extern void _rl_fix_point PARAMS((int));
extern int _rl_replace_text PARAMS((const char *, int, int));
+extern int _rl_forward_char_internal PARAMS((int));
extern int _rl_insert_char PARAMS((int, int));
extern int _rl_overwrite_char PARAMS((int, int));
extern int _rl_overwrite_rubout PARAMS((int, int));
@@ -366,6 +392,7 @@ extern void _rl_vi_reset_last PARAMS((void));
extern void _rl_vi_set_last PARAMS((int, int, int));
extern int _rl_vi_textmod_command PARAMS((int));
extern void _rl_vi_done_inserting PARAMS((void));
+extern int _rl_vi_domove_callback PARAMS((_rl_vimotion_cxt *));
/*************************************************************************
* Undocumented private variables *
@@ -385,11 +412,14 @@ extern int _rl_complete_show_unmodified;
extern int _rl_complete_mark_directories;
extern int _rl_complete_mark_symlink_dirs;
extern int _rl_completion_prefix_display_length;
+extern int _rl_completion_columns;
extern int _rl_print_completions_horizontally;
extern int _rl_completion_case_fold;
+extern int _rl_completion_case_map;
extern int _rl_match_hidden_files;
extern int _rl_page_completions;
extern int _rl_skip_completed_text;
+extern int _rl_menu_complete_prefix_first;
/* display.c */
extern int _rl_vis_botlin;
@@ -471,5 +501,6 @@ extern int _rl_undo_group_level;
/* vi_mode.c */
extern int _rl_vi_last_command;
+extern _rl_vimotion_cxt *_rl_vimvcxt;
#endif /* _RL_PRIVATE_H_ */
diff --git a/lib/readline/rltty.c b/lib/readline/rltty.c
index 0dd5d10..d237b1c 100644
--- a/lib/readline/rltty.c
+++ b/lib/readline/rltty.c
@@ -604,7 +604,7 @@ rl_prep_terminal (meta_flag)
/* Try to keep this function from being INTerrupted. */
_rl_block_sigint ();
- tty = fileno (rl_instream);
+ tty = rl_instream ? fileno (rl_instream) : fileno (stdin);
if (get_tty_settings (tty, &tio) < 0)
{
@@ -678,7 +678,7 @@ rl_deprep_terminal ()
/* Try to keep this function from being interrupted. */
_rl_block_sigint ();
- tty = fileno (rl_instream);
+ tty = rl_instream ? fileno (rl_instream) : fileno (stdout);
if (_rl_enable_keypad)
_rl_control_keypad (0);
diff --git a/lib/readline/savestring.c b/lib/readline/savestring.c
index 63f467a..af98538 100644
--- a/lib/readline/savestring.c
+++ b/lib/readline/savestring.c
@@ -33,5 +33,9 @@ char *
savestring (s)
const char *s;
{
- return ((char *)strcpy ((char *)xmalloc (1 + strlen (s)), (s)));
+ char *ret;
+
+ ret = (char *)xmalloc (strlen (s) + 1);
+ strcpy (ret, s);
+ return ret;
}
diff --git a/lib/readline/search.c b/lib/readline/search.c
index 82984f1..04468fc 100644
--- a/lib/readline/search.c
+++ b/lib/readline/search.c
@@ -211,7 +211,7 @@ _rl_nsearch_init (dir, pchar)
p = _rl_make_prompt_for_search (pchar ? pchar : ':');
rl_message ("%s", p, 0);
- free (p);
+ xfree (p);
RL_SETSTATE(RL_STATE_NSEARCH);
diff --git a/lib/readline/shell.c b/lib/readline/shell.c
index 18b4f03..ac0fb36 100644
--- a/lib/readline/shell.c
+++ b/lib/readline/shell.c
@@ -130,12 +130,12 @@ sh_set_lines_and_columns (lines, cols)
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1);
sprintf (b, "%d", lines);
setenv ("LINES", b, 1);
- free (b);
+ xfree (b);
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1);
sprintf (b, "%d", cols);
setenv ("COLUMNS", b, 1);
- free (b);
+ xfree (b);
#else /* !HAVE_SETENV */
# if defined (HAVE_PUTENV)
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("LINES=") + 1);
diff --git a/lib/readline/signals.c b/lib/readline/signals.c
index 4fbc019..6a68d78 100644
--- a/lib/readline/signals.c
+++ b/lib/readline/signals.c
@@ -131,6 +131,7 @@ static sighandler_cxt old_winch;
/* Called from RL_CHECK_SIGNALS() macro */
RETSIGTYPE
_rl_signal_handler (sig)
+ int sig;
{
_rl_caught_signal = 0; /* XXX */
diff --git a/lib/readline/terminal.c b/lib/readline/terminal.c
index ee13092..f8c2f6e 100644
--- a/lib/readline/terminal.c
+++ b/lib/readline/terminal.c
@@ -96,12 +96,12 @@ static char *term_string_buffer = (char *)NULL;
static int tcap_initialized;
-#if !defined (__linux__)
+#if !defined (__linux__) && !defined (NCURSES_VERSION)
# if defined (__EMX__) || defined (NEED_EXTERN_PC)
extern
# endif /* __EMX__ || NEED_EXTERN_PC */
char PC, *BC, *UP;
-#endif /* __linux__ */
+#endif /* !__linux__ && !NCURSES_VERSION */
/* Some strings to control terminal actions. These are output by tputs (). */
char *_rl_term_clreol;
@@ -350,9 +350,9 @@ rl_reset_screen_size ()
void
rl_resize_terminal ()
{
+ _rl_get_screen_size (fileno (rl_instream), 1);
if (_rl_echoing_p)
{
- _rl_get_screen_size (fileno (rl_instream), 1);
if (CUSTOM_REDISPLAY_FUNC ())
rl_forced_update_display ();
else if (RL_ISSTATE(RL_STATE_REDISPLAYING) == 0)
diff --git a/lib/readline/text.c b/lib/readline/text.c
index fc39189..536e31a 100644
--- a/lib/readline/text.c
+++ b/lib/readline/text.c
@@ -1,6 +1,6 @@
/* text.c -- text handling commands for readline. */
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2010 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.
@@ -150,7 +150,7 @@ rl_delete_text (from, to)
if (_rl_doing_an_undo == 0)
rl_add_undo (UNDO_DELETE, from, to, text);
else
- free (text);
+ xfree (text);
rl_end -= diff;
rl_line_buffer[rl_end] = '\0';
@@ -265,11 +265,13 @@ rl_forward_byte (count, key)
if (count > 0)
{
- int end = rl_point + count;
+ int end, lend;
+
+ end = rl_point + count;
#if defined (VI_MODE)
- int lend = rl_end > 0 ? rl_end - (VI_COMMAND_MODE()) : rl_end;
+ lend = rl_end > 0 ? rl_end - (VI_COMMAND_MODE()) : rl_end;
#else
- int lend = rl_end;
+ lend = rl_end;
#endif
if (end > lend)
@@ -287,6 +289,31 @@ rl_forward_byte (count, key)
return 0;
}
+int
+_rl_forward_char_internal (count)
+ int count;
+{
+ int point;
+
+#if defined (HANDLE_MULTIBYTE)
+ point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
+
+#if defined (VI_MODE)
+ if (point >= rl_end && VI_COMMAND_MODE())
+ point = _rl_find_prev_mbchar (rl_line_buffer, rl_end, MB_FIND_NONZERO);
+#endif
+
+ if (rl_end < 0)
+ rl_end = 0;
+#else
+ point = rl_point + count;
+ if (point > rl_end)
+ point = rl_end;
+#endif
+
+ return (point);
+}
+
#if defined (HANDLE_MULTIBYTE)
/* Move forward COUNT characters. */
int
@@ -309,20 +336,12 @@ rl_forward_char (count, key)
return 0;
}
- point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
-
-#if defined (VI_MODE)
- if (point >= rl_end && VI_COMMAND_MODE())
- point = _rl_find_prev_mbchar (rl_line_buffer, rl_end, MB_FIND_NONZERO);
-#endif
+ point = _rl_forward_char_internal (count);
if (rl_point == point)
rl_ding ();
rl_point = point;
-
- if (rl_end < 0)
- rl_end = 0;
}
return 0;
@@ -752,7 +771,7 @@ _rl_insert_char (count, c)
string[i] = '\0';
rl_insert_text (string);
- free (string);
+ xfree (string);
return 0;
}
@@ -779,7 +798,7 @@ _rl_insert_char (count, c)
count -= decreaser;
}
- free (string);
+ xfree (string);
incoming_length = 0;
stored_count = 0;
#else /* !HANDLE_MULTIBYTE */
@@ -805,8 +824,9 @@ _rl_insert_char (count, c)
/* We are inserting a single character.
If there is pending input, then make a string of all of the
pending characters that are bound to rl_insert, and insert
- them all. */
- if (_rl_any_typein ())
+ them all. Don't do this if we're current reading input from
+ a macro. */
+ if ((RL_ISSTATE (RL_STATE_MACROINPUT) == 0) && _rl_any_typein ())
_rl_insert_typein (c);
else
{
@@ -1407,8 +1427,8 @@ rl_transpose_words (count, key)
/* I think that does it. */
rl_end_undo_group ();
- free (word1);
- free (word2);
+ xfree (word1);
+ xfree (word2);
return 0;
}
@@ -1467,7 +1487,7 @@ rl_transpose_chars (count, key)
rl_end_undo_group ();
#if defined (HANDLE_MULTIBYTE)
- free (dummy);
+ xfree (dummy);
#endif
return 0;
@@ -1495,6 +1515,9 @@ _rl_char_search_internal (count, dir, schar)
int prepos;
#endif
+ if (dir == 0)
+ return -1;
+
pos = rl_point;
inc = (dir < 0) ? -1 : 1;
while (count)
diff --git a/lib/readline/tilde.c b/lib/readline/tilde.c
index 088ff15..1c53a45 100644
--- a/lib/readline/tilde.c
+++ b/lib/readline/tilde.c
@@ -378,7 +378,7 @@ tilde_expand_word (filename)
{
dirname = glue_prefix_and_suffix (expansion, filename, user_len);
xfree (username);
- free (expansion);
+ xfree (expansion);
return (dirname);
}
}
@@ -401,7 +401,7 @@ tilde_expand_word (filename)
if (expansion)
{
dirname = glue_prefix_and_suffix (expansion, filename, user_len);
- free (expansion);
+ xfree (expansion);
}
}
/* If we don't have a failure hook, or if the failure hook did not
diff --git a/lib/readline/util.c b/lib/readline/util.c
index 6bb64c2..6c68ad8 100644
--- a/lib/readline/util.c
+++ b/lib/readline/util.c
@@ -1,6 +1,6 @@
/* util.c -- readline utility functions */
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2010 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.
@@ -366,41 +366,56 @@ _rl_strpbrk (string1, string2)
#if !defined (HAVE_STRCASECMP)
/* Compare at most COUNT characters from string1 to string2. Case
- doesn't matter. */
+ doesn't matter (strncasecmp). */
int
_rl_strnicmp (string1, string2, count)
char *string1, *string2;
int count;
{
- register char ch1, ch2;
+ register char *s1, *s2;
+ int d;
- while (count)
+ if (count <= 0 || (string1 == string2))
+ return 0;
+
+ s1 = string1;
+ s2 = string2;
+ do
{
- ch1 = *string1++;
- ch2 = *string2++;
- if (_rl_to_upper(ch1) == _rl_to_upper(ch2))
- count--;
- else
+ d = _rl_to_lower (*s1) - _rl_to_lower (*s2); /* XXX - cast to unsigned char? */
+ if (d != 0)
+ return d;
+ if (*s1++ == '\0')
break;
+ s2++;
}
- return (count);
+ while (--count != 0)
+
+ return (0);
}
-/* strcmp (), but caseless. */
+/* strcmp (), but caseless (strcasecmp). */
int
_rl_stricmp (string1, string2)
char *string1, *string2;
{
- register char ch1, ch2;
+ register char *s1, *s2;
+ int d;
- while (*string1 && *string2)
+ s1 = string1;
+ s2 = string2;
+
+ if (s1 == s2)
+ return 0;
+
+ while ((d = _rl_to_lower (*s1) - _rl_to_lower (*s2)) == 0)
{
- ch1 = *string1++;
- ch2 = *string2++;
- if (_rl_to_upper(ch1) != _rl_to_upper(ch2))
- return (1);
+ if (*s1++ == '\0')
+ return 0;
+ s2++;
}
- return (*string1 - *string2);
+
+ return (d);
}
#endif /* !HAVE_STRCASECMP */
diff --git a/lib/readline/vi_mode.c b/lib/readline/vi_mode.c
index 2a120c0..41e1dbb 100644
--- a/lib/readline/vi_mode.c
+++ b/lib/readline/vi_mode.c
@@ -1,7 +1,7 @@
/* vi_mode.c -- A vi emulation mode for Bash.
Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2010 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.
@@ -65,6 +65,8 @@
int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
+_rl_vimotion_cxt *_rl_vimvcxt = 0;
+
/* Non-zero means enter insertion mode. */
static int _rl_vi_doing_insert;
@@ -128,6 +130,16 @@ static int _rl_vi_callback_change_char PARAMS((_rl_callback_generic_arg *));
static int _rl_vi_callback_char_search PARAMS((_rl_callback_generic_arg *));
#endif
+static int rl_domove_read_callback PARAMS((_rl_vimotion_cxt *));
+static int rl_domove_motion_callback PARAMS((_rl_vimotion_cxt *));
+static int rl_vi_domove_getchar PARAMS((_rl_vimotion_cxt *));
+
+static int vi_change_dispatch PARAMS((_rl_vimotion_cxt *));
+static int vi_delete_dispatch PARAMS((_rl_vimotion_cxt *));
+static int vi_yank_dispatch PARAMS((_rl_vimotion_cxt *));
+
+static int vidomove_dispatch PARAMS((_rl_vimotion_cxt *));
+
void
_rl_vi_initialize_line ()
{
@@ -618,12 +630,16 @@ _rl_vi_append_forward (key)
if (MB_CUR_MAX == 1 || rl_byte_oriented)
rl_point++;
else
- {
- point = rl_point;
- rl_forward_char (1, key);
- if (point == rl_point)
- rl_point = rl_end;
- }
+ {
+ point = rl_point;
+#if 0
+ rl_forward_char (1, key);
+#else
+ rl_point = _rl_forward_char_internal (1);
+#endif
+ if (point == rl_point)
+ rl_point = rl_end;
+ }
}
}
@@ -721,7 +737,7 @@ _rl_vi_done_inserting ()
_rl_vi_last_key_before_insert == 'a' ||
_rl_vi_last_key_before_insert == 'I' ||
_rl_vi_last_key_before_insert == 'A'))
- _rl_vi_save_insert (rl_undo_list);
+ _rl_vi_save_insert (rl_undo_list);
/* XXX - Other keys probably need to be checked. */
else if (_rl_vi_last_key_before_insert == 'C')
rl_end_undo_group ();
@@ -781,7 +797,7 @@ _rl_vi_change_mbchar_case (count)
if (MB_INVALIDCH (m))
wc = (wchar_t)rl_line_buffer[rl_point];
else if (MB_NULLWCH (m))
- wc = L'\0';
+ wc = L'\0';
if (iswupper (wc))
wc = towlower (wc);
else if (iswlower (wc))
@@ -809,7 +825,7 @@ _rl_vi_change_mbchar_case (count)
rl_vi_check ();
}
else
- rl_forward_char (1, 0);
+ rl_forward_char (1, 0);
}
return 0;
@@ -856,7 +872,7 @@ rl_vi_change_case (count, ignore)
_rl_insert_char (1, c);
rl_end_undo_group ();
rl_vi_check ();
- }
+ }
else
rl_forward_char (1, c);
}
@@ -894,7 +910,7 @@ rl_vi_check ()
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
else
- rl_point--;
+ rl_point--;
}
return (0);
}
@@ -910,59 +926,106 @@ rl_vi_column (count, key)
return (0);
}
-int
-rl_vi_domove (key, nextkey)
- int key, *nextkey;
+/* Process C as part of the current numeric argument. Return -1 if the
+ argument should be aborted, 0 if we should not read any more chars, and
+ 1 if we should continue to read chars. */
+static int
+_rl_vi_arg_dispatch (c)
+ int c;
{
- int c, save;
- int old_end;
-
- rl_mark = rl_point;
- RL_SETSTATE(RL_STATE_MOREINPUT);
- c = rl_read_key ();
- RL_UNSETSTATE(RL_STATE_MOREINPUT);
+ int key;
- if (c < 0)
+ key = c;
+ if (c >= 0 && _rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
{
- *nextkey = 0;
- return -1;
+ rl_numeric_arg *= 4;
+ return 1;
}
- *nextkey = c;
+ c = UNMETA (c);
- if (!member (c, vi_motion))
+ if (_rl_digit_p (c))
{
- if (_rl_digit_p (c))
- {
- save = rl_numeric_arg;
- rl_numeric_arg = _rl_digit_value (c);
- rl_explicit_arg = 1;
- RL_SETSTATE (RL_STATE_NUMERICARG|RL_STATE_VIMOTION);
- rl_digit_loop1 ();
- RL_UNSETSTATE (RL_STATE_VIMOTION);
- rl_numeric_arg *= save;
- RL_SETSTATE(RL_STATE_MOREINPUT);
- c = rl_read_key (); /* real command */
- RL_UNSETSTATE(RL_STATE_MOREINPUT);
- if (c < 0)
- {
- *nextkey = 0;
- return -1;
- }
- *nextkey = c;
- }
- else if (key == c && (key == 'd' || key == 'y' || key == 'c'))
- {
- rl_mark = rl_end;
- rl_beg_of_line (1, c);
- _rl_vi_last_motion = c;
- return (0);
- }
+ if (rl_explicit_arg)
+ rl_numeric_arg = (rl_numeric_arg * 10) + _rl_digit_value (c);
else
- return (-1);
+ rl_numeric_arg = _rl_digit_value (c);
+ rl_explicit_arg = 1;
+ return 1; /* keep going */
+ }
+ else
+ {
+ rl_clear_message ();
+ rl_stuff_char (key);
+ return 0; /* done */
+ }
+}
+
+/* A simplified loop for vi. Don't dispatch key at end.
+ Don't recognize minus sign?
+ Should this do rl_save_prompt/rl_restore_prompt? */
+static int
+rl_digit_loop1 ()
+{
+ int c, r;
+
+ while (1)
+ {
+ if (_rl_arg_overflow ())
+ return 1;
+
+ c = _rl_arg_getchar ();
+
+ r = _rl_vi_arg_dispatch (c);
+ if (r <= 0)
+ break;
}
- _rl_vi_last_motion = c;
+ RL_UNSETSTATE(RL_STATE_NUMERICARG);
+ return (0);
+}
+
+static void
+_rl_mvcxt_init (m, op, key)
+ _rl_vimotion_cxt *m;
+ int op, key;
+{
+ m->op = op;
+ m->state = m->flags = 0;
+ m->ncxt = 0;
+ m->numeric_arg = -1;
+ m->start = rl_point;
+ m->end = rl_end;
+ m->key = key;
+ m->motion = -1;
+}
+
+static _rl_vimotion_cxt *
+_rl_mvcxt_alloc (op, key)
+ int op, key;
+{
+ _rl_vimotion_cxt *m;
+
+ m = xmalloc (sizeof (_rl_vimotion_cxt));
+ _rl_mvcxt_init (m, op, key);
+ return m;
+}
+
+static void
+_rl_mvcxt_dispose (m)
+ _rl_vimotion_cxt *m;
+{
+ xfree (m);
+}
+
+static int
+rl_domove_motion_callback (m)
+ _rl_vimotion_cxt *m;
+{
+ int c, save, r;
+ int old_end;
+
+ _rl_vi_last_motion = c = m->motion;
/* Append a blank character temporarily so that the motion routines
work right at the end of the line. */
@@ -991,7 +1054,7 @@ rl_vi_domove (key, nextkey)
/* If cw or cW, back up to the end of a word, so the behaviour of ce
or cE is the actual result. Brute-force, no subtlety. */
- if (key == 'c' && rl_point >= rl_mark && (_rl_to_upper (c) == 'W'))
+ if (m->key == 'c' && rl_point >= rl_mark && (_rl_to_upper (c) == 'W'))
{
/* Don't move farther back than where we started. */
while (rl_point > rl_mark && whitespace (rl_line_buffer[rl_point]))
@@ -1000,7 +1063,7 @@ rl_vi_domove (key, nextkey)
/* Posix.2 says that if cw or cW moves the cursor towards the end of
the line, the character under the cursor should be deleted. */
if (rl_point == rl_mark)
- rl_point++;
+ rl_point++;
else
{
/* Move past the end of the word so that the kill doesn't
@@ -1014,90 +1077,141 @@ rl_vi_domove (key, nextkey)
if (rl_mark < rl_point)
SWAP (rl_point, rl_mark);
- return (0);
+#if defined (READLINE_CALLBACKS)
+ if (RL_ISSTATE (RL_STATE_CALLBACK))
+ (*rl_redisplay_function)(); /* make sure motion is displayed */
+#endif
+
+ r = vidomove_dispatch (m);
+
+ return (r);
}
-/* Process C as part of the current numeric argument. Return -1 if the
- argument should be aborted, 0 if we should not read any more chars, and
- 1 if we should continue to read chars. */
+#define RL_VIMOVENUMARG() (RL_ISSTATE (RL_STATE_VIMOTION) && RL_ISSTATE (RL_STATE_NUMERICARG))
+
static int
-_rl_vi_arg_dispatch (c)
- int c;
+rl_domove_read_callback (m)
+ _rl_vimotion_cxt *m;
{
- int key;
+ int c, save;
- key = c;
- if (c >= 0 && _rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
+ c = m->motion;
+
+ if (member (c, vi_motion))
{
- rl_numeric_arg *= 4;
- return 1;
+#if defined (READLINE_CALLBACKS)
+ /* If we just read a vi-mode motion command numeric argument, turn off
+ the `reading numeric arg' state */
+ if (RL_ISSTATE (RL_STATE_CALLBACK) && RL_VIMOVENUMARG())
+ RL_UNSETSTATE (RL_STATE_NUMERICARG);
+#endif
+ /* Should do everything, including turning off RL_STATE_VIMOTION */
+ return (rl_domove_motion_callback (m));
}
-
- c = UNMETA (c);
-
- if (_rl_digit_p (c))
+ else if (m->key == c && (m->key == 'd' || m->key == 'y' || m->key == 'c'))
{
- if (rl_explicit_arg)
- rl_numeric_arg = (rl_numeric_arg * 10) + _rl_digit_value (c);
- else
- rl_numeric_arg = _rl_digit_value (c);
+ rl_mark = rl_end;
+ rl_beg_of_line (1, c);
+ _rl_vi_last_motion = c;
+ RL_UNSETSTATE (RL_STATE_VIMOTION);
+ return (0);
+ }
+#if defined (READLINE_CALLBACKS)
+ /* XXX - these need to handle rl_universal_argument bindings */
+ /* Reading vi motion char continuing numeric argument */
+ else if (_rl_digit_p (c) && RL_ISSTATE (RL_STATE_CALLBACK) && RL_VIMOVENUMARG())
+ {
+ return (_rl_vi_arg_dispatch (c));
+ }
+ /* Readine vi motion char starting numeric argument */
+ else if (_rl_digit_p (c) && RL_ISSTATE (RL_STATE_CALLBACK) && RL_ISSTATE (RL_STATE_VIMOTION) && (RL_ISSTATE (RL_STATE_NUMERICARG) == 0))
+ {
+ RL_SETSTATE (RL_STATE_NUMERICARG);
+ return (_rl_vi_arg_dispatch (c));
+ }
+#endif
+ else if (_rl_digit_p (c))
+ {
+ /* This code path taken when not in callback mode */
+ save = rl_numeric_arg;
+ rl_numeric_arg = _rl_digit_value (c);
rl_explicit_arg = 1;
- return 1;
+ RL_SETSTATE (RL_STATE_NUMERICARG);
+ rl_digit_loop1 ();
+ rl_numeric_arg *= save;
+ c = rl_vi_domove_getchar (m);
+ if (c < 0)
+ {
+ m->motion = 0;
+ return -1;
+ }
+ m->motion = c;
+ return (rl_domove_motion_callback (m));
}
else
{
- rl_clear_message ();
- rl_stuff_char (key);
- return 0;
+ RL_UNSETSTATE (RL_STATE_VIMOTION);
+ RL_UNSETSTATE (RL_STATE_NUMERICARG);
+ return (1);
}
}
-/* A simplified loop for vi. Don't dispatch key at end.
- Don't recognize minus sign?
- Should this do rl_save_prompt/rl_restore_prompt? */
static int
-rl_digit_loop1 ()
+rl_vi_domove_getchar (m)
+ _rl_vimotion_cxt *m;
{
- int c, r;
+ int c;
- while (1)
- {
- if (_rl_arg_overflow ())
- return 1;
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ c = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
- c = _rl_arg_getchar ();
+ return c;
+}
- r = _rl_vi_arg_dispatch (c);
- if (r <= 0)
- break;
- }
+#if defined (READLINE_CALLBACKS)
+int
+_rl_vi_domove_callback (m)
+ _rl_vimotion_cxt *m;
+{
+ int c, r;
- RL_UNSETSTATE(RL_STATE_NUMERICARG);
- return (0);
+ m->motion = c = rl_vi_domove_getchar (m);
+ /* XXX - what to do if this returns -1? Should we return 1 for eof to
+ callback code? */
+ r = rl_domove_read_callback (m);
+
+ return ((r == 0) ? r : 1); /* normalize return values */
}
+#endif
+/* This code path taken when not in callback mode. */
int
-rl_vi_delete_to (count, key)
- int count, key;
+rl_vi_domove (x, ignore)
+ int x, *ignore;
{
- int c, start_pos;
-
- if (_rl_uppercase_p (key))
- rl_stuff_char ('$');
- else if (vi_redoing)
- rl_stuff_char (_rl_vi_last_motion);
+ int r;
+ _rl_vimotion_cxt *m;
- start_pos = rl_point;
+ m = _rl_vimvcxt;
+ *ignore = m->motion = rl_vi_domove_getchar (m);
- if (rl_vi_domove (key, &c))
+ if (m->motion < 0)
{
- rl_ding ();
+ m->motion = 0;
return -1;
}
+ return (rl_domove_read_callback (m));
+}
+
+static int
+vi_delete_dispatch (m)
+ _rl_vimotion_cxt *m;
+{
/* These are the motion commands that do not require adjusting the
mark. */
- if (((strchr (" l|h^0bBFT`", c) == 0) && (rl_point >= start_pos)) &&
+ if (((strchr (" l|h^0bBFT`", m->motion) == 0) && (rl_point >= m->start)) &&
(rl_mark < rl_end))
rl_mark++;
@@ -1106,34 +1220,61 @@ rl_vi_delete_to (count, key)
}
int
-rl_vi_change_to (count, key)
+rl_vi_delete_to (count, key)
int count, key;
{
- int c, start_pos;
+ int c, r;
+ _rl_vimvcxt = _rl_mvcxt_alloc (VIM_DELETE, key);
+ _rl_vimvcxt->start = rl_point;
+
+ rl_mark = rl_point;
if (_rl_uppercase_p (key))
- rl_stuff_char ('$');
+ {
+ _rl_vimvcxt->motion = '$';
+ r = rl_domove_motion_callback (_rl_vimvcxt);
+ }
else if (vi_redoing)
- rl_stuff_char (_rl_vi_last_motion);
-
- start_pos = rl_point;
+ {
+ _rl_vimvcxt->motion = _rl_vi_last_motion;
+ r = rl_domove_motion_callback (_rl_vimvcxt);
+ }
+#if defined (READLINE_CALLBACKS)
+ else if (RL_ISSTATE (RL_STATE_CALLBACK))
+ {
+ RL_SETSTATE (RL_STATE_VIMOTION);
+ return (0);
+ }
+#endif
+ else
+ r = rl_vi_domove (key, &c);
- if (rl_vi_domove (key, &c))
+ if (r < 0)
{
rl_ding ();
- return -1;
+ r = -1;
}
+ _rl_mvcxt_dispose (_rl_vimvcxt);
+ _rl_vimvcxt = 0;
+
+ return r;
+}
+
+static int
+vi_change_dispatch (m)
+ _rl_vimotion_cxt *m;
+{
/* These are the motion commands that do not require adjusting the
mark. c[wW] are handled by special-case code in rl_vi_domove(),
and already leave the mark at the correct location. */
- if (((strchr (" l|hwW^0bBFT`", c) == 0) && (rl_point >= start_pos)) &&
+ if (((strchr (" l|hwW^0bBFT`", m->motion) == 0) && (rl_point >= m->start)) &&
(rl_mark < rl_end))
rl_mark++;
/* The cursor never moves with c[wW]. */
- if ((_rl_to_upper (c) == 'W') && rl_point < start_pos)
- rl_point = start_pos;
+ if ((_rl_to_upper (m->motion) == 'W') && rl_point < m->start)
+ rl_point = m->start;
if (vi_redoing)
{
@@ -1151,34 +1292,64 @@ rl_vi_change_to (count, key)
rl_begin_undo_group (); /* to make the `u' command work */
rl_kill_text (rl_point, rl_mark);
/* `C' does not save the text inserted for undoing or redoing. */
- if (_rl_uppercase_p (key) == 0)
- _rl_vi_doing_insert = 1;
- rl_vi_start_inserting (key, rl_numeric_arg, rl_arg_sign);
+ if (_rl_uppercase_p (m->key) == 0)
+ _rl_vi_doing_insert = 1;
+ /* XXX -- TODO -- use m->numericarg? */
+ rl_vi_start_inserting (m->key, rl_numeric_arg, rl_arg_sign);
}
return (0);
}
int
-rl_vi_yank_to (count, key)
+rl_vi_change_to (count, key)
int count, key;
{
- int c, start_pos;
+ int c, r;
- if (_rl_uppercase_p (key))
- rl_stuff_char ('$');
+ _rl_vimvcxt = _rl_mvcxt_alloc (VIM_CHANGE, key);
+ _rl_vimvcxt->start = rl_point;
- start_pos = rl_point;
+ rl_mark = rl_point;
+ if (_rl_uppercase_p (key))
+ {
+ _rl_vimvcxt->motion = '$';
+ r = rl_domove_motion_callback (_rl_vimvcxt);
+ }
+ else if (vi_redoing)
+ {
+ _rl_vimvcxt->motion = _rl_vi_last_motion;
+ r = rl_domove_motion_callback (_rl_vimvcxt);
+ }
+#if defined (READLINE_CALLBACKS)
+ else if (RL_ISSTATE (RL_STATE_CALLBACK))
+ {
+ RL_SETSTATE (RL_STATE_VIMOTION);
+ return (0);
+ }
+#endif
+ else
+ r = rl_vi_domove (key, &c);
- if (rl_vi_domove (key, &c))
+ if (r < 0)
{
rl_ding ();
- return -1;
+ r = -1; /* normalize return value */
}
+ _rl_mvcxt_dispose (_rl_vimvcxt);
+ _rl_vimvcxt = 0;
+
+ return r;
+}
+
+static int
+vi_yank_dispatch (m)
+ _rl_vimotion_cxt *m;
+{
/* These are the motion commands that do not require adjusting the
mark. */
- if (((strchr (" l|h^0%bBFT`", c) == 0) && (rl_point >= start_pos)) &&
+ if (((strchr (" l|h^0%bBFT`", m->motion) == 0) && (rl_point >= m->start)) &&
(rl_mark < rl_end))
rl_mark++;
@@ -1186,12 +1357,76 @@ rl_vi_yank_to (count, key)
rl_kill_text (rl_point, rl_mark);
rl_end_undo_group ();
rl_do_undo ();
- rl_point = start_pos;
+ rl_point = m->start;
return (0);
}
int
+rl_vi_yank_to (count, key)
+ int count, key;
+{
+ int c, r;
+
+ _rl_vimvcxt = _rl_mvcxt_alloc (VIM_YANK, key);
+ _rl_vimvcxt->start = rl_point;
+
+ rl_mark = rl_point;
+ if (_rl_uppercase_p (key))
+ {
+ _rl_vimvcxt->motion = '$';
+ r = rl_domove_motion_callback (_rl_vimvcxt);
+ }
+#if defined (READLINE_CALLBACKS)
+ else if (RL_ISSTATE (RL_STATE_CALLBACK))
+ {
+ RL_SETSTATE (RL_STATE_VIMOTION);
+ return (0);
+ }
+#endif
+ else
+ r = rl_vi_domove (key, &c);
+
+ if (r < 0)
+ {
+ rl_ding ();
+ r = -1;
+ }
+
+ _rl_mvcxt_dispose (_rl_vimvcxt);
+ _rl_vimvcxt = 0;
+
+ return r;
+}
+
+static int
+vidomove_dispatch (m)
+ _rl_vimotion_cxt *m;
+{
+ int r;
+
+ switch (m->op)
+ {
+ case VIM_DELETE:
+ r = vi_delete_dispatch (m);
+ break;
+ case VIM_CHANGE:
+ r = vi_change_dispatch (m);
+ break;
+ case VIM_YANK:
+ r = vi_yank_dispatch (m);
+ break;
+ default:
+ _rl_errmsg ("vidomove_dispatch: unknown operator %d", m->op);
+ r = 1;
+ break;
+ }
+
+ RL_UNSETSTATE (RL_STATE_VIMOTION);
+ return r;
+}
+
+int
rl_vi_rubout (count, key)
int count, key;
{
@@ -1317,27 +1552,38 @@ rl_vi_char_search (count, key)
#endif
if (key == ';' || key == ',')
- _rl_cs_dir = (key == ';') ? _rl_cs_orig_dir : -_rl_cs_orig_dir;
+ {
+ if (_rl_cs_orig_dir == 0)
+ return -1;
+#if defined (HANDLE_MULTIBYTE)
+ if (_rl_vi_last_search_mblen == 0)
+ return -1;
+#else
+ if (_rl_vi_last_search_char == 0)
+ return -1;
+#endif
+ _rl_cs_dir = (key == ';') ? _rl_cs_orig_dir : -_rl_cs_orig_dir;
+ }
else
{
switch (key)
- {
- case 't':
- _rl_cs_orig_dir = _rl_cs_dir = FTO;
- break;
+ {
+ case 't':
+ _rl_cs_orig_dir = _rl_cs_dir = FTO;
+ break;
- case 'T':
- _rl_cs_orig_dir = _rl_cs_dir = BTO;
- break;
+ case 'T':
+ _rl_cs_orig_dir = _rl_cs_dir = BTO;
+ break;
- case 'f':
- _rl_cs_orig_dir = _rl_cs_dir = FFIND;
- break;
+ case 'f':
+ _rl_cs_orig_dir = _rl_cs_dir = FFIND;
+ break;
- case 'F':
- _rl_cs_orig_dir = _rl_cs_dir = BFIND;
- break;
- }
+ case 'F':
+ _rl_cs_orig_dir = _rl_cs_dir = BFIND;
+ break;
+ }
if (vi_redoing)
{
@@ -1345,12 +1591,12 @@ rl_vi_char_search (count, key)
}
#if defined (READLINE_CALLBACKS)
else if (RL_ISSTATE (RL_STATE_CALLBACK))
- {
- _rl_callback_data = _rl_callback_data_alloc (count);
- _rl_callback_data->i1 = _rl_cs_dir;
- _rl_callback_func = _rl_vi_callback_char_search;
- return (0);
- }
+ {
+ _rl_callback_data = _rl_callback_data_alloc (count);
+ _rl_callback_data->i1 = _rl_cs_dir;
+ _rl_callback_func = _rl_vi_callback_char_search;
+ return (0);
+ }
#endif
else
{
@@ -1401,7 +1647,7 @@ rl_vi_match (ignore, key)
pre = rl_point;
rl_forward_char (1, key);
if (pre == rl_point)
- break;
+ break;
}
}
else
@@ -1430,7 +1676,7 @@ rl_vi_match (ignore, key)
{
pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
if (tmp == pos)
- pos--;
+ pos--;
}
if (pos >= 0)
{
@@ -1678,8 +1924,8 @@ rl_vi_replace (count, key)
vi_replace_map[NEWLINE].function = rl_newline;
/* If the normal vi insertion keymap has ^H bound to erase, do the
- same here. Probably should remove the assignment to RUBOUT up
- there, but I don't think it will make a difference in real life. */
+ same here. Probably should remove the assignment to RUBOUT up
+ there, but I don't think it will make a difference in real life. */
if (vi_insertion_keymap[CTRL ('H')].type == ISFUNC &&
vi_insertion_keymap[CTRL ('H')].function == rl_rubout)
vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete;
diff --git a/lib/readline/xfree.c b/lib/readline/xfree.c
new file mode 100644
index 0000000..37a81e6
--- /dev/null
+++ b/lib/readline/xfree.c
@@ -0,0 +1,50 @@
+/* xfree.c -- safe version of free that ignores attempts to free NUL */
+
+/* Copyright (C) 1991-2010 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library (Readline), a library
+ for reading lines of text with interactive input and history editing.
+
+ Readline is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Readline is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Readline. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#define READLINE_LIBRARY
+
+#if defined (HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#include "xmalloc.h"
+
+/* **************************************************************** */
+/* */
+/* Memory Deallocation. */
+/* */
+/* **************************************************************** */
+
+/* Use this as the function to call when adding unwind protects so we
+ don't need to know what free() returns. */
+void
+xfree (string)
+ PTR_T string;
+{
+ if (string)
+ free (string);
+}
diff --git a/lib/readline/xmalloc.c b/lib/readline/xmalloc.c
index 97d8f2e..c77d763 100644
--- a/lib/readline/xmalloc.c
+++ b/lib/readline/xmalloc.c
@@ -77,13 +77,3 @@ xrealloc (pointer, bytes)
memory_error_and_abort ("xrealloc");
return (temp);
}
-
-/* Use this as the function to call when adding unwind protects so we
- don't need to know what free() returns. */
-void
-xfree (string)
- PTR_T string;
-{
- if (string)
- free (string);
-}
diff --git a/lib/sh/Android.mk b/lib/sh/Android.mk
index 78344df..197b34f 100644
--- a/lib/sh/Android.mk
+++ b/lib/sh/Android.mk
@@ -13,7 +13,8 @@ LOCAL_SRC_FILES:= \
strtrans.c snprintf.c mailstat.c fmtulong.c \
fmtullong.c fmtumax.c zcatfd.c zmapfd.c winsize.c wcsdup.c \
fpurge.c zgetline.c mbscmp.c uconvert.c ufuncs.c casemod.c \
- fdprintf.c input_avail.c mbscasecmp.c fnxform.c mbschr.c
+ fdprintf.c input_avail.c mbscasecmp.c fnxform.c mbschr.c \
+ shmbchar.c unicode.c
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/../.. \
diff --git a/lib/sh/Makefile.in b/lib/sh/Makefile.in
index 80f6cc5..d97cd99 100644
--- a/lib/sh/Makefile.in
+++ b/lib/sh/Makefile.in
@@ -2,7 +2,7 @@
# Makefile for the Bash library
#
#
-# Copyright (C) 1998-2009 Free Software Foundation, Inc.
+# Copyright (C) 1998-2010 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -91,7 +91,8 @@ CSOURCES = clktck.c clock.c getcwd.c getenv.c oslib.c setlinebuf.c \
strtoll.c strtoull.c strtoimax.c strtoumax.c memset.c strstr.c \
mktime.c strftime.c mbschr.c zcatfd.c zmapfd.c winsize.c eaccess.c \
wcsdup.c fpurge.c zgetline.c mbscmp.c uconvert.c ufuncs.c \
- casemod.c fdprintf.c input_avail.c mbscasecmp.c fnxform.c
+ casemod.c dprintf.c input_avail.c mbscasecmp.c fnxform.c \
+ strchrnul.c unicode.c wcswidth.c shmbchar.c
# The header files for this library.
HSOURCES =
@@ -105,7 +106,7 @@ OBJECTS = clktck.o clock.o getenv.o oslib.o setlinebuf.o strnlen.o \
strtrans.o snprintf.o mailstat.o fmtulong.o \
fmtullong.o fmtumax.o zcatfd.o zmapfd.o winsize.o wcsdup.o \
fpurge.o zgetline.o mbscmp.o uconvert.o ufuncs.o casemod.o \
- fdprintf.o input_avail.o mbscasecmp.o fnxform.o ${LIBOBJS}
+ input_avail.o mbscasecmp.o fnxform.o unicode.o shmbchar.o ${LIBOBJS}
SUPPORT = Makefile
@@ -144,7 +145,7 @@ casemod.o: casemod.c
clktck.o: clktck.c
clock.o: clock.c
eaccess.o: eaccess.c
-fdprintf.o: fdprintf.c
+dprintf.o: dprintf.c
fmtullong.o: fmtullong.c
fmtulong.o: fmtulong.c
fmtumax.o: fmtumax.c
@@ -168,6 +169,7 @@ pathcanon.o: pathcanon.c
pathphys.o: pathphys.c
rename.o: rename.c
setlinebuf.o: setlinebuf.c
+shmbchar.o: shmbchar.c
shquote.o: shquote.c
shtty.o: shtty.c
snprintf.o: snprintf.c
@@ -195,6 +197,7 @@ uconvert.o: uconvert.c
ufuncs.o: ufuncs.c
vprint.o: vprint.c
wcsdup.o: wcsdup.c
+wcswidth.o: wcswidth.c
mbschr.o: mbschr.c
zcatfd.o: zcatfd.c
zmapfd.o: zmapfd.c
@@ -214,7 +217,7 @@ casemod.o: ${BUILD_DIR}/config.h
clktck.o: ${BUILD_DIR}/config.h
clock.o: ${BUILD_DIR}/config.h
eaccess.o: ${BUILD_DIR}/config.h
-fdprintf.o: ${BUILD_DIR}/config.h
+dprintf.o: ${BUILD_DIR}/config.h
fmtullong.o: ${BUILD_DIR}/config.h
fmtulong.o: ${BUILD_DIR}/config.h
fmtumax.o: ${BUILD_DIR}/config.h
@@ -238,6 +241,7 @@ pathcanon.o: ${BUILD_DIR}/config.h
pathphys.o: ${BUILD_DIR}/config.h
rename.o: ${BUILD_DIR}/config.h
setlinebuf.o: ${BUILD_DIR}/config.h
+shmbchare.o: ${BUILD_DIR}/config.h
shquote.o: ${BUILD_DIR}/config.h
shtty.o: ${BUILD_DIR}/config.h
snprintf.o: ${BUILD_DIR}/config.h
@@ -265,6 +269,7 @@ uconvert.o: ${BUILD_DIR}/config.h
ufuncs.o: ${BUILD_DIR}/config.h
vprint.o: ${BUILD_DIR}/config.h
wcsdup.o: ${BUILD_DIR}/config.h
+wcswidth.o: ${BUILD_DIR}/config.h
mbschr.o: ${BUILD_DIR}/config.h
zcatfd.o: ${BUILD_DIR}/config.h
zgetline.o: ${BUILD_DIR}/config.h
@@ -505,9 +510,12 @@ wcsdup.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
wcsdup.o: ${BASHINCDIR}/stdc.h
wcsdup.o: ${topdir}/xmalloc.h
+wcswidth.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
+wcswidth.o: ${BASHINCDIR}/stdc.h
+
mbschr.o: ${topdir}/bashansi.h
mbschr.o: ${BASHINCDIR}/ansi_stdlib.h
-mbschr.o: ${BASHINCDIR}/shmbutil.h
+mbschr.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h
zgetline.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
zgetline.o: ${BASHINCDIR}/stdc.h
@@ -526,10 +534,10 @@ casemod.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
casemod.o: ${BASHINCDIR}/stdc.h
casemod.o: ${topdir}/xmalloc.h
casemod.o: ${topdir}/bashtypes.h
-casemod.o: ${BASHINCDIR}/shmbutil.h
+casemod.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h
casemod.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h
-fdprintf.o: ${BASHINCDIR}/stdc.h
+dprintf.o: ${BASHINCDIR}/stdc.h
input_avail.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
input_avail.o: ${BASHINCDIR}/stdc.h
@@ -542,3 +550,5 @@ fnxform.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
fnxform.o: ${BASHINCDIR}/stdc.h
fnxform.o: ${topdir}/bashtypes.h
fnxform.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h
+
+shmbchar.o: ${BASHINCDIR}/shmbchar.h
diff --git a/lib/sh/casemod.c b/lib/sh/casemod.c
index d85549a..3127d8c 100644
--- a/lib/sh/casemod.c
+++ b/lib/sh/casemod.c
@@ -111,6 +111,13 @@ sh_modcase (string, pat, flags)
mbstate_t state;
#endif
+ if (string == 0 || *string == 0)
+ {
+ ret = (char *)xmalloc (1);
+ ret[0] = '\0';
+ return ret;
+ }
+
#if defined (HANDLE_MULTIBYTE)
memset (&state, 0, sizeof (mbstate_t));
#endif
diff --git a/lib/sh/dprintf.c b/lib/sh/dprintf.c
new file mode 100644
index 0000000..b3b5d64
--- /dev/null
+++ b/lib/sh/dprintf.c
@@ -0,0 +1,70 @@
+/* dprintf -- printf to a file descriptor */
+
+/* Copyright (C) 2008-2010 Free Software Foundation, Inc.
+
+ This file is part of GNU Bash, the Bourne Again SHell.
+
+ Bash is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Bash is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Bash. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdc.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
+
+#if defined (PREFER_STDARG)
+# include <stdarg.h>
+#else
+# include <varargs.h>
+#endif
+
+#include <stdio.h>
+
+int
+#if defined (PREFER_STDARG)
+dprintf(int fd, const char *format, ...)
+#else
+dprintf(fd, format, va_alist)
+ int fd;
+ const char *format;
+ va_dcl
+#endif
+{
+ FILE *fp;
+ int fd2, rc, r2;
+ va_list args;
+
+ if ((fd2 = dup(fd)) < 0)
+ return -1;
+ fp = fdopen (fd2, "w");
+ if (fp == 0)
+ {
+ close (fd2);
+ return -1;
+ }
+
+ SH_VA_START (args, format);
+ rc = vfprintf (fp, format, args);
+ fflush (fp);
+ va_end (args);
+
+ r2 = fclose (fp); /* check here */
+
+ return rc;
+}
diff --git a/lib/sh/eaccess.c b/lib/sh/eaccess.c
index 989bc22..d9bca8c 100644
--- a/lib/sh/eaccess.c
+++ b/lib/sh/eaccess.c
@@ -1,6 +1,6 @@
/* eaccess.c - eaccess replacement for the shell, plus other access functions. */
-/* Copyright (C) 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2006-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -198,11 +198,20 @@ sh_eaccess (path, mode)
char *path;
int mode;
{
+ int ret;
+
if (path_is_devfd (path))
return (sh_stataccess (path, mode));
-#if defined (HAVE_EACCESS) /* FreeBSD */
- return (eaccess (path, mode));
+#if defined (HAVE_FACCESSAT) && defined (AT_EACCESS)
+ return (faccessat (AT_FDCWD, path, mode, AT_EACCESS));
+#elif defined (HAVE_EACCESS) /* FreeBSD */
+ ret = eaccess (path, mode); /* XXX -- not always correct for X_OK */
+# if defined (__FreeBSD__)
+ if (ret == 0 && current_user.euid == 0 && mode == X_OK)
+ return (sh_stataccess (path, mode));
+# endif
+ return ret;
#elif defined (EFF_ONLY_OK) /* SVR4(?), SVR4.2 */
return access (path, mode|EFF_ONLY_OK);
#else
@@ -215,7 +224,15 @@ sh_eaccess (path, mode)
# endif
if (current_user.uid == current_user.euid && current_user.gid == current_user.egid)
- return (access (path, mode));
+ {
+ ret = access (path, mode);
+#if defined (__FreeBSD__) || defined (SOLARIS)
+ if (ret == 0 && current_user.euid == 0 && mode == X_OK)
+ return (sh_stataccess (path, mode));
+#endif
+ return ret;
+
+ }
return (sh_stataccess (path, mode));
#endif
diff --git a/lib/sh/fnxform.c b/lib/sh/fnxform.c
index d95274f..d7e1b5a 100644
--- a/lib/sh/fnxform.c
+++ b/lib/sh/fnxform.c
@@ -1,6 +1,6 @@
/* fnxform - use iconv(3) to transform strings to and from "filename" format */
-/* Copyright (C) 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2009-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -72,7 +72,7 @@ curencoding ()
mod = strchr (dot, '@');
if (mod)
*mod = '\0';
- return dot;
+ return ++dot;
#endif
}
diff --git a/lib/sh/fpurge.c b/lib/sh/fpurge.c
index f9e1b9d..13e8c78 100644
--- a/lib/sh/fpurge.c
+++ b/lib/sh/fpurge.c
@@ -1,6 +1,6 @@
/* fpurge - Flushing buffers of a FILE stream. */
-/* Copyright (C) 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -36,6 +36,90 @@ extern int fpurge __P((FILE *stream));
#endif
#include <stdlib.h>
+/* Inline contents of gnulib:stdio-impl.h */
+
+/* Many stdio implementations have the same logic and therefore can share
+ the same implementation of stdio extension API, except that some fields
+ have different naming conventions, or their access requires some casts. */
+
+/* BSD stdio derived implementations. */
+
+#if defined __NetBSD__ /* NetBSD */
+/* Get __NetBSD_Version__. */
+# include <sys/param.h>
+#endif
+
+#if defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */
+
+# if defined __DragonFly__ /* DragonFly */
+ /* See <http://www.dragonflybsd.org/cvsweb/src/lib/libc/stdio/priv_stdio.h?rev=HEAD&content-type=text/x-cvsweb-markup>. */
+# define fp_ ((struct { struct __FILE_public pub; \
+ struct { unsigned char *_base; int _size; } _bf; \
+ void *cookie; \
+ void *_close; \
+ void *_read; \
+ void *_seek; \
+ void *_write; \
+ struct { unsigned char *_base; int _size; } _ub; \
+ int _ur; \
+ unsigned char _ubuf[3]; \
+ unsigned char _nbuf[1]; \
+ struct { unsigned char *_base; int _size; } _lb; \
+ int _blksize; \
+ fpos_t _offset; \
+ /* More fields, not relevant here. */ \
+ } *) fp)
+ /* See <http://www.dragonflybsd.org/cvsweb/src/include/stdio.h?rev=HEAD&content-type=text/x-cvsweb-markup>. */
+# define _p pub._p
+# define _flags pub._flags
+# define _r pub._r
+# define _w pub._w
+# else
+# define fp_ fp
+# endif
+
+# if (defined __NetBSD__ && __NetBSD_Version__ >= 105270000) || defined __OpenBSD__ /* NetBSD >= 1.5ZA, OpenBSD */
+ /* See <http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup>
+ and <http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup> */
+ struct __sfileext
+ {
+ struct __sbuf _ub; /* ungetc buffer */
+ /* More fields, not relevant here. */
+ };
+# define fp_ub ((struct __sfileext *) fp->_ext._base)->_ub
+# else /* FreeBSD, NetBSD <= 1.5Z, DragonFly, MacOS X, Cygwin */
+# define fp_ub fp_->_ub
+# endif
+
+# define HASUB(fp) (fp_ub._base != NULL)
+
+#endif
+
+/* SystemV derived implementations. */
+
+#if defined _IOERR
+
+# if defined __sun && defined _LP64 /* Solaris/{SPARC,AMD64} 64-bit */
+# define fp_ ((struct { unsigned char *_ptr; \
+ unsigned char *_base; \
+ unsigned char *_end; \
+ long _cnt; \
+ int _file; \
+ unsigned int _flag; \
+ } *) fp)
+# else
+# define fp_ fp
+# endif
+
+# if defined _SCO_DS /* OpenServer */
+# define _cnt __cnt
+# define _ptr __ptr
+# define _base __base
+# define _flag __flag
+# endif
+
+#endif
+
int
fpurge (FILE *fp)
{
@@ -45,7 +129,7 @@ fpurge (FILE *fp)
/* The __fpurge function does not have a return value. */
return 0;
-#elif HAVE_FPURGE /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X */
+#elif HAVE_FPURGE /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin 1.7 */
/* Call the system's fpurge function. */
# undef fpurge
@@ -59,10 +143,10 @@ fpurge (FILE *fp)
<stdio.h> on BSD systems says:
"The following always hold: if _flags & __SRD, _w is 0."
If this invariant is not fulfilled and the stream is read-write but
- currently writing, subsequent putc or fputc calls will write directly
+ currently reading, subsequent putc or fputc calls will write directly
into the buffer, although they shouldn't be allowed to. */
- if ((fp->_flags & __SRD) != 0)
- fp->_w = 0;
+ if ((fp_->_flags & __SRD) != 0)
+ fp_->_w = 0;
# endif
return result;
@@ -101,7 +185,7 @@ fpurge (FILE *fp)
fp->_wcount = 0;
fp->_ungetc_count = 0;
return 0;
-# elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw */
+# elif defined _IOERR || defined __TANDEM /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw */
fp->_ptr = fp->_base;
if (fp->_ptr != NULL)
fp->_cnt = 0;
diff --git a/lib/sh/oslib.c b/lib/sh/oslib.c
index d47f9dc..b3470d1 100644
--- a/lib/sh/oslib.c
+++ b/lib/sh/oslib.c
@@ -1,6 +1,6 @@
/* oslib.c - functions present only in some unix versions. */
-/* Copyright (C) 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1995,2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -37,6 +37,10 @@
#include <filecntl.h>
#include <bashansi.h>
+#if !defined (HAVE_KILLPG)
+# include <signal.h>
+#endif
+
#include <stdio.h>
#include <errno.h>
#include <chartypes.h>
@@ -209,7 +213,8 @@ gethostname (name, namelen)
# else /* !HAVE_UNAME */
int
gethostname (name, namelen)
- int name, namelen;
+ char *name;
+ int namelen;
{
strncpy (name, "unknown", namelen);
name[namelen] = '\0';
diff --git a/lib/sh/shmatch.c b/lib/sh/shmatch.c
index 6de1dc1..3abefed 100644
--- a/lib/sh/shmatch.c
+++ b/lib/sh/shmatch.c
@@ -62,7 +62,7 @@ sh_regmatch (string, pattern, flags)
#if defined (ARRAY_VARS)
rematch = (SHELL_VAR *)NULL;
#endif
-
+
rflags = REG_EXTENDED;
if (glob_ignore_case || match_ignore_case)
rflags |= REG_ICASE;
diff --git a/lib/sh/shmbchar.c b/lib/sh/shmbchar.c
new file mode 100644
index 0000000..c5badc1
--- /dev/null
+++ b/lib/sh/shmbchar.c
@@ -0,0 +1,92 @@
+/* Copyright (C) 2001, 2006, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+
+#include <config.h>
+
+#if defined (HANDLE_MULTIBYTE)
+#include <stdlib.h>
+#include <limits.h>
+
+#include <shmbutil.h>
+#include <shmbchar.h>
+
+#if IS_BASIC_ASCII
+
+/* Bit table of characters in the ISO C "basic character set". */
+const unsigned int is_basic_table [UCHAR_MAX / 32 + 1] =
+{
+ 0x00001a00, /* '\t' '\v' '\f' */
+ 0xffffffef, /* ' '...'#' '%'...'?' */
+ 0xfffffffe, /* 'A'...'Z' '[' '\\' ']' '^' '_' */
+ 0x7ffffffe /* 'a'...'z' '{' '|' '}' '~' */
+ /* The remaining bits are 0. */
+};
+
+#endif /* IS_BASIC_ASCII */
+
+size_t
+mbstrlen (s)
+ const char *s;
+{
+ size_t clen, nc;
+ mbstate_t mbs = { 0 }, mbsbak = { 0 };
+ int f;
+
+ nc = 0;
+ while (*s && (clen = (f = is_basic (*s)) ? 1 : mbrlen(s, MB_CUR_MAX, &mbs)) != 0)
+ {
+ if (MB_INVALIDCH(clen))
+ {
+ clen = 1; /* assume single byte */
+ mbs = mbsbak;
+ }
+
+ if (f == 0)
+ mbsbak = mbs;
+
+ s += clen;
+ nc++;
+ }
+ return nc;
+}
+
+/* Return pointer to first multibyte char in S, or NULL if none. */
+char *
+mbsmbchar (s)
+ const char *s;
+{
+ char *t;
+ size_t clen;
+ mbstate_t mbs = { 0 };
+
+ for (t = (char *)s; *t; t++)
+ {
+ if (is_basic (*t))
+ continue;
+
+ clen = mbrlen (t, MB_CUR_MAX, &mbs);
+
+ if (clen == 0)
+ return 0;
+ if (MB_INVALIDCH(clen))
+ continue;
+
+ if (clen > 1)
+ return t;
+ }
+ return 0;
+}
+#endif
diff --git a/lib/sh/shquote.c b/lib/sh/shquote.c
index a267d38..a1e9146 100644
--- a/lib/sh/shquote.c
+++ b/lib/sh/shquote.c
@@ -42,10 +42,11 @@
Used by alias and trap, among others. */
char *
sh_single_quote (string)
- char *string;
+ const char *string;
{
register int c;
- char *result, *r, *s;
+ char *result, *r;
+ const char *s;
result = (char *)xmalloc (3 + (4 * strlen (string)));
r = result;
@@ -72,10 +73,11 @@ sh_single_quote (string)
/* Quote STRING using double quotes. Return a new string. */
char *
sh_double_quote (string)
- char *string;
+ const char *string;
{
register unsigned char c;
- char *result, *r, *s;
+ char *result, *r;
+ const char *s;
result = (char *)xmalloc (3 + (2 * strlen (string)));
r = result;
diff --git a/lib/sh/snprintf.c b/lib/sh/snprintf.c
index d681b16..d46b2d9 100644
--- a/lib/sh/snprintf.c
+++ b/lib/sh/snprintf.c
@@ -9,7 +9,7 @@
Unix snprintf implementation.
derived from inetutils/libinetutils/snprintf.c Version 1.1
- Copyright (C) 2001,2006 Free Software Foundation, Inc.
+ Copyright (C) 2001,2006,2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
diff --git a/lib/sh/strchrnul.c b/lib/sh/strchrnul.c
new file mode 100644
index 0000000..2e1608e
--- /dev/null
+++ b/lib/sh/strchrnul.c
@@ -0,0 +1,144 @@
+/* Searching in a string.
+ Copyright (C) 2003, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include <string.h>
+
+ /* On 32-bit hardware, choosing longword to be a 32-bit unsigned
+ long instead of a 64-bit uintmax_t tends to give better
+ performance. On 64-bit hardware, unsigned long is generally 64
+ bits already. Change this typedef to experiment with
+ performance. */
+ typedef unsigned long int longword;
+
+/* Find the first occurrence of C in S or the final NUL byte. */
+char *
+strchrnul (s, c_in)
+ const char *s;
+ int c_in;
+{
+ const unsigned char *char_ptr;
+ const longword *longword_ptr;
+ longword repeated_one;
+ longword repeated_c;
+ unsigned char c;
+
+ c = (unsigned char) c_in;
+ if (c == 0) /* find final null byte */
+ return (char *)(s ? (s + strlen (s)) : s);
+
+ /* Handle the first few bytes by reading one byte at a time.
+ Do this until CHAR_PTR is aligned on a longword boundary. */
+ for (char_ptr = (const unsigned char *) s;
+ (size_t) char_ptr % sizeof (longword) != 0;
+ ++char_ptr)
+ if (!*char_ptr || *char_ptr == c)
+ return (char *) char_ptr;
+
+ longword_ptr = (const longword *) char_ptr;
+
+ /* All these elucidatory comments refer to 4-byte longwords,
+ but the theory applies equally well to any size longwords. */
+
+ /* Compute auxiliary longword values:
+ repeated_one is a value which has a 1 in every byte.
+ repeated_c has c in every byte. */
+ repeated_one = 0x01010101;
+ repeated_c = c | (c << 8);
+ repeated_c |= repeated_c << 16;
+ if (0xffffffffU < (longword) -1)
+ {
+ repeated_one |= repeated_one << 31 << 1;
+ repeated_c |= repeated_c << 31 << 1;
+ if (8 < sizeof (longword))
+ {
+ size_t i;
+
+ for (i = 64; i < sizeof (longword) * 8; i *= 2)
+ {
+ repeated_one |= repeated_one << i;
+ repeated_c |= repeated_c << i;
+ }
+ }
+ }
+
+ /* Instead of the traditional loop which tests each byte, we will
+ test a longword at a time. The tricky part is testing if *any of
+ the four* bytes in the longword in question are equal to NUL or
+ c. We first use an xor with repeated_c. This reduces the task
+ to testing whether *any of the four* bytes in longword1 or
+ longword2 is zero.
+
+ Let's consider longword1. We compute tmp =
+ ((longword1 - repeated_one) & ~longword1) & (repeated_one << 7).
+ That is, we perform the following operations:
+ 1. Subtract repeated_one.
+ 2. & ~longword1.
+ 3. & a mask consisting of 0x80 in every byte.
+ Consider what happens in each byte:
+ - If a byte of longword1 is zero, step 1 and 2 transform it into 0xff,
+ and step 3 transforms it into 0x80. A carry can also be propagated
+ to more significant bytes.
+ - If a byte of longword1 is nonzero, let its lowest 1 bit be at
+ position k (0 <= k <= 7); so the lowest k bits are 0. After step 1,
+ the byte ends in a single bit of value 0 and k bits of value 1.
+ After step 2, the result is just k bits of value 1: 2^k - 1. After
+ step 3, the result is 0. And no carry is produced.
+ So, if longword1 has only non-zero bytes, tmp is zero.
+ Whereas if longword1 has a zero byte, call j the position of the least
+ significant zero byte. Then the result has a zero at positions 0, ...,
+ j-1 and a 0x80 at position j. We cannot predict the result at the more
+ significant bytes (positions j+1..3), but it does not matter since we
+ already have a non-zero bit at position 8*j+7.
+
+ The test whether any byte in longword1 or longword2 is zero is equivalent
+ to testing whether tmp1 is nonzero or tmp2 is nonzero. We can combine
+ this into a single test, whether (tmp1 | tmp2) is nonzero.
+
+ This test can read more than one byte beyond the end of a string,
+ depending on where the terminating NUL is encountered. However,
+ this is considered safe since the initialization phase ensured
+ that the read will be aligned, therefore, the read will not cross
+ page boundaries and will not cause a fault. */
+
+ while (1)
+ {
+ longword longword1 = *longword_ptr ^ repeated_c;
+ longword longword2 = *longword_ptr;
+
+ if (((((longword1 - repeated_one) & ~longword1)
+ | ((longword2 - repeated_one) & ~longword2))
+ & (repeated_one << 7)) != 0)
+ break;
+ longword_ptr++;
+ }
+
+ char_ptr = (const unsigned char *) longword_ptr;
+
+ /* At this point, we know that one of the sizeof (longword) bytes
+ starting at char_ptr is == 0 or == c. On little-endian machines,
+ we could determine the first such byte without any further memory
+ accesses, just by looking at the tmp result from the last loop
+ iteration. But this does not work on big-endian machines.
+ Choose code that works in both cases. */
+
+ char_ptr = (unsigned char *) longword_ptr;
+ while (*char_ptr && (*char_ptr != c))
+ char_ptr++;
+ return (char *) char_ptr;
+}
diff --git a/lib/sh/strftime.c b/lib/sh/strftime.c
index 572baae..aa3fc85 100644
--- a/lib/sh/strftime.c
+++ b/lib/sh/strftime.c
@@ -24,9 +24,6 @@
* It also doesn't worry about multi-byte characters.
* So there.
*
- * This file is also shipped with GAWK (GNU Awk), gawk specific bits of
- * code are included if GAWK is defined.
- *
* Arnold Robbins
* January, February, March, 1991
* Updated March, April 1992
@@ -39,6 +36,8 @@
* Updated July, 1997
* Updated October, 1999
* Updated September, 2000
+ * Updated December, 2001
+ * Updated January, 2011
*
* Fixes from ado@elsie.nci.nih.gov,
* February 1991, May 1992
@@ -54,14 +53,15 @@
* July 1997
* Moved to C99 specification.
* September 2000
+ * Fixes from Tanaka Akira <akr@m17n.org>
+ * December 2001
*/
#include <config.h>
-#ifndef GAWK
#include <stdio.h>
#include <ctype.h>
#include <time.h>
-#endif
+
#if defined(TM_IN_SYS_TIME)
#include <sys/types.h>
#include <sys/time.h>
@@ -74,9 +74,7 @@
#define SUNOS_EXT 1 /* stuff in SunOS strftime routine */
#define VMS_EXT 1 /* include %v for VMS date format */
#define HPUX_EXT 1 /* non-conflicting stuff in HP-UX date */
-#ifndef GAWK
#define POSIX_SEMANTICS 1 /* call tzset() if TZ changes */
-#endif
#undef strchr /* avoid AIX weirdness */
@@ -114,6 +112,11 @@ extern int timezone, altzone;
#undef min /* just in case */
+/* format for %+ -- currently unused */
+#ifndef NATIONAL_FORMAT
+#define NATIONAL_FORMAT "%a %b %e %H:%M:%S %Z %Y"
+#endif
+
/* min --- return minimum of two numbers */
static inline int
@@ -141,7 +144,8 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
char *start = s;
auto char tbuf[100];
long off;
- int i, w, y;
+ int i, w;
+ long y;
static short first = 1;
#ifdef POSIX_SEMANTICS
static char *savetz = NULL;
@@ -282,7 +286,7 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
case 'C':
century:
- sprintf(tbuf, "%02d", (timeptr->tm_year + 1900) / 100);
+ sprintf(tbuf, "%02ld", (timeptr->tm_year + 1900L) / 100);
break;
case 'd': /* day of the month, 01 - 31 */
@@ -319,16 +323,16 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
*/
w = iso8601wknum(timeptr);
if (timeptr->tm_mon == 11 && w == 1)
- y = 1900 + timeptr->tm_year + 1;
+ y = 1900L + timeptr->tm_year + 1;
else if (timeptr->tm_mon == 0 && w >= 52)
- y = 1900 + timeptr->tm_year - 1;
+ y = 1900L + timeptr->tm_year - 1;
else
- y = 1900 + timeptr->tm_year;
+ y = 1900L + timeptr->tm_year;
if (*format == 'G')
- sprintf(tbuf, "%d", y);
+ sprintf(tbuf, "%ld", y);
else
- sprintf(tbuf, "%02d", y % 100);
+ sprintf(tbuf, "%02ld", y % 100);
break;
case 'h': /* abbreviated month name */
@@ -387,7 +391,7 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
strftime(tbuf, sizeof tbuf, "%H:%M", timeptr);
break;
-#if defined(HAVE_MKTIME) || defined(GAWK)
+#if defined(HAVE_MKTIME)
case 's': /* time as seconds since the Epoch */
{
struct tm non_const_timeptr;
@@ -396,7 +400,7 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
sprintf(tbuf, "%ld", mktime(& non_const_timeptr));
break;
}
-#endif /* defined(HAVE_MKTIME) || defined(GAWK) */
+#endif /* defined(HAVE_MKTIME) */
case 'S': /* second, 00 - 60 */
i = range(0, timeptr->tm_sec, 60);
@@ -452,7 +456,7 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
case 'Y': /* year with century */
fullyear:
- sprintf(tbuf, "%d", 1900 + timeptr->tm_year);
+ sprintf(tbuf, "%ld", 1900L + timeptr->tm_year);
break;
/*
@@ -495,6 +499,7 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
# ifdef HPUX
off = -timezone / 60;
# else
+ /* ADR: 4 August 2001, fixed this per gazelle@interaccess.com */
off = -(daylight ? altzone : timezone) / 60;
# endif /* !HPUX */
#else /* !HAVE_TZNAME */
@@ -509,7 +514,7 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
} else {
tbuf[0] = '+';
}
- sprintf(tbuf+1, "%02d%02d", off/60, off%60);
+ sprintf(tbuf+1, "%02ld%02ld", off/60, off%60);
break;
case 'Z': /* time zone name or abbrevation */
@@ -558,10 +563,10 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
#ifdef VMS_EXT
case 'v': /* date as dd-bbb-YYYY */
- sprintf(tbuf, "%2d-%3.3s-%4d",
+ sprintf(tbuf, "%2d-%3.3s-%4ld",
range(1, timeptr->tm_mday, 31),
months_a[range(0, timeptr->tm_mon, 11)],
- timeptr->tm_year + 1900);
+ timeptr->tm_year + 1900L);
for (i = 3; i < 6; i++)
if (islower(tbuf[i]))
tbuf[i] = toupper(tbuf[i]);
@@ -594,7 +599,7 @@ out:
/* isleap --- is a year a leap year? */
static int
-isleap(int year)
+isleap(long year)
{
return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
}
@@ -677,7 +682,7 @@ iso8601wknum(const struct tm *timeptr)
dec31ly.tm_mon = 11;
dec31ly.tm_mday = 31;
dec31ly.tm_wday = (jan1day == 0) ? 6 : jan1day - 1;
- dec31ly.tm_yday = 364 + isleap(dec31ly.tm_year + 1900);
+ dec31ly.tm_yday = 364 + isleap(dec31ly.tm_year + 1900L);
weeknum = iso8601wknum(& dec31ly);
#endif
}
diff --git a/lib/sh/strtrans.c b/lib/sh/strtrans.c
index 355a306..2265782 100644
--- a/lib/sh/strtrans.c
+++ b/lib/sh/strtrans.c
@@ -1,6 +1,6 @@
/* strtrans.c - Translate and untranslate strings with ANSI-C escape sequences. */
-/* Copyright (C) 2000 Free Software Foundation, Inc.
+/* Copyright (C) 2000-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -51,11 +51,16 @@ ansicstr (string, len, flags, sawc, rlen)
{
int c, temp;
char *ret, *r, *s;
+ unsigned long v;
if (string == 0 || *string == '\0')
return ((char *)NULL);
+#if defined (HANDLE_MULTIBYTE)
+ ret = (char *)xmalloc (4*len + 1);
+#else
ret = (char *)xmalloc (2*len + 1); /* 2*len for possible CTLESC */
+#endif
for (r = ret, s = string; s && *s; )
{
c = *s++;
@@ -128,6 +133,29 @@ ansicstr (string, len, flags, sawc, rlen)
}
c &= 0xFF;
break;
+#if defined (HANDLE_MULTIBYTE)
+ case 'u':
+ case 'U':
+ temp = (c == 'u') ? 4 : 8; /* \uNNNN \UNNNNNNNN */
+ for (v = 0; ISXDIGIT ((unsigned char)*s) && temp--; s++)
+ v = (v * 16) + HEXVALUE (*s);
+ if (temp == ((c == 'u') ? 4 : 8))
+ {
+ *r++ = '\\'; /* c remains unchanged */
+ break;
+ }
+ else if (v <= UCHAR_MAX)
+ {
+ c = v;
+ break;
+ }
+ else
+ {
+ temp = u32cconv (v, r);
+ r += temp;
+ continue;
+ }
+#endif
case '\\':
break;
case '\'': case '"': case '?':
@@ -143,9 +171,13 @@ ansicstr (string, len, flags, sawc, rlen)
*rlen = r - ret;
return ret;
}
+ else if ((flags & 1) == 0 && *s == 0)
+ ; /* pass \c through */
else if ((flags & 1) == 0 && (c = *s))
{
s++;
+ if ((flags & 2) && c == '\\' && c == *s)
+ s++; /* Posix requires $'\c\\' do backslash escaping */
c = TOCTRL(c);
break;
}
diff --git a/lib/sh/tmpfile.c b/lib/sh/tmpfile.c
index a87c254..0bbc287 100644
--- a/lib/sh/tmpfile.c
+++ b/lib/sh/tmpfile.c
@@ -40,7 +40,7 @@
extern int errno;
#endif
-#define BASEOPENFLAGS (O_CREAT | O_TRUNC | O_EXCL)
+#define BASEOPENFLAGS (O_CREAT | O_TRUNC | O_EXCL | O_BINARY)
#define DEFAULT_TMPDIR "." /* bogus default, should be changed */
#define DEFAULT_NAMEROOT "shtmp"
diff --git a/lib/sh/unicode.c b/lib/sh/unicode.c
new file mode 100644
index 0000000..d34fa08
--- /dev/null
+++ b/lib/sh/unicode.c
@@ -0,0 +1,235 @@
+/* unicode.c - functions to convert unicode characters */
+
+/* Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This file is part of GNU Bash, the Bourne Again SHell.
+
+ Bash is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Bash is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Bash. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <config.h>
+
+#if defined (HANDLE_MULTIBYTE)
+
+#include <stdc.h>
+#include <wchar.h>
+#include <bashansi.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <limits.h>
+
+#if HAVE_ICONV
+# include <iconv.h>
+#endif
+
+#include <xmalloc.h>
+
+#ifndef USHORT_MAX
+# ifdef USHRT_MAX
+# define USHORT_MAX USHRT_MAX
+# else
+# define USHORT_MAX ((unsigned short) ~(unsigned short)0)
+# endif
+#endif
+
+#if !defined (STREQ)
+# define STREQ(a, b) ((a)[0] == (b)[0] && strcmp ((a), (b)) == 0)
+#endif /* !STREQ */
+
+#if defined (HAVE_LOCALE_CHARSET)
+extern const char *locale_charset __P((void));
+#else
+extern char *get_locale_var __P((char *));
+#endif
+
+static int u32init = 0;
+static int utf8locale = 0;
+#if defined (HAVE_ICONV)
+static iconv_t localconv;
+#endif
+
+#ifndef HAVE_LOCALE_CHARSET
+static char *
+stub_charset ()
+{
+ char *locale, *s, *t;
+
+ locale = get_locale_var ("LC_CTYPE");
+ if (locale == 0 || *locale == 0)
+ return "ASCII";
+ s = strrchr (locale, '.');
+ if (s)
+ {
+ t = strchr (s, '@');
+ if (t)
+ *t = 0;
+ return ++s;
+ }
+ else if (STREQ (locale, "UTF-8"))
+ return "UTF-8";
+ else
+ return "ASCII";
+}
+#endif
+
+/* u32toascii ? */
+int
+u32tochar (wc, s)
+ wchar_t wc;
+ char *s;
+{
+ unsigned long x;
+ int l;
+
+ x = wc;
+ l = (x <= UCHAR_MAX) ? 1 : ((x <= USHORT_MAX) ? 2 : 4);
+
+ if (x <= UCHAR_MAX)
+ s[0] = x & 0xFF;
+ else if (x <= USHORT_MAX) /* assume unsigned short = 16 bits */
+ {
+ s[0] = (x >> 8) & 0xFF;
+ s[1] = x & 0xFF;
+ }
+ else
+ {
+ s[0] = (x >> 24) & 0xFF;
+ s[1] = (x >> 16) & 0xFF;
+ s[2] = (x >> 8) & 0xFF;
+ s[3] = x & 0xFF;
+ }
+ s[l] = '\0';
+ return l;
+}
+
+int
+u32toutf8 (wc, s)
+ wchar_t wc;
+ char *s;
+{
+ int l;
+
+ l = (wc < 0x0080) ? 1 : ((wc < 0x0800) ? 2 : 3);
+
+ if (wc < 0x0080)
+ s[0] = (unsigned char)wc;
+ else if (wc < 0x0800)
+ {
+ s[0] = (wc >> 6) | 0xc0;
+ s[1] = (wc & 0x3f) | 0x80;
+ }
+ else
+ {
+ s[0] = (wc >> 12) | 0xe0;
+ s[1] = ((wc >> 6) & 0x3f) | 0x80;
+ s[2] = (wc & 0x3f) | 0x80;
+ }
+ s[l] = '\0';
+ return l;
+}
+
+/* convert a single unicode-32 character into a multibyte string and put the
+ result in S, which must be large enough (at least MB_LEN_MAX bytes) */
+int
+u32cconv (c, s)
+ unsigned long c;
+ char *s;
+{
+ wchar_t wc;
+ int n;
+#if HAVE_ICONV
+ const char *charset;
+ char obuf[25], *optr;
+ size_t obytesleft;
+ const char *iptr;
+ size_t sn;
+#endif
+
+ wc = c;
+
+#if __STDC_ISO_10646__
+ if (sizeof (wchar_t) == 4)
+ {
+ n = wctomb (s, wc);
+ return n;
+ }
+#endif
+
+#if HAVE_NL_LANGINFO
+ codeset = nl_langinfo (CODESET);
+ if (STREQ (codeset, "UTF-8"))
+ {
+ n = u32toutf8 (wc, s);
+ return n;
+ }
+#endif
+
+#if HAVE_ICONV
+ /* this is mostly from coreutils-8.5/lib/unicodeio.c */
+ if (u32init == 0)
+ {
+# if HAVE_LOCALE_CHARSET
+ charset = locale_charset (); /* XXX - fix later */
+# else
+ charset = stub_charset ();
+# endif
+ if (STREQ (charset, "UTF-8"))
+ utf8locale = 1;
+ else
+ {
+ localconv = iconv_open (charset, "UTF-8");
+ if (localconv == (iconv_t)-1)
+ localconv = iconv_open (charset, "ASCII");
+ }
+ u32init = 1;
+ }
+
+ if (utf8locale)
+ {
+ n = u32toutf8 (wc, s);
+ return n;
+ }
+
+ if (localconv == (iconv_t)-1)
+ {
+ n = u32tochar (wc, s);
+ return n;
+ }
+
+ n = u32toutf8 (wc, s);
+
+ optr = obuf;
+ obytesleft = sizeof (obuf);
+ iptr = s;
+ sn = n;
+
+ iconv (localconv, NULL, NULL, NULL, NULL);
+
+ if (iconv (localconv, (ICONV_CONST char **)&iptr, &sn, &optr, &obytesleft) == (size_t)-1)
+ return n; /* You get utf-8 if iconv fails */
+
+ *optr = '\0';
+
+ /* number of chars to be copied is optr - obuf if we want to do bounds
+ checking */
+ strcpy (s, obuf);
+ return (optr - obuf);
+#endif
+
+ n = u32tochar (wc, s); /* fallback */
+ return n;
+}
+
+#endif /* HANDLE_MULTIBYTE */
diff --git a/lib/sh/wcswidth.c b/lib/sh/wcswidth.c
new file mode 100644
index 0000000..1a30d9f
--- /dev/null
+++ b/lib/sh/wcswidth.c
@@ -0,0 +1,46 @@
+/* wcswidth.c - compute display width of wide character string */
+
+/* Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This file is part of GNU Bash, the Bourne Again SHell.
+
+ Bash is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Bash is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Bash. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <config.h>
+
+#if defined (HANDLE_MULTIBYTE) && !defined (HAVE_WCSWIDTH)
+
+#include <stdc.h>
+#include <wchar.h>
+#include <bashansi.h>
+
+int
+wcswidth(pwcs, n)
+ const wchar_t *pwcs;
+ size_t n;
+{
+ wchar_t wc;
+ int len, l;
+
+ len = 0;
+ while (n-- > 0 && (wc = *pwcs++) != L'\0')
+ {
+ if ((l = wcwidth(wc)) < 0)
+ return (-1);
+ len += l;
+ }
+ return (len);
+}
+#endif
diff --git a/lib/tilde/tilde.c b/lib/tilde/tilde.c
index 088ff15..1c53a45 100644
--- a/lib/tilde/tilde.c
+++ b/lib/tilde/tilde.c
@@ -378,7 +378,7 @@ tilde_expand_word (filename)
{
dirname = glue_prefix_and_suffix (expansion, filename, user_len);
xfree (username);
- free (expansion);
+ xfree (expansion);
return (dirname);
}
}
@@ -401,7 +401,7 @@ tilde_expand_word (filename)
if (expansion)
{
dirname = glue_prefix_and_suffix (expansion, filename, user_len);
- free (expansion);
+ xfree (expansion);
}
}
/* If we don't have a failure hook, or if the failure hook did not