Bash-4.2 distribution sources and documentation
This commit is contained in:
parent
30d188c293
commit
495aee441b
341 changed files with 108751 additions and 36060 deletions
|
@ -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
|
||||
|
|
314
lib/glob/gmisc.c
Normal file
314
lib/glob/gmisc.c
Normal file
|
@ -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;
|
||||
}
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
@ -1662,6 +1666,19 @@ sv_compquery (value)
|
|||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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, "e_char);
|
||||
#else
|
||||
if (what_to_do == TAB)
|
||||
{
|
||||
if (*matches[0])
|
||||
insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, "e_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, "e_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, "e_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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -338,7 +338,7 @@ free_history_entry (hist)
|
|||
FREE (hist->line);
|
||||
FREE (hist->timestamp);
|
||||
x = hist->data;
|
||||
free (hist);
|
||||
xfree (hist);
|
||||
return (x);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/* Translate the keys we do something with to opcodes. */
|
||||
if (c >= 0 && _rl_keymap[c].type == ISFUNC)
|
||||
/* 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)
|
||||
{
|
||||
f = _rl_keymap[c].function;
|
||||
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 && cxt->keymap[c].type == ISFUNC)
|
||||
{
|
||||
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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
|
|
|
@ -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 */
|
||||
|
|
47
lib/readline/posixselect.h
Normal file
47
lib/readline/posixselect.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/* posixselect.h -- wrapper for select(2) includes and definitions */
|
||||
|
||||
/* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _POSIXSELECT_H_
|
||||
#define _POSIXSELECT_H_
|
||||
|
||||
#if defined (FD_SET) && !defined (HAVE_SELECT)
|
||||
# define HAVE_SELECT 1
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_SELECT)
|
||||
# if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX)
|
||||
# include <sys/time.h>
|
||||
# endif
|
||||
#endif /* HAVE_SELECT */
|
||||
#if defined (HAVE_SYS_SELECT_H)
|
||||
# include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#ifndef USEC_PER_SEC
|
||||
# define USEC_PER_SEC 1000000
|
||||
#endif
|
||||
|
||||
#define USEC_TO_TIMEVAL(us, tv) \
|
||||
do { \
|
||||
(tv).tv_sec = (us) / USEC_PER_SEC; \
|
||||
(tv).tv_usec = (us) % USEC_PER_SEC; \
|
||||
} while (0)
|
||||
|
||||
#endif /* _POSIXSELECT_H_ */
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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,113 +926,6 @@ rl_vi_column (count, key)
|
|||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_domove (key, nextkey)
|
||||
int key, *nextkey;
|
||||
{
|
||||
int c, save;
|
||||
int old_end;
|
||||
|
||||
rl_mark = rl_point;
|
||||
RL_SETSTATE(RL_STATE_MOREINPUT);
|
||||
c = rl_read_key ();
|
||||
RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
||||
|
||||
if (c < 0)
|
||||
{
|
||||
*nextkey = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*nextkey = c;
|
||||
|
||||
if (!member (c, vi_motion))
|
||||
{
|
||||
if (_rl_digit_p (c))
|
||||
{
|
||||
save = rl_numeric_arg;
|
||||
rl_numeric_arg = _rl_digit_value (c);
|
||||
rl_explicit_arg = 1;
|
||||
RL_SETSTATE (RL_STATE_NUMERICARG|RL_STATE_VIMOTION);
|
||||
rl_digit_loop1 ();
|
||||
RL_UNSETSTATE (RL_STATE_VIMOTION);
|
||||
rl_numeric_arg *= save;
|
||||
RL_SETSTATE(RL_STATE_MOREINPUT);
|
||||
c = rl_read_key (); /* real command */
|
||||
RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
||||
if (c < 0)
|
||||
{
|
||||
*nextkey = 0;
|
||||
return -1;
|
||||
}
|
||||
*nextkey = c;
|
||||
}
|
||||
else if (key == c && (key == 'd' || key == 'y' || key == 'c'))
|
||||
{
|
||||
rl_mark = rl_end;
|
||||
rl_beg_of_line (1, c);
|
||||
_rl_vi_last_motion = c;
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
return (-1);
|
||||
}
|
||||
|
||||
_rl_vi_last_motion = c;
|
||||
|
||||
/* Append a blank character temporarily so that the motion routines
|
||||
work right at the end of the line. */
|
||||
old_end = rl_end;
|
||||
rl_line_buffer[rl_end++] = ' ';
|
||||
rl_line_buffer[rl_end] = '\0';
|
||||
|
||||
_rl_dispatch (c, _rl_keymap);
|
||||
|
||||
/* Remove the blank that we added. */
|
||||
rl_end = old_end;
|
||||
rl_line_buffer[rl_end] = '\0';
|
||||
if (rl_point > rl_end)
|
||||
rl_point = rl_end;
|
||||
|
||||
/* No change in position means the command failed. */
|
||||
if (rl_mark == rl_point)
|
||||
return (-1);
|
||||
|
||||
/* rl_vi_f[wW]ord () leaves the cursor on the first character of the next
|
||||
word. If we are not at the end of the line, and we are on a
|
||||
non-whitespace character, move back one (presumably to whitespace). */
|
||||
if ((_rl_to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark &&
|
||||
!whitespace (rl_line_buffer[rl_point]))
|
||||
rl_point--;
|
||||
|
||||
/* If cw or cW, back up to the end of a word, so the behaviour of ce
|
||||
or cE is the actual result. Brute-force, no subtlety. */
|
||||
if (key == 'c' && rl_point >= rl_mark && (_rl_to_upper (c) == 'W'))
|
||||
{
|
||||
/* Don't move farther back than where we started. */
|
||||
while (rl_point > rl_mark && whitespace (rl_line_buffer[rl_point]))
|
||||
rl_point--;
|
||||
|
||||
/* Posix.2 says that if cw or cW moves the cursor towards the end of
|
||||
the line, the character under the cursor should be deleted. */
|
||||
if (rl_point == rl_mark)
|
||||
rl_point++;
|
||||
else
|
||||
{
|
||||
/* Move past the end of the word so that the kill doesn't
|
||||
remove the last letter of the previous word. Only do this
|
||||
if we are not at the end of the line. */
|
||||
if (rl_point >= 0 && rl_point < (rl_end - 1) && !whitespace (rl_line_buffer[rl_point]))
|
||||
rl_point++;
|
||||
}
|
||||
}
|
||||
|
||||
if (rl_mark < rl_point)
|
||||
SWAP (rl_point, rl_mark);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Process C as part of the current numeric argument. Return -1 if the
|
||||
argument should be aborted, 0 if we should not read any more chars, and
|
||||
1 if we should continue to read chars. */
|
||||
|
@ -1042,13 +951,13 @@ _rl_vi_arg_dispatch (c)
|
|||
else
|
||||
rl_numeric_arg = _rl_digit_value (c);
|
||||
rl_explicit_arg = 1;
|
||||
return 1;
|
||||
return 1; /* keep going */
|
||||
}
|
||||
else
|
||||
{
|
||||
rl_clear_message ();
|
||||
rl_stuff_char (key);
|
||||
return 0;
|
||||
return 0; /* done */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1076,28 +985,233 @@ rl_digit_loop1 ()
|
|||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_delete_to (count, key)
|
||||
int count, key;
|
||||
static void
|
||||
_rl_mvcxt_init (m, op, key)
|
||||
_rl_vimotion_cxt *m;
|
||||
int op, key;
|
||||
{
|
||||
int c, start_pos;
|
||||
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;
|
||||
}
|
||||
|
||||
if (_rl_uppercase_p (key))
|
||||
rl_stuff_char ('$');
|
||||
else if (vi_redoing)
|
||||
rl_stuff_char (_rl_vi_last_motion);
|
||||
static _rl_vimotion_cxt *
|
||||
_rl_mvcxt_alloc (op, key)
|
||||
int op, key;
|
||||
{
|
||||
_rl_vimotion_cxt *m;
|
||||
|
||||
start_pos = rl_point;
|
||||
m = xmalloc (sizeof (_rl_vimotion_cxt));
|
||||
_rl_mvcxt_init (m, op, key);
|
||||
return m;
|
||||
}
|
||||
|
||||
if (rl_vi_domove (key, &c))
|
||||
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. */
|
||||
old_end = rl_end;
|
||||
rl_line_buffer[rl_end++] = ' ';
|
||||
rl_line_buffer[rl_end] = '\0';
|
||||
|
||||
_rl_dispatch (c, _rl_keymap);
|
||||
|
||||
/* Remove the blank that we added. */
|
||||
rl_end = old_end;
|
||||
rl_line_buffer[rl_end] = '\0';
|
||||
if (rl_point > rl_end)
|
||||
rl_point = rl_end;
|
||||
|
||||
/* No change in position means the command failed. */
|
||||
if (rl_mark == rl_point)
|
||||
return (-1);
|
||||
|
||||
/* rl_vi_f[wW]ord () leaves the cursor on the first character of the next
|
||||
word. If we are not at the end of the line, and we are on a
|
||||
non-whitespace character, move back one (presumably to whitespace). */
|
||||
if ((_rl_to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark &&
|
||||
!whitespace (rl_line_buffer[rl_point]))
|
||||
rl_point--;
|
||||
|
||||
/* If cw or cW, back up to the end of a word, so the behaviour of ce
|
||||
or cE is the actual result. Brute-force, no subtlety. */
|
||||
if (m->key == 'c' && rl_point >= rl_mark && (_rl_to_upper (c) == 'W'))
|
||||
{
|
||||
rl_ding ();
|
||||
/* Don't move farther back than where we started. */
|
||||
while (rl_point > rl_mark && whitespace (rl_line_buffer[rl_point]))
|
||||
rl_point--;
|
||||
|
||||
/* Posix.2 says that if cw or cW moves the cursor towards the end of
|
||||
the line, the character under the cursor should be deleted. */
|
||||
if (rl_point == rl_mark)
|
||||
rl_point++;
|
||||
else
|
||||
{
|
||||
/* Move past the end of the word so that the kill doesn't
|
||||
remove the last letter of the previous word. Only do this
|
||||
if we are not at the end of the line. */
|
||||
if (rl_point >= 0 && rl_point < (rl_end - 1) && !whitespace (rl_line_buffer[rl_point]))
|
||||
rl_point++;
|
||||
}
|
||||
}
|
||||
|
||||
if (rl_mark < rl_point)
|
||||
SWAP (rl_point, rl_mark);
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
#define RL_VIMOVENUMARG() (RL_ISSTATE (RL_STATE_VIMOTION) && RL_ISSTATE (RL_STATE_NUMERICARG))
|
||||
|
||||
static int
|
||||
rl_domove_read_callback (m)
|
||||
_rl_vimotion_cxt *m;
|
||||
{
|
||||
int c, save;
|
||||
|
||||
c = m->motion;
|
||||
|
||||
if (member (c, vi_motion))
|
||||
{
|
||||
#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));
|
||||
}
|
||||
else if (m->key == c && (m->key == 'd' || m->key == 'y' || m->key == '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;
|
||||
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_UNSETSTATE (RL_STATE_VIMOTION);
|
||||
RL_UNSETSTATE (RL_STATE_NUMERICARG);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
rl_vi_domove_getchar (m)
|
||||
_rl_vimotion_cxt *m;
|
||||
{
|
||||
int c;
|
||||
|
||||
RL_SETSTATE(RL_STATE_MOREINPUT);
|
||||
c = rl_read_key ();
|
||||
RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
#if defined (READLINE_CALLBACKS)
|
||||
int
|
||||
_rl_vi_domove_callback (m)
|
||||
_rl_vimotion_cxt *m;
|
||||
{
|
||||
int c, r;
|
||||
|
||||
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_domove (x, ignore)
|
||||
int x, *ignore;
|
||||
{
|
||||
int r;
|
||||
_rl_vimotion_cxt *m;
|
||||
|
||||
m = _rl_vimvcxt;
|
||||
*ignore = m->motion = rl_vi_domove_getchar (m);
|
||||
|
||||
if (m->motion < 0)
|
||||
{
|
||||
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);
|
||||
{
|
||||
_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);
|
||||
|
||||
start_pos = rl_point;
|
||||
|
||||
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,44 +1292,138 @@ 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_change_to (count, key)
|
||||
int count, key;
|
||||
{
|
||||
int c, r;
|
||||
|
||||
_rl_vimvcxt = _rl_mvcxt_alloc (VIM_CHANGE, 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);
|
||||
}
|
||||
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 (r < 0)
|
||||
{
|
||||
rl_ding ();
|
||||
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`", m->motion) == 0) && (rl_point >= m->start)) &&
|
||||
(rl_mark < rl_end))
|
||||
rl_mark++;
|
||||
|
||||
rl_begin_undo_group ();
|
||||
rl_kill_text (rl_point, rl_mark);
|
||||
rl_end_undo_group ();
|
||||
rl_do_undo ();
|
||||
rl_point = m->start;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_yank_to (count, key)
|
||||
int count, key;
|
||||
{
|
||||
int c, start_pos;
|
||||
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_stuff_char ('$');
|
||||
{
|
||||
_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);
|
||||
|
||||
start_pos = rl_point;
|
||||
|
||||
if (rl_vi_domove (key, &c))
|
||||
if (r < 0)
|
||||
{
|
||||
rl_ding ();
|
||||
return -1;
|
||||
r = -1;
|
||||
}
|
||||
|
||||
/* These are the motion commands that do not require adjusting the
|
||||
mark. */
|
||||
if (((strchr (" l|h^0%bBFT`", c) == 0) && (rl_point >= start_pos)) &&
|
||||
(rl_mark < rl_end))
|
||||
rl_mark++;
|
||||
_rl_mvcxt_dispose (_rl_vimvcxt);
|
||||
_rl_vimvcxt = 0;
|
||||
|
||||
rl_begin_undo_group ();
|
||||
rl_kill_text (rl_point, rl_mark);
|
||||
rl_end_undo_group ();
|
||||
rl_do_undo ();
|
||||
rl_point = start_pos;
|
||||
return r;
|
||||
}
|
||||
|
||||
return (0);
|
||||
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
|
||||
|
@ -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;
|
||||
|
|
50
lib/readline/xfree.c
Normal file
50
lib/readline/xfree.c
Normal file
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
70
lib/sh/dprintf.c
Normal file
70
lib/sh/dprintf.c
Normal file
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
199
lib/sh/fnxform.c
Normal file
199
lib/sh/fnxform.c
Normal file
|
@ -0,0 +1,199 @@
|
|||
/* fnxform - use iconv(3) to transform strings to and from "filename" format */
|
||||
|
||||
/* Copyright (C) 2009-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 (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include "bashansi.h"
|
||||
#include <stdio.h>
|
||||
#include "bashtypes.h"
|
||||
|
||||
#include "stdc.h"
|
||||
#include "bashintl.h"
|
||||
#include <xmalloc.h>
|
||||
|
||||
#if defined (HAVE_ICONV)
|
||||
# include <iconv.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_LOCALE_CHARSET)
|
||||
extern const char *locale_charset __P((void));
|
||||
#else
|
||||
extern char *get_locale_var __P((char *));
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_ICONV)
|
||||
static iconv_t conv_fromfs = (iconv_t)-1;
|
||||
static iconv_t conv_tofs = (iconv_t)-1;
|
||||
|
||||
#define OUTLEN_MAX 4096
|
||||
|
||||
static char *outbuf = 0;
|
||||
static size_t outlen = 0;
|
||||
|
||||
static char *curencoding __P((void));
|
||||
static void init_tofs __P((void));
|
||||
static void init_fromfs __P((void));
|
||||
|
||||
static char *
|
||||
curencoding ()
|
||||
{
|
||||
char *loc;
|
||||
#if defined (HAVE_LOCALE_CHARSET)
|
||||
loc = (char *)locale_charset ();
|
||||
return loc;
|
||||
#else
|
||||
char *dot, *mod;
|
||||
|
||||
loc = get_locale_var ("LC_CTYPE");
|
||||
if (loc == 0 || *loc == 0)
|
||||
return "";
|
||||
dot = strchr (loc, '.');
|
||||
if (dot == 0)
|
||||
return loc;
|
||||
mod = strchr (dot, '@');
|
||||
if (mod)
|
||||
*mod = '\0';
|
||||
return ++dot;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
init_tofs ()
|
||||
{
|
||||
char *cur;
|
||||
|
||||
cur = curencoding ();
|
||||
conv_tofs = iconv_open ("UTF-8-MAC", cur);
|
||||
}
|
||||
|
||||
static void
|
||||
init_fromfs ()
|
||||
{
|
||||
char *cur;
|
||||
|
||||
cur = curencoding ();
|
||||
conv_fromfs = iconv_open (cur, "UTF-8-MAC");
|
||||
}
|
||||
|
||||
char *
|
||||
fnx_tofs (string, len)
|
||||
char *string;
|
||||
size_t len;
|
||||
{
|
||||
#ifdef MACOSX
|
||||
ICONV_CONST char *inbuf;
|
||||
char *tempbuf;
|
||||
size_t templen;
|
||||
|
||||
if (conv_tofs == (iconv_t)-1)
|
||||
init_tofs ();
|
||||
if (conv_tofs == (iconv_t)-1)
|
||||
return string;
|
||||
|
||||
/* Free and reallocate outbuf if it's *too* big */
|
||||
if (outlen >= OUTLEN_MAX && len < OUTLEN_MAX - 8)
|
||||
{
|
||||
free (outbuf);
|
||||
outbuf = 0;
|
||||
outlen = 0;
|
||||
}
|
||||
|
||||
inbuf = string;
|
||||
if (outbuf == 0 || outlen < len + 8)
|
||||
{
|
||||
outlen = len + 8;
|
||||
outbuf = outbuf ? xrealloc (outbuf, outlen + 1) : xmalloc (outlen + 1);
|
||||
}
|
||||
tempbuf = outbuf;
|
||||
templen = outlen;
|
||||
|
||||
iconv (conv_tofs, NULL, NULL, NULL, NULL);
|
||||
|
||||
if (iconv (conv_tofs, &inbuf, &len, &tempbuf, &templen) == (size_t)-1)
|
||||
return string;
|
||||
|
||||
*tempbuf = '\0';
|
||||
return outbuf;
|
||||
#else
|
||||
return string;
|
||||
#endif
|
||||
}
|
||||
|
||||
char *
|
||||
fnx_fromfs (string, len)
|
||||
char *string;
|
||||
size_t len;
|
||||
{
|
||||
#ifdef MACOSX
|
||||
ICONV_CONST char *inbuf;
|
||||
char *tempbuf;
|
||||
size_t templen;
|
||||
|
||||
if (conv_fromfs == (iconv_t)-1)
|
||||
init_fromfs ();
|
||||
if (conv_fromfs == (iconv_t)-1)
|
||||
return string;
|
||||
|
||||
/* Free and reallocate outbuf if it's *too* big */
|
||||
if (outlen >= OUTLEN_MAX && len < OUTLEN_MAX - 8)
|
||||
{
|
||||
free (outbuf);
|
||||
outbuf = 0;
|
||||
outlen = 0;
|
||||
}
|
||||
|
||||
inbuf = string;
|
||||
if (outbuf == 0 || outlen < (len + 8))
|
||||
{
|
||||
outlen = len + 8;
|
||||
outbuf = outbuf ? xrealloc (outbuf, outlen + 1) : xmalloc (outlen + 1);
|
||||
}
|
||||
tempbuf = outbuf;
|
||||
templen = outlen;
|
||||
|
||||
iconv (conv_fromfs, NULL, NULL, NULL, NULL);
|
||||
|
||||
if (iconv (conv_fromfs, &inbuf, &len, &tempbuf, &templen) == (size_t)-1)
|
||||
return string;
|
||||
|
||||
*tempbuf = '\0';
|
||||
return outbuf;
|
||||
#else
|
||||
return string;
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
char *
|
||||
fnx_tofs (string)
|
||||
char *string;
|
||||
{
|
||||
return string;
|
||||
}
|
||||
|
||||
char *
|
||||
fnx_fromfs (string)
|
||||
char *string;
|
||||
{
|
||||
return string;
|
||||
}
|
||||
#endif
|
|
@ -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;
|
||||
|
|
78
lib/sh/mbscasecmp.c
Normal file
78
lib/sh/mbscasecmp.c
Normal file
|
@ -0,0 +1,78 @@
|
|||
/* mbscasecmp - case-insensitive multibyte string comparison. */
|
||||
|
||||
/* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if !defined (HAVE_MBSCASECMP) && defined (HANDLE_MULTIBYTE)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
|
||||
/* Compare MBS1 and MBS2 without regard to case. */
|
||||
int
|
||||
mbscasecmp (mbs1, mbs2)
|
||||
const char *mbs1;
|
||||
const char *mbs2;
|
||||
{
|
||||
int len1, len2;
|
||||
wchar_t c1, c2, l1, l2;
|
||||
|
||||
len1 = len2 = 0;
|
||||
/* Reset multibyte characters to their initial state. */
|
||||
(void) mblen ((char *) NULL, 0);
|
||||
|
||||
do
|
||||
{
|
||||
len1 = mbtowc (&c1, mbs1, MB_CUR_MAX);
|
||||
len2 = mbtowc (&c2, mbs2, MB_CUR_MAX);
|
||||
|
||||
if (len1 == 0)
|
||||
return len2 == 0 ? 0 : -1;
|
||||
else if (len2 == 0)
|
||||
return 1;
|
||||
else if (len1 > 0 && len2 < 0)
|
||||
return -1;
|
||||
else if (len1 < 0 && len2 > 0)
|
||||
return 1;
|
||||
else if (len1 < 0 && len2 < 0)
|
||||
{
|
||||
len1 = strlen (mbs1);
|
||||
len2 = strlen (mbs2);
|
||||
return (len1 == len2 ? memcmp (mbs1, mbs2, len1)
|
||||
: ((len1 < len2) ? (memcmp (mbs1, mbs2, len1) > 0 ? 1 : -1)
|
||||
: (memcmp (mbs1, mbs2, len2) >= 0 ? 1 : -1)));
|
||||
}
|
||||
|
||||
l1 = towlower (c1);
|
||||
l2 = towlower (c2);
|
||||
|
||||
mbs1 += len1;
|
||||
mbs2 += len2;
|
||||
}
|
||||
while (l1 == l2);
|
||||
|
||||
return l1 - l2;
|
||||
}
|
||||
|
||||
#endif
|
78
lib/sh/mbschr.c
Normal file
78
lib/sh/mbschr.c
Normal file
|
@ -0,0 +1,78 @@
|
|||
/* mbschr.c - strchr(3) that handles multibyte characters. */
|
||||
|
||||
/* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include "bashansi.h"
|
||||
#include "shmbutil.h"
|
||||
|
||||
#undef mbschr
|
||||
|
||||
/* In some locales, the non-first byte of some multibyte characters have
|
||||
the same value as some ascii character. Faced with these strings, a
|
||||
legacy strchr() might return the wrong value. */
|
||||
|
||||
char *
|
||||
#if defined (PROTOTYPES)
|
||||
mbschr (const char *s, int c)
|
||||
#else
|
||||
mbschr (s, c)
|
||||
const char *s;
|
||||
int c;
|
||||
#endif
|
||||
{
|
||||
#if HANDLE_MULTIBYTE
|
||||
char *pos;
|
||||
mbstate_t state;
|
||||
size_t strlength, mblength;
|
||||
|
||||
/* The locale encodings with said weird property are BIG5, BIG5-HKSCS,
|
||||
GBK, GB18030, SHIFT_JIS, and JOHAB. They exhibit the problem only
|
||||
when c >= 0x30. We can therefore use the faster bytewise search if
|
||||
c <= 0x30. */
|
||||
if ((unsigned char)c >= '0' && MB_CUR_MAX > 1)
|
||||
{
|
||||
pos = (char *)s;
|
||||
memset (&state, '\0', sizeof(mbstate_t));
|
||||
strlength = strlen (s);
|
||||
|
||||
while (strlength > 0)
|
||||
{
|
||||
mblength = mbrlen (pos, strlength, &state);
|
||||
if (mblength == (size_t)-2 || mblength == (size_t)-1 || mblength == (size_t)0)
|
||||
mblength = 1;
|
||||
|
||||
if (mblength == 1 && c == (unsigned char)*pos)
|
||||
return pos;
|
||||
|
||||
strlength -= mblength;
|
||||
pos += mblength;
|
||||
}
|
||||
|
||||
return ((char *)NULL);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
return (strchr (s, c));
|
||||
}
|
|
@ -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';
|
||||
|
|
|
@ -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;
|
||||
|
|
92
lib/sh/shmbchar.c
Normal file
92
lib/sh/shmbchar.c
Normal file
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
46
lib/sh/strcasestr.c
Normal file
46
lib/sh/strcasestr.c
Normal file
|
@ -0,0 +1,46 @@
|
|||
/* strcasestr.c - Find if one string appears as a substring of another string,
|
||||
without regard to case. */
|
||||
|
||||
/* Copyright (C) 2000 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <bashansi.h>
|
||||
#include <chartypes.h>
|
||||
|
||||
#include <stdc.h>
|
||||
|
||||
/* Determine if s2 occurs in s1. If so, return a pointer to the
|
||||
match in s1. The compare is case insensitive. This is a
|
||||
case-insensitive strstr(3). */
|
||||
char *
|
||||
strcasestr (s1, s2)
|
||||
const char *s1;
|
||||
const char *s2;
|
||||
{
|
||||
register int i, l, len, c;
|
||||
|
||||
c = TOLOWER ((unsigned char)s2[0]);
|
||||
len = strlen (s1);
|
||||
l = strlen (s2);
|
||||
for (i = 0; (len - i) >= l; i++)
|
||||
if ((TOLOWER ((unsigned char)s1[i]) == c) && (strncasecmp (s1 + i, s2, l) == 0))
|
||||
return ((char *)s1 + i);
|
||||
return ((char *)0);
|
||||
}
|
144
lib/sh/strchrnul.c
Normal file
144
lib/sh/strchrnul.c
Normal file
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
235
lib/sh/unicode.c
Normal file
235
lib/sh/unicode.c
Normal file
|
@ -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 */
|
46
lib/sh/wcswidth.c
Normal file
46
lib/sh/wcswidth.c
Normal file
|
@ -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
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue