bash-4.2 remove leftover and stray files

This commit is contained in:
Chet Ramey
2011-12-12 22:16:30 -05:00
parent e3af937042
commit 9519c7f69c
192 changed files with 0 additions and 230379 deletions
-162
View File
@@ -1,162 +0,0 @@
## -*- text -*- ####################################################
# #
# Makefile for the GNU Glob Library. #
# #
####################################################################
#
# Copyright (C) 1996-2009 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/>.
srcdir = @srcdir@
VPATH = .:@srcdir@
topdir = @top_srcdir@
BUILD_DIR = @BUILD_DIR@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CC = @CC@
RANLIB = @RANLIB@
AR = @AR@
ARFLAGS = @ARFLAGS@
RM = rm -f
CP = cp
MV = mv
SHELL = @MAKE_SHELL@
PROFILE_FLAGS = @PROFILE_FLAGS@
CFLAGS = @CFLAGS@
LOCAL_CFLAGS = @LOCAL_CFLAGS@
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@ @LOCAL_LDFLAGS@
DEFS = @DEFS@
LOCAL_DEFS = @LOCAL_DEFS@
BASHINCDIR = ${topdir}/include
INCLUDES = -I. -I../.. -I$(topdir) -I$(BASHINCDIR) -I$(topdir)/lib
CCFLAGS = $(PROFILE_FLAGS) $(DEFS) $(LOCAL_DEFS) $(CPPFLAGS) ${INCLUDES} \
$(LOCAL_CFLAGS) $(CFLAGS)
# Here is a rule for making .o files from .c files that doesn't force
# the type of the machine (like -sun3) into the flags.
.c.o:
$(RM) $@
$(CC) -c $(CCFLAGS) $<
# The name of the library target.
LIBRARY_NAME = libglob.a
# The C code source files for this library.
CSOURCES = $(srcdir)/glob.c $(srcdir)/strmatch.c $(srcdir)/smatch.c \
$(srcdir)/xmbsrtowcs.c
# The header files for this library.
HSOURCES = $(srcdir)/strmatch.h
OBJECTS = glob.o strmatch.o smatch.o xmbsrtowcs.o
# The texinfo files which document this library.
DOCSOURCE = doc/glob.texi
DOCOBJECT = doc/glob.dvi
DOCSUPPORT = doc/Makefile
DOCUMENTATION = $(DOCSOURCE) $(DOCOBJECT) $(DOCSUPPORT)
SUPPORT = Makefile ChangeLog $(DOCSUPPORT)
SOURCES = $(CSOURCES) $(HSOURCES) $(DOCSOURCE)
THINGS_TO_TAR = $(SOURCES) $(SUPPORT)
######################################################################
all: $(LIBRARY_NAME)
$(LIBRARY_NAME): $(OBJECTS)
$(RM) -f $@
$(AR) $(ARFLAGS) $@ $(OBJECTS)
-test -n "$(RANLIB)" && $(RANLIB) $@
what-tar:
@for file in $(THINGS_TO_TAR); do \
echo $(selfdir)$$file; \
done
documentation: force
-(cd doc; $(MAKE) $(MFLAGS))
force:
# The rule for 'includes' is written funny so that the if statement
# always returns TRUE unless there really was an error installing the
# include files.
install:
clean:
rm -f $(OBJECTS) $(LIBRARY_NAME)
-(cd doc && $(MAKE) $(MFLAGS) $@ )
realclean distclean maintainer-clean: clean
-( cd doc && $(MAKE) $(MFLAGS) $@ )
$(RM) -f Makefile
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. #
# #
######################################################################
smatch.o: strmatch.h
smatch.o: $(BUILD_DIR)/config.h
smatch.o: $(BASHINCDIR)/chartypes.h
smatch.o: $(BASHINCDIR)/ansi_stdlib.h $(topdir)/bashansi.h
smatch.o: $(BASHINCDIR)/shmbutil.h
smatch.o: $(topdir)/xmalloc.h
strmatch.o: strmatch.h
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
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
strmatch.o: strmatch.c
smatch.o: smatch.c
xmbsrtowcs.o: xmbsrtowcs.c
# dependencies for C files that include other C files
glob.o: glob_loop.c
smatch.o: sm_loop.c
-314
View File
@@ -1,314 +0,0 @@
/* 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 = 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 = 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;
}
-406
View File
@@ -1,406 +0,0 @@
/* strmatch.c -- ksh-like extended pattern matching for the shell and filename
globbing. */
/* Copyright (C) 1991-2011 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 <stdio.h> /* for debugging */
#include "strmatch.h"
#include <chartypes.h>
#include "bashansi.h"
#include "shmbutil.h"
#include "xmalloc.h"
#include "externs.h"
/* First, compile `sm_loop.c' for single-byte characters. */
#define CHAR unsigned char
#define U_CHAR unsigned char
#define XCHAR char
#define INT int
#define L(CS) CS
#define INVALID -1
#undef STREQ
#undef STREQN
#define STREQ(a, b) ((a)[0] == (b)[0] && strcmp(a, b) == 0)
#define STREQN(a, b, n) ((a)[0] == (b)[0] && strncmp(a, b, n) == 0)
/* We use strcoll(3) for range comparisons in bracket expressions,
even though it can have unwanted side effects in locales
other than POSIX or US. For instance, in the de locale, [A-Z] matches
all characters. */
#if defined (HAVE_STRCOLL)
/* Helper function for collating symbol equivalence. */
static int rangecmp (c1, c2)
int c1, c2;
{
static char s1[2] = { ' ', '\0' };
static char s2[2] = { ' ', '\0' };
int ret;
/* Eight bits only. Period. */
c1 &= 0xFF;
c2 &= 0xFF;
if (c1 == c2)
return (0);
s1[0] = c1;
s2[0] = c2;
if ((ret = strcoll (s1, s2)) != 0)
return ret;
return (c1 - c2);
}
#else /* !HAVE_STRCOLL */
# define rangecmp(c1, c2) ((int)(c1) - (int)(c2))
#endif /* !HAVE_STRCOLL */
#if defined (HAVE_STRCOLL)
static int
collequiv (c1, c2)
int c1, c2;
{
return (rangecmp (c1, c2) == 0);
}
#else
# define collequiv(c1, c2) ((c1) == (c2))
#endif
#define _COLLSYM _collsym
#define __COLLSYM __collsym
#define POSIXCOLL posix_collsyms
#include "collsyms.h"
static int
collsym (s, len)
CHAR *s;
int len;
{
register struct _collsym *csp;
char *x;
x = (char *)s;
for (csp = posix_collsyms; csp->name; csp++)
{
if (STREQN(csp->name, x, len) && csp->name[len] == '\0')
return (csp->code);
}
if (len == 1)
return s[0];
return INVALID;
}
/* unibyte character classification */
#if !defined (isascii) && !defined (HAVE_ISASCII)
# define isascii(c) ((unsigned int)(c) <= 0177)
#endif
enum char_class
{
CC_NO_CLASS = 0,
CC_ASCII, CC_ALNUM, CC_ALPHA, CC_BLANK, CC_CNTRL, CC_DIGIT, CC_GRAPH,
CC_LOWER, CC_PRINT, CC_PUNCT, CC_SPACE, CC_UPPER, CC_WORD, CC_XDIGIT
};
static char const *const cclass_name[] =
{
"",
"ascii", "alnum", "alpha", "blank", "cntrl", "digit", "graph",
"lower", "print", "punct", "space", "upper", "word", "xdigit"
};
#define N_CHAR_CLASS (sizeof(cclass_name) / sizeof (cclass_name[0]))
static int
is_cclass (c, name)
int c;
const char *name;
{
enum char_class char_class = CC_NO_CLASS;
int i, result;
for (i = 1; i < N_CHAR_CLASS; i++)
{
if (STREQ (name, cclass_name[i]))
{
char_class = (enum char_class)i;
break;
}
}
if (char_class == 0)
return -1;
switch (char_class)
{
case CC_ASCII:
result = isascii (c);
break;
case CC_ALNUM:
result = ISALNUM (c);
break;
case CC_ALPHA:
result = ISALPHA (c);
break;
case CC_BLANK:
result = ISBLANK (c);
break;
case CC_CNTRL:
result = ISCNTRL (c);
break;
case CC_DIGIT:
result = ISDIGIT (c);
break;
case CC_GRAPH:
result = ISGRAPH (c);
break;
case CC_LOWER:
result = ISLOWER (c);
break;
case CC_PRINT:
result = ISPRINT (c);
break;
case CC_PUNCT:
result = ISPUNCT (c);
break;
case CC_SPACE:
result = ISSPACE (c);
break;
case CC_UPPER:
result = ISUPPER (c);
break;
case CC_WORD:
result = (ISALNUM (c) || c == '_');
break;
case CC_XDIGIT:
result = ISXDIGIT (c);
break;
default:
result = -1;
break;
}
return result;
}
/* Now include `sm_loop.c' for single-byte characters. */
/* The result of FOLD is an `unsigned char' */
# define FOLD(c) ((flags & FNM_CASEFOLD) \
? TOLOWER ((unsigned char)c) \
: ((unsigned char)c))
#define FCT internal_strmatch
#define GMATCH gmatch
#define COLLSYM collsym
#define PARSE_COLLSYM parse_collsym
#define BRACKMATCH brackmatch
#define PATSCAN patscan
#define STRCOMPARE strcompare
#define EXTMATCH extmatch
#define STRCHR(S, C) strchr((S), (C))
#define STRCOLL(S1, S2) strcoll((S1), (S2))
#define STRLEN(S) strlen(S)
#define STRCMP(S1, S2) strcmp((S1), (S2))
#define RANGECMP(C1, C2) rangecmp((C1), (C2))
#define COLLEQUIV(C1, C2) collequiv((C1), (C2))
#define CTYPE_T enum char_class
#define IS_CCLASS(C, S) is_cclass((C), (S))
#include "sm_loop.c"
#if HANDLE_MULTIBYTE
# define CHAR wchar_t
# define U_CHAR wint_t
# define XCHAR wchar_t
# define INT wint_t
# define L(CS) L##CS
# define INVALID WEOF
# undef STREQ
# undef STREQN
# 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;
{
static wchar_t s1[2] = { L' ', L'\0' };
static wchar_t s2[2] = { L' ', L'\0' };
if (c1 == c2)
return 0;
s1[0] = c1;
s2[0] = c2;
return (wcscoll (s1, s2));
}
static int
collequiv_wc (c, equiv)
wint_t c, equiv;
{
return (!(c - equiv));
}
/* Helper function for collating symbol. */
# define _COLLSYM _collwcsym
# define __COLLSYM __collwcsym
# define POSIXCOLL posix_collwcsyms
# include "collsyms.h"
static wint_t
collwcsym (s, len)
wchar_t *s;
int len;
{
register struct _collwcsym *csp;
for (csp = posix_collwcsyms; csp->name; csp++)
{
if (STREQN(csp->name, s, len) && csp->name[len] == L'\0')
return (csp->code);
}
if (len == 1)
return s[0];
return INVALID;
}
static int
is_wcclass (wc, name)
wint_t wc;
wchar_t *name;
{
char *mbs;
mbstate_t state;
size_t mbslength;
wctype_t desc;
int want_word;
if ((wctype ("ascii") == (wctype_t)0) && (wcscmp (name, L"ascii") == 0))
{
int c;
if ((c = wctob (wc)) == EOF)
return 0;
else
return (c <= 0x7F);
}
want_word = (wcscmp (name, L"word") == 0);
if (want_word)
name = L"alnum";
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);
if (mbslength == (size_t)-1 || mbslength == (size_t)-2)
{
free (mbs);
return -1;
}
desc = wctype (mbs);
free (mbs);
if (desc == (wctype_t)0)
return -1;
if (want_word)
return (iswctype (wc, desc) || wc == L'_');
else
return (iswctype (wc, desc));
}
/* Now include `sm_loop.c' for multibyte characters. */
#define FOLD(c) ((flags & FNM_CASEFOLD) && iswupper (c) ? towlower (c) : (c))
#define FCT internal_wstrmatch
#define GMATCH gmatch_wc
#define COLLSYM collwcsym
#define PARSE_COLLSYM parse_collwcsym
#define BRACKMATCH brackmatch_wc
#define PATSCAN patscan_wc
#define STRCOMPARE wscompare
#define EXTMATCH extmatch_wc
#define STRCHR(S, C) wcschr((S), (C))
#define STRCOLL(S1, S2) wcscoll((S1), (S2))
#define STRLEN(S) wcslen(S)
#define STRCMP(S1, S2) wcscmp((S1), (S2))
#define RANGECMP(C1, C2) rangecmp_wc((C1), (C2))
#define COLLEQUIV(C1, C2) collequiv_wc((C1), (C2))
#define CTYPE_T enum char_class
#define IS_CCLASS(C, S) is_wcclass((C), (S))
#include "sm_loop.c"
#endif /* HAVE_MULTIBYTE */
int
xstrmatch (pattern, string, flags)
char *pattern;
char *string;
int flags;
{
#if HANDLE_MULTIBYTE
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));
n = xdupmbstowcs (&wpattern, NULL, pattern);
if (n == (size_t)-1 || n == (size_t)-2)
return (internal_strmatch ((unsigned char *)pattern, (unsigned char *)string, flags));
n = xdupmbstowcs (&wstring, NULL, string);
if (n == (size_t)-1 || n == (size_t)-2)
{
free (wpattern);
return (internal_strmatch ((unsigned char *)pattern, (unsigned char *)string, flags));
}
ret = internal_wstrmatch (wpattern, wstring, flags);
free (wpattern);
free (wstring);
return ret;
#else
return (internal_strmatch ((unsigned char *)pattern, (unsigned char *)string, flags));
#endif /* !HANDLE_MULTIBYTE */
}
-366
View File
@@ -1,366 +0,0 @@
/* xmbsrtowcs.c -- replacement function for mbsrtowcs */
/* Copyright (C) 2002-2004 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/>.
*/
/* 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>
/* <wchar.h>, <wctype.h> and <stdlib.h> are included in "shmbutil.h".
If <wchar.h>, <wctype.h>, mbsrtowcs(), exist, HANDLE_MULTIBYTE
is defined as 1. */
#include <shmbutil.h>
#if HANDLE_MULTIBYTE
#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>. */
static mbstate_t local_state;
static int local_state_use = 0;
size_t
xmbsrtowcs (dest, src, len, pstate)
wchar_t *dest;
const char **src;
size_t len;
mbstate_t *pstate;
{
mbstate_t *ps;
size_t mblength, wclength, n;
ps = pstate;
if (pstate == NULL)
{
if (!local_state_use)
{
memset (&local_state, '\0', sizeof(mbstate_t));
local_state_use = 1;
}
ps = &local_state;
}
n = strlen (*src);
if (dest == NULL)
{
wchar_t *wsbuf;
const char *mbs;
mbstate_t psbuf;
/* It doesn't matter if malloc fails here, since mbsrtowcs should do
the right thing with a NULL first argument. */
wsbuf = (wchar_t *) malloc ((n + 1) * sizeof(wchar_t));
mbs = *src;
psbuf = *ps;
wclength = mbsrtowcs (wsbuf, &mbs, n, &psbuf);
if (wsbuf)
free (wsbuf);
return wclength;
}
for (wclength = 0; wclength < len; wclength++, dest++)
{
if (mbsinit(ps))
{
if (**src == '\0')
{
*dest = L'\0';
*src = NULL;
return (wclength);
}
else if (**src == '\\')
{
*dest = L'\\';
mblength = 1;
}
else
mblength = mbrtowc(dest, *src, n, ps);
}
else
mblength = mbrtowc(dest, *src, n, ps);
/* Cannot convert multibyte character to wide character. */
if (mblength == (size_t)-1 || mblength == (size_t)-2)
return (size_t)-1;
*src += mblength;
n -= mblength;
/* The multibyte string has been completely converted,
including the terminating '\0'. */
if (*dest == L'\0')
{
*src = NULL;
break;
}
}
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.
The return value is the length of the wide character string. Returns a
pointer to the wide character string in DESTP. If INDICESP is not NULL,
INDICESP stores the pointer to the pointer array. Each pointer is to
the first byte of each multibyte character. Memory for the pointer array
is obtained with malloc, too.
If conversion is failed, the return value is (size_t)-1 and the values
of DESTP and INDICESP are NULL. */
#define WSBUF_INC 32
size_t
xdupmbstowcs (destp, indicesp, src)
wchar_t **destp; /* Store the pointer to the wide character string */
char ***indicesp; /* Store the pointer to the pointer array. */
const char *src; /* Multibyte character string */
{
const char *p; /* Conversion start position of src */
wchar_t wc; /* Created wide character by conversion */
wchar_t *wsbuf; /* Buffer for wide characters. */
char **indices; /* Buffer for indices. */
size_t wsbuf_size; /* Size of WSBUF */
size_t wcnum; /* Number of wide characters in WSBUF */
mbstate_t state; /* Conversion State */
/* In case SRC or DESP is NULL, conversion doesn't take place. */
if (src == NULL || destp == NULL)
{
if (destp)
*destp = NULL;
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;
wsbuf = (wchar_t *) malloc (wsbuf_size * sizeof(wchar_t));
if (wsbuf == NULL)
{
*destp = NULL;
return (size_t)-1;
}
indices = NULL;
if (indicesp)
{
indices = (char **) malloc (wsbuf_size * sizeof(char *));
if (indices == NULL)
{
free (wsbuf);
*destp = NULL;
return (size_t)-1;
}
}
p = src;
wcnum = 0;
do
{
size_t mblength; /* Byte length of one multibyte character. */
if (mbsinit (&state))
{
if (*p == '\0')
{
wc = L'\0';
mblength = 1;
}
else if (*p == '\\')
{
wc = L'\\';
mblength = 1;
}
else
mblength = mbrtowc(&wc, p, MB_LEN_MAX, &state);
}
else
mblength = mbrtowc(&wc, p, MB_LEN_MAX, &state);
/* Conversion failed. */
if (MB_INVALIDCH (mblength))
{
free (wsbuf);
FREE (indices);
*destp = NULL;
return (size_t)-1;
}
++wcnum;
/* Resize buffers when they are not large enough. */
if (wsbuf_size < wcnum)
{
wchar_t *wstmp;
char **idxtmp;
wsbuf_size += WSBUF_INC;
wstmp = (wchar_t *) realloc (wsbuf, wsbuf_size * sizeof (wchar_t));
if (wstmp == NULL)
{
free (wsbuf);
FREE (indices);
*destp = NULL;
return (size_t)-1;
}
wsbuf = wstmp;
if (indicesp)
{
idxtmp = (char **) realloc (indices, wsbuf_size * sizeof (char **));
if (idxtmp == NULL)
{
free (wsbuf);
free (indices);
*destp = NULL;
return (size_t)-1;
}
indices = idxtmp;
}
}
wsbuf[wcnum - 1] = wc;
if (indices)
indices[wcnum - 1] = (char *)p;
p += mblength;
}
while (MB_NULLWCH (wc) == 0);
/* Return the length of the wide character string, not including `\0'. */
*destp = wsbuf;
if (indicesp != NULL)
*indicesp = indices;
return (wcnum - 1);
}
#endif /* HANDLE_MULTIBYTE */
-339
View File
@@ -1,339 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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 2 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, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
-367
View File
@@ -1,367 +0,0 @@
## -*- text -*- #############################################################
# #
# Makefile for the Bash versions of the GNU Readline and History Libraries. #
# #
#############################################################################
# Copyright (C) 1994-2009 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/>.
PACKAGE = @PACKAGE_NAME@
VERSION = @PACKAGE_VERSION@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_VERSION = @PACKAGE_VERSION@
srcdir = @srcdir@
VPATH = .:@srcdir@
topdir = @top_srcdir@
BUILD_DIR = @BUILD_DIR@
datarootdir = @datarootdir@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CC = @CC@
RANLIB = @RANLIB@
AR = @AR@
ARFLAGS = @ARFLAGS@
RM = rm -f
CP = cp
MV = mv
SHELL = @MAKE_SHELL@
# Programs to make tags files.
ETAGS = etags -tw
CTAGS = ctags -tw
CFLAGS = @CFLAGS@
LOCAL_CFLAGS = @LOCAL_CFLAGS@
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
DEFS = @DEFS@
LOCAL_DEFS = @LOCAL_DEFS@
INCLUDES = -I. -I$(BUILD_DIR) -I$(topdir) -I$(topdir)/lib
CCFLAGS = $(DEFS) $(LOCAL_DEFS) $(APP_CFLAGS) $(CPPFLAGS) ${INCLUDES} $(LOCAL_CFLAGS) $(CFLAGS)
.c.o:
${RM} $@
$(CC) -c $(CCFLAGS) $<
# The name of the main library target.
LIBRARY_NAME = libreadline.a
# The C code source files for this library.
CSOURCES = $(srcdir)/readline.c $(srcdir)/funmap.c $(srcdir)/keymaps.c \
$(srcdir)/vi_mode.c $(srcdir)/parens.c $(srcdir)/rltty.c \
$(srcdir)/complete.c $(srcdir)/bind.c $(srcdir)/isearch.c \
$(srcdir)/display.c $(srcdir)/signals.c $(srcdir)/emacs_keymap.c \
$(srcdir)/vi_keymap.c $(srcdir)/util.c $(srcdir)/kill.c \
$(srcdir)/undo.c $(srcdir)/macro.c $(srcdir)/input.c \
$(srcdir)/callback.c $(srcdir)/terminal.c $(srcdir)/xmalloc.c \
$(srcdir)/history.c $(srcdir)/histsearch.c $(srcdir)/histexpand.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
# The header files for this library.
HSOURCES = readline.h rldefs.h chardefs.h keymaps.h history.h histlib.h \
posixstat.h posixdir.h posixjmp.h tilde.h rlconf.h rltty.h \
ansi_stdlib.h rlstdc.h tcap.h xmalloc.h rlprivate.h rlshell.h \
rltypedefs.h rlmbutil.h
HISTOBJ = history.o histexpand.o histfile.o histsearch.o shell.o savestring.o \
mbutil.o
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
# The texinfo files which document this library.
DOCSOURCE = doc/rlman.texinfo doc/rltech.texinfo doc/rluser.texinfo
DOCOBJECT = doc/readline.dvi
DOCSUPPORT = doc/Makefile
DOCUMENTATION = $(DOCSOURCE) $(DOCOBJECT) $(DOCSUPPORT)
SUPPORT = Makefile ChangeLog $(DOCSUPPORT) examples/[-a-z.]*
SOURCES = $(CSOURCES) $(HSOURCES) $(DOCSOURCE)
THINGS_TO_TAR = $(SOURCES) $(SUPPORT)
INSTALLED_HEADERS = readline.h chardefs.h keymaps.h history.h tilde.h \
rlstdc.h rlconf.h rltypedefs.h
##########################################################################
all: libreadline.a libhistory.a
libreadline.a: $(OBJECTS)
$(RM) $@
$(AR) $(ARFLAGS) $@ $(OBJECTS)
-test -n "$(RANLIB)" && $(RANLIB) $@
libhistory.a: $(HISTOBJ) xmalloc.o
$(RM) $@
$(AR) $(ARFLAGS) $@ $(HISTOBJ) xmalloc.o
-test -n "$(RANLIB)" && $(RANLIB) $@
documentation: force
test -d doc || mkdir doc
-( cd doc && $(MAKE) $(MFLAGS) )
# Since tilde.c is shared between readline and bash, make sure we compile
# it with the right flags when it's built as part of readline
tilde.o: tilde.c
rm -f $@
$(CC) $(CCFLAGS) -DREADLINE_LIBRARY -c $(srcdir)/tilde.c
force:
install:
@echo "This version of the readline library should not be installed."
uninstall:
@echo "This version of the readline library should not be installed."
TAGS: force
$(ETAGS) $(CSOURCES) $(HSOURCES)
tags: force
$(CTAGS) $(CSOURCES) $(HSOURCES)
clean: force
$(RM) $(OBJECTS) *.a
-( cd doc && $(MAKE) $(MFLAGS) $@ )
mostlyclean: clean
-( cd doc && $(MAKE) $(MFLAGS) $@ )
distclean maintainer-clean: clean
-( cd doc && $(MAKE) $(MFLAGS) $@ )
$(RM) Makefile
$(RM) TAGS tags
# Dependencies
bind.o: ansi_stdlib.h posixstat.h
bind.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
bind.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
bind.o: history.h rlstdc.h
callback.o: rlconf.h ansi_stdlib.h
callback.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
callback.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h
compat.o: rlstdc.h
complete.o: ansi_stdlib.h posixdir.h posixstat.h
complete.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
complete.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h
display.o: ansi_stdlib.h posixstat.h
display.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
display.o: tcap.h
display.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
display.o: history.h rlstdc.h
funmap.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
funmap.o: rlconf.h ansi_stdlib.h rlstdc.h
funmap.o: ${BUILD_DIR}/config.h
histexpand.o: ansi_stdlib.h
histexpand.o: history.h histlib.h rlstdc.h
histexpand.o: ${BUILD_DIR}/config.h
histfile.o: ansi_stdlib.h
histfile.o: history.h histlib.h rlstdc.h
histfile.o: ${BUILD_DIR}/config.h
history.o: ansi_stdlib.h
history.o: history.h histlib.h rlstdc.h
history.o: ${BUILD_DIR}/config.h
histsearch.o: ansi_stdlib.h
histsearch.o: history.h histlib.h rlstdc.h
histsearch.o: ${BUILD_DIR}/config.h
input.o: ansi_stdlib.h
input.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
input.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h
isearch.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
isearch.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
isearch.o: ansi_stdlib.h history.h rlstdc.h
keymaps.o: emacs_keymap.c vi_keymap.c
keymaps.o: keymaps.h rltypedefs.h chardefs.h rlconf.h ansi_stdlib.h
keymaps.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
keymaps.o: ${BUILD_DIR}/config.h rlstdc.h
kill.o: ansi_stdlib.h
kill.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
kill.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
kill.o: history.h rlstdc.h
macro.o: ansi_stdlib.h
macro.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
macro.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
macro.o: history.h rlstdc.h
mbutil.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h rlmbutil.h
mbutil.o: readline.h keymaps.h rltypedefs.h chardefs.h rlstdc.h
misc.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
misc.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
misc.o: history.h rlstdc.h ansi_stdlib.h
nls.o: ansi_stdlib.h
nls.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
nls.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
nls.o: history.h rlstdc.h
parens.o: rlconf.h
parens.o: ${BUILD_DIR}/config.h
parens.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h
readline.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
readline.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
readline.o: history.h rlstdc.h
readline.o: posixstat.h ansi_stdlib.h posixjmp.h
rltty.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
rltty.o: rltty.h
rltty.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h
search.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
search.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
search.o: ansi_stdlib.h history.h rlstdc.h
shell.o: ${BUILD_DIR}/config.h ansi_stdlib.h
signals.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
signals.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
signals.o: history.h rlstdc.h
terminal.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
terminal.o: tcap.h
terminal.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
terminal.o: history.h rlstdc.h
text.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
text.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
text.o: history.h rlstdc.h ansi_stdlib.h
rltty.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
tilde.o: ansi_stdlib.h
tilde.o: ${BUILD_DIR}/config.h
tilde.o: tilde.h
undo.o: ansi_stdlib.h
undo.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
undo.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
undo.o: history.h rlstdc.h xmalloc.h
util.o: posixjmp.h ansi_stdlib.h
util.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
util.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h
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
bind.o: rlshell.h
histfile.o: rlshell.h
nls.o: rlshell.h
readline.o: rlshell.h
shell.o: rlshell.h
terminal.o: rlshell.h
histexpand.o: rlshell.h
bind.o: rlprivate.h
callback.o: rlprivate.h
complete.o: rlprivate.h
display.o: rlprivate.h
input.o: rlprivate.h
isearch.o: rlprivate.h
kill.o: rlprivate.h
macro.o: rlprivate.h
mbutil.o: rlprivate.h
misc.o: rlprivate.h
nls.o: rlprivate.h
parens.o: rlprivate.h
readline.o: rlprivate.h
rltty.o: rlprivate.h
search.o: rlprivate.h
signals.o: rlprivate.h
terminal.o: rlprivate.h
text.o: rlprivate.h
undo.o: rlprivate.h
util.o: rlprivate.h
vi_mode.o: rlprivate.h
bind.o: xmalloc.h
complete.o: xmalloc.h
display.o: xmalloc.h
funmap.o: xmalloc.h
histexpand.o: xmalloc.h
histfile.o: xmalloc.h
history.o: xmalloc.h
input.o: xmalloc.h
isearch.o: xmalloc.h
keymaps.o: xmalloc.h
kill.o: xmalloc.h
macro.o: xmalloc.h
mbutil.o: xmalloc.h
misc.o: xmalloc.h
readline.o: xmalloc.h
savestring.o: xmalloc.h
search.o: xmalloc.h
shell.o: xmalloc.h
terminal.o: xmalloc.h
text.o: xmalloc.h
tilde.o: xmalloc.h
undo.o: xmalloc.h
util.o: xmalloc.h
vi_mode.o: xmalloc.h
xmalloc.o: xmalloc.h
complete.o: rlmbutil.h
display.o: rlmbutil.h
histexpand.o: rlmbutil.h
input.o: rlmbutil.h
isearch.o: rlmbutil.h
mbutil.o: rlmbutil.h
misc.o: rlmbutil.h
readline.o: rlmbutil.h
search.o: rlmbutil.h
text.o: rlmbutil.h
vi_mode.o: rlmbutil.h
# Rules for deficient makes, like SunOS and Solaris
bind.o: bind.c
callback.o: callback.c
compat.o: compat.c
complete.o: complete.c
display.o: display.c
funmap.o: funmap.c
input.o: input.c
isearch.o: isearch.c
keymaps.o: keymaps.c emacs_keymap.c vi_keymap.c
kill.o: kill.c
macro.o: macro.c
mbutil.o: mbutil.c
misc.o: misc.c
nls.o: nls.c
parens.o: parens.c
readline.o: readline.c
rltty.o: rltty.c
savestring.o: savestring.c
search.o: search.c
shell.o: shell.c
signals.o: signals.c
terminal.o: terminal.c
text.o: text.c
tilde.o: tilde.c
undo.o: undo.c
util.o: util.c
vi_mode.o: vi_mode.c
xmalloc.o: xmalloc.c
histexpand.o: histexpand.c
histfile.o: histfile.c
history.o: history.c
histsearch.o: histsearch.c
-2391
View File
File diff suppressed because it is too large Load Diff
-270
View File
@@ -1,270 +0,0 @@
/* callback.c -- functions to use readline as an X `callback' mechanism. */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Readline is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include "rlconf.h"
#if defined (READLINE_CALLBACKS)
#include <sys/types.h>
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif
#include <stdio.h>
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#include "readline.h"
#include "rlprivate.h"
#include "xmalloc.h"
/* Private data for callback registration functions. See comments in
rl_callback_read_char for more details. */
_rl_callback_func_t *_rl_callback_func = 0;
_rl_callback_generic_arg *_rl_callback_data = 0;
/* **************************************************************** */
/* */
/* Callback Readline Functions */
/* */
/* **************************************************************** */
/* Allow using readline in situations where a program may have multiple
things to handle at once, and dispatches them via select(). Call
rl_callback_handler_install() with the prompt and a function to call
whenever a complete line of input is ready. The user must then
call rl_callback_read_char() every time some input is available, and
rl_callback_read_char() will call the user's function with the complete
text read in at each end of line. The terminal is kept prepped and
signals handled all the time, except during calls to the user's function. */
rl_vcpfunc_t *rl_linefunc; /* user callback function */
static int in_handler; /* terminal_prepped and signals set? */
/* Make sure the terminal is set up, initialize readline, and prompt. */
static void
_rl_callback_newline ()
{
rl_initialize ();
if (in_handler == 0)
{
in_handler = 1;
if (rl_prep_term_function)
(*rl_prep_term_function) (_rl_meta_flag);
#if defined (HANDLE_SIGNALS)
rl_set_signals ();
#endif
}
readline_internal_setup ();
RL_CHECK_SIGNALS ();
}
/* Install a readline handler, set up the terminal, and issue the prompt. */
void
rl_callback_handler_install (prompt, linefunc)
const char *prompt;
rl_vcpfunc_t *linefunc;
{
rl_set_prompt (prompt);
RL_SETSTATE (RL_STATE_CALLBACK);
rl_linefunc = linefunc;
_rl_callback_newline ();
}
/* Read one character, and dispatch to the handler if it ends the line. */
void
rl_callback_read_char ()
{
char *line;
int eof, jcode;
static procenv_t olevel;
if (rl_linefunc == NULL)
{
_rl_errmsg ("readline_callback_read_char() called with no handler!");
abort ();
}
memcpy ((void *)olevel, (void *)_rl_top_level, sizeof (procenv_t));
jcode = setjmp (_rl_top_level);
if (jcode)
{
(*rl_redisplay_function) ();
_rl_want_redisplay = 0;
memcpy ((void *)_rl_top_level, (void *)olevel, sizeof (procenv_t));
return;
}
do
{
RL_CHECK_SIGNALS ();
if (RL_ISSTATE (RL_STATE_ISEARCH))
{
eof = _rl_isearch_callback (_rl_iscxt);
if (eof == 0 && (RL_ISSTATE (RL_STATE_ISEARCH) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING))
rl_callback_read_char ();
return;
}
else if (RL_ISSTATE (RL_STATE_NSEARCH))
{
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 and turning off
RL_STATE_VIMOTION */
return;
}
#endif
else if (RL_ISSTATE (RL_STATE_NUMERICARG))
{
eof = _rl_arg_callback (_rl_argcxt);
if (eof == 0 && (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING))
rl_callback_read_char ();
/* XXX - this should handle _rl_last_command_was_kill better */
else if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)
_rl_internal_char_cleanup ();
return;
}
else if (RL_ISSTATE (RL_STATE_MULTIKEY))
{
eof = _rl_dispatch_callback (_rl_kscxt); /* For now */
while ((eof == -1 || eof == -2) && RL_ISSTATE (RL_STATE_MULTIKEY) && _rl_kscxt && (_rl_kscxt->flags & KSEQ_DISPATCHED))
eof = _rl_dispatch_callback (_rl_kscxt);
if (RL_ISSTATE (RL_STATE_MULTIKEY) == 0)
{
_rl_internal_char_cleanup ();
_rl_want_redisplay = 1;
}
}
else if (_rl_callback_func)
{
/* This allows functions that simply need to read an additional
character (like quoted-insert) to register a function to be
called when input is available. _rl_callback_data is simply a
pointer to a struct that has the argument count originally
passed to the registering function and space for any additional
parameters. */
eof = (*_rl_callback_func) (_rl_callback_data);
/* If the function `deregisters' itself, make sure the data is
cleaned up. */
if (_rl_callback_func == 0)
{
if (_rl_callback_data)
{
_rl_callback_data_dispose (_rl_callback_data);
_rl_callback_data = 0;
}
_rl_internal_char_cleanup ();
}
}
else
eof = readline_internal_char ();
RL_CHECK_SIGNALS ();
if (rl_done == 0 && _rl_want_redisplay)
{
(*rl_redisplay_function) ();
_rl_want_redisplay = 0;
}
if (rl_done)
{
line = readline_internal_teardown (eof);
if (rl_deprep_term_function)
(*rl_deprep_term_function) ();
#if defined (HANDLE_SIGNALS)
rl_clear_signals ();
#endif
in_handler = 0;
(*rl_linefunc) (line);
/* If the user did not clear out the line, do it for him. */
if (rl_line_buffer[0])
_rl_init_line_state ();
/* Redisplay the prompt if readline_handler_{install,remove}
not called. */
if (in_handler == 0 && rl_linefunc)
_rl_callback_newline ();
}
}
while (rl_pending_input || _rl_pushed_input_available () || RL_ISSTATE (RL_STATE_MACROINPUT));
}
/* Remove the handler, and make sure the terminal is in its normal state. */
void
rl_callback_handler_remove ()
{
rl_linefunc = NULL;
RL_UNSETSTATE (RL_STATE_CALLBACK);
RL_CHECK_SIGNALS ();
if (in_handler)
{
in_handler = 0;
if (rl_deprep_term_function)
(*rl_deprep_term_function) ();
#if defined (HANDLE_SIGNALS)
rl_clear_signals ();
#endif
}
}
_rl_callback_generic_arg *
_rl_callback_data_alloc (count)
int count;
{
_rl_callback_generic_arg *arg;
arg = (_rl_callback_generic_arg *)xmalloc (sizeof (_rl_callback_generic_arg));
arg->count = count;
arg->i1 = arg->i2 = 0;
return arg;
}
void _rl_callback_data_dispose (arg)
_rl_callback_generic_arg *arg;
{
xfree (arg);
}
#endif
File diff suppressed because it is too large Load Diff
-76
View File
@@ -1,76 +0,0 @@
# This makefile for Readline library documentation is in -*- text -*- mode.
# Emacs likes it that way.
RM = rm -f
MAKEINFO = makeinfo
TEXI2DVI = texi2dvi
TEXI2HTML = texi2html
QUIETPS = #set this to -q to shut up dvips
DVIPS = dvips -D 300 $(QUIETPS) -o $@ # tricky
INSTALL_DATA = cp
infodir = /usr/local/info
RLSRC = rlman.texinfo rluser.texinfo rltech.texinfo
HISTSRC = hist.texinfo hsuser.texinfo hstech.texinfo
DVIOBJ = readline.dvi history.dvi
INFOOBJ = readline.info history.info
PSOBJ = readline.ps history.ps
HTMLOBJ = readline.html history.html
all: info dvi html ps
nodvi: info html
readline.dvi: $(RLSRC)
$(TEXI2DVI) rlman.texinfo
mv rlman.dvi readline.dvi
readline.info: $(RLSRC)
$(MAKEINFO) --no-split -o $@ rlman.texinfo
history.dvi: ${HISTSRC}
$(TEXI2DVI) hist.texinfo
mv hist.dvi history.dvi
history.info: ${HISTSRC}
$(MAKEINFO) --no-split -o $@ hist.texinfo
readline.ps: readline.dvi
$(RM) $@
$(DVIPS) readline.dvi
history.ps: history.dvi
$(RM) $@
$(DVIPS) history.dvi
readline.html: ${RLSRC}
$(TEXI2HTML) rlman.texinfo
sed -e 's:rlman.html:readline.html:' -e 's:rlman_toc.html:readline_toc.html:' rlman.html > readline.html
sed -e 's:rlman.html:readline.html:' -e 's:rlman_toc.html:readline_toc.html:' rlman_toc.html > readline_toc.html
$(RM) rlman.html rlman_toc.html
history.html: ${HISTSRC}
$(TEXI2HTML) hist.texinfo
sed -e 's:hist.html:history.html:' -e 's:hist_toc.html:history_toc.html:' hist.html > history.html
sed -e 's:hist.html:history.html:' -e 's:hist_toc.html:history_toc.html:' hist_toc.html > history_toc.html
$(RM) hist.html hist_toc.html
info: $(INFOOBJ)
dvi: $(DVIOBJ)
ps: $(PSOBJ)
html: $(HTMLOBJ)
clean:
$(RM) *.aux *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps *.pgs \
*.fns *.kys *.tps *.vrs *.o core
distclean: clean
mostlyclean: clean
maintainer-clean: clean
$(RM) *.dvi *.info *.info-* *.ps *.html
install: info
${INSTALL_DATA} readline.info $(infodir)/readline.info
${INSTALL_DATA} history.info $(infodir)/history.info
-672
View File
@@ -1,672 +0,0 @@
.\"
.\" MAN PAGE COMMENTS to
.\"
.\" Chet Ramey
.\" Information Network Services
.\" Case Western Reserve University
.\" chet@ins.CWRU.Edu
.\"
.\" Last Change: Tue Aug 3 15:23:38 EDT 2010
.\"
.TH HISTORY 3 "2010 August 3" "GNU History 6.2"
.\"
.\" File Name macro. This used to be `.PN', for Path Name,
.\" but Sun doesn't seem to like that very much.
.\"
.de FN
\fI\|\\$1\|\fP
..
.ds lp \fR\|(\fP
.ds rp \fR\|)\fP
.\" FnN return-value fun-name N arguments
.de Fn1
\fI\\$1\fP \fB\\$2\fP \\*(lp\fI\\$3\fP\\*(rp
.br
..
.de Fn2
.if t \fI\\$1\fP \fB\\$2\fP \\*(lp\fI\\$3,\|\\$4\fP\\*(rp
.if n \fI\\$1\fP \fB\\$2\fP \\*(lp\fI\\$3, \\$4\fP\\*(rp
.br
..
.de Fn3
.if t \fI\\$1\fP \fB\\$2\fP \\*(lp\fI\\$3,\|\\$4,\|\\$5\fP\|\\*(rp
.if n \fI\\$1\fP \fB\\$2\fP \\*(lp\fI\\$3, \\$4, \\$5\fP\\*(rp
.br
..
.de Vb
\fI\\$1\fP \fB\\$2\fP
.br
..
.SH NAME
history \- GNU History Library
.SH COPYRIGHT
.if t The GNU History Library is Copyright \(co 1989-2010 by the Free Software Foundation, Inc.
.if n The GNU History Library is Copyright (C) 1989-2010 by the Free Software Foundation, Inc.
.SH DESCRIPTION
Many programs read input from the user a line at a time. The GNU
History library is able to keep track of those lines, associate arbitrary
data with each line, and utilize information from previous lines in
composing new ones.
.PP
.SH "HISTORY EXPANSION"
.PP
The history library supports a history expansion feature that
is identical to the history expansion in
.BR bash.
This section describes what syntax features are available.
.PP
History expansions introduce words from the history list into
the input stream, making it easy to repeat commands, insert the
arguments to a previous command into the current input line, or
fix errors in previous commands quickly.
.PP
History expansion is usually performed immediately after a complete line
is read.
It takes place in two parts.
The first is to determine which line from the history list
to use during substitution.
The second is to select portions of that line for inclusion into
the current one.
The line selected from the history is the \fIevent\fP,
and the portions of that line that are acted upon are \fIwords\fP.
Various \fImodifiers\fP are available to manipulate the selected words.
The line is broken into words in the same fashion as \fBbash\fP
does when reading input,
so that several words that would otherwise be separated
are considered one word when surrounded by quotes (see the
description of \fBhistory_tokenize()\fP below).
History expansions are introduced by the appearance of the
history expansion character, which is \^\fB!\fP\^ by default.
Only backslash (\^\fB\e\fP\^) and single quotes can quote
the history expansion character.
.SS Event Designators
.PP
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.
.PP
.PD 0
.TP
.B !
Start a history substitution, except when followed by a
.BR blank ,
newline, = or (.
.TP
.B !\fIn\fR
Refer to command line
.IR n .
.TP
.B !\-\fIn\fR
Refer to the current command minus
.IR n .
.TP
.B !!
Refer to the previous command. This is a synonym for `!\-1'.
.TP
.B !\fIstring\fR
Refer to the most recent command
preceding the current position in the history list
starting with
.IR string .
.TP
.B !?\fIstring\fR\fB[?]\fR
Refer to the most recent command
preceding the current postition in the history list
containing
.IR string .
The trailing \fB?\fP may be omitted if
.I string
is followed immediately by a newline.
.TP
.B \d\s+2^\s-2\u\fIstring1\fP\d\s+2^\s-2\u\fIstring2\fP\d\s+2^\s-2\u
Quick substitution. Repeat the last command, replacing
.I string1
with
.IR string2 .
Equivalent to
``!!:s/\fIstring1\fP/\fIstring2\fP/''
(see \fBModifiers\fP below).
.TP
.B !#
The entire command line typed so far.
.PD
.SS Word Designators
.PP
Word designators are used to select desired words from the event.
A
.B :
separates the event specification from the word designator.
It may be omitted if the word designator begins with a
.BR ^ ,
.BR $ ,
.BR * ,
.BR \- ,
or
.BR % .
Words are numbered from the beginning of the line,
with the first word being denoted by 0 (zero).
Words are inserted into the current line separated by single spaces.
.PP
.PD 0
.TP
.B 0 (zero)
The zeroth word. For the shell, this is the command
word.
.TP
.I n
The \fIn\fRth word.
.TP
.B ^
The first argument. That is, word 1.
.TP
.B $
The last argument.
.TP
.B %
The word matched by the most recent `?\fIstring\fR?' search.
.TP
.I x\fB\-\fPy
A range of words; `\-\fIy\fR' abbreviates `0\-\fIy\fR'.
.TP
.B *
All of the words but the zeroth. This is a synonym
for `\fI1\-$\fP'. It is not an error to use
.B *
if there is just one
word in the event; the empty string is returned in that case.
.TP
.B x*
Abbreviates \fIx\-$\fP.
.TP
.B x\-
Abbreviates \fIx\-$\fP like \fBx*\fP, but omits the last word.
.PD
.PP
If a word designator is supplied without an event specification, the
previous command is used as the event.
.SS Modifiers
.PP
After the optional word designator, there may appear a sequence of
one or more of the following modifiers, each preceded by a `:'.
.PP
.PD 0
.PP
.TP
.B h
Remove a trailing file name component, leaving only the head.
.TP
.B t
Remove all leading file name components, leaving the tail.
.TP
.B r
Remove a trailing suffix of the form \fI.xxx\fP, leaving the
basename.
.TP
.B e
Remove all but the trailing suffix.
.TP
.B p
Print the new command but do not execute it.
.TP
.B q
Quote the substituted words, escaping further substitutions.
.TP
.B x
Quote the substituted words as with
.BR q ,
but break into words at
.B blanks
and newlines.
.TP
.B s/\fIold\fP/\fInew\fP/
Substitute
.I new
for the first occurrence of
.I old
in the event line. Any delimiter can be used in place of /. The
final delimiter is optional if it is the last character of the
event line. The delimiter may be quoted in
.I old
and
.I new
with a single backslash. If & appears in
.IR new ,
it is replaced by
.IR old .
A single backslash will quote the &. If
.I old
is null, it is set to the last
.I old
substituted, or, if no previous history substitutions took place,
the last
.I string
in a
.B !?\fIstring\fR\fB[?]\fR
search.
.TP
.B &
Repeat the previous substitution.
.TP
.B g
Cause changes to be applied over the entire event line. This is
used in conjunction with `\fB:s\fP' (e.g., `\fB:gs/\fIold\fP/\fInew\fP/\fR')
or `\fB:&\fP'. If used with
`\fB:s\fP', any delimiter can be used
in place of /, and the final delimiter is optional
if it is the last character of the event line.
An \fBa\fP may be used as a synonym for \fBg\fP.
.TP
.B G
Apply the following `\fBs\fP' modifier once to each word in the event line.
.PD
.SH "PROGRAMMING WITH HISTORY FUNCTIONS"
This section describes how to use the History library in other programs.
.SS Introduction to History
.PP
The programmer using the History library has available functions
for remembering lines on a history list, associating arbitrary data
with a line, removing lines from the list, searching through the list
for a line containing an arbitrary text string, and referencing any line
in the list directly. In addition, a history \fIexpansion\fP function
is available which provides for a consistent user interface across
different programs.
.PP
The user using programs written with the History library has the
benefit of a consistent user interface with a set of well-known
commands for manipulating the text of previous lines and using that text
in new commands. The basic history manipulation commands are
identical to
the history substitution provided by \fBbash\fP.
.PP
If the programmer desires, he can use the Readline library, which
includes some history manipulation by default, and has the added
advantage of command line editing.
.PP
Before declaring any functions using any functionality the History
library provides in other code, an application writer should include
the file
.FN <readline/history.h>
in any file that uses the
History library's features. It supplies extern declarations for all
of the library's public functions and variables, and declares all of
the public data structures.
.SS History Storage
.PP
The history list is an array of history entries. A history entry is
declared as follows:
.PP
.Vb "typedef void *" histdata_t;
.PP
.nf
typedef struct _hist_entry {
char *line;
char *timestamp;
histdata_t data;
} HIST_ENTRY;
.fi
.PP
The history list itself might therefore be declared as
.PP
.Vb "HIST_ENTRY **" the_history_list;
.PP
The state of the History library is encapsulated into a single structure:
.PP
.nf
/*
* A structure used to pass around the current state of the history.
*/
typedef struct _hist_state {
HIST_ENTRY **entries; /* Pointer to the entries themselves. */
int offset; /* The location pointer within this array. */
int length; /* Number of elements within this array. */
int size; /* Number of slots allocated to this array. */
int flags;
} HISTORY_STATE;
.fi
.PP
If the flags member includes \fBHS_STIFLED\fP, the history has been
stifled.
.SH "History Functions"
.PP
This section describes the calling sequence for the various functions
exported by the GNU History library.
.SS Initializing History and State Management
This section describes functions used to initialize and manage
the state of the History library when you want to use the history
functions in your program.
.Fn1 void using_history void
Begin a session in which the history functions might be used. This
initializes the interactive variables.
.Fn1 "HISTORY_STATE *" history_get_history_state void
Return a structure describing the current state of the input history.
.Fn1 void history_set_history_state "HISTORY_STATE *state"
Set the state of the history list according to \fIstate\fP.
.SS History List Management
These functions manage individual entries on the history list, or set
parameters managing the list itself.
.Fn1 void add_history "const char *string"
Place \fIstring\fP at the end of the history list. The associated data
field (if any) is set to \fBNULL\fP.
.Fn1 void add_history_time "const char *string"
Change the time stamp associated with the most recent history entry to
\fIstring\fP.
.Fn1 "HIST_ENTRY *" remove_history "int which"
Remove history entry at offset \fIwhich\fP from the history. The
removed element is returned so you can free the line, data,
and containing structure.
.Fn1 "histdata_t" free_history_entry "HIST_ENTRY *histent"
Free the history entry \fIhistent\fP and any history library private
data associated with it. Returns the application-specific data
so the caller can dispose of it.
.Fn3 "HIST_ENTRY *" replace_history_entry "int which" "const char *line" "histdata_t data"
Make the history entry at offset \fIwhich\fP have \fIline\fP and \fIdata\fP.
This returns the old entry so the caller can dispose of any
application-specific data. In the case
of an invalid \fIwhich\fP, a \fBNULL\fP pointer is returned.
.Fn1 void clear_history "void"
Clear the history list by deleting all the entries.
.Fn1 void stifle_history "int max"
Stifle the history list, remembering only the last \fImax\fP entries.
.Fn1 int unstifle_history "void"
Stop stifling the history. This returns the previously-set
maximum number of history entries (as set by \fBstifle_history()\fP).
history was stifled. The value is positive if the history was
stifled, negative if it wasn't.
.Fn1 int history_is_stifled "void"
Returns non-zero if the history is stifled, zero if it is not.
.SS Information About the History List
These functions return information about the entire history list or
individual list entries.
.Fn1 "HIST_ENTRY **" history_list "void"
Return a \fBNULL\fP terminated array of \fIHIST_ENTRY *\fP which is the
current input history. Element 0 of this list is the beginning of time.
If there is no history, return \fBNULL\fP.
.Fn1 int where_history "void"
Returns the offset of the current history element.
.Fn1 "HIST_ENTRY *" current_history "void"
Return the history entry at the current position, as determined by
\fBwhere_history()\fP. If there is no entry there, return a \fBNULL\fP
pointer.
.Fn1 "HIST_ENTRY *" history_get "int offset"
Return the history entry at position \fIoffset\fP, starting from
\fBhistory_base\fP.
If there is no entry there, or if \fIoffset\fP
is greater than the history length, return a \fBNULL\fP pointer.
.Fn1 "time_t" history_get_time "HIST_ENTRY *"
Return the time stamp associated with the history entry passed as the argument.
.Fn1 int history_total_bytes "void"
Return the number of bytes that the primary history entries are using.
This function returns the sum of the lengths of all the lines in the
history.
.SS Moving Around the History List
These functions allow the current index into the history list to be
set or changed.
.Fn1 int history_set_pos "int pos"
Set the current history offset to \fIpos\fP, an absolute index
into the list.
Returns 1 on success, 0 if \fIpos\fP is less than zero or greater
than the number of history entries.
.Fn1 "HIST_ENTRY *" previous_history "void"
Back up the current history offset to the previous history entry, and
return a pointer to that entry. If there is no previous entry, return
a \fBNULL\fP pointer.
.Fn1 "HIST_ENTRY *" next_history "void"
Move the current history offset forward to the next history entry, and
return the a pointer to that entry. If there is no next entry, return
a \fBNULL\fP pointer.
.SS Searching the History List
These functions allow searching of the history list for entries containing
a specific string. Searching may be performed both forward and backward
from the current history position. The search may be \fIanchored\fP,
meaning that the string must match at the beginning of the history entry.
.Fn2 int history_search "const char *string" "int direction"
Search the history for \fIstring\fP, starting at the current history offset.
If \fIdirection\fP is less than 0, then the search is through
previous entries, otherwise through subsequent entries.
If \fIstring\fP is found, then
the current history index is set to that history entry, and the value
returned is the offset in the line of the entry where
\fIstring\fP was found. Otherwise, nothing is changed, and a -1 is
returned.
.Fn2 int history_search_prefix "const char *string" "int direction"
Search the history for \fIstring\fP, starting at the current history
offset. The search is anchored: matching lines must begin with
\fIstring\fP. If \fIdirection\fP is less than 0, then the search is
through previous entries, otherwise through subsequent entries.
If \fIstring\fP is found, then the
current history index is set to that entry, and the return value is 0.
Otherwise, nothing is changed, and a -1 is returned.
.Fn3 int history_search_pos "const char *string" "int direction" "int pos"
Search for \fIstring\fP in the history list, starting at \fIpos\fP, an
absolute index into the list. If \fIdirection\fP is negative, the search
proceeds backward from \fIpos\fP, otherwise forward. Returns the absolute
index of the history element where \fIstring\fP was found, or -1 otherwise.
.SS Managing the History File
The History library can read the history from and write it to a file.
This section documents the functions for managing a history file.
.Fn1 int read_history "const char *filename"
Add the contents of \fIfilename\fP to the history list, a line at a time.
If \fIfilename\fP is \fBNULL\fP, then read from \fI~/.history\fP.
Returns 0 if successful, or \fBerrno\fP if not.
.Fn3 int read_history_range "const char *filename" "int from" "int to"
Read a range of lines from \fIfilename\fP, adding them to the history list.
Start reading at line \fIfrom\fP and end at \fIto\fP.
If \fIfrom\fP is zero, start at the beginning. If \fIto\fP is less than
\fIfrom\fP, then read until the end of the file. If \fIfilename\fP is
\fBNULL\fP, then read from \fI~/.history\fP. Returns 0 if successful,
or \fBerrno\fP if not.
.Fn1 int write_history "const char *filename"
Write the current history to \fIfilename\fP, overwriting \fIfilename\fP
if necessary.
If \fIfilename\fP is \fBNULL\fP, then write the history list to \fI~/.history\fP.
Returns 0 on success, or \fBerrno\fP on a read or write error.
.Fn2 int append_history "int nelements" "const char *filename"
Append the last \fInelements\fP of the history list to \fIfilename\fP.
If \fIfilename\fP is \fBNULL\fP, then append to \fI~/.history\fP.
Returns 0 on success, or \fBerrno\fP on a read or write error.
.Fn2 int history_truncate_file "const char *filename" "int nlines"
Truncate the history file \fIfilename\fP, leaving only the last
\fInlines\fP lines.
If \fIfilename\fP is \fBNULL\fP, then \fI~/.history\fP is truncated.
Returns 0 on success, or \fBerrno\fP on failure.
.SS History Expansion
These functions implement history expansion.
.Fn2 int history_expand "char *string" "char **output"
Expand \fIstring\fP, placing the result into \fIoutput\fP, a pointer
to a string. Returns:
.RS
.PD 0
.TP
0
If no expansions took place (or, if the only change in
the text was the removal of escape characters preceding the history expansion
character);
.TP
1
if expansions did take place;
.TP
-1
if there was an error in expansion;
.TP
2
if the returned line should be displayed, but not executed,
as with the \fB:p\fP modifier.
.PD
.RE
If an error ocurred in expansion, then \fIoutput\fP contains a descriptive
error message.
.Fn3 "char *" get_history_event "const char *string" "int *cindex" "int qchar"
Returns the text of the history event beginning at \fIstring\fP +
\fI*cindex\fP. \fI*cindex\fP is modified to point to after the event
specifier. At function entry, \fIcindex\fP points to the index into
\fIstring\fP where the history event specification begins. \fIqchar\fP
is a character that is allowed to end the event specification in addition
to the ``normal'' terminating characters.
.Fn1 "char **" history_tokenize "const char *string"
Return an array of tokens parsed out of \fIstring\fP, much as the
shell might.
The tokens are split on the characters in the
\fBhistory_word_delimiters\fP variable,
and shell quoting conventions are obeyed.
.Fn3 "char *" history_arg_extract "int first" "int last" "const char *string"
Extract a string segment consisting of the \fIfirst\fP through \fIlast\fP
arguments present in \fIstring\fP. Arguments are split using
\fBhistory_tokenize()\fP.
.SS History Variables
This section describes the externally-visible variables exported by
the GNU History Library.
.Vb int history_base
The logical offset of the first entry in the history list.
.Vb int history_length
The number of entries currently stored in the history list.
.Vb int history_max_entries
The maximum number of history entries. This must be changed using
\fBstifle_history()\fP.
.Vb int history_wite_timestamps
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 \fIhistory_comment_char\fP
to delimit timestamp entries in the history file. If that variable does
not have a value (the default), timestamps will not be written.
.Vb char history_expansion_char
The character that introduces a history event. The default is \fB!\fP.
Setting this to 0 inhibits history expansion.
.Vb char history_subst_char
The character that invokes word substitution if found at the start of
a line. The default is \fB^\fP.
.Vb char history_comment_char
During tokenization, if this character is seen as the first character
of a word, then it and all subsequent characters up to a newline are
ignored, suppressing history expansion for the remainder of the line.
This is disabled by default.
.Vb "char *" history_word_delimiters
The characters that separate tokens for \fBhistory_tokenize()\fP.
The default value is \fB"\ \et\en()<>;&|"\fP.
.Vb "char *" history_no_expand_chars
The list of characters which inhibit history expansion if found immediately
following \fBhistory_expansion_char\fP. The default is space, tab, newline,
\fB\er\fP, and \fB=\fP.
.Vb "char *" history_search_delimiter_chars
The list of additional characters which can delimit a history search
string, in addition to space, tab, \fI:\fP and \fI?\fP in the case of
a substring search. The default is empty.
.Vb int history_quotes_inhibit_expansion
If non-zero, single-quoted words are not scanned for the history expansion
character. The default value is 0.
.Vb "rl_linebuf_func_t *" history_inhibit_expansion_function
This should be set to the address of a function that takes two arguments:
a \fBchar *\fP (\fIstring\fP)
and an \fBint\fP index into that string (\fIi\fP).
It should return a non-zero value if the history expansion starting at
\fIstring[i]\fP should not be performed; zero if the expansion should
be done.
It is intended for use by applications like \fBbash\fP that use the history
expansion character for additional purposes.
By default, this variable is set to \fBNULL\fP.
.SH FILES
.PD 0
.TP
.FN ~/.history
Default filename for reading and writing saved history
.PD
.SH "SEE ALSO"
.PD 0
.TP
\fIThe Gnu Readline Library\fP, Brian Fox and Chet Ramey
.TP
\fIThe Gnu History Library\fP, Brian Fox and Chet Ramey
.TP
\fIbash\fP(1)
.TP
\fIreadline\fP(3)
.PD
.SH AUTHORS
Brian Fox, Free Software Foundation
.br
bfox@gnu.org
.PP
Chet Ramey, Case Western Reserve University
.br
chet@ins.CWRU.Edu
.SH BUG REPORTS
If you find a bug in the
.B history
library, you should report it. But first, you should
make sure that it really is a bug, and that it appears in the latest
version of the
.B history
library that you have.
.PP
Once you have determined that a bug actually exists, mail a
bug report to \fIbug\-readline\fP@\fIgnu.org\fP.
If you have a fix, you are welcome to mail that
as well! Suggestions and `philosophical' bug reports may be mailed
to \fPbug-readline\fP@\fIgnu.org\fP or posted to the Usenet
newsgroup
.BR gnu.bash.bug .
.PP
Comments and bug reports concerning
this manual page should be directed to
.IR chet@ins.CWRU.Edu .
-573
View File
@@ -1,573 +0,0 @@
@ignore
This file documents the user interface to the GNU History library.
Copyright (C) 1988-2007 Free Software Foundation, Inc.
Authored by Brian Fox and Chet Ramey.
Permission is granted to make and distribute verbatim copies of this manual
provided the copyright notice and this permission notice are preserved on
all copies.
Permission is granted to process this file through Tex and print the
results, provided the printed document carries copying permission notice
identical to this one except for the removal of this paragraph (this
paragraph not being relevant to the printed manual).
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that the
GNU Copyright statement is available to the distributee, and provided that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions.
@end ignore
@node Programming with GNU History
@chapter Programming with GNU History
This chapter describes how to interface programs that you write
with the @sc{gnu} History Library.
It should be considered a technical guide.
For information on the interactive use of @sc{gnu} History, @pxref{Using
History Interactively}.
@menu
* Introduction to History:: What is the GNU History library for?
* History Storage:: How information is stored.
* History Functions:: Functions that you can use.
* History Variables:: Variables that control behaviour.
* History Programming Example:: Example of using the GNU History Library.
@end menu
@node Introduction to History
@section Introduction to History
Many programs read input from the user a line at a time. The @sc{gnu}
History library is able to keep track of those lines, associate arbitrary
data with each line, and utilize information from previous lines in
composing new ones.
The programmer using the History library has available functions
for remembering lines on a history list, associating arbitrary data
with a line, removing lines from the list, searching through the list
for a line containing an arbitrary text string, and referencing any line
in the list directly. In addition, a history @dfn{expansion} function
is available which provides for a consistent user interface across
different programs.
The user using programs written with the History library has the
benefit of a consistent user interface with a set of well-known
commands for manipulating the text of previous lines and using that text
in new commands. The basic history manipulation commands are similar to
the history substitution provided by @code{csh}.
If the programmer desires, he can use the Readline library, which
includes some history manipulation by default, and has the added
advantage of command line editing.
Before declaring any functions using any functionality the History
library provides in other code, an application writer should include
the file @code{<readline/history.h>} in any file that uses the
History library's features. It supplies extern declarations for all
of the library's public functions and variables, and declares all of
the public data structures.
@node History Storage
@section History Storage
The history list is an array of history entries. A history entry is
declared as follows:
@example
typedef void *histdata_t;
typedef struct _hist_entry @{
char *line;
char *timestamp;
histdata_t data;
@} HIST_ENTRY;
@end example
The history list itself might therefore be declared as
@example
HIST_ENTRY **the_history_list;
@end example
The state of the History library is encapsulated into a single structure:
@example
/*
* A structure used to pass around the current state of the history.
*/
typedef struct _hist_state @{
HIST_ENTRY **entries; /* Pointer to the entries themselves. */
int offset; /* The location pointer within this array. */
int length; /* Number of elements within this array. */
int size; /* Number of slots allocated to this array. */
int flags;
@} HISTORY_STATE;
@end example
If the flags member includes @code{HS_STIFLED}, the history has been
stifled.
@node History Functions
@section History Functions
This section describes the calling sequence for the various functions
exported by the @sc{gnu} History library.
@menu
* Initializing History and State Management:: Functions to call when you
want to use history in a
program.
* History List Management:: Functions used to manage the list
of history entries.
* Information About the History List:: Functions returning information about
the history list.
* Moving Around the History List:: Functions used to change the position
in the history list.
* Searching the History List:: Functions to search the history list
for entries containing a string.
* Managing the History File:: Functions that read and write a file
containing the history list.
* History Expansion:: Functions to perform csh-like history
expansion.
@end menu
@node Initializing History and State Management
@subsection Initializing History and State Management
This section describes functions used to initialize and manage
the state of the History library when you want to use the history
functions in your program.
@deftypefun void using_history (void)
Begin a session in which the history functions might be used. This
initializes the interactive variables.
@end deftypefun
@deftypefun {HISTORY_STATE *} history_get_history_state (void)
Return a structure describing the current state of the input history.
@end deftypefun
@deftypefun void history_set_history_state (HISTORY_STATE *state)
Set the state of the history list according to @var{state}.
@end deftypefun
@node History List Management
@subsection History List Management
These functions manage individual entries on the history list, or set
parameters managing the list itself.
@deftypefun void add_history (const char *string)
Place @var{string} at the end of the history list. The associated data
field (if any) is set to @code{NULL}.
@end deftypefun
@deftypefun void add_history_time (const char *string)
Change the time stamp associated with the most recent history entry to
@var{string}.
@end deftypefun
@deftypefun {HIST_ENTRY *} remove_history (int which)
Remove history entry at offset @var{which} from the history. The
removed element is returned so you can free the line, data,
and containing structure.
@end deftypefun
@deftypefun {histdata_t} free_history_entry (HIST_ENTRY *histent)
Free the history entry @var{histent} and any history library private
data associated with it. Returns the application-specific data
so the caller can dispose of it.
@end deftypefun
@deftypefun {HIST_ENTRY *} replace_history_entry (int which, const char *line, histdata_t data)
Make the history entry at offset @var{which} have @var{line} and @var{data}.
This returns the old entry so the caller can dispose of any
application-specific data. In the case
of an invalid @var{which}, a @code{NULL} pointer is returned.
@end deftypefun
@deftypefun void clear_history (void)
Clear the history list by deleting all the entries.
@end deftypefun
@deftypefun void stifle_history (int max)
Stifle the history list, remembering only the last @var{max} entries.
@end deftypefun
@deftypefun int unstifle_history (void)
Stop stifling the history. This returns the previously-set
maximum number of history entries (as set by @code{stifle_history()}).
The value is positive if the history was
stifled, negative if it wasn't.
@end deftypefun
@deftypefun int history_is_stifled (void)
Returns non-zero if the history is stifled, zero if it is not.
@end deftypefun
@node Information About the History List
@subsection Information About the History List
These functions return information about the entire history list or
individual list entries.
@deftypefun {HIST_ENTRY **} history_list (void)
Return a @code{NULL} terminated array of @code{HIST_ENTRY *} which is the
current input history. Element 0 of this list is the beginning of time.
If there is no history, return @code{NULL}.
@end deftypefun
@deftypefun int where_history (void)
Returns the offset of the current history element.
@end deftypefun
@deftypefun {HIST_ENTRY *} current_history (void)
Return the history entry at the current position, as determined by
@code{where_history()}. If there is no entry there, return a @code{NULL}
pointer.
@end deftypefun
@deftypefun {HIST_ENTRY *} history_get (int offset)
Return the history entry at position @var{offset}, starting from
@code{history_base} (@pxref{History Variables}).
If there is no entry there, or if @var{offset}
is greater than the history length, return a @code{NULL} pointer.
@end deftypefun
@deftypefun time_t history_get_time (HIST_ENTRY *entry)
Return the time stamp associated with the history entry @var{entry}.
@end deftypefun
@deftypefun int history_total_bytes (void)
Return the number of bytes that the primary history entries are using.
This function returns the sum of the lengths of all the lines in the
history.
@end deftypefun
@node Moving Around the History List
@subsection Moving Around the History List
These functions allow the current index into the history list to be
set or changed.
@deftypefun int history_set_pos (int pos)
Set the current history offset to @var{pos}, an absolute index
into the list.
Returns 1 on success, 0 if @var{pos} is less than zero or greater
than the number of history entries.
@end deftypefun
@deftypefun {HIST_ENTRY *} previous_history (void)
Back up the current history offset to the previous history entry, and
return a pointer to that entry. If there is no previous entry, return
a @code{NULL} pointer.
@end deftypefun
@deftypefun {HIST_ENTRY *} next_history (void)
Move the current history offset forward to the next history entry, and
return the a pointer to that entry. If there is no next entry, return
a @code{NULL} pointer.
@end deftypefun
@node Searching the History List
@subsection Searching the History List
@cindex History Searching
These functions allow searching of the history list for entries containing
a specific string. Searching may be performed both forward and backward
from the current history position. The search may be @dfn{anchored},
meaning that the string must match at the beginning of the history entry.
@cindex anchored search
@deftypefun int history_search (const char *string, int direction)
Search the history for @var{string}, starting at the current history offset.
If @var{direction} is less than 0, then the search is through
previous entries, otherwise through subsequent entries.
If @var{string} is found, then
the current history index is set to that history entry, and the value
returned is the offset in the line of the entry where
@var{string} was found. Otherwise, nothing is changed, and a -1 is
returned.
@end deftypefun
@deftypefun int history_search_prefix (const char *string, int direction)
Search the history for @var{string}, starting at the current history
offset. The search is anchored: matching lines must begin with
@var{string}. If @var{direction} is less than 0, then the search is
through previous entries, otherwise through subsequent entries.
If @var{string} is found, then the
current history index is set to that entry, and the return value is 0.
Otherwise, nothing is changed, and a -1 is returned.
@end deftypefun
@deftypefun int history_search_pos (const char *string, int direction, int pos)
Search for @var{string} in the history list, starting at @var{pos}, an
absolute index into the list. If @var{direction} is negative, the search
proceeds backward from @var{pos}, otherwise forward. Returns the absolute
index of the history element where @var{string} was found, or -1 otherwise.
@end deftypefun
@node Managing the History File
@subsection Managing the History File
The History library can read the history from and write it to a file.
This section documents the functions for managing a history file.
@deftypefun int read_history (const char *filename)
Add the contents of @var{filename} to the history list, a line at a time.
If @var{filename} is @code{NULL}, then read from @file{~/.history}.
Returns 0 if successful, or @code{errno} if not.
@end deftypefun
@deftypefun int read_history_range (const char *filename, int from, int to)
Read a range of lines from @var{filename}, adding them to the history list.
Start reading at line @var{from} and end at @var{to}.
If @var{from} is zero, start at the beginning. If @var{to} is less than
@var{from}, then read until the end of the file. If @var{filename} is
@code{NULL}, then read from @file{~/.history}. Returns 0 if successful,
or @code{errno} if not.
@end deftypefun
@deftypefun int write_history (const char *filename)
Write the current history to @var{filename}, overwriting @var{filename}
if necessary.
If @var{filename} is @code{NULL}, then write the history list to
@file{~/.history}.
Returns 0 on success, or @code{errno} on a read or write error.
@end deftypefun
@deftypefun int append_history (int nelements, const char *filename)
Append the last @var{nelements} of the history list to @var{filename}.
If @var{filename} is @code{NULL}, then append to @file{~/.history}.
Returns 0 on success, or @code{errno} on a read or write error.
@end deftypefun
@deftypefun int history_truncate_file (const char *filename, int nlines)
Truncate the history file @var{filename}, leaving only the last
@var{nlines} lines.
If @var{filename} is @code{NULL}, then @file{~/.history} is truncated.
Returns 0 on success, or @code{errno} on failure.
@end deftypefun
@node History Expansion
@subsection History Expansion
These functions implement history expansion.
@deftypefun int history_expand (char *string, char **output)
Expand @var{string}, placing the result into @var{output}, a pointer
to a string (@pxref{History Interaction}). Returns:
@table @code
@item 0
If no expansions took place (or, if the only change in
the text was the removal of escape characters preceding the history expansion
character);
@item 1
if expansions did take place;
@item -1
if there was an error in expansion;
@item 2
if the returned line should be displayed, but not executed,
as with the @code{:p} modifier (@pxref{Modifiers}).
@end table
If an error ocurred in expansion, then @var{output} contains a descriptive
error message.
@end deftypefun
@deftypefun {char *} get_history_event (const char *string, int *cindex, int qchar)
Returns the text of the history event beginning at @var{string} +
@var{*cindex}. @var{*cindex} is modified to point to after the event
specifier. At function entry, @var{cindex} points to the index into
@var{string} where the history event specification begins. @var{qchar}
is a character that is allowed to end the event specification in addition
to the ``normal'' terminating characters.
@end deftypefun
@deftypefun {char **} history_tokenize (const char *string)
Return an array of tokens parsed out of @var{string}, much as the
shell might. The tokens are split on the characters in the
@var{history_word_delimiters} variable,
and shell quoting conventions are obeyed.
@end deftypefun
@deftypefun {char *} history_arg_extract (int first, int last, const char *string)
Extract a string segment consisting of the @var{first} through @var{last}
arguments present in @var{string}. Arguments are split using
@code{history_tokenize}.
@end deftypefun
@node History Variables
@section History Variables
This section describes the externally-visible variables exported by
the @sc{gnu} History Library.
@deftypevar int history_base
The logical offset of the first entry in the history list.
@end deftypevar
@deftypevar int history_length
The number of entries currently stored in the history list.
@end deftypevar
@deftypevar int history_max_entries
The maximum number of history entries. This must be changed using
@code{stifle_history()}.
@end deftypevar
@deftypevar int history_write_timestamps
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.
@end deftypevar
@deftypevar char history_expansion_char
The character that introduces a history event. The default is @samp{!}.
Setting this to 0 inhibits history expansion.
@end deftypevar
@deftypevar char history_subst_char
The character that invokes word substitution if found at the start of
a line. The default is @samp{^}.
@end deftypevar
@deftypevar char history_comment_char
During tokenization, if this character is seen as the first character
of a word, then it and all subsequent characters up to a newline are
ignored, suppressing history expansion for the remainder of the line.
This is disabled by default.
@end deftypevar
@deftypevar {char *} history_word_delimiters
The characters that separate tokens for @code{history_tokenize()}.
The default value is @code{" \t\n()<>;&|"}.
@end deftypevar
@deftypevar {char *} history_search_delimiter_chars
The list of additional characters which can delimit a history search
string, in addition to space, TAB, @samp{:} and @samp{?} in the case of
a substring search. The default is empty.
@end deftypevar
@deftypevar {char *} history_no_expand_chars
The list of characters which inhibit history expansion if found immediately
following @var{history_expansion_char}. The default is space, tab, newline,
carriage return, and @samp{=}.
@end deftypevar
@deftypevar int history_quotes_inhibit_expansion
If non-zero, single-quoted words are not scanned for the history expansion
character. The default value is 0.
@end deftypevar
@deftypevar {rl_linebuf_func_t *} history_inhibit_expansion_function
This should be set to the address of a function that takes two arguments:
a @code{char *} (@var{string})
and an @code{int} index into that string (@var{i}).
It should return a non-zero value if the history expansion starting at
@var{string[i]} should not be performed; zero if the expansion should
be done.
It is intended for use by applications like Bash that use the history
expansion character for additional purposes.
By default, this variable is set to @code{NULL}.
@end deftypevar
@node History Programming Example
@section History Programming Example
The following program demonstrates simple use of the @sc{gnu} History Library.
@smallexample
#include <stdio.h>
#include <readline/history.h>
main (argc, argv)
int argc;
char **argv;
@{
char line[1024], *t;
int len, done = 0;
line[0] = 0;
using_history ();
while (!done)
@{
printf ("history$ ");
fflush (stdout);
t = fgets (line, sizeof (line) - 1, stdin);
if (t && *t)
@{
len = strlen (t);
if (t[len - 1] == '\n')
t[len - 1] = '\0';
@}
if (!t)
strcpy (line, "quit");
if (line[0])
@{
char *expansion;
int result;
result = history_expand (line, &expansion);
if (result)
fprintf (stderr, "%s\n", expansion);
if (result < 0 || result == 2)
@{
free (expansion);
continue;
@}
add_history (expansion);
strncpy (line, expansion, sizeof (line) - 1);
free (expansion);
@}
if (strcmp (line, "quit") == 0)
done = 1;
else if (strcmp (line, "save") == 0)
write_history ("history_file");
else if (strcmp (line, "read") == 0)
read_history ("history_file");
else if (strcmp (line, "list") == 0)
@{
register HIST_ENTRY **the_list;
register int i;
the_list = history_list ();
if (the_list)
for (i = 0; the_list[i]; i++)
printf ("%d: %s\n", i + history_base, the_list[i]->line);
@}
else if (strncmp (line, "delete", 6) == 0)
@{
int which;
if ((sscanf (line + 6, "%d", &which)) == 1)
@{
HIST_ENTRY *entry = remove_history (which);
if (!entry)
fprintf (stderr, "No such entry %d\n", which);
else
@{
free (entry->line);
free (entry);
@}
@}
else
@{
fprintf (stderr, "non-numeric arg given to `delete'\n");
@}
@}
@}
@}
@end smallexample
-471
View File
@@ -1,471 +0,0 @@
@ignore
This file documents the user interface to the GNU History library.
Copyright (C) 1988-2010 Free Software Foundation, Inc.
Authored by Brian Fox and Chet Ramey.
Permission is granted to make and distribute verbatim copies of this manual
provided the copyright notice and this permission notice are preserved on
all copies.
Permission is granted to process this file through Tex and print the
results, provided the printed document carries copying permission notice
identical to this one except for the removal of this paragraph (this
paragraph not being relevant to the printed manual).
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that the
GNU Copyright statement is available to the distributee, and provided that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions.
@end ignore
@node Using History Interactively
@chapter Using History Interactively
@ifclear BashFeatures
@defcodeindex bt
@end ifclear
@ifset BashFeatures
This chapter describes how to use the @sc{gnu} History Library
interactively, from a user's standpoint.
It should be considered a user's guide.
For information on using the @sc{gnu} History Library in other programs,
see the @sc{gnu} Readline Library Manual.
@end ifset
@ifclear BashFeatures
This chapter describes how to use the @sc{gnu} History Library interactively,
from a user's standpoint. It should be considered a user's guide. For
information on using the @sc{gnu} History Library in your own programs,
@pxref{Programming with GNU History}.
@end ifclear
@ifset BashFeatures
@menu
* Bash History Facilities:: How Bash lets you manipulate your command
history.
* Bash History Builtins:: The Bash builtin commands that manipulate
the command history.
* History Interaction:: What it feels like using History as a user.
@end menu
@end ifset
@ifclear BashFeatures
@menu
* History Interaction:: What it feels like using History as a user.
@end menu
@end ifclear
@ifset BashFeatures
@node Bash History Facilities
@section Bash History Facilities
@cindex command history
@cindex history list
When the @option{-o history} option to the @code{set} builtin
is enabled (@pxref{The Set Builtin}),
the shell provides access to the @dfn{command history},
the list of commands previously typed.
The value of the @env{HISTSIZE} shell variable is used as the
number of commands to save in a history list.
The text of the last @env{$HISTSIZE}
commands (default 500) is saved.
The shell stores each command in the history list prior to
parameter and variable expansion
but after history expansion is performed, subject to the
values of the shell variables
@env{HISTIGNORE} and @env{HISTCONTROL}.
When the shell starts up, the history is initialized from the
file named by the @env{HISTFILE} variable (default @file{~/.bash_history}).
The file named by the value of @env{HISTFILE} is truncated, if
necessary, to contain no more than the number of lines specified by
the value of the @env{HISTFILESIZE} variable.
When an interactive shell exits, the last
@env{$HISTSIZE} lines are copied from the history list to the file
named by @env{$HISTFILE}.
If the @code{histappend} shell option is set (@pxref{Bash Builtins}),
the lines are appended to the history file,
otherwise the history file is overwritten.
If @env{HISTFILE}
is unset, or if the history file is unwritable, the history is
not saved. After saving the history, the history file is truncated
to contain no more than @env{$HISTFILESIZE}
lines. If @env{HISTFILESIZE} is not set, no truncation is performed.
If the @env{HISTTIMEFORMAT} is set, the time stamp information
associated with each history entry is written to the history file,
marked with the history comment character.
When the history file is read, lines beginning with the history
comment character followed immediately by a digit are interpreted
as timestamps for the previous history line.
The builtin command @code{fc} may be used to list or edit and re-execute
a portion of the history list.
The @code{history} builtin may be used to display or modify the history
list and manipulate the history file.
When using command-line editing, search commands
are available in each editing mode that provide access to the
history list (@pxref{Commands For History}).
The shell allows control over which commands are saved on the history
list. The @env{HISTCONTROL} and @env{HISTIGNORE}
variables may be set to cause the shell to save only a subset of the
commands entered.
The @code{cmdhist}
shell option, if enabled, causes the shell to attempt to save each
line of a multi-line command in the same history entry, adding
semicolons where necessary to preserve syntactic correctness.
The @code{lithist}
shell option causes the shell to save the command with embedded newlines
instead of semicolons.
The @code{shopt} builtin is used to set these options.
@xref{Bash Builtins}, for a description of @code{shopt}.
@node Bash History Builtins
@section Bash History Builtins
@cindex history builtins
Bash provides two builtin commands which manipulate the
history list and history file.
@table @code
@item fc
@btindex fc
@example
@code{fc [-e @var{ename}] [-lnr] [@var{first}] [@var{last}]}
@code{fc -s [@var{pat}=@var{rep}] [@var{command}]}
@end example
Fix Command. In the first form, a range of commands from @var{first} to
@var{last} is selected from the history list. Both @var{first} and
@var{last} may be specified as a string (to locate the most recent
command beginning with that string) or as a number (an index into the
history list, where a negative number is used as an offset from the
current command number). If @var{last} is not specified it is set to
@var{first}. If @var{first} is not specified it is set to the previous
command for editing and @minus{}16 for listing. If the @option{-l} flag is
given, the commands are listed on standard output. The @option{-n} flag
suppresses the command numbers when listing. The @option{-r} flag
reverses the order of the listing. Otherwise, the editor given by
@var{ename} is invoked on a file containing those commands. If
@var{ename} is not given, the value of the following variable expansion
is used: @code{$@{FCEDIT:-$@{EDITOR:-vi@}@}}. This says to use the
value of the @env{FCEDIT} variable if set, or the value of the
@env{EDITOR} variable if that is set, or @code{vi} if neither is set.
When editing is complete, the edited commands are echoed and executed.
In the second form, @var{command} is re-executed after each instance
of @var{pat} in the selected command is replaced by @var{rep}.
A useful alias to use with the @code{fc} command is @code{r='fc -s'}, so
that typing @samp{r cc} runs the last command beginning with @code{cc}
and typing @samp{r} re-executes the last command (@pxref{Aliases}).
@item history
@btindex history
@example
history [@var{n}]
history -c
history -d @var{offset}
history [-anrw] [@var{filename}]
history -ps @var{arg}
@end example
With no options, display the history list with line numbers.
Lines prefixed with a @samp{*} have been modified.
An argument of @var{n} lists only the last @var{n} lines.
If the shell variable @env{HISTTIMEFORMAT} is set and not null,
it is used as a format string for @var{strftime} to display
the time stamp associated with each displayed history entry.
No intervening blank is printed between the formatted time stamp
and the history line.
Options, if supplied, have the following meanings:
@table @code
@item -c
Clear the history list. This may be combined
with the other options to replace the history list completely.
@item -d @var{offset}
Delete the history entry at position @var{offset}.
@var{offset} should be specified as it appears when the history is
displayed.
@item -a
Append the new
history lines (history lines entered since the beginning of the
current Bash session) to the history file.
@item -n
Append the history lines not already read from the history file
to the current history list. These are lines appended to the history
file since the beginning of the current Bash session.
@item -r
Read the current history file and append its contents to
the history list.
@item -w
Write out the current history to the history file.
@item -p
Perform history substitution on the @var{arg}s and display the result
on the standard output, without storing the results in the history list.
@item -s
The @var{arg}s are added to the end of
the history list as a single entry.
@end table
When any of the @option{-w}, @option{-r}, @option{-a}, or @option{-n} options is
used, if @var{filename}
is given, then it is used as the history file. If not, then
the value of the @env{HISTFILE} variable is used.
@end table
@end ifset
@node History Interaction
@section History Expansion
@cindex history expansion
The History library provides a history expansion feature that is similar
to the history expansion provided by @code{csh}. This section
describes the syntax used to manipulate the history information.
History expansions introduce words from the history list into
the input stream, making it easy to repeat commands, insert the
arguments to a previous command into the current input line, or
fix errors in previous commands quickly.
History expansion takes place in two parts. The first is to determine
which line from the history list should be used during substitution.
The second is to select portions of that line for inclusion into the
current one. The line selected from the history is called the
@dfn{event}, and the portions of that line that are acted upon are
called @dfn{words}. Various @dfn{modifiers} are available to manipulate
the selected words. The line is broken into words in the same fashion
that Bash does, so that several words
surrounded by quotes are considered one word.
History expansions are introduced by the appearance of the
history expansion character, which is @samp{!} by default.
@ifset BashFeatures
Only @samp{\} and @samp{'} may be used to escape the history expansion
character.
@end ifset
@ifset BashFeatures
Several shell options settable with the @code{shopt}
builtin (@pxref{Bash Builtins}) may be used to tailor
the behavior of history expansion. If the
@code{histverify} shell option is enabled, and Readline
is being used, history substitutions are not immediately passed to
the shell parser.
Instead, the expanded line is reloaded into the Readline
editing buffer for further modification.
If Readline is being used, and the @code{histreedit}
shell option is enabled, a failed history expansion will be
reloaded into the Readline editing buffer for correction.
The @option{-p} option to the @code{history} builtin command
may be used to see what a history expansion will do before using it.
The @option{-s} option to the @code{history} builtin may be used to
add commands to the end of the history list without actually executing
them, so that they are available for subsequent recall.
This is most useful in conjunction with Readline.
The shell allows control of the various characters used by the
history expansion mechanism with the @code{histchars} variable,
as explained above (@pxref{Bash Variables}). The shell uses
the history comment character to mark history timestamps when
writing the history file.
@end ifset
@menu
* Event Designators:: How to specify which history line to use.
* Word Designators:: Specifying which words are of interest.
* Modifiers:: Modifying the results of substitution.
@end menu
@node Event Designators
@subsection Event Designators
@cindex event designators
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
@item @code{!}
@ifset BashFeatures
Start a history substitution, except when followed by a space, tab,
the end of the line, @samp{=} or @samp{(} (when the
@code{extglob} shell option is enabled using the @code{shopt} builtin).
@end ifset
@ifclear BashFeatures
Start a history substitution, except when followed by a space, tab,
the end of the line, or @samp{=}.
@end ifclear
@item @code{!@var{n}}
Refer to command line @var{n}.
@item @code{!-@var{n}}
Refer to the command @var{n} lines back.
@item @code{!!}
Refer to the previous command. This is a synonym for @samp{!-1}.
@item @code{!@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
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.
@item @code{^@var{string1}^@var{string2}^}
Quick Substitution. Repeat the last command, replacing @var{string1}
with @var{string2}. Equivalent to
@code{!!:s/@var{string1}/@var{string2}/}.
@item @code{!#}
The entire command line typed so far.
@end table
@node Word Designators
@subsection Word Designators
Word designators are used to select desired words from the event.
A @samp{:} separates the event specification from the word designator. It
may be omitted if the word designator begins with a @samp{^}, @samp{$},
@samp{*}, @samp{-}, or @samp{%}. Words are numbered from the beginning
of the line, with the first word being denoted by 0 (zero). Words are
inserted into the current line separated by single spaces.
@need 0.75
For example,
@table @code
@item !!
designates the preceding command. When you type this, the preceding
command is repeated in toto.
@item !!:$
designates the last argument of the preceding command. This may be
shortened to @code{!$}.
@item !fi:2
designates the second argument of the most recent command starting with
the letters @code{fi}.
@end table
@need 0.75
Here are the word designators:
@table @code
@item 0 (zero)
The @code{0}th word. For many applications, this is the command word.
@item @var{n}
The @var{n}th word.
@item ^
The first argument; that is, word 1.
@item $
The last argument.
@item %
The word matched by the most recent @samp{?@var{string}?} search.
@item @var{x}-@var{y}
A range of words; @samp{-@var{y}} abbreviates @samp{0-@var{y}}.
@item *
All of the words, except the @code{0}th. This is a synonym for @samp{1-$}.
It is not an error to use @samp{*} if there is just one word in the event;
the empty string is returned in that case.
@item @var{x}*
Abbreviates @samp{@var{x}-$}
@item @var{x}-
Abbreviates @samp{@var{x}-$} like @samp{@var{x}*}, but omits the last word.
@end table
If a word designator is supplied without an event specification, the
previous command is used as the event.
@node Modifiers
@subsection Modifiers
After the optional word designator, you can add a sequence of one or more
of the following modifiers, each preceded by a @samp{:}.
@table @code
@item h
Remove a trailing pathname component, leaving only the head.
@item t
Remove all leading pathname components, leaving the tail.
@item r
Remove a trailing suffix of the form @samp{.@var{suffix}}, leaving
the basename.
@item e
Remove all but the trailing suffix.
@item p
Print the new command but do not execute it.
@ifset BashFeatures
@item q
Quote the substituted words, escaping further substitutions.
@item x
Quote the substituted words as with @samp{q},
but break into words at spaces, tabs, and newlines.
@end ifset
@item s/@var{old}/@var{new}/
Substitute @var{new} for the first occurrence of @var{old} in the
event line. Any delimiter may be used in place of @samp{/}.
The delimiter may be quoted in @var{old} and @var{new}
with a single backslash. If @samp{&} appears in @var{new},
it is replaced by @var{old}. A single backslash will quote
the @samp{&}. The final delimiter is optional if it is the last
character on the input line.
@item &
Repeat the previous substitution.
@item g
@itemx a
Cause changes to be applied over the entire event line. Used in
conjunction with @samp{s}, as in @code{gs/@var{old}/@var{new}/},
or with @samp{&}.
@item G
Apply the following @samp{s} modifier once to each word in the event.
@end table
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-83
View File
@@ -1,83 +0,0 @@
\input texinfo @c -*-texinfo-*-
@comment %**start of header (This is for running Texinfo on a region.)
@setfilename rluserman.info
@settitle GNU Readline Library
@comment %**end of header (This is for running Texinfo on a region.)
@include version.texi
@copying
This manual describes the end user interface of the GNU Readline Library
(version @value{VERSION}, @value{UPDATED}), a library which aids in the
consistency of user interface across discrete programs which provide
a command line interface.
Copyright @copyright{} 1988--2009 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.
@quotation
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with the Front-Cover texts being ``A GNU Manual'',
and with the Back-Cover Texts as in (a) below. A copy of the license is
included in the section entitled ``GNU Free Documentation License''.
(a) The FSF's Back-Cover Text is: You are free to copy and modify
this GNU manual. Buying copies from GNU Press supports the FSF in
developing GNU and promoting software freedom.''
@end quotation
@end copying
@dircategory Libraries
@direntry
* RLuserman: (rluserman). The GNU readline library User's Manual.
@end direntry
@titlepage
@title GNU Readline Library User Interface
@subtitle Edition @value{EDITION}, for @code{Readline Library} Version @value{VERSION}.
@subtitle @value{UPDATED-MONTH}
@author Chet Ramey, Case Western Reserve University
@author Brian Fox, Free Software Foundation
@page
@vskip 0pt plus 1filll
@insertcopying
@sp 1
Published by the Free Software Foundation @*
59 Temple Place, Suite 330, @*
Boston, MA 02111-1307 @*
USA @*
@end titlepage
@contents
@ifnottex
@node Top
@top GNU Readline Library
This document describes the end user interface of the GNU Readline Library,
a utility which aids in the consistency of user interface across discrete
programs which provide a command line interface.
@menu
* Command Line Editing:: GNU Readline User's Manual.
* GNU Free Documentation License:: License for copying this manual.
@end menu
@end ifnottex
@include rluser.texi
@node GNU Free Documentation License
@appendix GNU Free Documentation License
@include fdl.texi
@bye
-10
View File
@@ -1,10 +0,0 @@
@ignore
Copyright (C) 1988-2010 Free Software Foundation, Inc.
@end ignore
@set EDITION 6.2
@set VERSION 6.2
@set UPDATED August 28 2010
@set UPDATED-MONTH August 2010
@set LASTCHANGE Sat Aug 28 18:57:07 EDT 2010
-263
View File
@@ -1,263 +0,0 @@
/* funmap.c -- attach names to functions. */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Readline is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#if !defined (BUFSIZ)
#include <stdio.h>
#endif /* BUFSIZ */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include "rlconf.h"
#include "readline.h"
#include "xmalloc.h"
#ifdef __STDC__
typedef int QSFUNC (const void *, const void *);
#else
typedef int QSFUNC ();
#endif
extern int _rl_qsort_string_compare PARAMS((char **, char **));
FUNMAP **funmap;
static int funmap_size;
static int funmap_entry;
/* After initializing the function map, this is the index of the first
program specific function. */
int funmap_program_specific_entry_start;
static const FUNMAP default_funmap[] = {
{ "abort", rl_abort },
{ "accept-line", rl_newline },
{ "arrow-key-prefix", rl_arrow_keys },
{ "backward-byte", rl_backward_byte },
{ "backward-char", rl_backward_char },
{ "backward-delete-char", rl_rubout },
{ "backward-kill-line", rl_backward_kill_line },
{ "backward-kill-word", rl_backward_kill_word },
{ "backward-word", rl_backward_word },
{ "beginning-of-history", rl_beginning_of_history },
{ "beginning-of-line", rl_beg_of_line },
{ "call-last-kbd-macro", rl_call_last_kbd_macro },
{ "capitalize-word", rl_capitalize_word },
{ "character-search", rl_char_search },
{ "character-search-backward", rl_backward_char_search },
{ "clear-screen", rl_clear_screen },
{ "complete", rl_complete },
{ "copy-backward-word", rl_copy_backward_word },
{ "copy-forward-word", rl_copy_forward_word },
{ "copy-region-as-kill", rl_copy_region_to_kill },
{ "delete-char", rl_delete },
{ "delete-char-or-list", rl_delete_or_show_completions },
{ "delete-horizontal-space", rl_delete_horizontal_space },
{ "digit-argument", rl_digit_argument },
{ "do-lowercase-version", rl_do_lowercase_version },
{ "downcase-word", rl_downcase_word },
{ "dump-functions", rl_dump_functions },
{ "dump-macros", rl_dump_macros },
{ "dump-variables", rl_dump_variables },
{ "emacs-editing-mode", rl_emacs_editing_mode },
{ "end-kbd-macro", rl_end_kbd_macro },
{ "end-of-history", rl_end_of_history },
{ "end-of-line", rl_end_of_line },
{ "exchange-point-and-mark", rl_exchange_point_and_mark },
{ "forward-backward-delete-char", rl_rubout_or_delete },
{ "forward-byte", rl_forward_byte },
{ "forward-char", rl_forward_char },
{ "forward-search-history", rl_forward_search_history },
{ "forward-word", rl_forward_word },
{ "history-search-backward", rl_history_search_backward },
{ "history-search-forward", rl_history_search_forward },
{ "insert-comment", rl_insert_comment },
{ "insert-completions", rl_insert_completions },
{ "kill-whole-line", rl_kill_full_line },
{ "kill-line", rl_kill_line },
{ "kill-region", rl_kill_region },
{ "kill-word", rl_kill_word },
{ "menu-complete", rl_menu_complete },
{ "menu-complete-backward", rl_backward_menu_complete },
{ "next-history", rl_get_next_history },
{ "non-incremental-forward-search-history", rl_noninc_forward_search },
{ "non-incremental-reverse-search-history", rl_noninc_reverse_search },
{ "non-incremental-forward-search-history-again", rl_noninc_forward_search_again },
{ "non-incremental-reverse-search-history-again", rl_noninc_reverse_search_again },
{ "old-menu-complete", rl_old_menu_complete },
{ "overwrite-mode", rl_overwrite_mode },
#ifdef __CYGWIN__
{ "paste-from-clipboard", rl_paste_from_clipboard },
#endif
{ "possible-completions", rl_possible_completions },
{ "previous-history", rl_get_previous_history },
{ "quoted-insert", rl_quoted_insert },
{ "re-read-init-file", rl_re_read_init_file },
{ "redraw-current-line", rl_refresh_line},
{ "reverse-search-history", rl_reverse_search_history },
{ "revert-line", rl_revert_line },
{ "self-insert", rl_insert },
{ "set-mark", rl_set_mark },
{ "skip-csi-sequence", rl_skip_csi_sequence },
{ "start-kbd-macro", rl_start_kbd_macro },
{ "tab-insert", rl_tab_insert },
{ "tilde-expand", rl_tilde_expand },
{ "transpose-chars", rl_transpose_chars },
{ "transpose-words", rl_transpose_words },
{ "tty-status", rl_tty_status },
{ "undo", rl_undo_command },
{ "universal-argument", rl_universal_argument },
{ "unix-filename-rubout", rl_unix_filename_rubout },
{ "unix-line-discard", rl_unix_line_discard },
{ "unix-word-rubout", rl_unix_word_rubout },
{ "upcase-word", rl_upcase_word },
{ "yank", rl_yank },
{ "yank-last-arg", rl_yank_last_arg },
{ "yank-nth-arg", rl_yank_nth_arg },
{ "yank-pop", rl_yank_pop },
#if defined (VI_MODE)
{ "vi-append-eol", rl_vi_append_eol },
{ "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 },
{ "vi-change-char", rl_vi_change_char },
{ "vi-change-to", rl_vi_change_to },
{ "vi-char-search", rl_vi_char_search },
{ "vi-column", rl_vi_column },
{ "vi-complete", rl_vi_complete },
{ "vi-delete", rl_vi_delete },
{ "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 },
{ "vi-insertion-mode", rl_vi_insertion_mode },
{ "vi-match", rl_vi_match },
{ "vi-movement-mode", rl_vi_movement_mode },
{ "vi-next-word", rl_vi_next_word },
{ "vi-overstrike", rl_vi_overstrike },
{ "vi-overstrike-delete", rl_vi_overstrike_delete },
{ "vi-prev-word", rl_vi_prev_word },
{ "vi-put", rl_vi_put },
{ "vi-redo", rl_vi_redo },
{ "vi-replace", rl_vi_replace },
{ "vi-rubout", rl_vi_rubout },
{ "vi-search", rl_vi_search },
{ "vi-search-again", rl_vi_search_again },
{ "vi-set-mark", rl_vi_set_mark },
{ "vi-subst", rl_vi_subst },
{ "vi-tilde-expand", rl_vi_tilde_expand },
{ "vi-yank-arg", rl_vi_yank_arg },
{ "vi-yank-to", rl_vi_yank_to },
#endif /* VI_MODE */
{(char *)NULL, (rl_command_func_t *)NULL }
};
int
rl_add_funmap_entry (name, function)
const char *name;
rl_command_func_t *function;
{
if (funmap_entry + 2 >= funmap_size)
{
funmap_size += 64;
funmap = (FUNMAP **)xrealloc (funmap, funmap_size * sizeof (FUNMAP *));
}
funmap[funmap_entry] = (FUNMAP *)xmalloc (sizeof (FUNMAP));
funmap[funmap_entry]->name = name;
funmap[funmap_entry]->function = function;
funmap[++funmap_entry] = (FUNMAP *)NULL;
return funmap_entry;
}
static int funmap_initialized;
/* Make the funmap contain all of the default entries. */
void
rl_initialize_funmap ()
{
register int i;
if (funmap_initialized)
return;
for (i = 0; default_funmap[i].name; i++)
rl_add_funmap_entry (default_funmap[i].name, default_funmap[i].function);
funmap_initialized = 1;
funmap_program_specific_entry_start = i;
}
/* Produce a NULL terminated array of known function names. The array
is sorted. The array itself is allocated, but not the strings inside.
You should free () the array when you done, but not the pointrs. */
const char **
rl_funmap_names ()
{
const char **result;
int result_size, result_index;
/* Make sure that the function map has been initialized. */
rl_initialize_funmap ();
for (result_index = result_size = 0, result = (const char **)NULL; funmap[result_index]; result_index++)
{
if (result_index + 2 > result_size)
{
result_size += 20;
result = (const char **)xrealloc (result, result_size * sizeof (char *));
}
result[result_index] = funmap[result_index]->name;
result[result_index + 1] = (char *)NULL;
}
qsort (result, result_index, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
return (result);
}
File diff suppressed because it is too large Load Diff
-552
View File
@@ -1,552 +0,0 @@
/* histfile.c - functions to manipulate the history file. */
/* 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.
History 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.
History 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 History. If not, see <http://www.gnu.org/licenses/>.
*/
/* The goal is to make the implementation transparent, so that you
don't have to know what data types are used, just what functions
you can call. I think I have done that. */
#define READLINE_LIBRARY
#if defined (__TANDEM)
# include <floss.h>
#endif
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h>
#include <sys/types.h>
#if ! defined (_MINIX) && defined (HAVE_SYS_FILE_H)
# include <sys/file.h>
#endif
#include "posixstat.h"
#include <fcntl.h>
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <ctype.h>
#if defined (__EMX__)
# undef HAVE_MMAP
#endif
#ifdef HISTORY_USE_MMAP
# include <sys/mman.h>
# ifdef MAP_FILE
# define MAP_RFLAGS (MAP_FILE|MAP_PRIVATE)
# define MAP_WFLAGS (MAP_FILE|MAP_SHARED)
# else
# define MAP_RFLAGS MAP_PRIVATE
# define MAP_WFLAGS MAP_SHARED
# endif
# ifndef MAP_FAILED
# define MAP_FAILED ((void *)-1)
# endif
#endif /* HISTORY_USE_MMAP */
/* If we're compiling for __EMX__ (OS/2) or __CYGWIN__ (cygwin32 environment
on win 95/98/nt), we want to open files with O_BINARY mode so that there
is no \n -> \r\n conversion performed. On other systems, we don't want to
mess around with O_BINARY at all, so we ensure that it's defined to 0. */
#if defined (__EMX__) || defined (__CYGWIN__)
# ifndef O_BINARY
# define O_BINARY 0
# endif
#else /* !__EMX__ && !__CYGWIN__ */
# undef O_BINARY
# define O_BINARY 0
#endif /* !__EMX__ && !__CYGWIN__ */
#include <errno.h>
#if !defined (errno)
extern int errno;
#endif /* !errno */
#include "history.h"
#include "histlib.h"
#include "rlshell.h"
#include "xmalloc.h"
/* If non-zero, we write timestamps to the history file in history_do_write() */
int history_write_timestamps = 0;
/* Does S look like the beginning of a history timestamp entry? Placeholder
for more extensive tests. */
#define HIST_TIMESTAMP_START(s) (*(s) == history_comment_char && isdigit ((s)[1]) )
/* Return the string that should be used in the place of this
filename. This only matters when you don't specify the
filename to read_history (), or write_history (). */
static char *
history_filename (filename)
const char *filename;
{
char *return_val;
const char *home;
int home_len;
return_val = filename ? savestring (filename) : (char *)NULL;
if (return_val)
return (return_val);
home = sh_get_env_value ("HOME");
if (home == 0)
{
#if 0
home = ".";
home_len = 1;
#else
return (NULL);
#endif
}
else
home_len = strlen (home);
return_val = (char *)xmalloc (2 + home_len + 8); /* strlen(".history") == 8 */
strcpy (return_val, home);
return_val[home_len] = '/';
#if defined (__MSDOS__)
strcpy (return_val + home_len + 1, "_history");
#else
strcpy (return_val + home_len + 1, ".history");
#endif
return (return_val);
}
/* Add the contents of FILENAME to the history list, a line at a time.
If FILENAME is NULL, then read from ~/.history. Returns 0 if
successful, or errno if not. */
int
read_history (filename)
const char *filename;
{
return (read_history_range (filename, 0, -1));
}
/* Read a range of lines from FILENAME, adding them to the history list.
Start reading at the FROM'th line and end at the TO'th. If FROM
is zero, start at the beginning. If TO is less than FROM, read
until the end of the file. If FILENAME is NULL, then read from
~/.history. Returns 0 if successful, or errno if not. */
int
read_history_range (filename, from, to)
const char *filename;
int from, to;
{
register char *line_start, *line_end, *p;
char *input, *buffer, *bufend, *last_ts;
int file, current_line, chars_read;
struct stat finfo;
size_t file_size;
#if defined (EFBIG)
int overflow_errno = EFBIG;
#elif defined (EOVERFLOW)
int overflow_errno = EOVERFLOW;
#else
int overflow_errno = EIO;
#endif
buffer = last_ts = (char *)NULL;
input = history_filename (filename);
file = input ? open (input, O_RDONLY|O_BINARY, 0666) : -1;
if ((file < 0) || (fstat (file, &finfo) == -1))
goto error_and_exit;
file_size = (size_t)finfo.st_size;
/* check for overflow on very large files */
if (file_size != finfo.st_size || file_size + 1 < file_size)
{
errno = overflow_errno;
goto error_and_exit;
}
#ifdef HISTORY_USE_MMAP
/* We map read/write and private so we can change newlines to NULs without
affecting the underlying object. */
buffer = (char *)mmap (0, file_size, PROT_READ|PROT_WRITE, MAP_RFLAGS, file, 0);
if ((void *)buffer == MAP_FAILED)
{
errno = overflow_errno;
goto error_and_exit;
}
chars_read = file_size;
#else
buffer = (char *)malloc (file_size + 1);
if (buffer == 0)
{
errno = overflow_errno;
goto error_and_exit;
}
chars_read = read (file, buffer, file_size);
#endif
if (chars_read < 0)
{
error_and_exit:
if (errno != 0)
chars_read = errno;
else
chars_read = EIO;
if (file >= 0)
close (file);
FREE (input);
#ifndef HISTORY_USE_MMAP
FREE (buffer);
#endif
return (chars_read);
}
close (file);
/* Set TO to larger than end of file if negative. */
if (to < 0)
to = chars_read;
/* Start at beginning of file, work to end. */
bufend = buffer + chars_read;
current_line = 0;
/* Skip lines until we are at FROM. */
for (line_start = line_end = buffer; line_end < bufend && current_line < from; line_end++)
if (*line_end == '\n')
{
p = line_end + 1;
/* If we see something we think is a timestamp, continue with this
line. We should check more extensively here... */
if (HIST_TIMESTAMP_START(p) == 0)
current_line++;
line_start = p;
}
/* If there are lines left to gobble, then gobble them now. */
for (line_end = line_start; line_end < bufend; line_end++)
if (*line_end == '\n')
{
/* Change to allow Windows-like \r\n end of line delimiter. */
if (line_end > line_start && line_end[-1] == '\r')
line_end[-1] = '\0';
else
*line_end = '\0';
if (*line_start)
{
if (HIST_TIMESTAMP_START(line_start) == 0)
{
add_history (line_start);
if (last_ts)
{
add_history_time (last_ts);
last_ts = NULL;
}
}
else
{
last_ts = line_start;
current_line--;
}
}
current_line++;
if (current_line >= to)
break;
line_start = line_end + 1;
}
FREE (input);
#ifndef HISTORY_USE_MMAP
FREE (buffer);
#else
munmap (buffer, file_size);
#endif
return (0);
}
/* Truncate the history file FNAME, leaving only LINES trailing lines.
If FNAME is NULL, then use ~/.history. Returns 0 on success, errno
on failure. */
int
history_truncate_file (fname, lines)
const char *fname;
int lines;
{
char *buffer, *filename, *bp, *bp1; /* bp1 == bp+1 */
int file, chars_read, rv;
struct stat finfo;
size_t file_size;
buffer = (char *)NULL;
filename = history_filename (fname);
file = filename ? open (filename, O_RDONLY|O_BINARY, 0666) : -1;
rv = 0;
/* Don't try to truncate non-regular files. */
if (file == -1 || fstat (file, &finfo) == -1)
{
rv = errno;
if (file != -1)
close (file);
goto truncate_exit;
}
if (S_ISREG (finfo.st_mode) == 0)
{
close (file);
#ifdef EFTYPE
rv = EFTYPE;
#else
rv = EINVAL;
#endif
goto truncate_exit;
}
file_size = (size_t)finfo.st_size;
/* check for overflow on very large files */
if (file_size != finfo.st_size || file_size + 1 < file_size)
{
close (file);
#if defined (EFBIG)
rv = errno = EFBIG;
#elif defined (EOVERFLOW)
rv = errno = EOVERFLOW;
#else
rv = errno = EINVAL;
#endif
goto truncate_exit;
}
buffer = (char *)malloc (file_size + 1);
if (buffer == 0)
{
close (file);
goto truncate_exit;
}
chars_read = read (file, buffer, file_size);
close (file);
if (chars_read <= 0)
{
rv = (chars_read < 0) ? errno : 0;
goto truncate_exit;
}
/* Count backwards from the end of buffer until we have passed
LINES lines. bp1 is set funny initially. But since bp[1] can't
be a comment character (since it's off the end) and *bp can't be
both a newline and the history comment character, it should be OK. */
for (bp1 = bp = buffer + chars_read - 1; lines && bp > buffer; bp--)
{
if (*bp == '\n' && HIST_TIMESTAMP_START(bp1) == 0)
lines--;
bp1 = bp;
}
/* If this is the first line, then the file contains exactly the
number of lines we want to truncate to, so we don't need to do
anything. It's the first line if we don't find a newline between
the current value of i and 0. Otherwise, write from the start of
this line until the end of the buffer. */
for ( ; bp > buffer; bp--)
{
if (*bp == '\n' && HIST_TIMESTAMP_START(bp1) == 0)
{
bp++;
break;
}
bp1 = bp;
}
/* Write only if there are more lines in the file than we want to
truncate to. */
if (bp > buffer && ((file = open (filename, O_WRONLY|O_TRUNC|O_BINARY, 0600)) != -1))
{
write (file, bp, chars_read - (bp - buffer));
#if defined (__BEOS__)
/* BeOS ignores O_TRUNC. */
ftruncate (file, chars_read - (bp - buffer));
#endif
close (file);
}
truncate_exit:
FREE (buffer);
free (filename);
return rv;
}
/* Workhorse function for writing history. Writes NELEMENT entries
from the history list to FILENAME. OVERWRITE is non-zero if you
wish to replace FILENAME with the entries. */
static int
history_do_write (filename, nelements, overwrite)
const char *filename;
int nelements, overwrite;
{
register int i;
char *output;
int file, mode, rv;
#ifdef HISTORY_USE_MMAP
size_t cursize;
mode = overwrite ? O_RDWR|O_CREAT|O_TRUNC|O_BINARY : O_RDWR|O_APPEND|O_BINARY;
#else
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 == -1)
{
FREE (output);
return (errno);
}
#ifdef HISTORY_USE_MMAP
cursize = overwrite ? 0 : lseek (file, 0, SEEK_END);
#endif
if (nelements > history_length)
nelements = history_length;
/* Build a buffer of all the lines to write, and write them in one syscall.
Suggested by Peter Ho (peter@robosts.oxford.ac.uk). */
{
HIST_ENTRY **the_history; /* local */
register int j;
int buffer_size;
char *buffer;
the_history = history_list ();
/* Calculate the total number of bytes to write. */
for (buffer_size = 0, i = history_length - nelements; i < history_length; i++)
#if 0
buffer_size += 2 + HISTENT_BYTES (the_history[i]);
#else
{
if (history_write_timestamps && the_history[i]->timestamp && the_history[i]->timestamp[0])
buffer_size += strlen (the_history[i]->timestamp) + 1;
buffer_size += strlen (the_history[i]->line) + 1;
}
#endif
/* Allocate the buffer, and fill it. */
#ifdef HISTORY_USE_MMAP
if (ftruncate (file, buffer_size+cursize) == -1)
goto mmap_error;
buffer = (char *)mmap (0, buffer_size, PROT_READ|PROT_WRITE, MAP_WFLAGS, file, cursize);
if ((void *)buffer == MAP_FAILED)
{
mmap_error:
rv = errno;
FREE (output);
close (file);
return rv;
}
#else
buffer = (char *)malloc (buffer_size);
if (buffer == 0)
{
rv = errno;
FREE (output);
close (file);
return rv;
}
#endif
for (j = 0, i = history_length - nelements; i < history_length; i++)
{
if (history_write_timestamps && the_history[i]->timestamp && the_history[i]->timestamp[0])
{
strcpy (buffer + j, the_history[i]->timestamp);
j += strlen (the_history[i]->timestamp);
buffer[j++] = '\n';
}
strcpy (buffer + j, the_history[i]->line);
j += strlen (the_history[i]->line);
buffer[j++] = '\n';
}
#ifdef HISTORY_USE_MMAP
if (msync (buffer, buffer_size, 0) != 0 || munmap (buffer, buffer_size) != 0)
rv = errno;
#else
if (write (file, buffer, buffer_size) < 0)
rv = errno;
free (buffer);
#endif
}
close (file);
FREE (output);
return (rv);
}
/* Append NELEMENT entries to FILENAME. The entries appended are from
the end of the list minus NELEMENTs up to the end of the list. */
int
append_history (nelements, filename)
int nelements;
const char *filename;
{
return (history_do_write (filename, nelements, HISTORY_APPEND));
}
/* Overwrite FILENAME with the current history. If FILENAME is NULL,
then write the history list to ~/.history. Values returned
are as in read_history ().*/
int
write_history (filename)
const char *filename;
{
return (history_do_write (filename, history_length, HISTORY_OVERWRITE));
}
-519
View File
@@ -1,519 +0,0 @@
/* history.c -- standalone history library */
/* Copyright (C) 1989-2009 Free Software Foundation, Inc.
This file contains the GNU History Library (History), a set of
routines for managing the text of previously typed lines.
History 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.
History 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 History. If not, see <http://www.gnu.org/licenses/>.
*/
/* The goal is to make the implementation transparent, so that you
don't have to know what data types are used, just what functions
you can call. I think I have done that. */
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h>
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#include "history.h"
#include "histlib.h"
#include "xmalloc.h"
/* The number of slots to increase the_history by. */
#define DEFAULT_HISTORY_GROW_SIZE 50
static char *hist_inittime PARAMS((void));
/* **************************************************************** */
/* */
/* History Functions */
/* */
/* **************************************************************** */
/* An array of HIST_ENTRY. This is where we store the history. */
static HIST_ENTRY **the_history = (HIST_ENTRY **)NULL;
/* Non-zero means that we have enforced a limit on the amount of
history that we save. */
static int history_stifled;
/* The current number of slots allocated to the input_history. */
static int history_size;
/* If HISTORY_STIFLED is non-zero, then this is the maximum number of
entries to remember. */
int history_max_entries;
int max_input_history; /* backwards compatibility */
/* The current location of the interactive history pointer. Just makes
life easier for outside callers. */
int history_offset;
/* The number of strings currently stored in the history list. */
int history_length;
/* The logical `base' of the history array. It defaults to 1. */
int history_base = 1;
/* Return the current HISTORY_STATE of the history. */
HISTORY_STATE *
history_get_history_state ()
{
HISTORY_STATE *state;
state = (HISTORY_STATE *)xmalloc (sizeof (HISTORY_STATE));
state->entries = the_history;
state->offset = history_offset;
state->length = history_length;
state->size = history_size;
state->flags = 0;
if (history_stifled)
state->flags |= HS_STIFLED;
return (state);
}
/* Set the state of the current history array to STATE. */
void
history_set_history_state (state)
HISTORY_STATE *state;
{
the_history = state->entries;
history_offset = state->offset;
history_length = state->length;
history_size = state->size;
if (state->flags & HS_STIFLED)
history_stifled = 1;
}
/* Begin a session in which the history functions might be used. This
initializes interactive variables. */
void
using_history ()
{
history_offset = history_length;
}
/* Return the number of bytes that the primary history entries are using.
This just adds up the lengths of the_history->lines and the associated
timestamps. */
int
history_total_bytes ()
{
register int i, result;
for (i = result = 0; the_history && the_history[i]; i++)
result += HISTENT_BYTES (the_history[i]);
return (result);
}
/* Returns the magic number which says what history element we are
looking at now. In this implementation, it returns history_offset. */
int
where_history ()
{
return (history_offset);
}
/* Make the current history item be the one at POS, an absolute index.
Returns zero if POS is out of range, else non-zero. */
int
history_set_pos (pos)
int pos;
{
if (pos > history_length || pos < 0 || !the_history)
return (0);
history_offset = pos;
return (1);
}
/* Return the current history array. The caller has to be careful, since this
is the actual array of data, and could be bashed or made corrupt easily.
The array is terminated with a NULL pointer. */
HIST_ENTRY **
history_list ()
{
return (the_history);
}
/* Return the history entry at the current position, as determined by
history_offset. If there is no entry there, return a NULL pointer. */
HIST_ENTRY *
current_history ()
{
return ((history_offset == history_length) || the_history == 0)
? (HIST_ENTRY *)NULL
: the_history[history_offset];
}
/* Back up history_offset to the previous history entry, and return
a pointer to that entry. If there is no previous entry then return
a NULL pointer. */
HIST_ENTRY *
previous_history ()
{
return history_offset ? the_history[--history_offset] : (HIST_ENTRY *)NULL;
}
/* Move history_offset forward to the next history entry, and return
a pointer to that entry. If there is no next entry then return a
NULL pointer. */
HIST_ENTRY *
next_history ()
{
return (history_offset == history_length) ? (HIST_ENTRY *)NULL : the_history[++history_offset];
}
/* Return the history entry which is logically at OFFSET in the history array.
OFFSET is relative to history_base. */
HIST_ENTRY *
history_get (offset)
int offset;
{
int local_index;
local_index = offset - history_base;
return (local_index >= history_length || local_index < 0 || the_history == 0)
? (HIST_ENTRY *)NULL
: the_history[local_index];
}
HIST_ENTRY *
alloc_history_entry (string, ts)
char *string;
char *ts;
{
HIST_ENTRY *temp;
temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
temp->line = string ? savestring (string) : string;
temp->data = (char *)NULL;
temp->timestamp = ts;
return temp;
}
time_t
history_get_time (hist)
HIST_ENTRY *hist;
{
char *ts;
time_t t;
if (hist == 0 || hist->timestamp == 0)
return 0;
ts = hist->timestamp;
if (ts[0] != history_comment_char)
return 0;
t = (time_t) atol (ts + 1); /* XXX - should use strtol() here */
return t;
}
static char *
hist_inittime ()
{
time_t t;
char ts[64], *ret;
t = (time_t) time ((time_t *)0);
#if defined (HAVE_VSNPRINTF) /* assume snprintf if vsnprintf exists */
snprintf (ts, sizeof (ts) - 1, "X%lu", (unsigned long) t);
#else
sprintf (ts, "X%lu", (unsigned long) t);
#endif
ret = savestring (ts);
ret[0] = history_comment_char;
return ret;
}
/* Place STRING at the end of the history list. The data field
is set to NULL. */
void
add_history (string)
const char *string;
{
HIST_ENTRY *temp;
if (history_stifled && (history_length == history_max_entries))
{
register int i;
/* If the history is stifled, and history_length is zero,
and it equals history_max_entries, we don't save items. */
if (history_length == 0)
return;
/* If there is something in the slot, then remove it. */
if (the_history[0])
(void) free_history_entry (the_history[0]);
/* Copy the rest of the entries, moving down one slot. */
for (i = 0; i < history_length; i++)
the_history[i] = the_history[i + 1];
history_base++;
}
else
{
if (history_size == 0)
{
history_size = DEFAULT_HISTORY_GROW_SIZE;
the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));
history_length = 1;
}
else
{
if (history_length == (history_size - 1))
{
history_size += DEFAULT_HISTORY_GROW_SIZE;
the_history = (HIST_ENTRY **)
xrealloc (the_history, history_size * sizeof (HIST_ENTRY *));
}
history_length++;
}
}
temp = alloc_history_entry (string, hist_inittime ());
the_history[history_length] = (HIST_ENTRY *)NULL;
the_history[history_length - 1] = temp;
}
/* Change the time stamp of the most recent history entry to STRING. */
void
add_history_time (string)
const char *string;
{
HIST_ENTRY *hs;
if (string == 0)
return;
hs = the_history[history_length - 1];
FREE (hs->timestamp);
hs->timestamp = savestring (string);
}
/* Free HIST and return the data so the calling application can free it
if necessary and desired. */
histdata_t
free_history_entry (hist)
HIST_ENTRY *hist;
{
histdata_t x;
if (hist == 0)
return ((histdata_t) 0);
FREE (hist->line);
FREE (hist->timestamp);
x = hist->data;
free (hist);
return (x);
}
HIST_ENTRY *
copy_history_entry (hist)
HIST_ENTRY *hist;
{
HIST_ENTRY *ret;
char *ts;
if (hist == 0)
return hist;
ret = alloc_history_entry (hist->line, (char *)NULL);
ts = hist->timestamp ? savestring (hist->timestamp) : hist->timestamp;
ret->timestamp = ts;
ret->data = hist->data;
return ret;
}
/* Make the history entry at WHICH have LINE and DATA. This returns
the old entry so you can dispose of the data. In the case of an
invalid WHICH, a NULL pointer is returned. */
HIST_ENTRY *
replace_history_entry (which, line, data)
int which;
const char *line;
histdata_t data;
{
HIST_ENTRY *temp, *old_value;
if (which < 0 || which >= history_length)
return ((HIST_ENTRY *)NULL);
temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
old_value = the_history[which];
temp->line = savestring (line);
temp->data = data;
temp->timestamp = savestring (old_value->timestamp);
the_history[which] = temp;
return (old_value);
}
/* Replace the DATA in the specified history entries, replacing OLD with
NEW. WHICH says which one(s) to replace: WHICH == -1 means to replace
all of the history entries where entry->data == OLD; WHICH == -2 means
to replace the `newest' history entry where entry->data == OLD; and
WHICH >= 0 means to replace that particular history entry's data, as
long as it matches OLD. */
void
replace_history_data (which,old, new)
int which;
histdata_t *old, *new;
{
HIST_ENTRY *entry;
register int i, last;
if (which < -2 || which >= history_length || history_length == 0 || the_history == 0)
return;
if (which >= 0)
{
entry = the_history[which];
if (entry && entry->data == old)
entry->data = new;
return;
}
last = -1;
for (i = 0; i < history_length; i++)
{
entry = the_history[i];
if (entry == 0)
continue;
if (entry->data == old)
{
last = i;
if (which == -1)
entry->data = new;
}
}
if (which == -2 && last >= 0)
{
entry = the_history[last];
entry->data = new; /* XXX - we don't check entry->old */
}
}
/* Remove history element WHICH from the history. The removed
element is returned to you so you can free the line, data,
and containing structure. */
HIST_ENTRY *
remove_history (which)
int which;
{
HIST_ENTRY *return_value;
register int i;
if (which < 0 || which >= history_length || history_length == 0 || the_history == 0)
return ((HIST_ENTRY *)NULL);
return_value = the_history[which];
for (i = which; i < history_length; i++)
the_history[i] = the_history[i + 1];
history_length--;
return (return_value);
}
/* Stifle the history list, remembering only MAX number of lines. */
void
stifle_history (max)
int max;
{
register int i, j;
if (max < 0)
max = 0;
if (history_length > max)
{
/* This loses because we cannot free the data. */
for (i = 0, j = history_length - max; i < j; i++)
free_history_entry (the_history[i]);
history_base = i;
for (j = 0, i = history_length - max; j < max; i++, j++)
the_history[j] = the_history[i];
the_history[j] = (HIST_ENTRY *)NULL;
history_length = j;
}
history_stifled = 1;
max_input_history = history_max_entries = max;
}
/* Stop stifling the history. This returns the previous maximum
number of history entries. The value is positive if the history
was stifled, negative if it wasn't. */
int
unstifle_history ()
{
if (history_stifled)
{
history_stifled = 0;
return (history_max_entries);
}
else
return (-history_max_entries);
}
int
history_is_stifled ()
{
return (history_stifled);
}
void
clear_history ()
{
register int i;
/* This loses because we cannot free the data. */
for (i = 0; i < history_length; i++)
{
free_history_entry (the_history[i]);
the_history[i] = (HIST_ENTRY *)NULL;
}
history_offset = history_length = 0;
}
-596
View File
@@ -1,596 +0,0 @@
/* input.c -- character input functions for readline. */
/* Copyright (C) 1994-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Readline is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (__TANDEM)
# include <floss.h>
#endif
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
#include <fcntl.h>
#if defined (HAVE_SYS_FILE_H)
# include <sys/file.h>
#endif /* HAVE_SYS_FILE_H */
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include "posixselect.h"
#if defined (FIONREAD_IN_SYS_IOCTL)
# include <sys/ioctl.h>
#endif
#include <stdio.h>
#include <errno.h>
#if !defined (errno)
extern int errno;
#endif /* !errno */
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#include "rlmbutil.h"
/* Some standard library routines. */
#include "readline.h"
#include "rlprivate.h"
#include "rlshell.h"
#include "xmalloc.h"
/* What kind of non-blocking I/O do we have? */
#if !defined (O_NDELAY) && defined (O_NONBLOCK)
# define O_NDELAY O_NONBLOCK /* Posix style */
#endif
/* Non-null means it is a pointer to a function to run while waiting for
character input. */
rl_hook_func_t *rl_event_hook = (rl_hook_func_t *)NULL;
rl_getc_func_t *rl_getc_function = rl_getc;
static int _keyboard_input_timeout = 100000; /* 0.1 seconds; it's in usec */
static int ibuffer_space PARAMS((void));
static int rl_get_char PARAMS((int *));
static int rl_gather_tyi PARAMS((void));
/* **************************************************************** */
/* */
/* Character Input Buffering */
/* */
/* **************************************************************** */
static int pop_index, push_index;
static unsigned char ibuffer[512];
static int ibuffer_len = sizeof (ibuffer) - 1;
#define any_typein (push_index != pop_index)
int
_rl_any_typein ()
{
return any_typein;
}
/* Return the amount of space available in the buffer for stuffing
characters. */
static int
ibuffer_space ()
{
if (pop_index > push_index)
return (pop_index - push_index - 1);
else
return (ibuffer_len - (push_index - pop_index));
}
/* Get a key from the buffer of characters to be read.
Return the key in KEY.
Result is KEY if there was a key, or 0 if there wasn't. */
static int
rl_get_char (key)
int *key;
{
if (push_index == pop_index)
return (0);
*key = ibuffer[pop_index++];
#if 0
if (pop_index >= ibuffer_len)
#else
if (pop_index > ibuffer_len)
#endif
pop_index = 0;
return (1);
}
/* Stuff KEY into the *front* of the input buffer.
Returns non-zero if successful, zero if there is
no space left in the buffer. */
int
_rl_unget_char (key)
int key;
{
if (ibuffer_space ())
{
pop_index--;
if (pop_index < 0)
pop_index = ibuffer_len;
ibuffer[pop_index] = key;
return (1);
}
return (0);
}
int
_rl_pushed_input_available ()
{
return (push_index != pop_index);
}
/* If a character is available to be read, then read it and stuff it into
IBUFFER. Otherwise, just return. Returns number of characters read
(0 if none available) and -1 on error (EIO). */
static int
rl_gather_tyi ()
{
int tty;
register int tem, result;
int chars_avail, k;
char input;
#if defined(HAVE_SELECT)
fd_set readfds, exceptfds;
struct timeval timeout;
#endif
chars_avail = 0;
tty = fileno (rl_instream);
#if defined (HAVE_SELECT)
FD_ZERO (&readfds);
FD_ZERO (&exceptfds);
FD_SET (tty, &readfds);
FD_SET (tty, &exceptfds);
USEC_TO_TIMEVAL (_keyboard_input_timeout, timeout);
result = select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout);
if (result <= 0)
return 0; /* Nothing to read. */
#endif
result = -1;
#if defined (FIONREAD)
errno = 0;
result = ioctl (tty, FIONREAD, &chars_avail);
if (result == -1 && errno == EIO)
return -1;
#endif
#if defined (O_NDELAY)
if (result == -1)
{
tem = fcntl (tty, F_GETFL, 0);
fcntl (tty, F_SETFL, (tem | O_NDELAY));
chars_avail = read (tty, &input, 1);
fcntl (tty, F_SETFL, tem);
if (chars_avail == -1 && errno == EAGAIN)
return 0;
if (chars_avail == 0) /* EOF */
{
rl_stuff_char (EOF);
return (0);
}
}
#endif /* O_NDELAY */
#if defined (__MINGW32__)
/* Use getch/_kbhit to check for available console input, in the same way
that we read it normally. */
chars_avail = isatty (tty) ? _kbhit () : 0;
result = 0;
#endif
/* If there's nothing available, don't waste time trying to read
something. */
if (chars_avail <= 0)
return 0;
tem = ibuffer_space ();
if (chars_avail > tem)
chars_avail = tem;
/* One cannot read all of the available input. I can only read a single
character at a time, or else programs which require input can be
thwarted. If the buffer is larger than one character, I lose.
Damn! */
if (tem < ibuffer_len)
chars_avail = 0;
if (result != -1)
{
while (chars_avail--)
{
RL_CHECK_SIGNALS ();
k = (*rl_getc_function) (rl_instream);
if (rl_stuff_char (k) == 0)
break; /* some problem; no more room */
if (k == NEWLINE || k == RETURN)
break;
}
}
else
{
if (chars_avail)
rl_stuff_char (input);
}
return 1;
}
int
rl_set_keyboard_input_timeout (u)
int u;
{
int o;
o = _keyboard_input_timeout;
if (u >= 0)
_keyboard_input_timeout = u;
return (o);
}
/* Is there input available to be read on the readline input file
descriptor? Only works if the system has select(2) or FIONREAD.
Uses the value of _keyboard_input_timeout as the timeout; if another
readline function wants to specify a timeout and not leave it up to
the user, it should use _rl_input_queued(timeout_value_in_microseconds)
instead. */
int
_rl_input_available ()
{
#if defined(HAVE_SELECT)
fd_set readfds, exceptfds;
struct timeval timeout;
#endif
#if !defined (HAVE_SELECT) && defined(FIONREAD)
int chars_avail;
#endif
int tty;
tty = fileno (rl_instream);
#if defined (HAVE_SELECT)
FD_ZERO (&readfds);
FD_ZERO (&exceptfds);
FD_SET (tty, &readfds);
FD_SET (tty, &exceptfds);
timeout.tv_sec = 0;
timeout.tv_usec = _keyboard_input_timeout;
return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0);
#else
#if defined (FIONREAD)
if (ioctl (tty, FIONREAD, &chars_avail) == 0)
return (chars_avail);
#endif
#endif
#if defined (__MINGW32__)
if (isatty (tty))
return (_kbhit ());
#endif
return 0;
}
int
_rl_input_queued (t)
int t;
{
int old_timeout, r;
old_timeout = rl_set_keyboard_input_timeout (t);
r = _rl_input_available ();
rl_set_keyboard_input_timeout (old_timeout);
return r;
}
void
_rl_insert_typein (c)
int c;
{
int key, t, i;
char *string;
i = key = 0;
string = (char *)xmalloc (ibuffer_len + 1);
string[i++] = (char) c;
while ((t = rl_get_char (&key)) &&
_rl_keymap[key].type == ISFUNC &&
_rl_keymap[key].function == rl_insert)
string[i++] = key;
if (t)
_rl_unget_char (key);
string[i] = '\0';
rl_insert_text (string);
xfree (string);
}
/* Add KEY to the buffer of characters to be read. Returns 1 if the
character was stuffed correctly; 0 otherwise. */
int
rl_stuff_char (key)
int key;
{
if (ibuffer_space () == 0)
return 0;
if (key == EOF)
{
key = NEWLINE;
rl_pending_input = EOF;
RL_SETSTATE (RL_STATE_INPUTPENDING);
}
ibuffer[push_index++] = key;
#if 0
if (push_index >= ibuffer_len)
#else
if (push_index > ibuffer_len)
#endif
push_index = 0;
return 1;
}
/* Make C be the next command to be executed. */
int
rl_execute_next (c)
int c;
{
rl_pending_input = c;
RL_SETSTATE (RL_STATE_INPUTPENDING);
return 0;
}
/* Clear any pending input pushed with rl_execute_next() */
int
rl_clear_pending_input ()
{
rl_pending_input = 0;
RL_UNSETSTATE (RL_STATE_INPUTPENDING);
return 0;
}
/* **************************************************************** */
/* */
/* Character Input */
/* */
/* **************************************************************** */
/* Read a key, including pending input. */
int
rl_read_key ()
{
int c;
rl_key_sequence_length++;
if (rl_pending_input)
{
c = rl_pending_input;
rl_clear_pending_input ();
}
else
{
/* If input is coming from a macro, then use that. */
if (c = _rl_next_macro_key ())
return (c);
/* If the user has an event function, then call it periodically. */
if (rl_event_hook)
{
while (rl_event_hook)
{
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
{
if (rl_get_char (&c) == 0)
c = (*rl_getc_function) (rl_instream);
RL_CHECK_SIGNALS ();
}
}
return (c);
}
int
rl_getc (stream)
FILE *stream;
{
int result;
unsigned char c;
while (1)
{
RL_CHECK_SIGNALS ();
#if defined (__MINGW32__)
if (isatty (fileno (stream)))
return (getch ());
#endif
result = read (fileno (stream), &c, sizeof (unsigned char));
if (result == sizeof (unsigned char))
return (c);
/* If zero characters are returned, then the file that we are
reading from is empty! Return EOF in that case. */
if (result == 0)
return (EOF);
#if defined (__BEOS__)
if (errno == EINTR)
continue;
#endif
#if defined (EWOULDBLOCK)
# define X_EWOULDBLOCK EWOULDBLOCK
#else
# define X_EWOULDBLOCK -99
#endif
#if defined (EAGAIN)
# define X_EAGAIN EAGAIN
#else
# define X_EAGAIN -99
#endif
if (errno == X_EWOULDBLOCK || errno == X_EAGAIN)
{
if (sh_unset_nodelay_mode (fileno (stream)) < 0)
return (EOF);
continue;
}
#undef X_EWOULDBLOCK
#undef X_EAGAIN
/* If the error that we received was SIGINT, then try again,
this is simply an interrupted system call to read ().
Otherwise, some error ocurred, also signifying EOF. */
if (errno != EINTR)
return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF);
}
}
#if defined (HANDLE_MULTIBYTE)
/* read multibyte char */
int
_rl_read_mbchar (mbchar, size)
char *mbchar;
int size;
{
int mb_len, c;
size_t mbchar_bytes_length;
wchar_t wc;
mbstate_t ps, ps_back;
memset(&ps, 0, sizeof (mbstate_t));
memset(&ps_back, 0, sizeof (mbstate_t));
mb_len = 0;
while (mb_len < size)
{
RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
if (c < 0)
break;
mbchar[mb_len++] = c;
mbchar_bytes_length = mbrtowc (&wc, mbchar, mb_len, &ps);
if (mbchar_bytes_length == (size_t)(-1))
break; /* invalid byte sequence for the current locale */
else if (mbchar_bytes_length == (size_t)(-2))
{
/* shorted bytes */
ps = ps_back;
continue;
}
else if (mbchar_bytes_length == 0)
{
mbchar[0] = '\0'; /* null wide character */
mb_len = 1;
break;
}
else if (mbchar_bytes_length > (size_t)(0))
break;
}
return mb_len;
}
/* Read a multibyte-character string whose first character is FIRST into
the buffer MB of length MLEN. Returns the last character read, which
may be FIRST. Used by the search functions, among others. Very similar
to _rl_read_mbchar. */
int
_rl_read_mbstring (first, mb, mlen)
int first;
char *mb;
int mlen;
{
int i, c;
mbstate_t ps;
c = first;
memset (mb, 0, mlen);
for (i = 0; c >= 0 && i < mlen; i++)
{
mb[i] = (char)c;
memset (&ps, 0, sizeof (mbstate_t));
if (_rl_get_char_len (mb, &ps) == -2)
{
/* Read more for multibyte character */
RL_SETSTATE (RL_STATE_MOREINPUT);
c = rl_read_key ();
RL_UNSETSTATE (RL_STATE_MOREINPUT);
}
else
break;
}
return c;
}
#endif /* HANDLE_MULTIBYTE */
-697
View File
@@ -1,697 +0,0 @@
/* isearch.c - incremental searching */
/* **************************************************************** */
/* */
/* I-Search and Searching */
/* */
/* **************************************************************** */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Readline is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif
#include "rldefs.h"
#include "rlmbutil.h"
#include "readline.h"
#include "history.h"
#include "rlprivate.h"
#include "xmalloc.h"
/* Variables exported to other files in the readline library. */
char *_rl_isearch_terminators = (char *)NULL;
_rl_search_cxt *_rl_iscxt = 0;
/* Variables imported from other files in the readline library. */
extern HIST_ENTRY *_rl_saved_line_for_history;
static int rl_search_history PARAMS((int, int));
static _rl_search_cxt *_rl_isearch_init PARAMS((int));
static void _rl_isearch_fini PARAMS((_rl_search_cxt *));
static int _rl_isearch_cleanup PARAMS((_rl_search_cxt *, int));
/* Last line found by the current incremental search, so we don't `find'
identical lines many times in a row. Now part of isearch context. */
/* static char *prev_line_found; */
/* Last search string and its length. */
static char *last_isearch_string;
static int last_isearch_string_len;
static char * const default_isearch_terminators = "\033\012";
_rl_search_cxt *
_rl_scxt_alloc (type, flags)
int type, flags;
{
_rl_search_cxt *cxt;
cxt = (_rl_search_cxt *)xmalloc (sizeof (_rl_search_cxt));
cxt->type = type;
cxt->sflags = flags;
cxt->search_string = 0;
cxt->search_string_size = cxt->search_string_index = 0;
cxt->lines = 0;
cxt->allocated_line = 0;
cxt->hlen = cxt->hindex = 0;
cxt->save_point = rl_point;
cxt->save_mark = rl_mark;
cxt->save_line = where_history ();
cxt->last_found_line = cxt->save_line;
cxt->prev_line_found = 0;
cxt->save_undo_list = 0;
cxt->keymap = _rl_keymap;
cxt->okeymap = _rl_keymap;
cxt->history_pos = 0;
cxt->direction = 0;
cxt->lastc = 0;
cxt->sline = 0;
cxt->sline_len = cxt->sline_index = 0;
cxt->search_terminators = 0;
return cxt;
}
void
_rl_scxt_dispose (cxt, flags)
_rl_search_cxt *cxt;
int flags;
{
FREE (cxt->search_string);
FREE (cxt->allocated_line);
FREE (cxt->lines);
xfree (cxt);
}
/* Search backwards through the history looking for a string which is typed
interactively. Start with the current line. */
int
rl_reverse_search_history (sign, key)
int sign, key;
{
return (rl_search_history (-sign, key));
}
/* Search forwards through the history looking for a string which is typed
interactively. Start with the current line. */
int
rl_forward_search_history (sign, key)
int sign, key;
{
return (rl_search_history (sign, key));
}
/* Display the current state of the search in the echo-area.
SEARCH_STRING contains the string that is being searched for,
DIRECTION is zero for forward, or non-zero for reverse,
WHERE is the history list number of the current line. If it is
-1, then this line is the starting one. */
static void
rl_display_search (search_string, reverse_p, where)
char *search_string;
int reverse_p, where;
{
char *message;
int msglen, searchlen;
searchlen = (search_string && *search_string) ? strlen (search_string) : 0;
message = (char *)xmalloc (searchlen + 33);
msglen = 0;
#if defined (NOTDEF)
if (where != -1)
{
sprintf (message, "[%d]", where + history_base);
msglen = strlen (message);
}
#endif /* NOTDEF */
message[msglen++] = '(';
if (reverse_p)
{
strcpy (message + msglen, "reverse-");
msglen += 8;
}
strcpy (message + msglen, "i-search)`");
msglen += 10;
if (search_string)
{
strcpy (message + msglen, search_string);
msglen += searchlen;
}
strcpy (message + msglen, "': ");
rl_message ("%s", message);
xfree (message);
(*rl_redisplay_function) ();
}
static _rl_search_cxt *
_rl_isearch_init (direction)
int direction;
{
_rl_search_cxt *cxt;
register int i;
HIST_ENTRY **hlist;
cxt = _rl_scxt_alloc (RL_SEARCH_ISEARCH, 0);
if (direction < 0)
cxt->sflags |= SF_REVERSE;
cxt->search_terminators = _rl_isearch_terminators ? _rl_isearch_terminators
: default_isearch_terminators;
/* Create an arrary of pointers to the lines that we want to search. */
hlist = history_list ();
rl_maybe_replace_line ();
i = 0;
if (hlist)
for (i = 0; hlist[i]; i++);
/* Allocate space for this many lines, +1 for the current input line,
and remember those lines. */
cxt->lines = (char **)xmalloc ((1 + (cxt->hlen = i)) * sizeof (char *));
for (i = 0; i < cxt->hlen; i++)
cxt->lines[i] = hlist[i]->line;
if (_rl_saved_line_for_history)
cxt->lines[i] = _rl_saved_line_for_history->line;
else
{
/* Keep track of this so we can free it. */
cxt->allocated_line = (char *)xmalloc (1 + strlen (rl_line_buffer));
strcpy (cxt->allocated_line, &rl_line_buffer[0]);
cxt->lines[i] = cxt->allocated_line;
}
cxt->hlen++;
/* The line where we start the search. */
cxt->history_pos = cxt->save_line;
rl_save_prompt ();
/* Initialize search parameters. */
cxt->search_string = (char *)xmalloc (cxt->search_string_size = 128);
cxt->search_string[cxt->search_string_index = 0] = '\0';
/* Normalize DIRECTION into 1 or -1. */
cxt->direction = (direction >= 0) ? 1 : -1;
cxt->sline = rl_line_buffer;
cxt->sline_len = strlen (cxt->sline);
cxt->sline_index = rl_point;
_rl_iscxt = cxt; /* save globally */
return cxt;
}
static void
_rl_isearch_fini (cxt)
_rl_search_cxt *cxt;
{
/* First put back the original state. */
strcpy (rl_line_buffer, cxt->lines[cxt->save_line]);
rl_restore_prompt ();
/* Save the search string for possible later use. */
FREE (last_isearch_string);
last_isearch_string = cxt->search_string;
last_isearch_string_len = cxt->search_string_index;
cxt->search_string = 0;
if (cxt->last_found_line < cxt->save_line)
rl_get_previous_history (cxt->save_line - cxt->last_found_line, 0);
else
rl_get_next_history (cxt->last_found_line - cxt->save_line, 0);
/* If the string was not found, put point at the end of the last matching
line. If last_found_line == orig_line, we didn't find any matching
history lines at all, so put point back in its original position. */
if (cxt->sline_index < 0)
{
if (cxt->last_found_line == cxt->save_line)
cxt->sline_index = cxt->save_point;
else
cxt->sline_index = strlen (rl_line_buffer);
rl_mark = cxt->save_mark;
}
rl_point = cxt->sline_index;
/* Don't worry about where to put the mark here; rl_get_previous_history
and rl_get_next_history take care of it. */
rl_clear_message ();
}
int
_rl_search_getchar (cxt)
_rl_search_cxt *cxt;
{
int c;
/* Read a key and decide how to proceed. */
RL_SETSTATE(RL_STATE_MOREINPUT);
c = cxt->lastc = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
c = cxt->lastc = _rl_read_mbstring (cxt->lastc, cxt->mb, MB_LEN_MAX);
#endif
return c;
}
/* Process just-read character C according to isearch context CXT. Return
-1 if the caller should just free the context and return, 0 if we should
break out of the loop, and 1 if we should continue to read characters. */
int
_rl_isearch_dispatch (cxt, c)
_rl_search_cxt *cxt;
int c;
{
int n, wstart, wlen, limit, cval;
rl_command_func_t *f;
f = (rl_command_func_t *)NULL;
if (c < 0)
{
cxt->sflags |= SF_FAILED;
cxt->history_pos = cxt->last_found_line;
return -1;
}
/* If we are moving into a new keymap, modify cxt->keymap and go on.
This can be a problem if c == ESC and we want to terminate the
incremental search, so we check */
if (c >= 0 && cxt->keymap[c].type == ISKMAP && strchr (cxt->search_terminators, cxt->lastc) == 0)
{
cxt->keymap = FUNCTION_TO_KEYMAP (cxt->keymap, c);
cxt->sflags |= SF_CHGKMAP;
/* XXX - we should probably save this sequence, so we can do
something useful if this doesn't end up mapping to a command. */
return 1;
}
/* Translate the keys we do something with to opcodes. */
if (c >= 0 && cxt->keymap[c].type == ISFUNC)
{
f = cxt->keymap[c].function;
if (f == rl_reverse_search_history)
cxt->lastc = (cxt->sflags & SF_REVERSE) ? -1 : -2;
else if (f == rl_forward_search_history)
cxt->lastc = (cxt->sflags & SF_REVERSE) ? -2 : -1;
else if (f == rl_rubout)
cxt->lastc = -3;
else if (c == CTRL ('G'))
cxt->lastc = -4;
else if (c == CTRL ('W')) /* XXX */
cxt->lastc = -5;
else if (c == CTRL ('Y')) /* 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 (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
with select(2)) it is used as a prefix character
with rl_execute_next. WATCH OUT FOR THIS! This is intended
to allow the arrow keys to be used like ^F and ^B are used
to terminate the search and execute the movement command.
XXX - since _rl_input_available depends on the application-
settable keyboard timeout value, this could alternatively
use _rl_input_queued(100000) */
if (cxt->lastc == ESC && _rl_input_available ())
rl_execute_next (ESC);
return (0);
}
#define ENDSRCH_CHAR(c) \
((CTRL_CHAR (c) || META_CHAR (c) || (c) == RUBOUT) && ((c) != CTRL ('G')))
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
if (cxt->lastc >= 0 && (cxt->mb[0] && cxt->mb[1] == '\0') && ENDSRCH_CHAR (cxt->lastc))
{
/* This sets rl_pending_input to LASTC; it will be picked up the next
time rl_read_key is called. */
rl_execute_next (cxt->lastc);
return (0);
}
}
else
#endif
if (cxt->lastc >= 0 && ENDSRCH_CHAR (cxt->lastc))
{
/* This sets rl_pending_input to LASTC; it will be picked up the next
time rl_read_key is called. */
rl_execute_next (cxt->lastc);
return (0);
}
/* Now dispatch on the character. `Opcodes' affect the search string or
state. Other characters are added to the string. */
switch (cxt->lastc)
{
/* search again */
case -1:
if (cxt->search_string_index == 0)
{
if (last_isearch_string)
{
cxt->search_string_size = 64 + last_isearch_string_len;
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
strcpy (cxt->search_string, last_isearch_string);
cxt->search_string_index = last_isearch_string_len;
rl_display_search (cxt->search_string, (cxt->sflags & SF_REVERSE), -1);
break;
}
return (1);
}
else if (cxt->sflags & SF_REVERSE)
cxt->sline_index--;
else if (cxt->sline_index != cxt->sline_len)
cxt->sline_index++;
else
rl_ding ();
break;
/* switch directions */
case -2:
cxt->direction = -cxt->direction;
if (cxt->direction < 0)
cxt->sflags |= SF_REVERSE;
else
cxt->sflags &= ~SF_REVERSE;
break;
/* delete character from search string. */
case -3: /* C-H, DEL */
/* This is tricky. To do this right, we need to keep a
stack of search positions for the current search, with
sentinels marking the beginning and end. But this will
do until we have a real isearch-undo. */
if (cxt->search_string_index == 0)
rl_ding ();
else
cxt->search_string[--cxt->search_string_index] = '\0';
break;
case -4: /* C-G, abort */
rl_replace_line (cxt->lines[cxt->save_line], 0);
rl_point = cxt->save_point;
rl_mark = cxt->save_mark;
rl_restore_prompt();
rl_clear_message ();
return -1;
case -5: /* C-W */
/* skip over portion of line we already matched and yank word */
wstart = rl_point + cxt->search_string_index;
if (wstart >= rl_end)
{
rl_ding ();
break;
}
/* if not in a word, move to one. */
cval = _rl_char_value (rl_line_buffer, wstart);
if (_rl_walphabetic (cval) == 0)
{
rl_ding ();
break;
}
n = MB_NEXTCHAR (rl_line_buffer, wstart, 1, MB_FIND_NONZERO);;
while (n < rl_end)
{
cval = _rl_char_value (rl_line_buffer, n);
if (_rl_walphabetic (cval) == 0)
break;
n = MB_NEXTCHAR (rl_line_buffer, n, 1, MB_FIND_NONZERO);;
}
wlen = n - wstart + 1;
if (cxt->search_string_index + wlen + 1 >= cxt->search_string_size)
{
cxt->search_string_size += wlen + 1;
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
}
for (; wstart < n; wstart++)
cxt->search_string[cxt->search_string_index++] = rl_line_buffer[wstart];
cxt->search_string[cxt->search_string_index] = '\0';
break;
case -6: /* C-Y */
/* skip over portion of line we already matched and yank rest */
wstart = rl_point + cxt->search_string_index;
if (wstart >= rl_end)
{
rl_ding ();
break;
}
n = rl_end - wstart + 1;
if (cxt->search_string_index + n + 1 >= cxt->search_string_size)
{
cxt->search_string_size += n + 1;
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
}
for (n = wstart; n < rl_end; n++)
cxt->search_string[cxt->search_string_index++] = rl_line_buffer[n];
cxt->search_string[cxt->search_string_index] = '\0';
break;
/* Add character to search string and continue search. */
default:
if (cxt->search_string_index + 2 >= cxt->search_string_size)
{
cxt->search_string_size += 128;
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
}
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
int j, l;
for (j = 0, l = strlen (cxt->mb); j < l; )
cxt->search_string[cxt->search_string_index++] = cxt->mb[j++];
}
else
#endif
cxt->search_string[cxt->search_string_index++] = c;
cxt->search_string[cxt->search_string_index] = '\0';
break;
}
for (cxt->sflags &= ~(SF_FOUND|SF_FAILED);; )
{
limit = cxt->sline_len - cxt->search_string_index + 1;
/* Search the current line. */
while ((cxt->sflags & SF_REVERSE) ? (cxt->sline_index >= 0) : (cxt->sline_index < limit))
{
if (STREQN (cxt->search_string, cxt->sline + cxt->sline_index, cxt->search_string_index))
{
cxt->sflags |= SF_FOUND;
break;
}
else
cxt->sline_index += cxt->direction;
}
if (cxt->sflags & SF_FOUND)
break;
/* Move to the next line, but skip new copies of the line
we just found and lines shorter than the string we're
searching for. */
do
{
/* Move to the next line. */
cxt->history_pos += cxt->direction;
/* At limit for direction? */
if ((cxt->sflags & SF_REVERSE) ? (cxt->history_pos < 0) : (cxt->history_pos == cxt->hlen))
{
cxt->sflags |= SF_FAILED;
break;
}
/* We will need these later. */
cxt->sline = cxt->lines[cxt->history_pos];
cxt->sline_len = strlen (cxt->sline);
}
while ((cxt->prev_line_found && STREQ (cxt->prev_line_found, cxt->lines[cxt->history_pos])) ||
(cxt->search_string_index > cxt->sline_len));
if (cxt->sflags & SF_FAILED)
break;
/* Now set up the line for searching... */
cxt->sline_index = (cxt->sflags & SF_REVERSE) ? cxt->sline_len - cxt->search_string_index : 0;
}
if (cxt->sflags & SF_FAILED)
{
/* We cannot find the search string. Ding the bell. */
rl_ding ();
cxt->history_pos = cxt->last_found_line;
return 1;
}
/* We have found the search string. Just display it. But don't
actually move there in the history list until the user accepts
the location. */
if (cxt->sflags & SF_FOUND)
{
cxt->prev_line_found = cxt->lines[cxt->history_pos];
rl_replace_line (cxt->lines[cxt->history_pos], 0);
rl_point = cxt->sline_index;
cxt->last_found_line = cxt->history_pos;
rl_display_search (cxt->search_string, (cxt->sflags & SF_REVERSE), (cxt->history_pos == cxt->save_line) ? -1 : cxt->history_pos);
}
return 1;
}
static int
_rl_isearch_cleanup (cxt, r)
_rl_search_cxt *cxt;
int r;
{
if (r >= 0)
_rl_isearch_fini (cxt);
_rl_scxt_dispose (cxt, 0);
_rl_iscxt = 0;
RL_UNSETSTATE(RL_STATE_ISEARCH);
return (r != 0);
}
/* Search through the history looking for an interactively typed string.
This is analogous to i-search. We start the search in the current line.
DIRECTION is which direction to search; >= 0 means forward, < 0 means
backwards. */
static int
rl_search_history (direction, invoking_key)
int direction, invoking_key;
{
_rl_search_cxt *cxt; /* local for now, but saved globally */
int c, r;
RL_SETSTATE(RL_STATE_ISEARCH);
cxt = _rl_isearch_init (direction);
rl_display_search (cxt->search_string, (cxt->sflags & SF_REVERSE), -1);
/* If we are using the callback interface, all we do is set up here and
return. The key is that we leave RL_STATE_ISEARCH set. */
if (RL_ISSTATE (RL_STATE_CALLBACK))
return (0);
r = -1;
for (;;)
{
c = _rl_search_getchar (cxt);
/* We might want to handle EOF here (c == 0) */
r = _rl_isearch_dispatch (cxt, cxt->lastc);
if (r <= 0)
break;
}
/* The searching is over. The user may have found the string that she
was looking for, or else she may have exited a failing search. If
LINE_INDEX is -1, then that shows that the string searched for was
not found. We use this to determine where to place rl_point. */
return (_rl_isearch_cleanup (cxt, r));
}
#if defined (READLINE_CALLBACKS)
/* Called from the callback functions when we are ready to read a key. The
callback functions know to call this because RL_ISSTATE(RL_STATE_ISEARCH).
If _rl_isearch_dispatch finishes searching, this function is responsible
for turning off RL_STATE_ISEARCH, which it does using _rl_isearch_cleanup. */
int
_rl_isearch_callback (cxt)
_rl_search_cxt *cxt;
{
int c, r;
c = _rl_search_getchar (cxt);
/* We might want to handle EOF here */
r = _rl_isearch_dispatch (cxt, cxt->lastc);
return (r <= 0) ? _rl_isearch_cleanup (cxt, r) : 0;
}
#endif
-162
View File
@@ -1,162 +0,0 @@
/* keymaps.c -- Functions and keymaps for the GNU Readline library. */
/* Copyright (C) 1988,1989-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Readline is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include <stdio.h> /* for FILE * definition for readline.h */
#include "readline.h"
#include "rlconf.h"
#include "emacs_keymap.c"
#if defined (VI_MODE)
#include "vi_keymap.c"
#endif
#include "xmalloc.h"
/* **************************************************************** */
/* */
/* Functions for manipulating Keymaps. */
/* */
/* **************************************************************** */
/* Return a new, empty keymap.
Free it with free() when you are done. */
Keymap
rl_make_bare_keymap ()
{
register int i;
Keymap keymap;
keymap = (Keymap)xmalloc (KEYMAP_SIZE * sizeof (KEYMAP_ENTRY));
for (i = 0; i < KEYMAP_SIZE; i++)
{
keymap[i].type = ISFUNC;
keymap[i].function = (rl_command_func_t *)NULL;
}
#if 0
for (i = 'A'; i < ('Z' + 1); i++)
{
keymap[i].type = ISFUNC;
keymap[i].function = rl_do_lowercase_version;
}
#endif
return (keymap);
}
/* Return a new keymap which is a copy of MAP. Just copies pointers, does
not copy text of macros or descend into child keymaps. */
Keymap
rl_copy_keymap (map)
Keymap map;
{
register int i;
Keymap temp;
temp = rl_make_bare_keymap ();
for (i = 0; i < KEYMAP_SIZE; i++)
{
temp[i].type = map[i].type;
temp[i].function = map[i].function;
}
return (temp);
}
/* Return a new keymap with the printing characters bound to rl_insert,
the uppercase Meta characters bound to run their lowercase equivalents,
and the Meta digits bound to produce numeric arguments. */
Keymap
rl_make_keymap ()
{
register int i;
Keymap newmap;
newmap = rl_make_bare_keymap ();
/* All ASCII printing characters are self-inserting. */
for (i = ' '; i < 127; i++)
newmap[i].function = rl_insert;
newmap[TAB].function = rl_insert;
newmap[RUBOUT].function = rl_rubout; /* RUBOUT == 127 */
newmap[CTRL('H')].function = rl_rubout;
#if KEYMAP_SIZE > 128
/* Printing characters in ISO Latin-1 and some 8-bit character sets. */
for (i = 128; i < 256; i++)
newmap[i].function = rl_insert;
#endif /* KEYMAP_SIZE > 128 */
return (newmap);
}
/* Free the storage associated with MAP. */
void
rl_discard_keymap (map)
Keymap map;
{
int i;
if (map == 0)
return;
for (i = 0; i < KEYMAP_SIZE; i++)
{
switch (map[i].type)
{
case ISFUNC:
break;
case ISKMAP:
rl_discard_keymap ((Keymap)map[i].function);
xfree ((char *)map[i].function);
break;
case ISMACR:
xfree ((char *)map[i].function);
break;
}
}
}
/* Convenience function that discards, then frees, MAP. */
void
rl_free_keymap (map)
Keymap map;
{
rl_discard_keymap (map);
free ((char *)map);
}
-694
View File
@@ -1,694 +0,0 @@
/* kill.c -- kill ring management. */
/* Copyright (C) 1994 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Readline is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h> /* for _POSIX_VERSION */
#endif /* HAVE_UNISTD_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include <stdio.h>
/* System-specific feature definitions and include files. */
#include "rldefs.h"
/* Some standard library routines. */
#include "readline.h"
#include "history.h"
#include "rlprivate.h"
#include "xmalloc.h"
/* **************************************************************** */
/* */
/* Killing Mechanism */
/* */
/* **************************************************************** */
/* What we assume for a max number of kills. */
#define DEFAULT_MAX_KILLS 10
/* The real variable to look at to find out when to flush kills. */
static int rl_max_kills = DEFAULT_MAX_KILLS;
/* Where to store killed text. */
static char **rl_kill_ring = (char **)NULL;
/* Where we are in the kill ring. */
static int rl_kill_index;
/* How many slots we have in the kill ring. */
static int rl_kill_ring_length;
static int _rl_copy_to_kill_ring PARAMS((char *, int));
static int region_kill_internal PARAMS((int));
static int _rl_copy_word_as_kill PARAMS((int, int));
static int rl_yank_nth_arg_internal PARAMS((int, int, int));
/* How to say that you only want to save a certain amount
of kill material. */
int
rl_set_retained_kills (num)
int num;
{
return 0;
}
/* Add TEXT to the kill ring, allocating a new kill ring slot as necessary.
This uses TEXT directly, so the caller must not free it. If APPEND is
non-zero, and the last command was a kill, the text is appended to the
current kill ring slot, otherwise prepended. */
static int
_rl_copy_to_kill_ring (text, append)
char *text;
int append;
{
char *old, *new;
int slot;
/* First, find the slot to work with. */
if (_rl_last_command_was_kill == 0)
{
/* Get a new slot. */
if (rl_kill_ring == 0)
{
/* If we don't have any defined, then make one. */
rl_kill_ring = (char **)
xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *));
rl_kill_ring[slot = 0] = (char *)NULL;
}
else
{
/* We have to add a new slot on the end, unless we have
exceeded the max limit for remembering kills. */
slot = rl_kill_ring_length;
if (slot == rl_max_kills)
{
register int i;
xfree (rl_kill_ring[0]);
for (i = 0; i < slot; i++)
rl_kill_ring[i] = rl_kill_ring[i + 1];
}
else
{
slot = rl_kill_ring_length += 1;
rl_kill_ring = (char **)xrealloc (rl_kill_ring, slot * sizeof (char *));
}
rl_kill_ring[--slot] = (char *)NULL;
}
}
else
slot = rl_kill_ring_length - 1;
/* If the last command was a kill, prepend or append. */
if (_rl_last_command_was_kill && rl_editing_mode != vi_mode)
{
old = rl_kill_ring[slot];
new = (char *)xmalloc (1 + strlen (old) + strlen (text));
if (append)
{
strcpy (new, old);
strcat (new, text);
}
else
{
strcpy (new, text);
strcat (new, old);
}
xfree (old);
xfree (text);
rl_kill_ring[slot] = new;
}
else
rl_kill_ring[slot] = text;
rl_kill_index = slot;
return 0;
}
/* The way to kill something. This appends or prepends to the last
kill, if the last command was a kill command. if FROM is less
than TO, then the text is appended, otherwise prepended. If the
last command was not a kill command, then a new slot is made for
this kill. */
int
rl_kill_text (from, to)
int from, to;
{
char *text;
/* Is there anything to kill? */
if (from == to)
{
_rl_last_command_was_kill++;
return 0;
}
text = rl_copy_text (from, to);
/* Delete the copied text from the line. */
rl_delete_text (from, to);
_rl_copy_to_kill_ring (text, from < to);
_rl_last_command_was_kill++;
return 0;
}
/* Now REMEMBER! In order to do prepending or appending correctly, kill
commands always make rl_point's original position be the FROM argument,
and rl_point's extent be the TO argument. */
/* **************************************************************** */
/* */
/* Killing Commands */
/* */
/* **************************************************************** */
/* Delete the word at point, saving the text in the kill ring. */
int
rl_kill_word (count, key)
int count, key;
{
int orig_point;
if (count < 0)
return (rl_backward_kill_word (-count, key));
else
{
orig_point = rl_point;
rl_forward_word (count, key);
if (rl_point != orig_point)
rl_kill_text (orig_point, rl_point);
rl_point = orig_point;
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
return 0;
}
/* Rubout the word before point, placing it on the kill ring. */
int
rl_backward_kill_word (count, ignore)
int count, ignore;
{
int orig_point;
if (count < 0)
return (rl_kill_word (-count, ignore));
else
{
orig_point = rl_point;
rl_backward_word (count, ignore);
if (rl_point != orig_point)
rl_kill_text (orig_point, rl_point);
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
return 0;
}
/* Kill from here to the end of the line. If DIRECTION is negative, kill
back to the line start instead. */
int
rl_kill_line (direction, ignore)
int direction, ignore;
{
int orig_point;
if (direction < 0)
return (rl_backward_kill_line (1, ignore));
else
{
orig_point = rl_point;
rl_end_of_line (1, ignore);
if (orig_point != rl_point)
rl_kill_text (orig_point, rl_point);
rl_point = orig_point;
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
return 0;
}
/* Kill backwards to the start of the line. If DIRECTION is negative, kill
forwards to the line end instead. */
int
rl_backward_kill_line (direction, ignore)
int direction, ignore;
{
int orig_point;
if (direction < 0)
return (rl_kill_line (1, ignore));
else
{
if (!rl_point)
rl_ding ();
else
{
orig_point = rl_point;
rl_beg_of_line (1, ignore);
if (rl_point != orig_point)
rl_kill_text (orig_point, rl_point);
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
}
return 0;
}
/* Kill the whole line, no matter where point is. */
int
rl_kill_full_line (count, ignore)
int count, ignore;
{
rl_begin_undo_group ();
rl_point = 0;
rl_kill_text (rl_point, rl_end);
rl_mark = 0;
rl_end_undo_group ();
return 0;
}
/* The next two functions mimic unix line editing behaviour, except they
save the deleted text on the kill ring. This is safer than not saving
it, and since we have a ring, nobody should get screwed. */
/* This does what C-w does in Unix. We can't prevent people from
using behaviour that they expect. */
int
rl_unix_word_rubout (count, key)
int count, key;
{
int orig_point;
if (rl_point == 0)
rl_ding ();
else
{
orig_point = rl_point;
if (count <= 0)
count = 1;
while (count--)
{
while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
rl_point--;
while (rl_point && (whitespace (rl_line_buffer[rl_point - 1]) == 0))
rl_point--;
}
rl_kill_text (orig_point, rl_point);
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
return 0;
}
/* This deletes one filename component in a Unix pathname. That is, it
deletes backward to directory separator (`/') or whitespace. */
int
rl_unix_filename_rubout (count, key)
int count, key;
{
int orig_point, c;
if (rl_point == 0)
rl_ding ();
else
{
orig_point = rl_point;
if (count <= 0)
count = 1;
while (count--)
{
c = rl_line_buffer[rl_point - 1];
while (rl_point && (whitespace (c) || c == '/'))
{
rl_point--;
c = rl_line_buffer[rl_point - 1];
}
while (rl_point && (whitespace (c) == 0) && c != '/')
{
rl_point--;
c = rl_line_buffer[rl_point - 1];
}
}
rl_kill_text (orig_point, rl_point);
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
return 0;
}
/* Here is C-u doing what Unix does. You don't *have* to use these
key-bindings. We have a choice of killing the entire line, or
killing from where we are to the start of the line. We choose the
latter, because if you are a Unix weenie, then you haven't backspaced
into the line at all, and if you aren't, then you know what you are
doing. */
int
rl_unix_line_discard (count, key)
int count, key;
{
if (rl_point == 0)
rl_ding ();
else
{
rl_kill_text (rl_point, 0);
rl_point = 0;
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
return 0;
}
/* Copy the text in the `region' to the kill ring. If DELETE is non-zero,
delete the text from the line as well. */
static int
region_kill_internal (delete)
int delete;
{
char *text;
if (rl_mark != rl_point)
{
text = rl_copy_text (rl_point, rl_mark);
if (delete)
rl_delete_text (rl_point, rl_mark);
_rl_copy_to_kill_ring (text, rl_point < rl_mark);
}
_rl_last_command_was_kill++;
return 0;
}
/* Copy the text in the region to the kill ring. */
int
rl_copy_region_to_kill (count, ignore)
int count, ignore;
{
return (region_kill_internal (0));
}
/* Kill the text between the point and mark. */
int
rl_kill_region (count, ignore)
int count, ignore;
{
int r, npoint;
npoint = (rl_point < rl_mark) ? rl_point : rl_mark;
r = region_kill_internal (1);
_rl_fix_point (1);
rl_point = npoint;
return r;
}
/* Copy COUNT words to the kill ring. DIR says which direction we look
to find the words. */
static int
_rl_copy_word_as_kill (count, dir)
int count, dir;
{
int om, op, r;
om = rl_mark;
op = rl_point;
if (dir > 0)
rl_forward_word (count, 0);
else
rl_backward_word (count, 0);
rl_mark = rl_point;
if (dir > 0)
rl_backward_word (count, 0);
else
rl_forward_word (count, 0);
r = region_kill_internal (0);
rl_mark = om;
rl_point = op;
return r;
}
int
rl_copy_forward_word (count, key)
int count, key;
{
if (count < 0)
return (rl_copy_backward_word (-count, key));
return (_rl_copy_word_as_kill (count, 1));
}
int
rl_copy_backward_word (count, key)
int count, key;
{
if (count < 0)
return (rl_copy_forward_word (-count, key));
return (_rl_copy_word_as_kill (count, -1));
}
/* Yank back the last killed text. This ignores arguments. */
int
rl_yank (count, ignore)
int count, ignore;
{
if (rl_kill_ring == 0)
{
_rl_abort_internal ();
return -1;
}
_rl_set_mark_at_pos (rl_point);
rl_insert_text (rl_kill_ring[rl_kill_index]);
return 0;
}
/* If the last command was yank, or yank_pop, and the text just
before point is identical to the current kill item, then
delete that text from the line, rotate the index down, and
yank back some other text. */
int
rl_yank_pop (count, key)
int count, key;
{
int l, n;
if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) ||
!rl_kill_ring)
{
_rl_abort_internal ();
return -1;
}
l = strlen (rl_kill_ring[rl_kill_index]);
n = rl_point - l;
if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l))
{
rl_delete_text (n, rl_point);
rl_point = n;
rl_kill_index--;
if (rl_kill_index < 0)
rl_kill_index = rl_kill_ring_length - 1;
rl_yank (1, 0);
return 0;
}
else
{
_rl_abort_internal ();
return -1;
}
}
/* Yank the COUNTh argument from the previous history line, skipping
HISTORY_SKIP lines before looking for the `previous line'. */
static int
rl_yank_nth_arg_internal (count, ignore, history_skip)
int count, ignore, history_skip;
{
register HIST_ENTRY *entry;
char *arg;
int i, pos;
pos = where_history ();
if (history_skip)
{
for (i = 0; i < history_skip; i++)
entry = previous_history ();
}
entry = previous_history ();
history_set_pos (pos);
if (entry == 0)
{
rl_ding ();
return -1;
}
arg = history_arg_extract (count, count, entry->line);
if (!arg || !*arg)
{
rl_ding ();
FREE (arg);
return -1;
}
rl_begin_undo_group ();
_rl_set_mark_at_pos (rl_point);
#if defined (VI_MODE)
/* Vi mode always inserts a space before yanking the argument, and it
inserts it right *after* rl_point. */
if (rl_editing_mode == vi_mode)
{
rl_vi_append_mode (1, ignore);
rl_insert_text (" ");
}
#endif /* VI_MODE */
rl_insert_text (arg);
xfree (arg);
rl_end_undo_group ();
return 0;
}
/* Yank the COUNTth argument from the previous history line. */
int
rl_yank_nth_arg (count, ignore)
int count, ignore;
{
return (rl_yank_nth_arg_internal (count, ignore, 0));
}
/* Yank the last argument from the previous history line. This `knows'
how rl_yank_nth_arg treats a count of `$'. With an argument, this
behaves the same as rl_yank_nth_arg. */
int
rl_yank_last_arg (count, key)
int count, key;
{
static int history_skip = 0;
static int explicit_arg_p = 0;
static int count_passed = 1;
static int direction = 1;
static int undo_needed = 0;
int retval;
if (rl_last_func != rl_yank_last_arg)
{
history_skip = 0;
explicit_arg_p = rl_explicit_arg;
count_passed = count;
direction = 1;
}
else
{
if (undo_needed)
rl_do_undo ();
if (count < 1)
direction = -direction;
history_skip += direction;
if (history_skip < 0)
history_skip = 0;
}
if (explicit_arg_p)
retval = rl_yank_nth_arg_internal (count_passed, key, history_skip);
else
retval = rl_yank_nth_arg_internal ('$', key, history_skip);
undo_needed = retval == 0;
return retval;
}
/* A special paste command for users of Cygnus's cygwin32. */
#if defined (__CYGWIN__)
#include <windows.h>
int
rl_paste_from_clipboard (count, key)
int count, key;
{
char *data, *ptr;
int len;
if (OpenClipboard (NULL) == 0)
return (0);
data = (char *)GetClipboardData (CF_TEXT);
if (data)
{
ptr = strchr (data, '\r');
if (ptr)
{
len = ptr - data;
ptr = (char *)xmalloc (len + 1);
ptr[len] = '\0';
strncpy (ptr, data, len);
}
else
ptr = data;
_rl_set_mark_at_pos (rl_point);
rl_insert_text (ptr);
if (ptr != data)
xfree (ptr);
CloseClipboard ();
}
return (0);
}
#endif /* __CYGWIN__ */
-655
View File
@@ -1,655 +0,0 @@
/* misc.c -- miscellaneous bindable readline functions. */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Readline is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#if defined (HAVE_LOCALE_H)
# include <locale.h>
#endif
#include <stdio.h>
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#include "rlmbutil.h"
/* Some standard library routines. */
#include "readline.h"
#include "history.h"
#include "rlprivate.h"
#include "rlshell.h"
#include "xmalloc.h"
static int rl_digit_loop PARAMS((void));
static void _rl_history_set_point PARAMS((void));
/* Forward declarations used in this file */
void _rl_free_history_entry PARAMS((HIST_ENTRY *));
/* If non-zero, rl_get_previous_history and rl_get_next_history attempt
to preserve the value of rl_point from line to line. */
int _rl_history_preserve_point = 0;
_rl_arg_cxt _rl_argcxt;
/* Saved target point for when _rl_history_preserve_point is set. Special
value of -1 means that point is at the end of the line. */
int _rl_history_saved_point = -1;
/* **************************************************************** */
/* */
/* Numeric Arguments */
/* */
/* **************************************************************** */
int
_rl_arg_overflow ()
{
if (rl_numeric_arg > 1000000)
{
_rl_argcxt = 0;
rl_explicit_arg = rl_numeric_arg = 0;
rl_ding ();
rl_restore_prompt ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
return 1;
}
return 0;
}
void
_rl_arg_init ()
{
rl_save_prompt ();
_rl_argcxt = 0;
RL_SETSTATE(RL_STATE_NUMERICARG);
}
int
_rl_arg_getchar ()
{
int c;
rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
return c;
}
/* 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. */
int
_rl_arg_dispatch (cxt, c)
_rl_arg_cxt cxt;
int c;
{
int key, r;
key = c;
/* If we see a key bound to `universal-argument' after seeing digits,
it ends the argument but is otherwise ignored. */
if (_rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
{
if ((cxt & NUM_SAWDIGITS) == 0)
{
rl_numeric_arg *= 4;
return 1;
}
else if (RL_ISSTATE (RL_STATE_CALLBACK))
{
_rl_argcxt |= NUM_READONE;
return 0; /* XXX */
}
else
{
RL_SETSTATE(RL_STATE_MOREINPUT);
key = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
rl_restore_prompt ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
if (key < 0)
return -1;
return (_rl_dispatch (key, _rl_keymap));
}
}
c = UNMETA (c);
if (_rl_digit_p (c))
{
r = _rl_digit_value (c);
rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) + r : r;
rl_explicit_arg = 1;
_rl_argcxt |= NUM_SAWDIGITS;
}
else if (c == '-' && rl_explicit_arg == 0)
{
rl_numeric_arg = 1;
_rl_argcxt |= NUM_SAWMINUS;
rl_arg_sign = -1;
}
else
{
/* Make M-- command equivalent to M--1 command. */
if ((_rl_argcxt & NUM_SAWMINUS) && rl_numeric_arg == 1 && rl_explicit_arg == 0)
rl_explicit_arg = 1;
rl_restore_prompt ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
r = _rl_dispatch (key, _rl_keymap);
if (RL_ISSTATE (RL_STATE_CALLBACK))
{
/* At worst, this will cause an extra redisplay. Otherwise,
we have to wait until the next character comes in. */
if (rl_done == 0)
(*rl_redisplay_function) ();
r = 0;
}
return r;
}
return 1;
}
/* Handle C-u style numeric args, as well as M--, and M-digits. */
static int
rl_digit_loop ()
{
int c, r;
while (1)
{
if (_rl_arg_overflow ())
return 1;
c = _rl_arg_getchar ();
if (c < 0)
{
_rl_abort_internal ();
return -1;
}
r = _rl_arg_dispatch (_rl_argcxt, c);
if (r <= 0 || (RL_ISSTATE (RL_STATE_NUMERICARG) == 0))
break;
}
return r;
}
/* Create a default argument. */
void
_rl_reset_argument ()
{
rl_numeric_arg = rl_arg_sign = 1;
rl_explicit_arg = 0;
_rl_argcxt = 0;
}
/* Start a numeric argument with initial value KEY */
int
rl_digit_argument (ignore, key)
int ignore, key;
{
_rl_arg_init ();
if (RL_ISSTATE (RL_STATE_CALLBACK))
{
_rl_arg_dispatch (_rl_argcxt, key);
rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
return 0;
}
else
{
rl_execute_next (key);
return (rl_digit_loop ());
}
}
/* C-u, universal argument. Multiply the current argument by 4.
Read a key. If the key has nothing to do with arguments, then
dispatch on it. If the key is the abort character then abort. */
int
rl_universal_argument (count, key)
int count, key;
{
_rl_arg_init ();
rl_numeric_arg *= 4;
return (RL_ISSTATE (RL_STATE_CALLBACK) ? 0 : rl_digit_loop ());
}
int
_rl_arg_callback (cxt)
_rl_arg_cxt cxt;
{
int c, r;
c = _rl_arg_getchar ();
if (_rl_argcxt & NUM_READONE)
{
_rl_argcxt &= ~NUM_READONE;
rl_restore_prompt ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
rl_execute_next (c);
return 0;
}
r = _rl_arg_dispatch (cxt, c);
return (r != 1);
}
/* What to do when you abort reading an argument. */
int
rl_discard_argument ()
{
rl_ding ();
rl_clear_message ();
_rl_reset_argument ();
return 0;
}
/* **************************************************************** */
/* */
/* History Utilities */
/* */
/* **************************************************************** */
/* We already have a history library, and that is what we use to control
the history features of readline. This is our local interface to
the history mechanism. */
/* While we are editing the history, this is the saved
version of the original line. */
HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
/* Set the history pointer back to the last entry in the history. */
void
_rl_start_using_history ()
{
using_history ();
if (_rl_saved_line_for_history)
_rl_free_history_entry (_rl_saved_line_for_history);
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
}
/* Free the contents (and containing structure) of a HIST_ENTRY. */
void
_rl_free_history_entry (entry)
HIST_ENTRY *entry;
{
if (entry == 0)
return;
FREE (entry->line);
FREE (entry->timestamp);
free (entry);
}
/* Perhaps put back the current line if it has changed. */
int
rl_maybe_replace_line ()
{
HIST_ENTRY *temp;
temp = current_history ();
/* If the current line has changed, save the changes. */
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);
FREE (temp->timestamp);
free (temp);
}
return 0;
}
/* Restore the _rl_saved_line_for_history if there is one. */
int
rl_maybe_unsave_line ()
{
if (_rl_saved_line_for_history)
{
/* Can't call with `1' because rl_undo_list might point to an undo
list from a history entry, as in rl_replace_from_history() below. */
rl_replace_line (_rl_saved_line_for_history->line, 0);
rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data;
_rl_free_history_entry (_rl_saved_line_for_history);
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
rl_point = rl_end; /* rl_replace_line sets rl_end */
}
else
rl_ding ();
return 0;
}
/* Save the current line in _rl_saved_line_for_history. */
int
rl_maybe_save_line ()
{
if (_rl_saved_line_for_history == 0)
{
_rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
_rl_saved_line_for_history->line = savestring (rl_line_buffer);
_rl_saved_line_for_history->timestamp = (char *)NULL;
_rl_saved_line_for_history->data = (char *)rl_undo_list;
}
return 0;
}
int
_rl_free_saved_history_line ()
{
if (_rl_saved_line_for_history)
{
_rl_free_history_entry (_rl_saved_line_for_history);
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
}
return 0;
}
static void
_rl_history_set_point ()
{
rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1)
? _rl_history_saved_point
: rl_end;
if (rl_point > rl_end)
rl_point = rl_end;
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode && _rl_keymap != vi_insertion_keymap)
rl_point = 0;
#endif /* VI_MODE */
if (rl_editing_mode == emacs_mode)
rl_mark = (rl_point == rl_end ? 0 : rl_end);
}
void
rl_replace_from_history (entry, flags)
HIST_ENTRY *entry;
int flags; /* currently unused */
{
/* Can't call with `1' because rl_undo_list might point to an undo list
from a history entry, just like we're setting up here. */
rl_replace_line (entry->line, 0);
rl_undo_list = (UNDO_LIST *)entry->data;
rl_point = rl_end;
rl_mark = 0;
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode)
{
rl_point = 0;
rl_mark = rl_end;
}
#endif
}
/* Process and free undo lists attached to each history entry prior to the
current entry, inclusive, reverting each line to its saved state. This
is destructive, and state about the current line is lost. This is not
intended to be called while actively editing, and the current line is
not assumed to have been added to the history list. */
void
_rl_revert_all_lines ()
{
int hpos;
HIST_ENTRY *entry;
UNDO_LIST *ul, *saved_undo_list;
char *lbuf;
lbuf = savestring (rl_line_buffer);
saved_undo_list = rl_undo_list;
hpos = where_history ();
entry = (hpos == history_length) ? previous_history () : current_history ();
while (entry)
{
if (ul = (UNDO_LIST *)entry->data)
{
if (ul == saved_undo_list)
saved_undo_list = 0;
/* Set up rl_line_buffer and other variables from history entry */
rl_replace_from_history (entry, 0); /* entry->line is now current */
/* Undo all changes to this history entry */
while (rl_undo_list)
rl_do_undo ();
/* And copy the reverted line back to the history entry, preserving
the timestamp. */
FREE (entry->line);
entry->line = savestring (rl_line_buffer);
entry->data = 0;
}
entry = previous_history ();
}
/* Restore history state */
rl_undo_list = saved_undo_list; /* may have been set to null */
history_set_pos (hpos);
/* reset the line buffer */
rl_replace_line (lbuf, 0);
_rl_set_the_line ();
/* and clean up */
free (lbuf);
}
/* **************************************************************** */
/* */
/* History Commands */
/* */
/* **************************************************************** */
/* Meta-< goes to the start of the history. */
int
rl_beginning_of_history (count, key)
int count, key;
{
return (rl_get_previous_history (1 + where_history (), key));
}
/* Meta-> goes to the end of the history. (The current line). */
int
rl_end_of_history (count, key)
int count, key;
{
rl_maybe_replace_line ();
using_history ();
rl_maybe_unsave_line ();
return 0;
}
/* Move down to the next history line. */
int
rl_get_next_history (count, key)
int count, key;
{
HIST_ENTRY *temp;
if (count < 0)
return (rl_get_previous_history (-count, key));
if (count == 0)
return 0;
rl_maybe_replace_line ();
/* either not saved by rl_newline or at end of line, so set appropriately. */
if (_rl_history_saved_point == -1 && (rl_point || rl_end))
_rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
temp = (HIST_ENTRY *)NULL;
while (count)
{
temp = next_history ();
if (!temp)
break;
--count;
}
if (temp == 0)
rl_maybe_unsave_line ();
else
{
rl_replace_from_history (temp, 0);
_rl_history_set_point ();
}
return 0;
}
/* Get the previous item out of our interactive history, making it the current
line. If there is no previous history, just ding. */
int
rl_get_previous_history (count, key)
int count, key;
{
HIST_ENTRY *old_temp, *temp;
if (count < 0)
return (rl_get_next_history (-count, key));
if (count == 0)
return 0;
/* either not saved by rl_newline or at end of line, so set appropriately. */
if (_rl_history_saved_point == -1 && (rl_point || rl_end))
_rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
/* If we don't have a line saved, then save this one. */
rl_maybe_save_line ();
/* If the current line has changed, save the changes. */
rl_maybe_replace_line ();
temp = old_temp = (HIST_ENTRY *)NULL;
while (count)
{
temp = previous_history ();
if (temp == 0)
break;
old_temp = temp;
--count;
}
/* If there was a large argument, and we moved back to the start of the
history, that is not an error. So use the last value found. */
if (!temp && old_temp)
temp = old_temp;
if (temp == 0)
rl_ding ();
else
{
rl_replace_from_history (temp, 0);
_rl_history_set_point ();
}
return 0;
}
/* **************************************************************** */
/* */
/* Editing Modes */
/* */
/* **************************************************************** */
/* How to toggle back and forth between editing modes. */
int
rl_vi_editing_mode (count, key)
int count, key;
{
#if defined (VI_MODE)
_rl_set_insert_mode (RL_IM_INSERT, 1); /* vi mode ignores insert mode */
rl_editing_mode = vi_mode;
rl_vi_insert_mode (1, key);
#endif /* VI_MODE */
return 0;
}
int
rl_emacs_editing_mode (count, key)
int count, key;
{
rl_editing_mode = emacs_mode;
_rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */
_rl_keymap = emacs_standard_keymap;
return 0;
}
/* Function for the rest of the library to use to set insert/overwrite mode. */
void
_rl_set_insert_mode (im, force)
int im, force;
{
#ifdef CURSOR_MODE
_rl_set_cursor (im, force);
#endif
rl_insert_mode = im;
}
/* Toggle overwrite mode. A positive explicit argument selects overwrite
mode. A negative or zero explicit argument selects insert mode. */
int
rl_overwrite_mode (count, key)
int count, key;
{
if (rl_explicit_arg == 0)
_rl_set_insert_mode (rl_insert_mode ^ 1, 0);
else if (count > 0)
_rl_set_insert_mode (RL_IM_OVERWRITE, 0);
else
_rl_set_insert_mode (RL_IM_INSERT, 0);
return 0;
}
-252
View File
@@ -1,252 +0,0 @@
/* nls.c -- skeletal internationalization code. */
/* Copyright (C) 1996-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Readline is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#if defined (HAVE_LOCALE_H)
# include <locale.h>
#endif
#include <ctype.h>
#include "rldefs.h"
#include "readline.h"
#include "rlshell.h"
#include "rlprivate.h"
#if !defined (HAVE_SETLOCALE)
/* A list of legal values for the LANG or LC_CTYPE environment variables.
If a locale name in this list is the value for the LC_ALL, LC_CTYPE,
or LANG environment variable (using the first of those with a value),
readline eight-bit mode is enabled. */
static char *legal_lang_values[] =
{
"iso88591",
"iso88592",
"iso88593",
"iso88594",
"iso88595",
"iso88596",
"iso88597",
"iso88598",
"iso88599",
"iso885910",
"koi8r",
0
};
static char *normalize_codeset PARAMS((char *));
static char *find_codeset PARAMS((char *, size_t *));
#endif /* !HAVE_SETLOCALE */
static char *_rl_get_locale_var PARAMS((const char *));
static char *
_rl_get_locale_var (v)
const char *v;
{
char *lspec;
lspec = sh_get_env_value ("LC_ALL");
if (lspec == 0 || *lspec == 0)
lspec = sh_get_env_value (v);
if (lspec == 0 || *lspec == 0)
lspec = sh_get_env_value ("LANG");
return lspec;
}
/* Check for LC_ALL, LC_CTYPE, and LANG and use the first with a value
to decide the defaults for 8-bit character input and output. Returns
1 if we set eight-bit mode. */
int
_rl_init_eightbit ()
{
/* If we have setlocale(3), just check the current LC_CTYPE category
value, and go into eight-bit mode if it's not C or POSIX. */
#if defined (HAVE_SETLOCALE)
char *lspec, *t;
/* Set the LC_CTYPE locale category from environment variables. */
lspec = _rl_get_locale_var ("LC_CTYPE");
/* Since _rl_get_locale_var queries the right environment variables,
we query the current locale settings with setlocale(), and, if
that doesn't return anything, we set lspec to the empty string to
force the subsequent call to setlocale() to define the `native'
environment. */
if (lspec == 0 || *lspec == 0)
lspec = setlocale (LC_CTYPE, (char *)NULL);
if (lspec == 0)
lspec = "";
t = setlocale (LC_CTYPE, lspec);
if (t && *t && (t[0] != 'C' || t[1]) && (STREQ (t, "POSIX") == 0))
{
_rl_meta_flag = 1;
_rl_convert_meta_chars_to_ascii = 0;
_rl_output_meta_chars = 1;
return (1);
}
else
return (0);
#else /* !HAVE_SETLOCALE */
char *lspec, *t;
int i;
/* We don't have setlocale. Finesse it. Check the environment for the
appropriate variables and set eight-bit mode if they have the right
values. */
lspec = _rl_get_locale_var ("LC_CTYPE");
if (lspec == 0 || (t = normalize_codeset (lspec)) == 0)
return (0);
for (i = 0; t && legal_lang_values[i]; i++)
if (STREQ (t, legal_lang_values[i]))
{
_rl_meta_flag = 1;
_rl_convert_meta_chars_to_ascii = 0;
_rl_output_meta_chars = 1;
break;
}
free (t);
return (legal_lang_values[i] ? 1 : 0);
#endif /* !HAVE_SETLOCALE */
}
#if !defined (HAVE_SETLOCALE)
static char *
normalize_codeset (codeset)
char *codeset;
{
size_t namelen, i;
int len, all_digits;
char *wp, *retval;
codeset = find_codeset (codeset, &namelen);
if (codeset == 0)
return (codeset);
all_digits = 1;
for (len = 0, i = 0; i < namelen; i++)
{
if (ISALNUM ((unsigned char)codeset[i]))
{
len++;
all_digits &= _rl_digit_p (codeset[i]);
}
}
retval = (char *)malloc ((all_digits ? 3 : 0) + len + 1);
if (retval == 0)
return ((char *)0);
wp = retval;
/* Add `iso' to beginning of an all-digit codeset */
if (all_digits)
{
*wp++ = 'i';
*wp++ = 's';
*wp++ = 'o';
}
for (i = 0; i < namelen; i++)
if (ISALPHA ((unsigned char)codeset[i]))
*wp++ = _rl_to_lower (codeset[i]);
else if (_rl_digit_p (codeset[i]))
*wp++ = codeset[i];
*wp = '\0';
return retval;
}
/* Isolate codeset portion of locale specification. */
static char *
find_codeset (name, lenp)
char *name;
size_t *lenp;
{
char *cp, *language, *result;
cp = language = name;
result = (char *)0;
while (*cp && *cp != '_' && *cp != '@' && *cp != '+' && *cp != ',')
cp++;
/* This does not make sense: language has to be specified. As
an exception we allow the variable to contain only the codeset
name. Perhaps there are funny codeset names. */
if (language == cp)
{
*lenp = strlen (language);
result = language;
}
else
{
/* Next is the territory. */
if (*cp == '_')
do
++cp;
while (*cp && *cp != '.' && *cp != '@' && *cp != '+' && *cp != ',' && *cp != '_');
/* Now, finally, is the codeset. */
result = cp;
if (*cp == '.')
do
++cp;
while (*cp && *cp != '@');
if (cp - result > 2)
{
result++;
*lenp = cp - result;
}
else
{
*lenp = strlen (language);
result = language;
}
}
return result;
}
#endif /* !HAVE_SETLOCALE */
File diff suppressed because it is too large Load Diff
-893
View File
@@ -1,893 +0,0 @@
/* Readline.h -- the names of functions callable from within readline. */
/* 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.
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/>.
*/
#if !defined (_READLINE_H_)
#define _READLINE_H_
#ifdef __cplusplus
extern "C" {
#endif
#if defined (READLINE_LIBRARY)
# include "rlstdc.h"
# include "rltypedefs.h"
# include "keymaps.h"
# include "tilde.h"
#else
# include <readline/rlstdc.h>
# include <readline/rltypedefs.h>
# include <readline/keymaps.h>
# include <readline/tilde.h>
#endif
/* Hex-encoded Readline version number. */
#define RL_READLINE_VERSION 0x0602 /* Readline 6.2 */
#define RL_VERSION_MAJOR 6
#define RL_VERSION_MINOR 2
/* Readline data structures. */
/* Maintaining the state of undo. We remember individual deletes and inserts
on a chain of things to do. */
/* The actions that undo knows how to undo. Notice that UNDO_DELETE means
to insert some text, and UNDO_INSERT means to delete some text. I.e.,
the code tells undo what to undo, not how to undo it. */
enum undo_code { UNDO_DELETE, UNDO_INSERT, UNDO_BEGIN, UNDO_END };
/* What an element of THE_UNDO_LIST looks like. */
typedef struct undo_list {
struct undo_list *next;
int start, end; /* Where the change took place. */
char *text; /* The text to insert, if undoing a delete. */
enum undo_code what; /* Delete, Insert, Begin, End. */
} UNDO_LIST;
/* The current undo list for RL_LINE_BUFFER. */
extern UNDO_LIST *rl_undo_list;
/* The data structure for mapping textual names to code addresses. */
typedef struct _funmap {
const char *name;
rl_command_func_t *function;
} FUNMAP;
extern FUNMAP **funmap;
/* **************************************************************** */
/* */
/* Functions available to bind to key sequences */
/* */
/* **************************************************************** */
/* Bindable commands for numeric arguments. */
extern int rl_digit_argument PARAMS((int, int));
extern int rl_universal_argument PARAMS((int, int));
/* Bindable commands for moving the cursor. */
extern int rl_forward_byte PARAMS((int, int));
extern int rl_forward_char PARAMS((int, int));
extern int rl_forward PARAMS((int, int));
extern int rl_backward_byte PARAMS((int, int));
extern int rl_backward_char PARAMS((int, int));
extern int rl_backward PARAMS((int, int));
extern int rl_beg_of_line PARAMS((int, int));
extern int rl_end_of_line PARAMS((int, int));
extern int rl_forward_word PARAMS((int, int));
extern int rl_backward_word PARAMS((int, int));
extern int rl_refresh_line PARAMS((int, int));
extern int rl_clear_screen PARAMS((int, int));
extern int rl_skip_csi_sequence PARAMS((int, int));
extern int rl_arrow_keys PARAMS((int, int));
/* Bindable commands for inserting and deleting text. */
extern int rl_insert PARAMS((int, int));
extern int rl_quoted_insert PARAMS((int, int));
extern int rl_tab_insert PARAMS((int, int));
extern int rl_newline PARAMS((int, int));
extern int rl_do_lowercase_version PARAMS((int, int));
extern int rl_rubout PARAMS((int, int));
extern int rl_delete PARAMS((int, int));
extern int rl_rubout_or_delete PARAMS((int, int));
extern int rl_delete_horizontal_space PARAMS((int, int));
extern int rl_delete_or_show_completions PARAMS((int, int));
extern int rl_insert_comment PARAMS((int, int));
/* Bindable commands for changing case. */
extern int rl_upcase_word PARAMS((int, int));
extern int rl_downcase_word PARAMS((int, int));
extern int rl_capitalize_word PARAMS((int, int));
/* Bindable commands for transposing characters and words. */
extern int rl_transpose_words PARAMS((int, int));
extern int rl_transpose_chars PARAMS((int, int));
/* Bindable commands for searching within a line. */
extern int rl_char_search PARAMS((int, int));
extern int rl_backward_char_search PARAMS((int, int));
/* Bindable commands for readline's interface to the command history. */
extern int rl_beginning_of_history PARAMS((int, int));
extern int rl_end_of_history PARAMS((int, int));
extern int rl_get_next_history PARAMS((int, int));
extern int rl_get_previous_history PARAMS((int, int));
/* Bindable commands for managing the mark and region. */
extern int rl_set_mark PARAMS((int, int));
extern int rl_exchange_point_and_mark PARAMS((int, int));
/* Bindable commands to set the editing mode (emacs or vi). */
extern int rl_vi_editing_mode PARAMS((int, int));
extern int rl_emacs_editing_mode PARAMS((int, int));
/* Bindable commands to change the insert mode (insert or overwrite) */
extern int rl_overwrite_mode PARAMS((int, int));
/* Bindable commands for managing key bindings. */
extern int rl_re_read_init_file PARAMS((int, int));
extern int rl_dump_functions PARAMS((int, int));
extern int rl_dump_macros PARAMS((int, int));
extern int rl_dump_variables PARAMS((int, int));
/* Bindable commands for word completion. */
extern int rl_complete PARAMS((int, int));
extern int rl_possible_completions PARAMS((int, int));
extern int rl_insert_completions PARAMS((int, int));
extern int rl_old_menu_complete PARAMS((int, int));
extern int rl_menu_complete PARAMS((int, int));
extern int rl_backward_menu_complete PARAMS((int, int));
/* Bindable commands for killing and yanking text, and managing the kill ring. */
extern int rl_kill_word PARAMS((int, int));
extern int rl_backward_kill_word PARAMS((int, int));
extern int rl_kill_line PARAMS((int, int));
extern int rl_backward_kill_line PARAMS((int, int));
extern int rl_kill_full_line PARAMS((int, int));
extern int rl_unix_word_rubout PARAMS((int, int));
extern int rl_unix_filename_rubout PARAMS((int, int));
extern int rl_unix_line_discard PARAMS((int, int));
extern int rl_copy_region_to_kill PARAMS((int, int));
extern int rl_kill_region PARAMS((int, int));
extern int rl_copy_forward_word PARAMS((int, int));
extern int rl_copy_backward_word PARAMS((int, int));
extern int rl_yank PARAMS((int, int));
extern int rl_yank_pop PARAMS((int, int));
extern int rl_yank_nth_arg PARAMS((int, int));
extern int rl_yank_last_arg PARAMS((int, int));
/* Not available unless __CYGWIN__ is defined. */
#ifdef __CYGWIN__
extern int rl_paste_from_clipboard PARAMS((int, int));
#endif
/* Bindable commands for incremental searching. */
extern int rl_reverse_search_history PARAMS((int, int));
extern int rl_forward_search_history PARAMS((int, int));
/* Bindable keyboard macro commands. */
extern int rl_start_kbd_macro PARAMS((int, int));
extern int rl_end_kbd_macro PARAMS((int, int));
extern int rl_call_last_kbd_macro PARAMS((int, int));
/* Bindable undo commands. */
extern int rl_revert_line PARAMS((int, int));
extern int rl_undo_command PARAMS((int, int));
/* Bindable tilde expansion commands. */
extern int rl_tilde_expand PARAMS((int, int));
/* Bindable terminal control commands. */
extern int rl_restart_output PARAMS((int, int));
extern int rl_stop_output PARAMS((int, int));
/* Miscellaneous bindable commands. */
extern int rl_abort PARAMS((int, int));
extern int rl_tty_status PARAMS((int, int));
/* Bindable commands for incremental and non-incremental history searching. */
extern int rl_history_search_forward PARAMS((int, int));
extern int rl_history_search_backward PARAMS((int, int));
extern int rl_noninc_forward_search PARAMS((int, int));
extern int rl_noninc_reverse_search PARAMS((int, int));
extern int rl_noninc_forward_search_again PARAMS((int, int));
extern int rl_noninc_reverse_search_again PARAMS((int, int));
/* Bindable command used when inserting a matching close character. */
extern int rl_insert_close PARAMS((int, int));
/* Not available unless READLINE_CALLBACKS is defined. */
extern void rl_callback_handler_install PARAMS((const char *, rl_vcpfunc_t *));
extern void rl_callback_read_char PARAMS((void));
extern void rl_callback_handler_remove PARAMS((void));
/* Things for vi mode. Not available unless readline is compiled -DVI_MODE. */
/* VI-mode bindable commands. */
extern int rl_vi_redo PARAMS((int, int));
extern int rl_vi_undo PARAMS((int, int));
extern int rl_vi_yank_arg PARAMS((int, int));
extern int rl_vi_fetch_history PARAMS((int, int));
extern int rl_vi_search_again PARAMS((int, int));
extern int rl_vi_search PARAMS((int, int));
extern int rl_vi_complete PARAMS((int, int));
extern int rl_vi_tilde_expand PARAMS((int, int));
extern int rl_vi_prev_word PARAMS((int, int));
extern int rl_vi_next_word PARAMS((int, int));
extern int rl_vi_end_word PARAMS((int, int));
extern int rl_vi_insert_beg PARAMS((int, int));
extern int rl_vi_append_mode PARAMS((int, int));
extern int rl_vi_append_eol PARAMS((int, int));
extern int rl_vi_eof_maybe PARAMS((int, int));
extern int rl_vi_insertion_mode PARAMS((int, int));
extern int rl_vi_insert_mode PARAMS((int, int));
extern int rl_vi_movement_mode PARAMS((int, int));
extern int rl_vi_arg_digit PARAMS((int, int));
extern int rl_vi_change_case PARAMS((int, int));
extern int rl_vi_put PARAMS((int, int));
extern int rl_vi_column PARAMS((int, int));
extern int rl_vi_delete_to PARAMS((int, int));
extern int rl_vi_change_to PARAMS((int, int));
extern int rl_vi_yank_to PARAMS((int, int));
extern int rl_vi_rubout PARAMS((int, int));
extern int rl_vi_delete PARAMS((int, int));
extern int rl_vi_back_to_indent PARAMS((int, int));
extern int rl_vi_first_print PARAMS((int, int));
extern int rl_vi_char_search PARAMS((int, int));
extern int rl_vi_match PARAMS((int, int));
extern int rl_vi_change_char PARAMS((int, int));
extern int rl_vi_subst PARAMS((int, int));
extern int rl_vi_overstrike PARAMS((int, int));
extern int rl_vi_overstrike_delete PARAMS((int, int));
extern int rl_vi_replace PARAMS((int, int));
extern int rl_vi_set_mark PARAMS((int, int));
extern int rl_vi_goto_mark PARAMS((int, int));
/* VI-mode utility functions. */
extern int rl_vi_check PARAMS((void));
extern int rl_vi_domove PARAMS((int, int *));
extern int rl_vi_bracktype PARAMS((int));
extern void rl_vi_start_inserting PARAMS((int, int, int));
/* VI-mode pseudo-bindable commands, used as utility functions. */
extern int rl_vi_fWord PARAMS((int, int));
extern int rl_vi_bWord PARAMS((int, int));
extern int rl_vi_eWord PARAMS((int, int));
extern int rl_vi_fword PARAMS((int, int));
extern int rl_vi_bword PARAMS((int, int));
extern int rl_vi_eword PARAMS((int, int));
/* **************************************************************** */
/* */
/* Well Published Functions */
/* */
/* **************************************************************** */
/* Readline functions. */
/* Read a line of input. Prompt with PROMPT. A NULL PROMPT means none. */
extern char *readline PARAMS((const char *));
extern int rl_set_prompt PARAMS((const char *));
extern int rl_expand_prompt PARAMS((char *));
extern int rl_initialize PARAMS((void));
/* Undocumented; unused by readline */
extern int rl_discard_argument PARAMS((void));
/* Utility functions to bind keys to readline commands. */
extern int rl_add_defun PARAMS((const char *, rl_command_func_t *, int));
extern int rl_bind_key PARAMS((int, rl_command_func_t *));
extern int rl_bind_key_in_map PARAMS((int, rl_command_func_t *, Keymap));
extern int rl_unbind_key PARAMS((int));
extern int rl_unbind_key_in_map PARAMS((int, Keymap));
extern int rl_bind_key_if_unbound PARAMS((int, rl_command_func_t *));
extern int rl_bind_key_if_unbound_in_map PARAMS((int, rl_command_func_t *, Keymap));
extern int rl_unbind_function_in_map PARAMS((rl_command_func_t *, Keymap));
extern int rl_unbind_command_in_map PARAMS((const char *, Keymap));
extern int rl_bind_keyseq PARAMS((const char *, rl_command_func_t *));
extern int rl_bind_keyseq_in_map PARAMS((const char *, rl_command_func_t *, Keymap));
extern int rl_bind_keyseq_if_unbound PARAMS((const char *, rl_command_func_t *));
extern int rl_bind_keyseq_if_unbound_in_map PARAMS((const char *, rl_command_func_t *, Keymap));
extern int rl_generic_bind PARAMS((int, const char *, char *, Keymap));
extern char *rl_variable_value PARAMS((const char *));
extern int rl_variable_bind PARAMS((const char *, const char *));
/* Backwards compatibility, use rl_bind_keyseq_in_map instead. */
extern int rl_set_key PARAMS((const char *, rl_command_func_t *, Keymap));
/* Backwards compatibility, use rl_generic_bind instead. */
extern int rl_macro_bind PARAMS((const char *, const char *, Keymap));
/* Undocumented in the texinfo manual; not really useful to programs. */
extern int rl_translate_keyseq PARAMS((const char *, char *, int *));
extern char *rl_untranslate_keyseq PARAMS((int));
extern rl_command_func_t *rl_named_function PARAMS((const char *));
extern rl_command_func_t *rl_function_of_keyseq PARAMS((const char *, Keymap, int *));
extern void rl_list_funmap_names PARAMS((void));
extern char **rl_invoking_keyseqs_in_map PARAMS((rl_command_func_t *, Keymap));
extern char **rl_invoking_keyseqs PARAMS((rl_command_func_t *));
extern void rl_function_dumper PARAMS((int));
extern void rl_macro_dumper PARAMS((int));
extern void rl_variable_dumper PARAMS((int));
extern int rl_read_init_file PARAMS((const char *));
extern int rl_parse_and_bind PARAMS((char *));
/* Functions for manipulating keymaps. */
extern Keymap rl_make_bare_keymap PARAMS((void));
extern Keymap rl_copy_keymap PARAMS((Keymap));
extern Keymap rl_make_keymap PARAMS((void));
extern void rl_discard_keymap PARAMS((Keymap));
extern Keymap rl_get_keymap_by_name PARAMS((const char *));
extern char *rl_get_keymap_name PARAMS((Keymap));
extern void rl_set_keymap PARAMS((Keymap));
extern Keymap rl_get_keymap PARAMS((void));
/* Undocumented; used internally only. */
extern void rl_set_keymap_from_edit_mode PARAMS((void));
extern char *rl_get_keymap_name_from_edit_mode PARAMS((void));
/* Functions for manipulating the funmap, which maps command names to functions. */
extern int rl_add_funmap_entry PARAMS((const char *, rl_command_func_t *));
extern const char **rl_funmap_names PARAMS((void));
/* Undocumented, only used internally -- there is only one funmap, and this
function may be called only once. */
extern void rl_initialize_funmap PARAMS((void));
/* Utility functions for managing keyboard macros. */
extern void rl_push_macro_input PARAMS((char *));
/* Functions for undoing, from undo.c */
extern void rl_add_undo PARAMS((enum undo_code, int, int, char *));
extern void rl_free_undo_list PARAMS((void));
extern int rl_do_undo PARAMS((void));
extern int rl_begin_undo_group PARAMS((void));
extern int rl_end_undo_group PARAMS((void));
extern int rl_modifying PARAMS((int, int));
/* Functions for redisplay. */
extern void rl_redisplay PARAMS((void));
extern int rl_on_new_line PARAMS((void));
extern int rl_on_new_line_with_prompt PARAMS((void));
extern int rl_forced_update_display PARAMS((void));
extern int rl_clear_message PARAMS((void));
extern int rl_reset_line_state PARAMS((void));
extern int rl_crlf PARAMS((void));
#if defined (USE_VARARGS) && defined (PREFER_STDARG)
extern int rl_message (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
#else
extern int rl_message ();
#endif
extern int rl_show_char PARAMS((int));
/* Undocumented in texinfo manual. */
extern int rl_character_len PARAMS((int, int));
/* Save and restore internal prompt redisplay information. */
extern void rl_save_prompt PARAMS((void));
extern void rl_restore_prompt PARAMS((void));
/* Modifying text. */
extern void rl_replace_line PARAMS((const char *, int));
extern int rl_insert_text PARAMS((const char *));
extern int rl_delete_text PARAMS((int, int));
extern int rl_kill_text PARAMS((int, int));
extern char *rl_copy_text PARAMS((int, int));
/* Terminal and tty mode management. */
extern void rl_prep_terminal PARAMS((int));
extern void rl_deprep_terminal PARAMS((void));
extern void rl_tty_set_default_bindings PARAMS((Keymap));
extern void rl_tty_unset_default_bindings PARAMS((Keymap));
extern int rl_reset_terminal PARAMS((const char *));
extern void rl_resize_terminal PARAMS((void));
extern void rl_set_screen_size PARAMS((int, int));
extern void rl_get_screen_size PARAMS((int *, int *));
extern void rl_reset_screen_size PARAMS((void));
extern char *rl_get_termcap PARAMS((const char *));
/* Functions for character input. */
extern int rl_stuff_char PARAMS((int));
extern int rl_execute_next PARAMS((int));
extern int rl_clear_pending_input PARAMS((void));
extern int rl_read_key PARAMS((void));
extern int rl_getc PARAMS((FILE *));
extern int rl_set_keyboard_input_timeout PARAMS((int));
/* `Public' utility functions . */
extern void rl_extend_line_buffer PARAMS((int));
extern int rl_ding PARAMS((void));
extern int rl_alphabetic PARAMS((int));
extern void rl_free PARAMS((void *));
/* Readline signal handling, from signals.c */
extern int rl_set_signals PARAMS((void));
extern int rl_clear_signals PARAMS((void));
extern void rl_cleanup_after_signal PARAMS((void));
extern void rl_reset_after_signal PARAMS((void));
extern void rl_free_line_state PARAMS((void));
extern void rl_echo_signal_char PARAMS((int));
extern int rl_set_paren_blink_timeout PARAMS((int));
/* Undocumented. */
extern int rl_maybe_save_line PARAMS((void));
extern int rl_maybe_unsave_line PARAMS((void));
extern int rl_maybe_replace_line PARAMS((void));
/* Completion functions. */
extern int rl_complete_internal PARAMS((int));
extern void rl_display_match_list PARAMS((char **, int, int));
extern char **rl_completion_matches PARAMS((const char *, rl_compentry_func_t *));
extern char *rl_username_completion_function PARAMS((const char *, int));
extern char *rl_filename_completion_function PARAMS((const char *, int));
extern int rl_completion_mode PARAMS((rl_command_func_t *));
#if 0
/* Backwards compatibility (compat.c). These will go away sometime. */
extern void free_undo_list PARAMS((void));
extern int maybe_save_line PARAMS((void));
extern int maybe_unsave_line PARAMS((void));
extern int maybe_replace_line PARAMS((void));
extern int ding PARAMS((void));
extern int alphabetic PARAMS((int));
extern int crlf PARAMS((void));
extern char **completion_matches PARAMS((char *, rl_compentry_func_t *));
extern char *username_completion_function PARAMS((const char *, int));
extern char *filename_completion_function PARAMS((const char *, int));
#endif
/* **************************************************************** */
/* */
/* Well Published Variables */
/* */
/* **************************************************************** */
/* The version of this incarnation of the readline library. */
extern const char *rl_library_version; /* e.g., "4.2" */
extern int rl_readline_version; /* e.g., 0x0402 */
/* True if this is real GNU readline. */
extern int rl_gnu_readline_p;
/* Flags word encapsulating the current readline state. */
extern int rl_readline_state;
/* Says which editing mode readline is currently using. 1 means emacs mode;
0 means vi mode. */
extern int rl_editing_mode;
/* Insert or overwrite mode for emacs mode. 1 means insert mode; 0 means
overwrite mode. Reset to insert mode on each input line. */
extern int rl_insert_mode;
/* The name of the calling program. You should initialize this to
whatever was in argv[0]. It is used when parsing conditionals. */
extern const char *rl_readline_name;
/* The prompt readline uses. This is set from the argument to
readline (), and should not be assigned to directly. */
extern char *rl_prompt;
/* The prompt string that is actually displayed by rl_redisplay. Public so
applications can more easily supply their own redisplay functions. */
extern char *rl_display_prompt;
/* The line buffer that is in use. */
extern char *rl_line_buffer;
/* The location of point, and end. */
extern int rl_point;
extern int rl_end;
/* The mark, or saved cursor position. */
extern int rl_mark;
/* Flag to indicate that readline has finished with the current input
line and should return it. */
extern int rl_done;
/* If set to a character value, that will be the next keystroke read. */
extern int rl_pending_input;
/* Non-zero if we called this function from _rl_dispatch(). It's present
so functions can find out whether they were called from a key binding
or directly from an application. */
extern int rl_dispatching;
/* Non-zero if the user typed a numeric argument before executing the
current function. */
extern int rl_explicit_arg;
/* The current value of the numeric argument specified by the user. */
extern int rl_numeric_arg;
/* The address of the last command function Readline executed. */
extern rl_command_func_t *rl_last_func;
/* The name of the terminal to use. */
extern const char *rl_terminal_name;
/* The input and output streams. */
extern FILE *rl_instream;
extern FILE *rl_outstream;
/* If non-zero, Readline gives values of LINES and COLUMNS from the environment
greater precedence than values fetched from the kernel when computing the
screen dimensions. */
extern int rl_prefer_env_winsize;
/* If non-zero, then this is the address of a function to call just
before readline_internal () prints the first prompt. */
extern rl_hook_func_t *rl_startup_hook;
/* If non-zero, this is the address of a function to call just before
readline_internal_setup () returns and readline_internal starts
reading input characters. */
extern rl_hook_func_t *rl_pre_input_hook;
/* The address of a function to call periodically while Readline is
awaiting character input, or NULL, for no event handling. */
extern rl_hook_func_t *rl_event_hook;
/* The address of the function to call to fetch a character from the current
Readline input stream */
extern rl_getc_func_t *rl_getc_function;
extern rl_voidfunc_t *rl_redisplay_function;
extern rl_vintfunc_t *rl_prep_term_function;
extern rl_voidfunc_t *rl_deprep_term_function;
/* Dispatch variables. */
extern Keymap rl_executing_keymap;
extern Keymap rl_binding_keymap;
/* Display variables. */
/* If non-zero, readline will erase the entire line, including any prompt,
if the only thing typed on an otherwise-blank line is something bound to
rl_newline. */
extern int rl_erase_empty_line;
/* If non-zero, the application has already printed the prompt (rl_prompt)
before calling readline, so readline should not output it the first time
redisplay is done. */
extern int rl_already_prompted;
/* A non-zero value means to read only this many characters rather than
up to a character bound to accept-line. */
extern int rl_num_chars_to_read;
/* The text of a currently-executing keyboard macro. */
extern char *rl_executing_macro;
/* Variables to control readline signal handling. */
/* If non-zero, readline will install its own signal handlers for
SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */
extern int rl_catch_signals;
/* If non-zero, readline will install a signal handler for SIGWINCH
that also attempts to call any calling application's SIGWINCH signal
handler. Note that the terminal is not cleaned up before the
application's signal handler is called; use rl_cleanup_after_signal()
to do that. */
extern int rl_catch_sigwinch;
/* Completion variables. */
/* Pointer to the generator function for completion_matches ().
NULL means to use rl_filename_completion_function (), the default
filename completer. */
extern rl_compentry_func_t *rl_completion_entry_function;
/* Optional generator for menu completion. Default is
rl_completion_entry_function (rl_filename_completion_function). */
extern rl_compentry_func_t *rl_menu_completion_entry_function;
/* If rl_ignore_some_completions_function is non-NULL it is the address
of a function to call after all of the possible matches have been
generated, but before the actual completion is done to the input line.
The function is called with one argument; a NULL terminated array
of (char *). If your function removes any of the elements, they
must be free()'ed. */
extern rl_compignore_func_t *rl_ignore_some_completions_function;
/* Pointer to alternative function to create matches.
Function is called with TEXT, START, and END.
START and END are indices in RL_LINE_BUFFER saying what the boundaries
of TEXT are.
If this function exists and returns NULL then call the value of
rl_completion_entry_function to try to match, otherwise use the
array of strings returned. */
extern rl_completion_func_t *rl_attempted_completion_function;
/* The basic list of characters that signal a break between words for the
completer routine. The initial contents of this variable is what
breaks words in the shell, i.e. "n\"\\'`@$>". */
extern const char *rl_basic_word_break_characters;
/* The list of characters that signal a break between words for
rl_complete_internal. The default list is the contents of
rl_basic_word_break_characters. */
extern /*const*/ char *rl_completer_word_break_characters;
/* Hook function to allow an application to set the completion word
break characters before readline breaks up the line. Allows
position-dependent word break characters. */
extern rl_cpvfunc_t *rl_completion_word_break_hook;
/* List of characters which can be used to quote a substring of the line.
Completion occurs on the entire substring, and within the substring
rl_completer_word_break_characters are treated as any other character,
unless they also appear within this list. */
extern const char *rl_completer_quote_characters;
/* List of quote characters which cause a word break. */
extern const char *rl_basic_quote_characters;
/* List of characters that need to be quoted in filenames by the completer. */
extern const char *rl_filename_quote_characters;
/* List of characters that are word break characters, but should be left
in TEXT when it is passed to the completion function. The shell uses
this to help determine what kind of completing to do. */
extern const char *rl_special_prefixes;
/* 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. It
changes what is displayed when the possible completions are printed
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. 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
directory entries from the filesystem for completion and comparing
them to the partial word to be completed. The function should
either return its first argument (if no conversion takes place) or
newly-allocated memory. This can, for instance, convert filenames
between character sets for comparison against what's typed at the
keyboard. The returned value is what is added to the list of
matches. The second argument is the length of the filename to be
converted. */
extern rl_dequote_func_t *rl_filename_rewrite_hook;
/* Backwards compatibility with previous versions of readline. */
#define rl_symbolic_link_hook rl_directory_completion_hook
/* If non-zero, then this is the address of a function to call when
completing a word would normally display the list of possible matches.
This function is called instead of actually doing the display.
It takes three arguments: (char **matches, int num_matches, int max_length)
where MATCHES is the array of strings that matched, NUM_MATCHES is the
number of strings in that array, and MAX_LENGTH is the length of the
longest string in that array. */
extern rl_compdisp_func_t *rl_completion_display_matches_hook;
/* Non-zero means that the results of the matches are to be treated
as filenames. This is ALWAYS zero on entry, and can only be changed
within a completion entry finder function. */
extern int rl_filename_completion_desired;
/* Non-zero means that the results of the matches are to be quoted using
double quotes (or an application-specific quoting mechanism) if the
filename contains any characters in rl_word_break_chars. This is
ALWAYS non-zero on entry, and can only be changed within a completion
entry finder function. */
extern int rl_filename_quoting_desired;
/* Set to a function to quote a filename in an application-specific fashion.
Called with the text to quote, the type of match found (single or multiple)
and a pointer to the quoting character to be used, which the function can
reset if desired. */
extern rl_quote_func_t *rl_filename_quoting_function;
/* Function to call to remove quoting characters from a filename. Called
before completion is attempted, so the embedded quotes do not interfere
with matching names in the file system. */
extern rl_dequote_func_t *rl_filename_dequoting_function;
/* Function to call to decide whether or not a word break character is
quoted. If a character is quoted, it does not break words for the
completer. */
extern rl_linebuf_func_t *rl_char_is_quoted_p;
/* Non-zero means to suppress normal filename completion after the
user-specified completion function has been called. */
extern int rl_attempted_completion_over;
/* Set to a character describing the type of completion being attempted by
rl_complete_internal; available for use by application completion
functions. */
extern int rl_completion_type;
/* Set to the last key used to invoke one of the completion functions */
extern int rl_completion_invoking_key;
/* Up to this many items will be displayed in response to a
possible-completions call. After that, we ask the user if she
is sure she wants to see them all. The default value is 100. */
extern int rl_completion_query_items;
/* Character appended to completed words when at the end of the line. The
default is a space. Nothing is added if this is '\0'. */
extern int rl_completion_append_character;
/* If set to non-zero by an application completion function,
rl_completion_append_character will not be appended. */
extern int rl_completion_suppress_append;
/* Set to any quote character readline thinks it finds before any application
completion function is called. */
extern int rl_completion_quote_character;
/* Set to a non-zero value if readline found quoting anywhere in the word to
be completed; set before any application completion function is called. */
extern int rl_completion_found_quote;
/* If non-zero, the completion functions don't append any closing quote.
This is set to 0 by rl_complete_internal and may be changed by an
application-specific completion function. */
extern int rl_completion_suppress_quote;
/* If non-zero, readline will sort the completion matches. On by default. */
extern int rl_sort_completion_matches;
/* If non-zero, a slash will be appended to completed filenames that are
symbolic links to directory names, subject to the value of the
mark-directories variable (which is user-settable). This exists so
that application completion functions can override the user's preference
(set via the mark-symlinked-directories variable) if appropriate.
It's set to the value of _rl_complete_mark_symlink_dirs in
rl_complete_internal before any application-specific completion
function is called, so without that function doing anything, the user's
preferences are honored. */
extern int rl_completion_mark_symlink_dirs;
/* If non-zero, then disallow duplicates in the matches. */
extern int rl_ignore_completion_duplicates;
/* If this is non-zero, completion is (temporarily) inhibited, and the
completion character will be inserted as any other. */
extern int rl_inhibit_completion;
/* Input error; can be returned by (*rl_getc_function) if readline is reading
a top-level command (RL_ISSTATE (RL_STATE_READCMD)). */
#define READERR (-2)
/* Definitions available for use by readline clients. */
#define RL_PROMPT_START_IGNORE '\001'
#define RL_PROMPT_END_IGNORE '\002'
/* Possible values for do_replace argument to rl_filename_quoting_function,
called by rl_complete_internal. */
#define NO_MATCH 0
#define SINGLE_MATCH 1
#define MULT_MATCH 2
/* Possible state values for rl_readline_state */
#define RL_STATE_NONE 0x000000 /* no state; before first call */
#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 */
#define RL_SETSTATE(x) (rl_readline_state |= (x))
#define RL_UNSETSTATE(x) (rl_readline_state &= ~(x))
#define RL_ISSTATE(x) (rl_readline_state & (x))
struct readline_state {
/* line state */
int point;
int end;
int mark;
char *buffer;
int buflen;
UNDO_LIST *ul;
char *prompt;
/* global state */
int rlstate;
int done;
Keymap kmap;
/* input state */
rl_command_func_t *lastfunc;
int insmode;
int edmode;
int kseqlen;
FILE *inf;
FILE *outf;
int pendingin;
char *macro;
/* signal state */
int catchsigs;
int catchsigwinch;
/* search state */
/* completion state */
/* options state */
/* reserved for future expansion, so the struct size doesn't change */
char reserved[64];
};
extern int rl_save_state PARAMS((struct readline_state *));
extern int rl_restore_state PARAMS((struct readline_state *));
#ifdef __cplusplus
}
#endif
#endif /* _READLINE_H_ */
-505
View File
@@ -1,505 +0,0 @@
/* rlprivate.h -- functions and variables global to the readline library,
but not intended for use by applications. */
/* 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.
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/>.
*/
#if !defined (_RL_PRIVATE_H_)
#define _RL_PRIVATE_H_
#include "rlconf.h" /* for VISIBLE_STATS */
#include "rlstdc.h"
#include "posixjmp.h" /* defines procenv_t */
/*************************************************************************
* *
* Convenience definitions *
* *
*************************************************************************/
#define EMACS_MODE() (rl_editing_mode == emacs_mode)
#define VI_COMMAND_MODE() (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap)
#define VI_INSERT_MODE() (rl_editing_mode == vi_mode && _rl_keymap == vi_insertion_keymap)
#define RL_CHECK_SIGNALS() \
do { \
if (_rl_caught_signal) _rl_signal_handler (_rl_caught_signal); \
} while (0)
/*************************************************************************
* *
* Global structs undocumented in texinfo manual and not in readline.h *
* *
*************************************************************************/
/* search types */
#define RL_SEARCH_ISEARCH 0x01 /* incremental search */
#define RL_SEARCH_NSEARCH 0x02 /* non-incremental search */
#define RL_SEARCH_CSEARCH 0x04 /* intra-line char search */
/* search flags */
#define SF_REVERSE 0x01
#define SF_FOUND 0x02
#define SF_FAILED 0x04
#define SF_CHGKMAP 0x08
typedef struct __rl_search_context
{
int type;
int sflags;
char *search_string;
int search_string_index;
int search_string_size;
char **lines;
char *allocated_line;
int hlen;
int hindex;
int save_point;
int save_mark;
int save_line;
int last_found_line;
char *prev_line_found;
UNDO_LIST *save_undo_list;
Keymap keymap; /* used when dispatching commands in search string */
Keymap okeymap; /* original keymap */
int history_pos;
int direction;
int lastc;
#if defined (HANDLE_MULTIBYTE)
char mb[MB_LEN_MAX];
#endif
char *sline;
int sline_len;
int sline_index;
char *search_terminators;
} _rl_search_cxt;
/* Callback data for reading numeric arguments */
#define NUM_SAWMINUS 0x01
#define NUM_SAWDIGITS 0x02
#define NUM_READONE 0x04
typedef int _rl_arg_cxt;
/* A context for reading key sequences longer than a single character when
using the callback interface. */
#define KSEQ_DISPATCHED 0x01
#define KSEQ_SUBSEQ 0x02
#define KSEQ_RECURSIVE 0x04
typedef struct __rl_keyseq_context
{
int flags;
int subseq_arg;
int subseq_retval; /* XXX */
Keymap dmap;
Keymap oldmap;
int okey;
struct __rl_keyseq_context *ocxt;
int childval;
} _rl_keyseq_cxt;
/* 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
{
int count;
int i1, i2;
/* add here as needed */
} _rl_callback_generic_arg;
typedef int _rl_callback_func_t PARAMS((_rl_callback_generic_arg *));
/*************************************************************************
* *
* Global functions undocumented in texinfo manual and not in readline.h *
* *
*************************************************************************/
/*************************************************************************
* *
* Global variables undocumented in texinfo manual and not in readline.h *
* *
*************************************************************************/
/* complete.c */
extern int rl_complete_with_tilde_expansion;
#if defined (VISIBLE_STATS)
extern int rl_visible_stats;
#endif /* VISIBLE_STATS */
/* readline.c */
extern int rl_line_buffer_len;
extern int rl_arg_sign;
extern int rl_visible_prompt_length;
extern int rl_key_sequence_length;
extern int rl_byte_oriented;
/* display.c */
extern int rl_display_fixed;
/* parens.c */
extern int rl_blink_matching_paren;
/*************************************************************************
* *
* Global functions and variables unsed and undocumented *
* *
*************************************************************************/
/* kill.c */
extern int rl_set_retained_kills PARAMS((int));
/* terminal.c */
extern void _rl_set_screen_size PARAMS((int, int));
/* undo.c */
extern int _rl_fix_last_undo_of_type PARAMS((int, int, int));
/* util.c */
extern char *_rl_savestring PARAMS((const char *));
/*************************************************************************
* *
* Functions and variables private to the readline library *
* *
*************************************************************************/
/* NOTE: Functions and variables prefixed with `_rl_' are
pseudo-global: they are global so they can be shared
between files in the readline library, but are not intended
to be visible to readline callers. */
/*************************************************************************
* Undocumented private functions *
*************************************************************************/
#if defined(READLINE_CALLBACKS)
/* readline.c */
extern void readline_internal_setup PARAMS((void));
extern char *readline_internal_teardown PARAMS((int));
extern int readline_internal_char PARAMS((void));
extern _rl_keyseq_cxt *_rl_keyseq_cxt_alloc PARAMS((void));
extern void _rl_keyseq_cxt_dispose PARAMS((_rl_keyseq_cxt *));
extern void _rl_keyseq_chain_dispose PARAMS((void));
extern int _rl_dispatch_callback PARAMS((_rl_keyseq_cxt *));
/* callback.c */
extern _rl_callback_generic_arg *_rl_callback_data_alloc PARAMS((int));
extern void _rl_callback_data_dispose PARAMS((_rl_callback_generic_arg *));
#endif /* READLINE_CALLBACKS */
/* bind.c */
/* complete.c */
extern void _rl_reset_completion_state PARAMS((void));
extern char _rl_find_completion_word PARAMS((int *, int *));
extern void _rl_free_match_list PARAMS((char **));
/* display.c */
extern char *_rl_strip_prompt PARAMS((char *));
extern void _rl_move_cursor_relative PARAMS((int, const char *));
extern void _rl_move_vert PARAMS((int));
extern void _rl_save_prompt PARAMS((void));
extern void _rl_restore_prompt PARAMS((void));
extern char *_rl_make_prompt_for_search PARAMS((int));
extern void _rl_erase_at_end_of_line PARAMS((int));
extern void _rl_clear_to_eol PARAMS((int));
extern void _rl_clear_screen PARAMS((void));
extern void _rl_update_final PARAMS((void));
extern void _rl_redisplay_after_sigwinch PARAMS((void));
extern void _rl_clean_up_for_exit PARAMS((void));
extern void _rl_erase_entire_line PARAMS((void));
extern int _rl_current_display_line PARAMS((void));
/* input.c */
extern int _rl_any_typein PARAMS((void));
extern int _rl_input_available PARAMS((void));
extern int _rl_input_queued PARAMS((int));
extern void _rl_insert_typein PARAMS((int));
extern int _rl_unget_char PARAMS((int));
extern int _rl_pushed_input_available PARAMS((void));
/* isearch.c */
extern _rl_search_cxt *_rl_scxt_alloc PARAMS((int, int));
extern void _rl_scxt_dispose PARAMS((_rl_search_cxt *, int));
extern int _rl_isearch_dispatch PARAMS((_rl_search_cxt *, int));
extern int _rl_isearch_callback PARAMS((_rl_search_cxt *));
extern int _rl_search_getchar PARAMS((_rl_search_cxt *));
/* macro.c */
extern void _rl_with_macro_input PARAMS((char *));
extern int _rl_next_macro_key PARAMS((void));
extern void _rl_push_executing_macro PARAMS((void));
extern void _rl_pop_executing_macro PARAMS((void));
extern void _rl_add_macro_char PARAMS((int));
extern void _rl_kill_kbd_macro PARAMS((void));
/* misc.c */
extern int _rl_arg_overflow PARAMS((void));
extern void _rl_arg_init PARAMS((void));
extern int _rl_arg_getchar PARAMS((void));
extern int _rl_arg_callback PARAMS((_rl_arg_cxt));
extern void _rl_reset_argument PARAMS((void));
extern void _rl_start_using_history PARAMS((void));
extern int _rl_free_saved_history_line PARAMS((void));
extern void _rl_set_insert_mode PARAMS((int, int));
extern void _rl_revert_all_lines PARAMS((void));
/* nls.c */
extern int _rl_init_eightbit PARAMS((void));
/* parens.c */
extern void _rl_enable_paren_matching PARAMS((int));
/* readline.c */
extern void _rl_init_line_state PARAMS((void));
extern void _rl_set_the_line PARAMS((void));
extern int _rl_dispatch PARAMS((int, Keymap));
extern int _rl_dispatch_subseq PARAMS((int, Keymap, int));
extern void _rl_internal_char_cleanup PARAMS((void));
/* rltty.c */
extern int _rl_disable_tty_signals PARAMS((void));
extern int _rl_restore_tty_signals PARAMS((void));
/* search.c */
extern int _rl_nsearch_callback PARAMS((_rl_search_cxt *));
/* signals.c */
extern void _rl_signal_handler PARAMS((int));
extern void _rl_block_sigint PARAMS((void));
extern void _rl_release_sigint PARAMS((void));
extern void _rl_block_sigwinch PARAMS((void));
extern void _rl_release_sigwinch PARAMS((void));
/* terminal.c */
extern void _rl_get_screen_size PARAMS((int, int));
extern int _rl_init_terminal_io PARAMS((const char *));
#ifdef _MINIX
extern void _rl_output_character_function PARAMS((int));
#else
extern int _rl_output_character_function PARAMS((int));
#endif
extern void _rl_output_some_chars PARAMS((const char *, int));
extern int _rl_backspace PARAMS((int));
extern void _rl_enable_meta_key PARAMS((void));
extern void _rl_control_keypad PARAMS((int));
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_insert_char PARAMS((int, int));
extern int _rl_overwrite_char PARAMS((int, int));
extern int _rl_overwrite_rubout PARAMS((int, int));
extern int _rl_rubout_char PARAMS((int, int));
#if defined (HANDLE_MULTIBYTE)
extern int _rl_char_search_internal PARAMS((int, int, char *, int));
#else
extern int _rl_char_search_internal PARAMS((int, int, int));
#endif
extern int _rl_set_mark_at_pos PARAMS((int));
/* undo.c */
extern UNDO_LIST *_rl_copy_undo_entry PARAMS((UNDO_LIST *));
extern UNDO_LIST *_rl_copy_undo_list PARAMS((UNDO_LIST *));
/* util.c */
#if defined (USE_VARARGS) && defined (PREFER_STDARG)
extern void _rl_ttymsg (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
extern void _rl_errmsg (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
extern void _rl_trace (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
#else
extern void _rl_ttymsg ();
extern void _rl_errmsg ();
extern void _rl_trace ();
#endif
extern int _rl_tropen PARAMS((void));
extern int _rl_abort_internal PARAMS((void));
extern int _rl_null_function PARAMS((int, int));
extern char *_rl_strindex PARAMS((const char *, const char *));
extern int _rl_qsort_string_compare PARAMS((char **, char **));
extern int (_rl_uppercase_p) PARAMS((int));
extern int (_rl_lowercase_p) PARAMS((int));
extern int (_rl_pure_alphabetic) PARAMS((int));
extern int (_rl_digit_p) PARAMS((int));
extern int (_rl_to_lower) PARAMS((int));
extern int (_rl_to_upper) PARAMS((int));
extern int (_rl_digit_value) PARAMS((int));
/* vi_mode.c */
extern void _rl_vi_initialize_line PARAMS((void));
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 *
*************************************************************************/
/* bind.c */
extern const char * const _rl_possible_control_prefixes[];
extern const char * const _rl_possible_meta_prefixes[];
/* callback.c */
extern _rl_callback_func_t *_rl_callback_func;
extern _rl_callback_generic_arg *_rl_callback_data;
/* complete.c */
extern int _rl_complete_show_all;
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;
extern int _rl_last_c_pos;
extern int _rl_suppress_redisplay;
extern int _rl_want_redisplay;
/* isearch.c */
extern char *_rl_isearch_terminators;
extern _rl_search_cxt *_rl_iscxt;
/* macro.c */
extern char *_rl_executing_macro;
/* misc.c */
extern int _rl_history_preserve_point;
extern int _rl_history_saved_point;
extern _rl_arg_cxt _rl_argcxt;
/* readline.c */
extern int _rl_echoing_p;
extern int _rl_horizontal_scroll_mode;
extern int _rl_mark_modified_lines;
extern int _rl_bell_preference;
extern int _rl_meta_flag;
extern int _rl_convert_meta_chars_to_ascii;
extern int _rl_output_meta_chars;
extern int _rl_bind_stty_chars;
extern int _rl_revert_all_at_newline;
extern int _rl_echo_control_chars;
extern char *_rl_comment_begin;
extern unsigned char _rl_parsing_conditionalized_out;
extern Keymap _rl_keymap;
extern FILE *_rl_in_stream;
extern FILE *_rl_out_stream;
extern int _rl_last_command_was_kill;
extern int _rl_eof_char;
extern procenv_t _rl_top_level;
extern _rl_keyseq_cxt *_rl_kscxt;
/* search.c */
extern _rl_search_cxt *_rl_nscxt;
/* signals.c */
extern int _rl_interrupt_immediately;
extern int volatile _rl_caught_signal;
extern int _rl_echoctl;
extern int _rl_intr_char;
extern int _rl_quit_char;
extern int _rl_susp_char;
/* terminal.c */
extern int _rl_enable_keypad;
extern int _rl_enable_meta;
extern char *_rl_term_clreol;
extern char *_rl_term_clrpag;
extern char *_rl_term_im;
extern char *_rl_term_ic;
extern char *_rl_term_ei;
extern char *_rl_term_DC;
extern char *_rl_term_up;
extern char *_rl_term_dc;
extern char *_rl_term_cr;
extern char *_rl_term_IC;
extern char *_rl_term_forward_char;
extern int _rl_screenheight;
extern int _rl_screenwidth;
extern int _rl_screenchars;
extern int _rl_terminal_can_insert;
extern int _rl_term_autowrap;
/* undo.c */
extern int _rl_doing_an_undo;
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_ */
-975
View File
@@ -1,975 +0,0 @@
/* rltty.c -- functions to prepare and restore the terminal for readline's
use. */
/* Copyright (C) 1992-2005 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Readline is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
#include <signal.h>
#include <errno.h>
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#include "rldefs.h"
#if defined (GWINSZ_IN_SYS_IOCTL)
# include <sys/ioctl.h>
#endif /* GWINSZ_IN_SYS_IOCTL */
#include "rltty.h"
#include "readline.h"
#include "rlprivate.h"
#if !defined (errno)
extern int errno;
#endif /* !errno */
rl_vintfunc_t *rl_prep_term_function = rl_prep_terminal;
rl_voidfunc_t *rl_deprep_term_function = rl_deprep_terminal;
static void set_winsize PARAMS((int));
/* **************************************************************** */
/* */
/* Saving and Restoring the TTY */
/* */
/* **************************************************************** */
/* Non-zero means that the terminal is in a prepped state. */
static int terminal_prepped;
static _RL_TTY_CHARS _rl_tty_chars, _rl_last_tty_chars;
/* If non-zero, means that this process has called tcflow(fd, TCOOFF)
and output is suspended. */
#if defined (__ksr1__)
static int ksrflow;
#endif
/* Dummy call to force a backgrounded readline to stop before it tries
to get the tty settings. */
static void
set_winsize (tty)
int tty;
{
#if defined (TIOCGWINSZ)
struct winsize w;
if (ioctl (tty, TIOCGWINSZ, &w) == 0)
(void) ioctl (tty, TIOCSWINSZ, &w);
#endif /* TIOCGWINSZ */
}
#if defined (NO_TTY_DRIVER)
/* Nothing */
#elif defined (NEW_TTY_DRIVER)
/* Values for the `flags' field of a struct bsdtty. This tells which
elements of the struct bsdtty have been fetched from the system and
are valid. */
#define SGTTY_SET 0x01
#define LFLAG_SET 0x02
#define TCHARS_SET 0x04
#define LTCHARS_SET 0x08
struct bsdtty {
struct sgttyb sgttyb; /* Basic BSD tty driver information. */
int lflag; /* Local mode flags, like LPASS8. */
#if defined (TIOCGETC)
struct tchars tchars; /* Terminal special characters, including ^S and ^Q. */
#endif
#if defined (TIOCGLTC)
struct ltchars ltchars; /* 4.2 BSD editing characters */
#endif
int flags; /* Bitmap saying which parts of the struct are valid. */
};
#define TIOTYPE struct bsdtty
static TIOTYPE otio;
static void save_tty_chars PARAMS((TIOTYPE *));
static int _get_tty_settings PARAMS((int, TIOTYPE *));
static int get_tty_settings PARAMS((int, TIOTYPE *));
static int _set_tty_settings PARAMS((int, TIOTYPE *));
static int set_tty_settings PARAMS((int, TIOTYPE *));
static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t));
static void
save_tty_chars (tiop)
TIOTYPE *tiop;
{
_rl_last_tty_chars = _rl_tty_chars;
if (tiop->flags & SGTTY_SET)
{
_rl_tty_chars.t_erase = tiop->sgttyb.sg_erase;
_rl_tty_chars.t_kill = tiop->sgttyb.sg_kill;
}
if (tiop->flags & TCHARS_SET)
{
_rl_intr_char = _rl_tty_chars.t_intr = tiop->tchars.t_intrc;
_rl_quit_char = _rl_tty_chars.t_quit = tiop->tchars.t_quitc;
_rl_tty_chars.t_start = tiop->tchars.t_startc;
_rl_tty_chars.t_stop = tiop->tchars.t_stopc;
_rl_tty_chars.t_eof = tiop->tchars.t_eofc;
_rl_tty_chars.t_eol = '\n';
_rl_tty_chars.t_eol2 = tiop->tchars.t_brkc;
}
if (tiop->flags & LTCHARS_SET)
{
_rl_susp_char = _rl_tty_chars.t_susp = tiop->ltchars.t_suspc;
_rl_tty_chars.t_dsusp = tiop->ltchars.t_dsuspc;
_rl_tty_chars.t_reprint = tiop->ltchars.t_rprntc;
_rl_tty_chars.t_flush = tiop->ltchars.t_flushc;
_rl_tty_chars.t_werase = tiop->ltchars.t_werasc;
_rl_tty_chars.t_lnext = tiop->ltchars.t_lnextc;
}
_rl_tty_chars.t_status = -1;
}
static int
get_tty_settings (tty, tiop)
int tty;
TIOTYPE *tiop;
{
set_winsize (tty);
tiop->flags = tiop->lflag = 0;
errno = 0;
if (ioctl (tty, TIOCGETP, &(tiop->sgttyb)) < 0)
return -1;
tiop->flags |= SGTTY_SET;
#if defined (TIOCLGET)
if (ioctl (tty, TIOCLGET, &(tiop->lflag)) == 0)
tiop->flags |= LFLAG_SET;
#endif
#if defined (TIOCGETC)
if (ioctl (tty, TIOCGETC, &(tiop->tchars)) == 0)
tiop->flags |= TCHARS_SET;
#endif
#if defined (TIOCGLTC)
if (ioctl (tty, TIOCGLTC, &(tiop->ltchars)) == 0)
tiop->flags |= LTCHARS_SET;
#endif
return 0;
}
static int
set_tty_settings (tty, tiop)
int tty;
TIOTYPE *tiop;
{
if (tiop->flags & SGTTY_SET)
{
ioctl (tty, TIOCSETN, &(tiop->sgttyb));
tiop->flags &= ~SGTTY_SET;
}
_rl_echoing_p = 1;
#if defined (TIOCLSET)
if (tiop->flags & LFLAG_SET)
{
ioctl (tty, TIOCLSET, &(tiop->lflag));
tiop->flags &= ~LFLAG_SET;
}
#endif
#if defined (TIOCSETC)
if (tiop->flags & TCHARS_SET)
{
ioctl (tty, TIOCSETC, &(tiop->tchars));
tiop->flags &= ~TCHARS_SET;
}
#endif
#if defined (TIOCSLTC)
if (tiop->flags & LTCHARS_SET)
{
ioctl (tty, TIOCSLTC, &(tiop->ltchars));
tiop->flags &= ~LTCHARS_SET;
}
#endif
return 0;
}
static void
prepare_terminal_settings (meta_flag, oldtio, tiop)
int meta_flag;
TIOTYPE oldtio, *tiop;
{
_rl_echoing_p = (oldtio.sgttyb.sg_flags & ECHO);
_rl_echoctl = (oldtio.sgttyb.sg_flags & ECHOCTL);
/* Copy the original settings to the structure we're going to use for
our settings. */
tiop->sgttyb = oldtio.sgttyb;
tiop->lflag = oldtio.lflag;
#if defined (TIOCGETC)
tiop->tchars = oldtio.tchars;
#endif
#if defined (TIOCGLTC)
tiop->ltchars = oldtio.ltchars;
#endif
tiop->flags = oldtio.flags;
/* First, the basic settings to put us into character-at-a-time, no-echo
input mode. */
tiop->sgttyb.sg_flags &= ~(ECHO | CRMOD);
tiop->sgttyb.sg_flags |= CBREAK;
/* If this terminal doesn't care how the 8th bit is used, then we can
use it for the meta-key. If only one of even or odd parity is
specified, then the terminal is using parity, and we cannot. */
#if !defined (ANYP)
# define ANYP (EVENP | ODDP)
#endif
if (((oldtio.sgttyb.sg_flags & ANYP) == ANYP) ||
((oldtio.sgttyb.sg_flags & ANYP) == 0))
{
tiop->sgttyb.sg_flags |= ANYP;
/* Hack on local mode flags if we can. */
#if defined (TIOCLGET)
# if defined (LPASS8)
tiop->lflag |= LPASS8;
# endif /* LPASS8 */
#endif /* TIOCLGET */
}
#if defined (TIOCGETC)
# if defined (USE_XON_XOFF)
/* Get rid of terminal output start and stop characters. */
tiop->tchars.t_stopc = -1; /* C-s */
tiop->tchars.t_startc = -1; /* C-q */
/* If there is an XON character, bind it to restart the output. */
if (oldtio.tchars.t_startc != -1)
rl_bind_key (oldtio.tchars.t_startc, rl_restart_output);
# endif /* USE_XON_XOFF */
/* If there is an EOF char, bind _rl_eof_char to it. */
if (oldtio.tchars.t_eofc != -1)
_rl_eof_char = oldtio.tchars.t_eofc;
# if defined (NO_KILL_INTR)
/* Get rid of terminal-generated SIGQUIT and SIGINT. */
tiop->tchars.t_quitc = -1; /* C-\ */
tiop->tchars.t_intrc = -1; /* C-c */
# endif /* NO_KILL_INTR */
#endif /* TIOCGETC */
#if defined (TIOCGLTC)
/* Make the interrupt keys go away. Just enough to make people happy. */
tiop->ltchars.t_dsuspc = -1; /* C-y */
tiop->ltchars.t_lnextc = -1; /* C-v */
#endif /* TIOCGLTC */
}
#else /* !defined (NEW_TTY_DRIVER) */
#if !defined (VMIN)
# define VMIN VEOF
#endif
#if !defined (VTIME)
# define VTIME VEOL
#endif
#if defined (TERMIOS_TTY_DRIVER)
# define TIOTYPE struct termios
# define DRAIN_OUTPUT(fd) tcdrain (fd)
# define GETATTR(tty, tiop) (tcgetattr (tty, tiop))
# ifdef M_UNIX
# define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop))
# else
# define SETATTR(tty, tiop) (tcsetattr (tty, TCSADRAIN, tiop))
# endif /* !M_UNIX */
#else
# define TIOTYPE struct termio
# define DRAIN_OUTPUT(fd)
# define GETATTR(tty, tiop) (ioctl (tty, TCGETA, tiop))
# define SETATTR(tty, tiop) (ioctl (tty, TCSETAW, tiop))
#endif /* !TERMIOS_TTY_DRIVER */
static TIOTYPE otio;
static void save_tty_chars PARAMS((TIOTYPE *));
static int _get_tty_settings PARAMS((int, TIOTYPE *));
static int get_tty_settings PARAMS((int, TIOTYPE *));
static int _set_tty_settings PARAMS((int, TIOTYPE *));
static int set_tty_settings PARAMS((int, TIOTYPE *));
static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t));
static void _rl_bind_tty_special_chars PARAMS((Keymap, TIOTYPE));
#if defined (FLUSHO)
# define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO)
#else
# define OUTPUT_BEING_FLUSHED(tp) 0
#endif
static void
save_tty_chars (tiop)
TIOTYPE *tiop;
{
_rl_last_tty_chars = _rl_tty_chars;
_rl_tty_chars.t_eof = tiop->c_cc[VEOF];
_rl_tty_chars.t_eol = tiop->c_cc[VEOL];
#ifdef VEOL2
_rl_tty_chars.t_eol2 = tiop->c_cc[VEOL2];
#endif
_rl_tty_chars.t_erase = tiop->c_cc[VERASE];
#ifdef VWERASE
_rl_tty_chars.t_werase = tiop->c_cc[VWERASE];
#endif
_rl_tty_chars.t_kill = tiop->c_cc[VKILL];
#ifdef VREPRINT
_rl_tty_chars.t_reprint = tiop->c_cc[VREPRINT];
#endif
_rl_intr_char = _rl_tty_chars.t_intr = tiop->c_cc[VINTR];
_rl_quit_char = _rl_tty_chars.t_quit = tiop->c_cc[VQUIT];
#ifdef VSUSP
_rl_susp_char = _rl_tty_chars.t_susp = tiop->c_cc[VSUSP];
#endif
#ifdef VDSUSP
_rl_tty_chars.t_dsusp = tiop->c_cc[VDSUSP];
#endif
#ifdef VSTART
_rl_tty_chars.t_start = tiop->c_cc[VSTART];
#endif
#ifdef VSTOP
_rl_tty_chars.t_stop = tiop->c_cc[VSTOP];
#endif
#ifdef VLNEXT
_rl_tty_chars.t_lnext = tiop->c_cc[VLNEXT];
#endif
#ifdef VDISCARD
_rl_tty_chars.t_flush = tiop->c_cc[VDISCARD];
#endif
#ifdef VSTATUS
_rl_tty_chars.t_status = tiop->c_cc[VSTATUS];
#endif
}
#if defined (_AIX) || defined (_AIX41)
/* Currently this is only used on AIX */
static void
rltty_warning (msg)
char *msg;
{
_rl_errmsg ("warning: %s", msg);
}
#endif
#if defined (_AIX)
void
setopost(tp)
TIOTYPE *tp;
{
if ((tp->c_oflag & OPOST) == 0)
{
_rl_errmsg ("warning: turning on OPOST for terminal\r");
tp->c_oflag |= OPOST|ONLCR;
}
}
#endif
static int
_get_tty_settings (tty, tiop)
int tty;
TIOTYPE *tiop;
{
int ioctl_ret;
while (1)
{
ioctl_ret = GETATTR (tty, tiop);
if (ioctl_ret < 0)
{
if (errno != EINTR)
return -1;
else
continue;
}
if (OUTPUT_BEING_FLUSHED (tiop))
{
#if defined (FLUSHO)
_rl_errmsg ("warning: turning off output flushing");
tiop->c_lflag &= ~FLUSHO;
break;
#else
continue;
#endif
}
break;
}
return 0;
}
static int
get_tty_settings (tty, tiop)
int tty;
TIOTYPE *tiop;
{
set_winsize (tty);
errno = 0;
if (_get_tty_settings (tty, tiop) < 0)
return -1;
#if defined (_AIX)
setopost(tiop);
#endif
return 0;
}
static int
_set_tty_settings (tty, tiop)
int tty;
TIOTYPE *tiop;
{
while (SETATTR (tty, tiop) < 0)
{
if (errno != EINTR)
return -1;
errno = 0;
}
return 0;
}
static int
set_tty_settings (tty, tiop)
int tty;
TIOTYPE *tiop;
{
if (_set_tty_settings (tty, tiop) < 0)
return -1;
#if 0
#if defined (TERMIOS_TTY_DRIVER)
# if defined (__ksr1__)
if (ksrflow)
{
ksrflow = 0;
tcflow (tty, TCOON);
}
# else /* !ksr1 */
tcflow (tty, TCOON); /* Simulate a ^Q. */
# endif /* !ksr1 */
#else
ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */
#endif /* !TERMIOS_TTY_DRIVER */
#endif /* 0 */
return 0;
}
static void
prepare_terminal_settings (meta_flag, oldtio, tiop)
int meta_flag;
TIOTYPE oldtio, *tiop;
{
_rl_echoing_p = (oldtio.c_lflag & ECHO);
#if defined (ECHOCTL)
_rl_echoctl = (oldtio.c_lflag & ECHOCTL);
#endif
tiop->c_lflag &= ~(ICANON | ECHO);
if ((unsigned char) oldtio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
_rl_eof_char = oldtio.c_cc[VEOF];
#if defined (USE_XON_XOFF)
#if defined (IXANY)
tiop->c_iflag &= ~(IXON | IXOFF | IXANY);
#else
/* `strict' Posix systems do not define IXANY. */
tiop->c_iflag &= ~(IXON | IXOFF);
#endif /* IXANY */
#endif /* USE_XON_XOFF */
/* Only turn this off if we are using all 8 bits. */
if (((tiop->c_cflag & CSIZE) == CS8) || meta_flag)
tiop->c_iflag &= ~(ISTRIP | INPCK);
/* Make sure we differentiate between CR and NL on input. */
tiop->c_iflag &= ~(ICRNL | INLCR);
#if !defined (HANDLE_SIGNALS)
tiop->c_lflag &= ~ISIG;
#else
tiop->c_lflag |= ISIG;
#endif
tiop->c_cc[VMIN] = 1;
tiop->c_cc[VTIME] = 0;
#if defined (FLUSHO)
if (OUTPUT_BEING_FLUSHED (tiop))
{
tiop->c_lflag &= ~FLUSHO;
oldtio.c_lflag &= ~FLUSHO;
}
#endif
/* Turn off characters that we need on Posix systems with job control,
just to be sure. This includes ^Y and ^V. This should not really
be necessary. */
#if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE)
#if defined (VLNEXT)
tiop->c_cc[VLNEXT] = _POSIX_VDISABLE;
#endif
#if defined (VDSUSP)
tiop->c_cc[VDSUSP] = _POSIX_VDISABLE;
#endif
#endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
}
#endif /* !NEW_TTY_DRIVER */
/* Put the terminal in CBREAK mode so that we can detect key presses. */
#if defined (NO_TTY_DRIVER)
void
rl_prep_terminal (meta_flag)
int meta_flag;
{
_rl_echoing_p = 1;
}
void
rl_deprep_terminal ()
{
}
#else /* ! NO_TTY_DRIVER */
void
rl_prep_terminal (meta_flag)
int meta_flag;
{
int tty;
TIOTYPE tio;
if (terminal_prepped)
return;
/* Try to keep this function from being INTerrupted. */
_rl_block_sigint ();
tty = fileno (rl_instream);
if (get_tty_settings (tty, &tio) < 0)
{
#if defined (ENOTSUP)
/* MacOS X and Linux, at least, lie about the value of errno if
tcgetattr fails. */
if (errno == ENOTTY || errno == EINVAL || errno == ENOTSUP)
#else
if (errno == ENOTTY || errno == EINVAL)
#endif
_rl_echoing_p = 1; /* XXX */
_rl_release_sigint ();
return;
}
otio = tio;
if (_rl_bind_stty_chars)
{
#if defined (VI_MODE)
/* If editing in vi mode, make sure we restore the bindings in the
insertion keymap no matter what keymap we ended up in. */
if (rl_editing_mode == vi_mode)
rl_tty_unset_default_bindings (vi_insertion_keymap);
else
#endif
rl_tty_unset_default_bindings (_rl_keymap);
}
save_tty_chars (&otio);
RL_SETSTATE(RL_STATE_TTYCSAVED);
if (_rl_bind_stty_chars)
{
#if defined (VI_MODE)
/* If editing in vi mode, make sure we set the bindings in the
insertion keymap no matter what keymap we ended up in. */
if (rl_editing_mode == vi_mode)
_rl_bind_tty_special_chars (vi_insertion_keymap, tio);
else
#endif
_rl_bind_tty_special_chars (_rl_keymap, tio);
}
prepare_terminal_settings (meta_flag, otio, &tio);
if (set_tty_settings (tty, &tio) < 0)
{
_rl_release_sigint ();
return;
}
if (_rl_enable_keypad)
_rl_control_keypad (1);
fflush (rl_outstream);
terminal_prepped = 1;
RL_SETSTATE(RL_STATE_TERMPREPPED);
_rl_release_sigint ();
}
/* Restore the terminal's normal settings and modes. */
void
rl_deprep_terminal ()
{
int tty;
if (!terminal_prepped)
return;
/* Try to keep this function from being interrupted. */
_rl_block_sigint ();
tty = fileno (rl_instream);
if (_rl_enable_keypad)
_rl_control_keypad (0);
fflush (rl_outstream);
if (set_tty_settings (tty, &otio) < 0)
{
_rl_release_sigint ();
return;
}
terminal_prepped = 0;
RL_UNSETSTATE(RL_STATE_TERMPREPPED);
_rl_release_sigint ();
}
#endif /* !NO_TTY_DRIVER */
/* **************************************************************** */
/* */
/* Bogus Flow Control */
/* */
/* **************************************************************** */
int
rl_restart_output (count, key)
int count, key;
{
#if defined (__MINGW32__)
return 0;
#else /* !__MING32__ */
int fildes = fileno (rl_outstream);
#if defined (TIOCSTART)
#if defined (apollo)
ioctl (&fildes, TIOCSTART, 0);
#else
ioctl (fildes, TIOCSTART, 0);
#endif /* apollo */
#else /* !TIOCSTART */
# if defined (TERMIOS_TTY_DRIVER)
# if defined (__ksr1__)
if (ksrflow)
{
ksrflow = 0;
tcflow (fildes, TCOON);
}
# else /* !ksr1 */
tcflow (fildes, TCOON); /* Simulate a ^Q. */
# endif /* !ksr1 */
# else /* !TERMIOS_TTY_DRIVER */
# if defined (TCXONC)
ioctl (fildes, TCXONC, TCOON);
# endif /* TCXONC */
# endif /* !TERMIOS_TTY_DRIVER */
#endif /* !TIOCSTART */
return 0;
#endif /* !__MINGW32__ */
}
int
rl_stop_output (count, key)
int count, key;
{
#if defined (__MINGW32__)
return 0;
#else
int fildes = fileno (rl_instream);
#if defined (TIOCSTOP)
# if defined (apollo)
ioctl (&fildes, TIOCSTOP, 0);
# else
ioctl (fildes, TIOCSTOP, 0);
# endif /* apollo */
#else /* !TIOCSTOP */
# if defined (TERMIOS_TTY_DRIVER)
# if defined (__ksr1__)
ksrflow = 1;
# endif /* ksr1 */
tcflow (fildes, TCOOFF);
# else
# if defined (TCXONC)
ioctl (fildes, TCXONC, TCOON);
# endif /* TCXONC */
# endif /* !TERMIOS_TTY_DRIVER */
#endif /* !TIOCSTOP */
return 0;
#endif /* !__MINGW32__ */
}
/* **************************************************************** */
/* */
/* Default Key Bindings */
/* */
/* **************************************************************** */
#if !defined (NO_TTY_DRIVER)
#define SET_SPECIAL(sc, func) set_special_char(kmap, &ttybuff, sc, func)
#endif
#if defined (NO_TTY_DRIVER)
#define SET_SPECIAL(sc, func)
#define RESET_SPECIAL(c)
#elif defined (NEW_TTY_DRIVER)
static void
set_special_char (kmap, tiop, sc, func)
Keymap kmap;
TIOTYPE *tiop;
int sc;
rl_command_func_t *func;
{
if (sc != -1 && kmap[(unsigned char)sc].type == ISFUNC)
kmap[(unsigned char)sc].function = func;
}
#define RESET_SPECIAL(c) \
if (c != -1 && kmap[(unsigned char)c].type == ISFUNC) \
kmap[(unsigned char)c].function = rl_insert;
static void
_rl_bind_tty_special_chars (kmap, ttybuff)
Keymap kmap;
TIOTYPE ttybuff;
{
if (ttybuff.flags & SGTTY_SET)
{
SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
}
# if defined (TIOCGLTC)
if (ttybuff.flags & LTCHARS_SET)
{
SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout);
SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
}
# endif /* TIOCGLTC */
}
#else /* !NEW_TTY_DRIVER */
static void
set_special_char (kmap, tiop, sc, func)
Keymap kmap;
TIOTYPE *tiop;
int sc;
rl_command_func_t *func;
{
unsigned char uc;
uc = tiop->c_cc[sc];
if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC)
kmap[uc].function = func;
}
/* used later */
#define RESET_SPECIAL(uc) \
if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
kmap[uc].function = rl_insert;
static void
_rl_bind_tty_special_chars (kmap, ttybuff)
Keymap kmap;
TIOTYPE ttybuff;
{
SET_SPECIAL (VERASE, rl_rubout);
SET_SPECIAL (VKILL, rl_unix_line_discard);
# if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
SET_SPECIAL (VLNEXT, rl_quoted_insert);
# endif /* VLNEXT && TERMIOS_TTY_DRIVER */
# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
SET_SPECIAL (VWERASE, rl_unix_word_rubout);
# endif /* VWERASE && TERMIOS_TTY_DRIVER */
}
#endif /* !NEW_TTY_DRIVER */
/* Set the system's default editing characters to their readline equivalents
in KMAP. Should be static, now that we have rl_tty_set_default_bindings. */
void
rltty_set_default_bindings (kmap)
Keymap kmap;
{
#if !defined (NO_TTY_DRIVER)
TIOTYPE ttybuff;
int tty;
tty = fileno (rl_instream);
if (get_tty_settings (tty, &ttybuff) == 0)
_rl_bind_tty_special_chars (kmap, ttybuff);
#endif
}
/* New public way to set the system default editing chars to their readline
equivalents. */
void
rl_tty_set_default_bindings (kmap)
Keymap kmap;
{
rltty_set_default_bindings (kmap);
}
/* Rebind all of the tty special chars that readline worries about back
to self-insert. Call this before saving the current terminal special
chars with save_tty_chars(). This only works on POSIX termios or termio
systems. */
void
rl_tty_unset_default_bindings (kmap)
Keymap kmap;
{
/* Don't bother before we've saved the tty special chars at least once. */
if (RL_ISSTATE(RL_STATE_TTYCSAVED) == 0)
return;
RESET_SPECIAL (_rl_tty_chars.t_erase);
RESET_SPECIAL (_rl_tty_chars.t_kill);
# if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
RESET_SPECIAL (_rl_tty_chars.t_lnext);
# endif /* VLNEXT && TERMIOS_TTY_DRIVER */
# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
RESET_SPECIAL (_rl_tty_chars.t_werase);
# endif /* VWERASE && TERMIOS_TTY_DRIVER */
}
#if defined (HANDLE_SIGNALS)
#if defined (NEW_TTY_DRIVER) || defined (NO_TTY_DRIVER)
int
_rl_disable_tty_signals ()
{
return 0;
}
int
_rl_restore_tty_signals ()
{
return 0;
}
#else
static TIOTYPE sigstty, nosigstty;
static int tty_sigs_disabled = 0;
int
_rl_disable_tty_signals ()
{
if (tty_sigs_disabled)
return 0;
if (_get_tty_settings (fileno (rl_instream), &sigstty) < 0)
return -1;
nosigstty = sigstty;
nosigstty.c_lflag &= ~ISIG;
nosigstty.c_iflag &= ~IXON;
if (_set_tty_settings (fileno (rl_instream), &nosigstty) < 0)
return (_set_tty_settings (fileno (rl_instream), &sigstty));
tty_sigs_disabled = 1;
return 0;
}
int
_rl_restore_tty_signals ()
{
int r;
if (tty_sigs_disabled == 0)
return 0;
r = _set_tty_settings (fileno (rl_instream), &sigstty);
if (r == 0)
tty_sigs_disabled = 0;
return r;
}
#endif /* !NEW_TTY_DRIVER */
#endif /* HANDLE_SIGNALS */
-37
View File
@@ -1,37 +0,0 @@
/* savestring.c - function version of savestring for backwards compatibility */
/* Copyright (C) 1998,2003 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
#include <config.h>
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#include "xmalloc.h"
/* Backwards compatibility, now that savestring has been removed from
all `public' readline header files. */
char *
savestring (s)
const char *s;
{
return ((char *)strcpy ((char *)xmalloc (1 + strlen (s)), (s)));
}
-570
View File
@@ -1,570 +0,0 @@
/* search.c - code for non-incremental searching in emacs and vi modes. */
/* Copyright (C) 1992-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Readline is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif
#include "rldefs.h"
#include "rlmbutil.h"
#include "readline.h"
#include "history.h"
#include "rlprivate.h"
#include "xmalloc.h"
#ifdef abs
# undef abs
#endif
#define abs(x) (((x) >= 0) ? (x) : -(x))
_rl_search_cxt *_rl_nscxt = 0;
extern HIST_ENTRY *_rl_saved_line_for_history;
/* Functions imported from the rest of the library. */
extern int _rl_free_history_entry PARAMS((HIST_ENTRY *));
static char *noninc_search_string = (char *) NULL;
static int noninc_history_pos;
static char *prev_line_found = (char *) NULL;
static int rl_history_search_len;
static int rl_history_search_pos;
static char *history_search_string;
static int history_string_size;
static void make_history_line_current PARAMS((HIST_ENTRY *));
static int noninc_search_from_pos PARAMS((char *, int, int));
static int noninc_dosearch PARAMS((char *, int));
static int noninc_search PARAMS((int, int));
static int rl_history_search_internal PARAMS((int, int));
static void rl_history_search_reinit PARAMS((void));
static _rl_search_cxt *_rl_nsearch_init PARAMS((int, int));
static int _rl_nsearch_cleanup PARAMS((_rl_search_cxt *, int));
static void _rl_nsearch_abort PARAMS((_rl_search_cxt *));
static int _rl_nsearch_dispatch PARAMS((_rl_search_cxt *, int));
/* Make the data from the history entry ENTRY be the contents of the
current line. This doesn't do anything with rl_point; the caller
must set it. */
static void
make_history_line_current (entry)
HIST_ENTRY *entry;
{
_rl_replace_text (entry->line, 0, rl_end);
_rl_fix_point (1);
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode)
/* POSIX.2 says that the `U' command doesn't affect the copy of any
command lines to the edit line. We're going to implement that by
making the undo list start after the matching line is copied to the
current editing buffer. */
rl_free_undo_list ();
#endif
if (_rl_saved_line_for_history)
_rl_free_history_entry (_rl_saved_line_for_history);
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
}
/* Search the history list for STRING starting at absolute history position
POS. If STRING begins with `^', the search must match STRING at the
beginning of a history line, otherwise a full substring match is performed
for STRING. DIR < 0 means to search backwards through the history list,
DIR >= 0 means to search forward. */
static int
noninc_search_from_pos (string, pos, dir)
char *string;
int pos, dir;
{
int ret, old;
if (pos < 0)
return -1;
old = where_history ();
if (history_set_pos (pos) == 0)
return -1;
RL_SETSTATE(RL_STATE_SEARCH);
if (*string == '^')
ret = history_search_prefix (string + 1, dir);
else
ret = history_search (string, dir);
RL_UNSETSTATE(RL_STATE_SEARCH);
if (ret != -1)
ret = where_history ();
history_set_pos (old);
return (ret);
}
/* Search for a line in the history containing STRING. If DIR is < 0, the
search is backwards through previous entries, else through subsequent
entries. Returns 1 if the search was successful, 0 otherwise. */
static int
noninc_dosearch (string, dir)
char *string;
int dir;
{
int oldpos, pos;
HIST_ENTRY *entry;
if (string == 0 || *string == '\0' || noninc_history_pos < 0)
{
rl_ding ();
return 0;
}
pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir);
if (pos == -1)
{
/* Search failed, current history position unchanged. */
rl_maybe_unsave_line ();
rl_clear_message ();
rl_point = 0;
rl_ding ();
return 0;
}
noninc_history_pos = pos;
oldpos = where_history ();
history_set_pos (noninc_history_pos);
entry = current_history ();
#if defined (VI_MODE)
if (rl_editing_mode != vi_mode)
#endif
history_set_pos (oldpos);
make_history_line_current (entry);
rl_point = 0;
rl_mark = rl_end;
rl_clear_message ();
return 1;
}
static _rl_search_cxt *
_rl_nsearch_init (dir, pchar)
int dir, pchar;
{
_rl_search_cxt *cxt;
char *p;
cxt = _rl_scxt_alloc (RL_SEARCH_NSEARCH, 0);
if (dir < 0)
cxt->sflags |= SF_REVERSE; /* not strictly needed */
cxt->direction = dir;
cxt->history_pos = cxt->save_line;
rl_maybe_save_line ();
/* Clear the undo list, since reading the search string should create its
own undo list, and the whole list will end up being freed when we
finish reading the search string. */
rl_undo_list = 0;
/* Use the line buffer to read the search string. */
rl_line_buffer[0] = 0;
rl_end = rl_point = 0;
p = _rl_make_prompt_for_search (pchar ? pchar : ':');
rl_message ("%s", p, 0);
free (p);
RL_SETSTATE(RL_STATE_NSEARCH);
_rl_nscxt = cxt;
return cxt;
}
static int
_rl_nsearch_cleanup (cxt, r)
_rl_search_cxt *cxt;
int r;
{
_rl_scxt_dispose (cxt, 0);
_rl_nscxt = 0;
RL_UNSETSTATE(RL_STATE_NSEARCH);
return (r != 1);
}
static void
_rl_nsearch_abort (cxt)
_rl_search_cxt *cxt;
{
rl_maybe_unsave_line ();
rl_clear_message ();
rl_point = cxt->save_point;
rl_mark = cxt->save_mark;
rl_restore_prompt ();
RL_UNSETSTATE (RL_STATE_NSEARCH);
}
/* Process just-read character C according to search context CXT. Return -1
if the caller should abort the search, 0 if we should break out of the
loop, and 1 if we should continue to read characters. */
static int
_rl_nsearch_dispatch (cxt, c)
_rl_search_cxt *cxt;
int c;
{
switch (c)
{
case CTRL('W'):
rl_unix_word_rubout (1, c);
break;
case CTRL('U'):
rl_unix_line_discard (1, c);
break;
case RETURN:
case NEWLINE:
return 0;
case CTRL('H'):
case RUBOUT:
if (rl_point == 0)
{
_rl_nsearch_abort (cxt);
return -1;
}
_rl_rubout_char (1, c);
break;
case CTRL('C'):
case CTRL('G'):
rl_ding ();
_rl_nsearch_abort (cxt);
return -1;
default:
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_insert_text (cxt->mb);
else
#endif
_rl_insert_char (1, c);
break;
}
(*rl_redisplay_function) ();
return 1;
}
/* Perform one search according to CXT, using NONINC_SEARCH_STRING. Return
-1 if the search should be aborted, any other value means to clean up
using _rl_nsearch_cleanup (). Returns 1 if the search was successful,
0 otherwise. */
static int
_rl_nsearch_dosearch (cxt)
_rl_search_cxt *cxt;
{
rl_mark = cxt->save_mark;
/* If rl_point == 0, we want to re-use the previous search string and
start from the saved history position. If there's no previous search
string, punt. */
if (rl_point == 0)
{
if (noninc_search_string == 0)
{
rl_ding ();
rl_restore_prompt ();
RL_UNSETSTATE (RL_STATE_NSEARCH);
return -1;
}
}
else
{
/* We want to start the search from the current history position. */
noninc_history_pos = cxt->save_line;
FREE (noninc_search_string);
noninc_search_string = savestring (rl_line_buffer);
/* If we don't want the subsequent undo list generated by the search
matching a history line to include the contents of the search string,
we need to clear rl_line_buffer here. For now, we just clear the
undo list generated by reading the search string. (If the search
fails, the old undo list will be restored by rl_maybe_unsave_line.) */
rl_free_undo_list ();
}
rl_restore_prompt ();
return (noninc_dosearch (noninc_search_string, cxt->direction));
}
/* Search non-interactively through the history list. DIR < 0 means to
search backwards through the history of previous commands; otherwise
the search is for commands subsequent to the current position in the
history list. PCHAR is the character to use for prompting when reading
the search string; if not specified (0), it defaults to `:'. */
static int
noninc_search (dir, pchar)
int dir;
int pchar;
{
_rl_search_cxt *cxt;
int c, r;
cxt = _rl_nsearch_init (dir, pchar);
if (RL_ISSTATE (RL_STATE_CALLBACK))
return (0);
/* Read the search string. */
r = 0;
while (1)
{
c = _rl_search_getchar (cxt);
if (c == 0)
break;
r = _rl_nsearch_dispatch (cxt, c);
if (r < 0)
return 1;
else if (r == 0)
break;
}
r = _rl_nsearch_dosearch (cxt);
return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
}
/* Search forward through the history list for a string. If the vi-mode
code calls this, KEY will be `?'. */
int
rl_noninc_forward_search (count, key)
int count, key;
{
return noninc_search (1, (key == '?') ? '?' : 0);
}
/* Reverse search the history list for a string. If the vi-mode code
calls this, KEY will be `/'. */
int
rl_noninc_reverse_search (count, key)
int count, key;
{
return noninc_search (-1, (key == '/') ? '/' : 0);
}
/* Search forward through the history list for the last string searched
for. If there is no saved search string, abort. */
int
rl_noninc_forward_search_again (count, key)
int count, key;
{
int r;
if (!noninc_search_string)
{
rl_ding ();
return (-1);
}
r = noninc_dosearch (noninc_search_string, 1);
return (r != 1);
}
/* Reverse search in the history list for the last string searched
for. If there is no saved search string, abort. */
int
rl_noninc_reverse_search_again (count, key)
int count, key;
{
int r;
if (!noninc_search_string)
{
rl_ding ();
return (-1);
}
r = noninc_dosearch (noninc_search_string, -1);
return (r != 1);
}
#if defined (READLINE_CALLBACKS)
int
_rl_nsearch_callback (cxt)
_rl_search_cxt *cxt;
{
int c, r;
c = _rl_search_getchar (cxt);
r = _rl_nsearch_dispatch (cxt, c);
if (r != 0)
return 1;
r = _rl_nsearch_dosearch (cxt);
return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
}
#endif
static int
rl_history_search_internal (count, dir)
int count, dir;
{
HIST_ENTRY *temp;
int ret, oldpos;
rl_maybe_save_line ();
temp = (HIST_ENTRY *)NULL;
/* Search COUNT times through the history for a line whose prefix
matches history_search_string. When this loop finishes, TEMP,
if non-null, is the history line to copy into the line buffer. */
while (count)
{
ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir);
if (ret == -1)
break;
/* Get the history entry we found. */
rl_history_search_pos = ret;
oldpos = where_history ();
history_set_pos (rl_history_search_pos);
temp = current_history ();
history_set_pos (oldpos);
/* Don't find multiple instances of the same line. */
if (prev_line_found && STREQ (prev_line_found, temp->line))
continue;
prev_line_found = temp->line;
count--;
}
/* If we didn't find anything at all, return. */
if (temp == 0)
{
rl_maybe_unsave_line ();
rl_ding ();
/* If you don't want the saved history line (last match) to show up
in the line buffer after the search fails, change the #if 0 to
#if 1 */
#if 0
if (rl_point > rl_history_search_len)
{
rl_point = rl_end = rl_history_search_len;
rl_line_buffer[rl_end] = '\0';
rl_mark = 0;
}
#else
rl_point = rl_history_search_len; /* rl_maybe_unsave_line changes it */
rl_mark = rl_end;
#endif
return 1;
}
/* Copy the line we found into the current line buffer. */
make_history_line_current (temp);
rl_point = rl_history_search_len;
rl_mark = rl_end;
return 0;
}
static void
rl_history_search_reinit ()
{
rl_history_search_pos = where_history ();
rl_history_search_len = rl_point;
prev_line_found = (char *)NULL;
if (rl_point)
{
if (rl_history_search_len >= history_string_size - 2)
{
history_string_size = rl_history_search_len + 2;
history_search_string = (char *)xrealloc (history_search_string, history_string_size);
}
history_search_string[0] = '^';
strncpy (history_search_string + 1, rl_line_buffer, rl_point);
history_search_string[rl_point + 1] = '\0';
}
_rl_free_saved_history_line ();
}
/* Search forward in the history for the string of characters
from the start of the line to rl_point. This is a non-incremental
search. */
int
rl_history_search_forward (count, ignore)
int count, ignore;
{
if (count == 0)
return (0);
if (rl_last_func != rl_history_search_forward &&
rl_last_func != rl_history_search_backward)
rl_history_search_reinit ();
if (rl_history_search_len == 0)
return (rl_get_next_history (count, ignore));
return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1));
}
/* Search backward through the history for the string of characters
from the start of the line to rl_point. This is a non-incremental
search. */
int
rl_history_search_backward (count, ignore)
int count, ignore;
{
if (count == 0)
return (0);
if (rl_last_func != rl_history_search_forward &&
rl_last_func != rl_history_search_backward)
rl_history_search_reinit ();
if (rl_history_search_len == 0)
return (rl_get_previous_history (count, ignore));
return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
}
-208
View File
@@ -1,208 +0,0 @@
/* shell.c -- readline utility functions that are normally provided by
bash when readline is linked as part of the shell. */
/* Copyright (C) 1997-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Readline is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#if defined (HAVE_STRING_H)
# include <string.h>
#else
# include <strings.h>
#endif /* !HAVE_STRING_H */
#if defined (HAVE_LIMITS_H)
# include <limits.h>
#endif
#if defined (HAVE_FCNTL_H)
#include <fcntl.h>
#endif
#if defined (HAVE_PWD_H)
#include <pwd.h>
#endif
#include <stdio.h>
#include "rlstdc.h"
#include "rlshell.h"
#include "xmalloc.h"
#if defined (HAVE_GETPWUID) && !defined (HAVE_GETPW_DECLS)
extern struct passwd *getpwuid PARAMS((uid_t));
#endif /* HAVE_GETPWUID && !HAVE_GETPW_DECLS */
#ifndef NULL
# define NULL 0
#endif
#ifndef CHAR_BIT
# define CHAR_BIT 8
#endif
/* Nonzero if the integer type T is signed. */
#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
/* Bound on length of the string representing an integer value of type T.
Subtract one for the sign bit if T is signed;
302 / 1000 is log10 (2) rounded up;
add one for integer division truncation;
add one more for a minus sign if t is signed. */
#define INT_STRLEN_BOUND(t) \
((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 \
+ 1 + TYPE_SIGNED (t))
/* All of these functions are resolved from bash if we are linking readline
as part of bash. */
/* Does shell-like quoting using single quotes. */
char *
sh_single_quote (string)
char *string;
{
register int c;
char *result, *r, *s;
result = (char *)xmalloc (3 + (4 * strlen (string)));
r = result;
*r++ = '\'';
for (s = string; s && (c = *s); s++)
{
*r++ = c;
if (c == '\'')
{
*r++ = '\\'; /* insert escaped single quote */
*r++ = '\'';
*r++ = '\''; /* start new quoted string */
}
}
*r++ = '\'';
*r = '\0';
return (result);
}
/* Set the environment variables LINES and COLUMNS to lines and cols,
respectively. */
void
sh_set_lines_and_columns (lines, cols)
int lines, cols;
{
char *b;
#if defined (HAVE_SETENV)
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1);
sprintf (b, "%d", lines);
setenv ("LINES", b, 1);
free (b);
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1);
sprintf (b, "%d", cols);
setenv ("COLUMNS", b, 1);
free (b);
#else /* !HAVE_SETENV */
# if defined (HAVE_PUTENV)
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("LINES=") + 1);
sprintf (b, "LINES=%d", lines);
putenv (b);
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("COLUMNS=") + 1);
sprintf (b, "COLUMNS=%d", cols);
putenv (b);
# endif /* HAVE_PUTENV */
#endif /* !HAVE_SETENV */
}
char *
sh_get_env_value (varname)
const char *varname;
{
return ((char *)getenv (varname));
}
char *
sh_get_home_dir ()
{
char *home_dir;
struct passwd *entry;
home_dir = (char *)NULL;
#if defined (HAVE_GETPWUID)
entry = getpwuid (getuid ());
if (entry)
home_dir = entry->pw_dir;
#endif
return (home_dir);
}
#if !defined (O_NDELAY)
# if defined (FNDELAY)
# define O_NDELAY FNDELAY
# endif
#endif
int
sh_unset_nodelay_mode (fd)
int fd;
{
#if defined (HAVE_FCNTL)
int flags, bflags;
if ((flags = fcntl (fd, F_GETFL, 0)) < 0)
return -1;
bflags = 0;
#ifdef O_NONBLOCK
bflags |= O_NONBLOCK;
#endif
#ifdef O_NDELAY
bflags |= O_NDELAY;
#endif
if (flags & bflags)
{
flags &= ~bflags;
return (fcntl (fd, F_SETFL, flags));
}
#endif
return 0;
}
-671
View File
@@ -1,671 +0,0 @@
/* signals.c -- signal handling support for readline. */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Readline is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h> /* Just for NULL. Yuck. */
#include <sys/types.h>
#include <signal.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#if defined (GWINSZ_IN_SYS_IOCTL)
# include <sys/ioctl.h>
#endif /* GWINSZ_IN_SYS_IOCTL */
/* Some standard library routines. */
#include "readline.h"
#include "history.h"
#include "rlprivate.h"
#if defined (HANDLE_SIGNALS)
#if !defined (RETSIGTYPE)
# if defined (VOID_SIGHANDLER)
# define RETSIGTYPE void
# else
# define RETSIGTYPE int
# endif /* !VOID_SIGHANDLER */
#endif /* !RETSIGTYPE */
#if defined (VOID_SIGHANDLER)
# define SIGHANDLER_RETURN return
#else
# define SIGHANDLER_RETURN return (0)
#endif
/* This typedef is equivalent to the one for Function; it allows us
to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
typedef RETSIGTYPE SigHandler ();
#if defined (HAVE_POSIX_SIGNALS)
typedef struct sigaction sighandler_cxt;
# define rl_sigaction(s, nh, oh) sigaction(s, nh, oh)
#else
typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt;
# define sigemptyset(m)
#endif /* !HAVE_POSIX_SIGNALS */
#ifndef SA_RESTART
# define SA_RESTART 0
#endif
static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
static RETSIGTYPE rl_signal_handler PARAMS((int));
static RETSIGTYPE _rl_handle_signal PARAMS((int));
/* Exported variables for use by applications. */
/* If non-zero, readline will install its own signal handlers for
SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */
int rl_catch_signals = 1;
/* If non-zero, readline will install a signal handler for SIGWINCH. */
#ifdef SIGWINCH
int rl_catch_sigwinch = 1;
#else
int rl_catch_sigwinch = 0; /* for the readline state struct in readline.c */
#endif
/* Private variables. */
int _rl_interrupt_immediately = 0;
int volatile _rl_caught_signal = 0; /* should be sig_atomic_t, but that requires including <signal.h> everywhere */
/* If non-zero, print characters corresponding to received signals as long as
the user has indicated his desire to do so (_rl_echo_control_chars). */
int _rl_echoctl = 0;
int _rl_intr_char = 0;
int _rl_quit_char = 0;
int _rl_susp_char = 0;
static int signals_set_flag;
static int sigwinch_set_flag;
/* **************************************************************** */
/* */
/* Signal Handling */
/* */
/* **************************************************************** */
static sighandler_cxt old_int, old_term, old_alrm, old_quit;
#if defined (SIGTSTP)
static sighandler_cxt old_tstp, old_ttou, old_ttin;
#endif
#if defined (SIGWINCH)
static sighandler_cxt old_winch;
#endif
/* Readline signal handler functions. */
/* Called from RL_CHECK_SIGNALS() macro */
RETSIGTYPE
_rl_signal_handler (sig)
{
_rl_caught_signal = 0; /* XXX */
_rl_handle_signal (sig);
SIGHANDLER_RETURN;
}
static RETSIGTYPE
rl_signal_handler (sig)
int sig;
{
fprintf(stderr, "rl_signal_handler: caught %d", sig);
if (_rl_interrupt_immediately || RL_ISSTATE(RL_STATE_CALLBACK))
{
_rl_interrupt_immediately = 0;
_rl_handle_signal (sig);
}
else
_rl_caught_signal = sig;
SIGHANDLER_RETURN;
}
static RETSIGTYPE
_rl_handle_signal (sig)
int sig;
{
#if defined (HAVE_POSIX_SIGNALS)
sigset_t set;
#else /* !HAVE_POSIX_SIGNALS */
# if defined (HAVE_BSD_SIGNALS)
long omask;
# else /* !HAVE_BSD_SIGNALS */
sighandler_cxt dummy_cxt; /* needed for rl_set_sighandler call */
# endif /* !HAVE_BSD_SIGNALS */
#endif /* !HAVE_POSIX_SIGNALS */
RL_SETSTATE(RL_STATE_SIGHANDLER);
#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
/* Since the signal will not be blocked while we are in the signal
handler, ignore it until rl_clear_signals resets the catcher. */
# if defined (SIGALRM)
if (sig == SIGINT || sig == SIGALRM)
# else
if (sig == SIGINT)
# endif
rl_set_sighandler (sig, SIG_IGN, &dummy_cxt);
#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
switch (sig)
{
case SIGINT:
_rl_reset_completion_state ();
rl_free_line_state ();
/* FALLTHROUGH */
case SIGTERM:
#if defined (SIGTSTP)
case SIGTSTP:
case SIGTTOU:
case SIGTTIN:
#endif /* SIGTSTP */
#if defined (SIGALRM)
case SIGALRM:
#endif
#if defined (SIGQUIT)
case SIGQUIT:
#endif
rl_echo_signal_char (sig);
rl_cleanup_after_signal ();
#if defined (HAVE_POSIX_SIGNALS)
sigemptyset (&set);
sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
sigdelset (&set, sig);
#else /* !HAVE_POSIX_SIGNALS */
# if defined (HAVE_BSD_SIGNALS)
omask = sigblock (0);
# endif /* HAVE_BSD_SIGNALS */
#endif /* !HAVE_POSIX_SIGNALS */
#if defined (__EMX__)
signal (sig, SIG_ACK);
#endif
#if defined (HAVE_KILL)
kill (getpid (), sig);
#else
raise (sig); /* assume we have raise */
#endif
/* Let the signal that we just sent through. */
#if defined (HAVE_POSIX_SIGNALS)
sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
#else /* !HAVE_POSIX_SIGNALS */
# if defined (HAVE_BSD_SIGNALS)
sigsetmask (omask & ~(sigmask (sig)));
# endif /* HAVE_BSD_SIGNALS */
#endif /* !HAVE_POSIX_SIGNALS */
rl_reset_after_signal ();
}
RL_UNSETSTATE(RL_STATE_SIGHANDLER);
SIGHANDLER_RETURN;
}
#if defined (SIGWINCH)
static RETSIGTYPE
rl_sigwinch_handler (sig)
int sig;
{
SigHandler *oh;
#if defined (MUST_REINSTALL_SIGHANDLERS)
sighandler_cxt dummy_winch;
/* We don't want to change old_winch -- it holds the state of SIGWINCH
disposition set by the calling application. We need this state
because we call the application's SIGWINCH handler after updating
our own idea of the screen size. */
rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch);
#endif
RL_SETSTATE(RL_STATE_SIGHANDLER);
rl_resize_terminal ();
/* If another sigwinch handler has been installed, call it. */
oh = (SigHandler *)old_winch.sa_handler;
if (oh && oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL)
(*oh) (sig);
RL_UNSETSTATE(RL_STATE_SIGHANDLER);
SIGHANDLER_RETURN;
}
#endif /* SIGWINCH */
/* Functions to manage signal handling. */
#if !defined (HAVE_POSIX_SIGNALS)
static int
rl_sigaction (sig, nh, oh)
int sig;
sighandler_cxt *nh, *oh;
{
oh->sa_handler = signal (sig, nh->sa_handler);
return 0;
}
#endif /* !HAVE_POSIX_SIGNALS */
/* Set up a readline-specific signal handler, saving the old signal
information in OHANDLER. Return the old signal handler, like
signal(). */
static SigHandler *
rl_set_sighandler (sig, handler, ohandler)
int sig;
SigHandler *handler;
sighandler_cxt *ohandler;
{
sighandler_cxt old_handler;
#if defined (HAVE_POSIX_SIGNALS)
struct sigaction act;
act.sa_handler = handler;
# if defined (SIGWINCH)
act.sa_flags = (sig == SIGWINCH) ? SA_RESTART : 0;
# else
act.sa_flags = 0;
# endif /* SIGWINCH */
sigemptyset (&act.sa_mask);
sigemptyset (&ohandler->sa_mask);
sigaction (sig, &act, &old_handler);
#else
old_handler.sa_handler = (SigHandler *)signal (sig, handler);
#endif /* !HAVE_POSIX_SIGNALS */
/* XXX -- assume we have memcpy */
/* If rl_set_signals is called twice in a row, don't set the old handler to
rl_signal_handler, because that would cause infinite recursion. */
if (handler != rl_signal_handler || old_handler.sa_handler != rl_signal_handler)
memcpy (ohandler, &old_handler, sizeof (sighandler_cxt));
return (ohandler->sa_handler);
}
static void
rl_maybe_set_sighandler (sig, handler, ohandler)
int sig;
SigHandler *handler;
sighandler_cxt *ohandler;
{
sighandler_cxt dummy;
SigHandler *oh;
sigemptyset (&dummy.sa_mask);
oh = rl_set_sighandler (sig, handler, ohandler);
if (oh == (SigHandler *)SIG_IGN)
rl_sigaction (sig, ohandler, &dummy);
}
int
rl_set_signals ()
{
sighandler_cxt dummy;
SigHandler *oh;
#if defined (HAVE_POSIX_SIGNALS)
static int sigmask_set = 0;
static sigset_t bset, oset;
#endif
#if defined (HAVE_POSIX_SIGNALS)
if (rl_catch_signals && sigmask_set == 0)
{
sigemptyset (&bset);
sigaddset (&bset, SIGINT);
sigaddset (&bset, SIGTERM);
#if defined (SIGQUIT)
sigaddset (&bset, SIGQUIT);
#endif
#if defined (SIGALRM)
sigaddset (&bset, SIGALRM);
#endif
#if defined (SIGTSTP)
sigaddset (&bset, SIGTSTP);
#endif
#if defined (SIGTTIN)
sigaddset (&bset, SIGTTIN);
#endif
#if defined (SIGTTOU)
sigaddset (&bset, SIGTTOU);
#endif
sigmask_set = 1;
}
#endif /* HAVE_POSIX_SIGNALS */
if (rl_catch_signals && signals_set_flag == 0)
{
#if defined (HAVE_POSIX_SIGNALS)
sigemptyset (&oset);
sigprocmask (SIG_BLOCK, &bset, &oset);
#endif
rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int);
rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
#if defined (SIGQUIT)
rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit);
#endif
#if defined (SIGALRM)
oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm);
if (oh == (SigHandler *)SIG_IGN)
rl_sigaction (SIGALRM, &old_alrm, &dummy);
#if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART)
/* If the application using readline has already installed a signal
handler with SA_RESTART, SIGALRM will cause reads to be restarted
automatically, so readline should just get out of the way. Since
we tested for SIG_IGN above, we can just test for SIG_DFL here. */
if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART))
rl_sigaction (SIGALRM, &old_alrm, &dummy);
#endif /* HAVE_POSIX_SIGNALS */
#endif /* SIGALRM */
#if defined (SIGTSTP)
rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
#endif /* SIGTSTP */
#if defined (SIGTTOU)
rl_maybe_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou);
#endif /* SIGTTOU */
#if defined (SIGTTIN)
rl_maybe_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin);
#endif /* SIGTTIN */
signals_set_flag = 1;
#if defined (HAVE_POSIX_SIGNALS)
sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
#endif
}
#if defined (SIGWINCH)
if (rl_catch_sigwinch && sigwinch_set_flag == 0)
{
rl_maybe_set_sighandler (SIGWINCH, rl_sigwinch_handler, &old_winch);
sigwinch_set_flag = 1;
}
#endif /* SIGWINCH */
return 0;
}
int
rl_clear_signals ()
{
sighandler_cxt dummy;
if (rl_catch_signals && signals_set_flag == 1)
{
sigemptyset (&dummy.sa_mask);
rl_sigaction (SIGINT, &old_int, &dummy);
rl_sigaction (SIGTERM, &old_term, &dummy);
#if defined (SIGQUIT)
rl_sigaction (SIGQUIT, &old_quit, &dummy);
#endif
#if defined (SIGALRM)
rl_sigaction (SIGALRM, &old_alrm, &dummy);
#endif
#if defined (SIGTSTP)
rl_sigaction (SIGTSTP, &old_tstp, &dummy);
#endif /* SIGTSTP */
#if defined (SIGTTOU)
rl_sigaction (SIGTTOU, &old_ttou, &dummy);
#endif /* SIGTTOU */
#if defined (SIGTTIN)
rl_sigaction (SIGTTIN, &old_ttin, &dummy);
#endif /* SIGTTIN */
signals_set_flag = 0;
}
#if defined (SIGWINCH)
if (rl_catch_sigwinch && sigwinch_set_flag == 1)
{
sigemptyset (&dummy.sa_mask);
rl_sigaction (SIGWINCH, &old_winch, &dummy);
sigwinch_set_flag = 0;
}
#endif
return 0;
}
/* Clean up the terminal and readline state after catching a signal, before
resending it to the calling application. */
void
rl_cleanup_after_signal ()
{
_rl_clean_up_for_exit ();
if (rl_deprep_term_function)
(*rl_deprep_term_function) ();
rl_clear_pending_input ();
rl_clear_signals ();
}
/* Reset the terminal and readline state after a signal handler returns. */
void
rl_reset_after_signal ()
{
if (rl_prep_term_function)
(*rl_prep_term_function) (_rl_meta_flag);
rl_set_signals ();
}
/* Free up the readline variable line state for the current line (undo list,
any partial history entry, any keyboard macros in progress, and any
numeric arguments in process) after catching a signal, before calling
rl_cleanup_after_signal(). */
void
rl_free_line_state ()
{
register HIST_ENTRY *entry;
rl_free_undo_list ();
entry = current_history ();
if (entry)
entry->data = (char *)NULL;
_rl_kill_kbd_macro ();
rl_clear_message ();
_rl_reset_argument ();
}
#endif /* HANDLE_SIGNALS */
/* **************************************************************** */
/* */
/* SIGINT Management */
/* */
/* **************************************************************** */
#if defined (HAVE_POSIX_SIGNALS)
static sigset_t sigint_set, sigint_oset;
static sigset_t sigwinch_set, sigwinch_oset;
#else /* !HAVE_POSIX_SIGNALS */
# if defined (HAVE_BSD_SIGNALS)
static int sigint_oldmask;
static int sigwinch_oldmask;
# endif /* HAVE_BSD_SIGNALS */
#endif /* !HAVE_POSIX_SIGNALS */
static int sigint_blocked;
static int sigwinch_blocked;
/* Cause SIGINT to not be delivered until the corresponding call to
release_sigint(). */
void
_rl_block_sigint ()
{
if (sigint_blocked)
return;
#if defined (HAVE_POSIX_SIGNALS)
sigemptyset (&sigint_set);
sigemptyset (&sigint_oset);
sigaddset (&sigint_set, SIGINT);
sigprocmask (SIG_BLOCK, &sigint_set, &sigint_oset);
#else /* !HAVE_POSIX_SIGNALS */
# if defined (HAVE_BSD_SIGNALS)
sigint_oldmask = sigblock (sigmask (SIGINT));
# else /* !HAVE_BSD_SIGNALS */
# if defined (HAVE_USG_SIGHOLD)
sighold (SIGINT);
# endif /* HAVE_USG_SIGHOLD */
# endif /* !HAVE_BSD_SIGNALS */
#endif /* !HAVE_POSIX_SIGNALS */
sigint_blocked = 1;
}
/* Allow SIGINT to be delivered. */
void
_rl_release_sigint ()
{
if (sigint_blocked == 0)
return;
#if defined (HAVE_POSIX_SIGNALS)
sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL);
#else
# if defined (HAVE_BSD_SIGNALS)
sigsetmask (sigint_oldmask);
# else /* !HAVE_BSD_SIGNALS */
# if defined (HAVE_USG_SIGHOLD)
sigrelse (SIGINT);
# endif /* HAVE_USG_SIGHOLD */
# endif /* !HAVE_BSD_SIGNALS */
#endif /* !HAVE_POSIX_SIGNALS */
sigint_blocked = 0;
}
/* Cause SIGWINCH to not be delivered until the corresponding call to
release_sigwinch(). */
void
_rl_block_sigwinch ()
{
if (sigwinch_blocked)
return;
#if defined (HAVE_POSIX_SIGNALS)
sigemptyset (&sigwinch_set);
sigemptyset (&sigwinch_oset);
sigaddset (&sigwinch_set, SIGWINCH);
sigprocmask (SIG_BLOCK, &sigwinch_set, &sigwinch_oset);
#else /* !HAVE_POSIX_SIGNALS */
# if defined (HAVE_BSD_SIGNALS)
sigwinch_oldmask = sigblock (sigmask (SIGWINCH));
# else /* !HAVE_BSD_SIGNALS */
# if defined (HAVE_USG_SIGHOLD)
sighold (SIGWINCH);
# endif /* HAVE_USG_SIGHOLD */
# endif /* !HAVE_BSD_SIGNALS */
#endif /* !HAVE_POSIX_SIGNALS */
sigwinch_blocked = 1;
}
/* Allow SIGWINCH to be delivered. */
void
_rl_release_sigwinch ()
{
if (sigwinch_blocked == 0)
return;
#if defined (HAVE_POSIX_SIGNALS)
sigprocmask (SIG_SETMASK, &sigwinch_oset, (sigset_t *)NULL);
#else
# if defined (HAVE_BSD_SIGNALS)
sigsetmask (sigwinch_oldmask);
# else /* !HAVE_BSD_SIGNALS */
# if defined (HAVE_USG_SIGHOLD)
sigrelse (SIGWINCH);
# endif /* HAVE_USG_SIGHOLD */
# endif /* !HAVE_BSD_SIGNALS */
#endif /* !HAVE_POSIX_SIGNALS */
sigwinch_blocked = 0;
}
/* **************************************************************** */
/* */
/* Echoing special control characters */
/* */
/* **************************************************************** */
void
rl_echo_signal_char (sig)
int sig;
{
char cstr[3];
int cslen, c;
if (_rl_echoctl == 0 || _rl_echo_control_chars == 0)
return;
switch (sig)
{
case SIGINT: c = _rl_intr_char; break;
#if defined (SIGQUIT)
case SIGQUIT: c = _rl_quit_char; break;
#endif
#if defined (SIGTSTP)
case SIGTSTP: c = _rl_susp_char; break;
#endif
default: return;
}
if (CTRL_CHAR (c) || c == RUBOUT)
{
cstr[0] = '^';
cstr[1] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
cstr[cslen = 2] = '\0';
}
else
{
cstr[0] = c;
cstr[cslen = 1] = '\0';
}
_rl_output_some_chars (cstr, cslen);
}
-731
View File
@@ -1,731 +0,0 @@
/* terminal.c -- controlling the terminal with termcap. */
/* Copyright (C) 1996-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Readline is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
#include "posixstat.h"
#include <fcntl.h>
#if defined (HAVE_SYS_FILE_H)
# include <sys/file.h>
#endif /* HAVE_SYS_FILE_H */
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#if defined (HAVE_LOCALE_H)
# include <locale.h>
#endif
#include <stdio.h>
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#if defined (GWINSZ_IN_SYS_IOCTL) && !defined (TIOCGWINSZ)
# include <sys/ioctl.h>
#endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */
#include "rltty.h"
#include "tcap.h"
/* Some standard library routines. */
#include "readline.h"
#include "history.h"
#include "rlprivate.h"
#include "rlshell.h"
#include "xmalloc.h"
#if defined (__MINGW32__)
# include <windows.h>
# include <wincon.h>
static void _win_get_screensize PARAMS((int *, int *));
#endif
#if defined (__EMX__)
static void _emx_get_screensize PARAMS((int *, int *));
#endif
#define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay)
#define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc)
/* If the calling application sets this to a non-zero value, readline will
use the $LINES and $COLUMNS environment variables to set its idea of the
window size before interrogating the kernel. */
int rl_prefer_env_winsize = 0;
/* **************************************************************** */
/* */
/* Terminal and Termcap */
/* */
/* **************************************************************** */
static char *term_buffer = (char *)NULL;
static char *term_string_buffer = (char *)NULL;
static int tcap_initialized;
#if !defined (__linux__)
# if defined (__EMX__) || defined (NEED_EXTERN_PC)
extern
# endif /* __EMX__ || NEED_EXTERN_PC */
char PC, *BC, *UP;
#endif /* __linux__ */
/* Some strings to control terminal actions. These are output by tputs (). */
char *_rl_term_clreol;
char *_rl_term_clrpag;
char *_rl_term_cr;
char *_rl_term_backspace;
char *_rl_term_goto;
char *_rl_term_pc;
/* Non-zero if we determine that the terminal can do character insertion. */
int _rl_terminal_can_insert = 0;
/* How to insert characters. */
char *_rl_term_im;
char *_rl_term_ei;
char *_rl_term_ic;
char *_rl_term_ip;
char *_rl_term_IC;
/* How to delete characters. */
char *_rl_term_dc;
char *_rl_term_DC;
char *_rl_term_forward_char;
/* How to go up a line. */
char *_rl_term_up;
/* A visible bell; char if the terminal can be made to flash the screen. */
static char *_rl_visible_bell;
/* Non-zero means the terminal can auto-wrap lines. */
int _rl_term_autowrap = -1;
/* Non-zero means that this terminal has a meta key. */
static int term_has_meta;
/* The sequences to write to turn on and off the meta key, if this
terminal has one. */
static char *_rl_term_mm;
static char *_rl_term_mo;
/* The key sequences output by the arrow keys, if this terminal has any. */
static char *_rl_term_ku;
static char *_rl_term_kd;
static char *_rl_term_kr;
static char *_rl_term_kl;
/* How to initialize and reset the arrow keys, if this terminal has any. */
static char *_rl_term_ks;
static char *_rl_term_ke;
/* The key sequences sent by the Home and End keys, if any. */
static char *_rl_term_kh;
static char *_rl_term_kH;
static char *_rl_term_at7; /* @7 */
/* Delete key */
static char *_rl_term_kD;
/* Insert key */
static char *_rl_term_kI;
/* Cursor control */
static char *_rl_term_vs; /* very visible */
static char *_rl_term_ve; /* normal */
static void bind_termcap_arrow_keys PARAMS((Keymap));
/* Variables that hold the screen dimensions, used by the display code. */
int _rl_screenwidth, _rl_screenheight, _rl_screenchars;
/* Non-zero means the user wants to enable the keypad. */
int _rl_enable_keypad;
/* Non-zero means the user wants to enable a meta key. */
int _rl_enable_meta = 1;
#if defined (__EMX__)
static void
_emx_get_screensize (swp, shp)
int *swp, *shp;
{
int sz[2];
_scrsize (sz);
if (swp)
*swp = sz[0];
if (shp)
*shp = sz[1];
}
#endif
#if defined (__MINGW32__)
static void
_win_get_screensize (swp, shp)
int *swp, *shp;
{
HANDLE hConOut;
CONSOLE_SCREEN_BUFFER_INFO scr;
hConOut = GetStdHandle (STD_OUTPUT_HANDLE);
if (hConOut != INVALID_HANDLE_VALUE)
{
if (GetConsoleScreenBufferInfo (hConOut, &scr))
{
*swp = scr.dwSize.X;
*shp = scr.srWindow.Bottom - scr.srWindow.Top + 1;
}
}
}
#endif
/* Get readline's idea of the screen size. TTY is a file descriptor open
to the terminal. If IGNORE_ENV is true, we do not pay attention to the
values of $LINES and $COLUMNS. The tests for TERM_STRING_BUFFER being
non-null serve to check whether or not we have initialized termcap. */
void
_rl_get_screen_size (tty, ignore_env)
int tty, ignore_env;
{
char *ss;
#if defined (TIOCGWINSZ)
struct winsize window_size;
#endif /* TIOCGWINSZ */
int wr, wc;
wr = wc = -1;
#if defined (TIOCGWINSZ)
if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
{
wc = (int) window_size.ws_col;
wr = (int) window_size.ws_row;
}
#endif /* TIOCGWINSZ */
#if defined (__EMX__)
_emx_get_screensize (&wc, &wr);
#elif defined (__MINGW32__)
_win_get_screensize (&wc, &wr);
#endif
if (ignore_env || rl_prefer_env_winsize == 0)
{
_rl_screenwidth = wc;
_rl_screenheight = wr;
}
else
_rl_screenwidth = _rl_screenheight = -1;
/* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV
is unset. If we prefer the environment, check it first before
assigning the value returned by the kernel. */
if (_rl_screenwidth <= 0)
{
if (ignore_env == 0 && (ss = sh_get_env_value ("COLUMNS")))
_rl_screenwidth = atoi (ss);
if (_rl_screenwidth <= 0)
_rl_screenwidth = wc;
#if !defined (__DJGPP__)
if (_rl_screenwidth <= 0 && term_string_buffer)
_rl_screenwidth = tgetnum ("co");
#endif
}
/* Environment variable LINES overrides setting of "li" if IGNORE_ENV
is unset. */
if (_rl_screenheight <= 0)
{
if (ignore_env == 0 && (ss = sh_get_env_value ("LINES")))
_rl_screenheight = atoi (ss);
if (_rl_screenheight <= 0)
_rl_screenheight = wr;
#if !defined (__DJGPP__)
if (_rl_screenheight <= 0 && term_string_buffer)
_rl_screenheight = tgetnum ("li");
#endif
}
/* If all else fails, default to 80x24 terminal. */
if (_rl_screenwidth <= 1)
_rl_screenwidth = 80;
if (_rl_screenheight <= 0)
_rl_screenheight = 24;
/* If we're being compiled as part of bash, set the environment
variables $LINES and $COLUMNS to new values. Otherwise, just
do a pair of putenv () or setenv () calls. */
sh_set_lines_and_columns (_rl_screenheight, _rl_screenwidth);
if (_rl_term_autowrap == 0)
_rl_screenwidth--;
_rl_screenchars = _rl_screenwidth * _rl_screenheight;
}
void
_rl_set_screen_size (rows, cols)
int rows, cols;
{
if (_rl_term_autowrap == -1)
_rl_init_terminal_io (rl_terminal_name);
if (rows > 0)
_rl_screenheight = rows;
if (cols > 0)
{
_rl_screenwidth = cols;
if (_rl_term_autowrap == 0)
_rl_screenwidth--;
}
if (rows > 0 || cols > 0)
_rl_screenchars = _rl_screenwidth * _rl_screenheight;
}
void
rl_set_screen_size (rows, cols)
int rows, cols;
{
_rl_set_screen_size (rows, cols);
}
void
rl_get_screen_size (rows, cols)
int *rows, *cols;
{
if (rows)
*rows = _rl_screenheight;
if (cols)
*cols = _rl_screenwidth;
}
void
rl_reset_screen_size ()
{
_rl_get_screen_size (fileno (rl_instream), 0);
}
void
rl_resize_terminal ()
{
_rl_get_screen_size (fileno (rl_instream), 1);
if (_rl_echoing_p)
{
if (CUSTOM_REDISPLAY_FUNC ())
rl_forced_update_display ();
else if (RL_ISSTATE(RL_STATE_REDISPLAYING) == 0)
_rl_redisplay_after_sigwinch ();
}
}
struct _tc_string {
const char * const tc_var;
char **tc_value;
};
/* This should be kept sorted, just in case we decide to change the
search algorithm to something smarter. */
static const struct _tc_string tc_strings[] =
{
{ "@7", &_rl_term_at7 },
{ "DC", &_rl_term_DC },
{ "IC", &_rl_term_IC },
{ "ce", &_rl_term_clreol },
{ "cl", &_rl_term_clrpag },
{ "cr", &_rl_term_cr },
{ "dc", &_rl_term_dc },
{ "ei", &_rl_term_ei },
{ "ic", &_rl_term_ic },
{ "im", &_rl_term_im },
{ "kD", &_rl_term_kD }, /* delete */
{ "kH", &_rl_term_kH }, /* home down ?? */
{ "kI", &_rl_term_kI }, /* insert */
{ "kd", &_rl_term_kd },
{ "ke", &_rl_term_ke }, /* end keypad mode */
{ "kh", &_rl_term_kh }, /* home */
{ "kl", &_rl_term_kl },
{ "kr", &_rl_term_kr },
{ "ks", &_rl_term_ks }, /* start keypad mode */
{ "ku", &_rl_term_ku },
{ "le", &_rl_term_backspace },
{ "mm", &_rl_term_mm },
{ "mo", &_rl_term_mo },
{ "nd", &_rl_term_forward_char },
{ "pc", &_rl_term_pc },
{ "up", &_rl_term_up },
{ "vb", &_rl_visible_bell },
{ "vs", &_rl_term_vs },
{ "ve", &_rl_term_ve },
};
#define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string))
/* Read the desired terminal capability strings into BP. The capabilities
are described in the TC_STRINGS table. */
static void
get_term_capabilities (bp)
char **bp;
{
#if !defined (__DJGPP__) /* XXX - doesn't DJGPP have a termcap library? */
register int i;
for (i = 0; i < NUM_TC_STRINGS; i++)
*(tc_strings[i].tc_value) = tgetstr ((char *)tc_strings[i].tc_var, bp);
#endif
tcap_initialized = 1;
}
int
_rl_init_terminal_io (terminal_name)
const char *terminal_name;
{
const char *term;
char *buffer;
int tty, tgetent_ret;
term = terminal_name ? terminal_name : sh_get_env_value ("TERM");
_rl_term_clrpag = _rl_term_cr = _rl_term_clreol = (char *)NULL;
tty = rl_instream ? fileno (rl_instream) : 0;
if (term == 0)
term = "dumb";
/* I've separated this out for later work on not calling tgetent at all
if the calling application has supplied a custom redisplay function,
(and possibly if the application has supplied a custom input function). */
if (CUSTOM_REDISPLAY_FUNC())
{
tgetent_ret = -1;
}
else
{
if (term_string_buffer == 0)
term_string_buffer = (char *)xmalloc(2032);
if (term_buffer == 0)
term_buffer = (char *)xmalloc(4080);
buffer = term_string_buffer;
tgetent_ret = tgetent (term_buffer, term);
}
if (tgetent_ret <= 0)
{
FREE (term_string_buffer);
FREE (term_buffer);
buffer = term_buffer = term_string_buffer = (char *)NULL;
_rl_term_autowrap = 0; /* used by _rl_get_screen_size */
/* Allow calling application to set default height and width, using
rl_set_screen_size */
if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
{
#if defined (__EMX__)
_emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
_rl_screenwidth--;
#else /* !__EMX__ */
_rl_get_screen_size (tty, 0);
#endif /* !__EMX__ */
}
/* Defaults. */
if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
{
_rl_screenwidth = 79;
_rl_screenheight = 24;
}
/* Everything below here is used by the redisplay code (tputs). */
_rl_screenchars = _rl_screenwidth * _rl_screenheight;
_rl_term_cr = "\r";
_rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL;
_rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL;
_rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL;
_rl_term_kh = _rl_term_kH = _rl_term_kI = _rl_term_kD = (char *)NULL;
_rl_term_ks = _rl_term_ke = _rl_term_at7 = (char *)NULL;
_rl_term_mm = _rl_term_mo = (char *)NULL;
_rl_term_ve = _rl_term_vs = (char *)NULL;
_rl_term_forward_char = (char *)NULL;
_rl_terminal_can_insert = term_has_meta = 0;
/* Reasonable defaults for tgoto(). Readline currently only uses
tgoto if _rl_term_IC or _rl_term_DC is defined, but just in case we
change that later... */
PC = '\0';
BC = _rl_term_backspace = "\b";
UP = _rl_term_up;
return 0;
}
get_term_capabilities (&buffer);
/* Set up the variables that the termcap library expects the application
to provide. */
PC = _rl_term_pc ? *_rl_term_pc : 0;
BC = _rl_term_backspace;
UP = _rl_term_up;
if (!_rl_term_cr)
_rl_term_cr = "\r";
_rl_term_autowrap = tgetflag ("am") && tgetflag ("xn");
/* Allow calling application to set default height and width, using
rl_set_screen_size */
if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
_rl_get_screen_size (tty, 0);
/* "An application program can assume that the terminal can do
character insertion if *any one of* the capabilities `IC',
`im', `ic' or `ip' is provided." But we can't do anything if
only `ip' is provided, so... */
_rl_terminal_can_insert = (_rl_term_IC || _rl_term_im || _rl_term_ic);
/* Check to see if this terminal has a meta key and clear the capability
variables if there is none. */
term_has_meta = tgetflag ("km") != 0;
if (term_has_meta == 0)
_rl_term_mm = _rl_term_mo = (char *)NULL;
/* Attempt to find and bind the arrow keys. Do not override already
bound keys in an overzealous attempt, however. */
bind_termcap_arrow_keys (emacs_standard_keymap);
#if defined (VI_MODE)
bind_termcap_arrow_keys (vi_movement_keymap);
bind_termcap_arrow_keys (vi_insertion_keymap);
#endif /* VI_MODE */
return 0;
}
/* Bind the arrow key sequences from the termcap description in MAP. */
static void
bind_termcap_arrow_keys (map)
Keymap map;
{
Keymap xkeymap;
xkeymap = _rl_keymap;
_rl_keymap = map;
rl_bind_keyseq_if_unbound (_rl_term_ku, rl_get_previous_history);
rl_bind_keyseq_if_unbound (_rl_term_kd, rl_get_next_history);
rl_bind_keyseq_if_unbound (_rl_term_kr, rl_forward_char);
rl_bind_keyseq_if_unbound (_rl_term_kl, rl_backward_char);
rl_bind_keyseq_if_unbound (_rl_term_kh, rl_beg_of_line); /* Home */
rl_bind_keyseq_if_unbound (_rl_term_at7, rl_end_of_line); /* End */
rl_bind_keyseq_if_unbound (_rl_term_kD, rl_delete);
_rl_keymap = xkeymap;
}
char *
rl_get_termcap (cap)
const char *cap;
{
register int i;
if (tcap_initialized == 0)
return ((char *)NULL);
for (i = 0; i < NUM_TC_STRINGS; i++)
{
if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0)
return *(tc_strings[i].tc_value);
}
return ((char *)NULL);
}
/* Re-initialize the terminal considering that the TERM/TERMCAP variable
has changed. */
int
rl_reset_terminal (terminal_name)
const char *terminal_name;
{
_rl_screenwidth = _rl_screenheight = 0;
_rl_init_terminal_io (terminal_name);
return 0;
}
/* A function for the use of tputs () */
#ifdef _MINIX
void
_rl_output_character_function (c)
int c;
{
putc (c, _rl_out_stream);
}
#else /* !_MINIX */
int
_rl_output_character_function (c)
int c;
{
return putc (c, _rl_out_stream);
}
#endif /* !_MINIX */
/* Write COUNT characters from STRING to the output stream. */
void
_rl_output_some_chars (string, count)
const char *string;
int count;
{
fwrite (string, 1, count, _rl_out_stream);
}
/* Move the cursor back. */
int
_rl_backspace (count)
int count;
{
register int i;
if (_rl_term_backspace)
for (i = 0; i < count; i++)
tputs (_rl_term_backspace, 1, _rl_output_character_function);
else
for (i = 0; i < count; i++)
putc ('\b', _rl_out_stream);
return 0;
}
/* Move to the start of the next line. */
int
rl_crlf ()
{
#if defined (NEW_TTY_DRIVER) || defined (__MINT__)
if (_rl_term_cr)
tputs (_rl_term_cr, 1, _rl_output_character_function);
#endif /* NEW_TTY_DRIVER || __MINT__ */
putc ('\n', _rl_out_stream);
return 0;
}
/* Ring the terminal bell. */
int
rl_ding ()
{
if (_rl_echoing_p)
{
switch (_rl_bell_preference)
{
case NO_BELL:
default:
break;
case VISIBLE_BELL:
if (_rl_visible_bell)
{
tputs (_rl_visible_bell, 1, _rl_output_character_function);
break;
}
/* FALLTHROUGH */
case AUDIBLE_BELL:
fprintf (stderr, "\007");
fflush (stderr);
break;
}
return (0);
}
return (-1);
}
/* **************************************************************** */
/* */
/* Controlling the Meta Key and Keypad */
/* */
/* **************************************************************** */
void
_rl_enable_meta_key ()
{
#if !defined (__DJGPP__)
if (term_has_meta && _rl_term_mm)
tputs (_rl_term_mm, 1, _rl_output_character_function);
#endif
}
void
_rl_control_keypad (on)
int on;
{
#if !defined (__DJGPP__)
if (on && _rl_term_ks)
tputs (_rl_term_ks, 1, _rl_output_character_function);
else if (!on && _rl_term_ke)
tputs (_rl_term_ke, 1, _rl_output_character_function);
#endif
}
/* **************************************************************** */
/* */
/* Controlling the Cursor */
/* */
/* **************************************************************** */
/* Set the cursor appropriately depending on IM, which is one of the
insert modes (insert or overwrite). Insert mode gets the normal
cursor. Overwrite mode gets a very visible cursor. Only does
anything if we have both capabilities. */
void
_rl_set_cursor (im, force)
int im, force;
{
if (_rl_term_ve && _rl_term_vs)
{
if (force || im != rl_insert_mode)
{
if (im == RL_IM_OVERWRITE)
tputs (_rl_term_vs, 1, _rl_output_character_function);
else
tputs (_rl_term_ve, 1, _rl_output_character_function);
}
}
}
-1701
View File
File diff suppressed because it is too large Load Diff
-526
View File
@@ -1,526 +0,0 @@
/* util.c -- readline utility functions */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Readline is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
#include <fcntl.h>
#include "posixjmp.h"
#if defined (HAVE_UNISTD_H)
# include <unistd.h> /* for _POSIX_VERSION */
#endif /* HAVE_UNISTD_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include <stdio.h>
#include <ctype.h>
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#include "rlmbutil.h"
#if defined (TIOCSTAT_IN_SYS_IOCTL)
# include <sys/ioctl.h>
#endif /* TIOCSTAT_IN_SYS_IOCTL */
/* Some standard library routines. */
#include "readline.h"
#include "rlprivate.h"
#include "xmalloc.h"
/* **************************************************************** */
/* */
/* Utility Functions */
/* */
/* **************************************************************** */
/* Return 0 if C is not a member of the class of characters that belong
in words, or 1 if it is. */
int _rl_allow_pathname_alphabetic_chars = 0;
static const char * const pathname_alphabetic_chars = "/-_=~.#$";
int
rl_alphabetic (c)
int c;
{
if (ALPHABETIC (c))
return (1);
return (_rl_allow_pathname_alphabetic_chars &&
strchr (pathname_alphabetic_chars, c) != NULL);
}
#if defined (HANDLE_MULTIBYTE)
int
_rl_walphabetic (wchar_t wc)
{
int c;
if (iswalnum (wc))
return (1);
c = wc & 0177;
return (_rl_allow_pathname_alphabetic_chars &&
strchr (pathname_alphabetic_chars, c) != NULL);
}
#endif
/* How to abort things. */
int
_rl_abort_internal ()
{
rl_ding ();
rl_clear_message ();
_rl_reset_argument ();
rl_clear_pending_input ();
RL_UNSETSTATE (RL_STATE_MACRODEF);
while (rl_executing_macro)
_rl_pop_executing_macro ();
rl_last_func = (rl_command_func_t *)NULL;
longjmp (_rl_top_level, 1);
return (0);
}
int
rl_abort (count, key)
int count, key;
{
return (_rl_abort_internal ());
}
int
_rl_null_function (count, key)
int count, key;
{
return 0;
}
int
rl_tty_status (count, key)
int count, key;
{
#if defined (TIOCSTAT)
ioctl (1, TIOCSTAT, (char *)0);
rl_refresh_line (count, key);
#else
rl_ding ();
#endif
return 0;
}
/* Return a copy of the string between FROM and TO.
FROM is inclusive, TO is not. */
char *
rl_copy_text (from, to)
int from, to;
{
register int length;
char *copy;
/* Fix it if the caller is confused. */
if (from > to)
SWAP (from, to);
length = to - from;
copy = (char *)xmalloc (1 + length);
strncpy (copy, rl_line_buffer + from, length);
copy[length] = '\0';
return (copy);
}
/* Increase the size of RL_LINE_BUFFER until it has enough space to hold
LEN characters. */
void
rl_extend_line_buffer (len)
int len;
{
while (len >= rl_line_buffer_len)
{
rl_line_buffer_len += DEFAULT_BUFFER_SIZE;
rl_line_buffer = (char *)xrealloc (rl_line_buffer, rl_line_buffer_len);
}
_rl_set_the_line ();
}
/* A function for simple tilde expansion. */
int
rl_tilde_expand (ignore, key)
int ignore, key;
{
register int start, end;
char *homedir, *temp;
int len;
end = rl_point;
start = end - 1;
if (rl_point == rl_end && rl_line_buffer[rl_point] == '~')
{
homedir = tilde_expand ("~");
_rl_replace_text (homedir, start, end);
xfree (homedir);
return (0);
}
else if (rl_line_buffer[start] != '~')
{
for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--)
;
start++;
}
end = start;
do
end++;
while (whitespace (rl_line_buffer[end]) == 0 && end < rl_end);
if (whitespace (rl_line_buffer[end]) || end >= rl_end)
end--;
/* If the first character of the current word is a tilde, perform
tilde expansion and insert the result. If not a tilde, do
nothing. */
if (rl_line_buffer[start] == '~')
{
len = end - start + 1;
temp = (char *)xmalloc (len + 1);
strncpy (temp, rl_line_buffer + start, len);
temp[len] = '\0';
homedir = tilde_expand (temp);
xfree (temp);
_rl_replace_text (homedir, start, end);
xfree (homedir);
}
return (0);
}
#if defined (USE_VARARGS)
void
#if defined (PREFER_STDARG)
_rl_ttymsg (const char *format, ...)
#else
_rl_ttymsg (va_alist)
va_dcl
#endif
{
va_list args;
#if defined (PREFER_VARARGS)
char *format;
#endif
#if defined (PREFER_STDARG)
va_start (args, format);
#else
va_start (args);
format = va_arg (args, char *);
#endif
fprintf (stderr, "readline: ");
vfprintf (stderr, format, args);
fprintf (stderr, "\n");
fflush (stderr);
va_end (args);
rl_forced_update_display ();
}
void
#if defined (PREFER_STDARG)
_rl_errmsg (const char *format, ...)
#else
_rl_errmsg (va_alist)
va_dcl
#endif
{
va_list args;
#if defined (PREFER_VARARGS)
char *format;
#endif
#if defined (PREFER_STDARG)
va_start (args, format);
#else
va_start (args);
format = va_arg (args, char *);
#endif
fprintf (stderr, "readline: ");
vfprintf (stderr, format, args);
fprintf (stderr, "\n");
fflush (stderr);
va_end (args);
}
#else /* !USE_VARARGS */
void
_rl_ttymsg (format, arg1, arg2)
char *format;
{
fprintf (stderr, "readline: ");
fprintf (stderr, format, arg1, arg2);
fprintf (stderr, "\n");
rl_forced_update_display ();
}
void
_rl_errmsg (format, arg1, arg2)
char *format;
{
fprintf (stderr, "readline: ");
fprintf (stderr, format, arg1, arg2);
fprintf (stderr, "\n");
}
#endif /* !USE_VARARGS */
/* **************************************************************** */
/* */
/* String Utility Functions */
/* */
/* **************************************************************** */
/* Determine if s2 occurs in s1. If so, return a pointer to the
match in s1. The compare is case insensitive. */
char *
_rl_strindex (s1, s2)
register const char *s1, *s2;
{
register int i, l, len;
for (i = 0, l = strlen (s2), len = strlen (s1); (len - i) >= l; i++)
if (_rl_strnicmp (s1 + i, s2, l) == 0)
return ((char *) (s1 + i));
return ((char *)NULL);
}
#ifndef HAVE_STRPBRK
/* Find the first occurrence in STRING1 of any character from STRING2.
Return a pointer to the character in STRING1. */
char *
_rl_strpbrk (string1, string2)
const char *string1, *string2;
{
register const char *scan;
#if defined (HANDLE_MULTIBYTE)
mbstate_t ps;
register int i, v;
memset (&ps, 0, sizeof (mbstate_t));
#endif
for (; *string1; string1++)
{
for (scan = string2; *scan; scan++)
{
if (*string1 == *scan)
return ((char *)string1);
}
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
v = _rl_get_char_len (string1, &ps);
if (v > 1)
string1 += v - 1; /* -1 to account for auto-increment in loop */
}
#endif
}
return ((char *)NULL);
}
#endif
#if !defined (HAVE_STRCASECMP)
/* Compare at most COUNT characters from string1 to string2. Case
doesn't matter (strncasecmp). */
int
_rl_strnicmp (string1, string2, count)
char *string1, *string2;
int count;
{
register char *s1, *s2;
int d;
if (count <= 0 || (string1 == string2))
return 0;
s1 = string1;
s2 = string2;
do
{
d = _rl_to_lower (*s1) - _rl_to_lower (*s2); /* XXX - cast to unsigned char? */
if (d != 0)
return d;
if (*s1++ == '\0')
break;
s2++;
}
while (--count != 0)
return (0);
}
/* strcmp (), but caseless (strcasecmp). */
int
_rl_stricmp (string1, string2)
char *string1, *string2;
{
register char *s1, *s2;
int d;
s1 = string1;
s2 = string2;
if (s1 == s2)
return 0;
while ((d = _rl_to_lower (*s1) - _rl_to_lower (*s2)) == 0)
{
if (*s1++ == '\0')
return 0;
s2++;
}
return (d);
}
#endif /* !HAVE_STRCASECMP */
/* Stupid comparison routine for qsort () ing strings. */
int
_rl_qsort_string_compare (s1, s2)
char **s1, **s2;
{
#if defined (HAVE_STRCOLL)
return (strcoll (*s1, *s2));
#else
int result;
result = **s1 - **s2;
if (result == 0)
result = strcmp (*s1, *s2);
return result;
#endif
}
/* Function equivalents for the macros defined in chardefs.h. */
#define FUNCTION_FOR_MACRO(f) int (f) (c) int c; { return f (c); }
FUNCTION_FOR_MACRO (_rl_digit_p)
FUNCTION_FOR_MACRO (_rl_digit_value)
FUNCTION_FOR_MACRO (_rl_lowercase_p)
FUNCTION_FOR_MACRO (_rl_pure_alphabetic)
FUNCTION_FOR_MACRO (_rl_to_lower)
FUNCTION_FOR_MACRO (_rl_to_upper)
FUNCTION_FOR_MACRO (_rl_uppercase_p)
/* A convenience function, to force memory deallocation to be performed
by readline. DLLs on Windows apparently require this. */
void
rl_free (mem)
void *mem;
{
if (mem)
free (mem);
}
/* Backwards compatibility, now that savestring has been removed from
all `public' readline header files. */
#undef _rl_savestring
char *
_rl_savestring (s)
const char *s;
{
return (strcpy ((char *)xmalloc (1 + (int)strlen (s)), (s)));
}
#if defined (USE_VARARGS)
static FILE *_rl_tracefp;
void
#if defined (PREFER_STDARG)
_rl_trace (const char *format, ...)
#else
_rl_trace (va_alist)
va_dcl
#endif
{
va_list args;
#if defined (PREFER_VARARGS)
char *format;
#endif
#if defined (PREFER_STDARG)
va_start (args, format);
#else
va_start (args);
format = va_arg (args, char *);
#endif
if (_rl_tracefp == 0)
_rl_tropen ();
vfprintf (_rl_tracefp, format, args);
fprintf (_rl_tracefp, "\n");
fflush (_rl_tracefp);
va_end (args);
}
int
_rl_tropen ()
{
char fnbuf[128];
if (_rl_tracefp)
fclose (_rl_tracefp);
sprintf (fnbuf, "/var/tmp/rltrace.%ld", getpid());
unlink(fnbuf);
_rl_tracefp = fopen (fnbuf, "w+");
return _rl_tracefp != 0;
}
int
_rl_trclose ()
{
int r;
r = fclose (_rl_tracefp);
_rl_tracefp = 0;
return r;
}
#endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-89
View File
@@ -1,89 +0,0 @@
/* xmalloc.c -- safe versions of malloc and realloc */
/* Copyright (C) 1991-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Readline is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
#include <config.h>
#endif
#include <stdio.h>
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include "xmalloc.h"
/* **************************************************************** */
/* */
/* Memory Allocation and Deallocation. */
/* */
/* **************************************************************** */
static void
memory_error_and_abort (fname)
char *fname;
{
fprintf (stderr, "%s: out of virtual memory\n", fname);
exit (2);
}
/* Return a pointer to free()able block of memory large enough
to hold BYTES number of bytes. If the memory cannot be allocated,
print an error message and abort. */
PTR_T
xmalloc (bytes)
size_t bytes;
{
PTR_T temp;
temp = malloc (bytes);
if (temp == 0)
memory_error_and_abort ("xmalloc");
return (temp);
}
PTR_T
xrealloc (pointer, bytes)
PTR_T pointer;
size_t bytes;
{
PTR_T temp;
temp = pointer ? realloc (pointer, bytes) : malloc (bytes);
if (temp == 0)
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);
}
-89
View File
@@ -1,89 +0,0 @@
/* xmalloc.c -- safe versions of malloc and realloc */
/* Copyright (C) 1991-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Readline is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
#include <config.h>
#endif
#include <stdio.h>
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include "xmalloc.h"
/* **************************************************************** */
/* */
/* Memory Allocation and Deallocation. */
/* */
/* **************************************************************** */
static void
memory_error_and_abort (fname)
char *fname;
{
fprintf (stderr, "%s: out of virtual memory\n", fname);
exit (2);
}
/* Return a pointer to free()able block of memory large enough
to hold BYTES number of bytes. If the memory cannot be allocated,
print an error message and abort. */
PTR_T
xmalloc (bytes)
size_t bytes;
{
PTR_T temp;
temp = malloc (bytes);
if (temp == 0)
memory_error_and_abort ("xmalloc");
return (temp);
}
PTR_T
xrealloc (pointer, bytes)
PTR_T pointer;
size_t bytes;
{
PTR_T temp;
temp = pointer ? realloc (pointer, bytes) : malloc (bytes);
if (temp == 0)
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);
}
-554
View File
@@ -1,554 +0,0 @@
#
# Makefile for the Bash library
#
#
# 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
# 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/>.
PACKAGE = @PACKAGE_NAME@
VERSION = @PACKAGE_VERSION@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_VERSION = @PACKAGE_VERSION@
srcdir = @srcdir@
VPATH = .:@srcdir@
topdir = @top_srcdir@
BUILD_DIR = @BUILD_DIR@
LIBBUILD = ${BUILD_DIR}/lib
BASHINCDIR = ${topdir}/include
INTL_LIBSRC = ${topdir}/lib/intl
INTL_BUILDDIR = ${LIBBUILD}/intl
INTL_INC = @INTL_INC@
LIBINTL_H = @LIBINTL_H@
datarootdir = @datarootdir@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CC = @CC@
RANLIB = @RANLIB@
AR = @AR@
ARFLAGS = @ARFLAGS@
RM = rm -f
CP = cp
MV = mv
SHELL = @MAKE_SHELL@
CFLAGS = @CFLAGS@
LOCAL_CFLAGS = @LOCAL_CFLAGS@ ${DEBUG}
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@ @LOCAL_LDFLAGS@
PROFILE_FLAGS = @PROFILE_FLAGS@
DEFS = @DEFS@
LOCAL_DEFS = @LOCAL_DEFS@
INCLUDES = -I. -I../.. -I$(topdir) -I$(topdir)/lib -I$(BASHINCDIR) -I$(srcdir) $(INTL_INC)
CCFLAGS = ${PROFILE_FLAGS} ${INCLUDES} $(DEFS) $(LOCAL_DEFS) $(LOCAL_CFLAGS) \
$(CFLAGS) $(CPPFLAGS)
GCC_LINT_FLAGS = -Wall -Wshadow -Wpointer-arith -Wcast-qual \
-Wcast-align -Wstrict-prototypes -Wconversion \
-Wmissing-prototypes -Wtraditional -Wredundant-decls -pedantic
.c.o:
$(CC) -c $(CCFLAGS) $<
# The name of the library target.
LIBRARY_NAME = libsh.a
# The C code source files for this library.
CSOURCES = clktck.c clock.c getcwd.c getenv.c oslib.c setlinebuf.c \
strcasecmp.c strerror.c strtod.c strtol.c strtoul.c \
vprint.c itos.c rename.c zread.c zwrite.c shtty.c \
inet_aton.c netconn.c netopen.c strpbrk.c timeval.c makepath.c \
pathcanon.c pathphys.c tmpfile.c stringlist.c stringvec.c spell.c \
shquote.c strtrans.c strcasestr.c snprintf.c mailstat.c \
fmtulong.c fmtullong.c fmtumax.c shmatch.c strnlen.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 dprintf.c input_avail.c mbscasecmp.c fnxform.c \
strchrnul.c unicode.c wcswidth.c shmbchar.c
# The header files for this library.
HSOURCES =
# The object files contained in $(LIBRARY_NAME)
LIBOBJS = @LIBOBJS@
OBJECTS = clktck.o clock.o getenv.o oslib.o setlinebuf.o strnlen.o \
itos.o zread.o zwrite.o shtty.o shmatch.o eaccess.o \
netconn.o netopen.o timeval.o makepath.o pathcanon.o \
pathphys.o tmpfile.o stringlist.o stringvec.o spell.o shquote.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 \
input_avail.o mbscasecmp.o fnxform.o unicode.o shmbchar.o ${LIBOBJS}
SUPPORT = Makefile
all: $(LIBRARY_NAME)
$(LIBRARY_NAME): $(OBJECTS)
$(RM) $@
$(AR) $(ARFLAGS) $@ $(OBJECTS)
-test -n "$(RANLIB)" && $(RANLIB) $@
force:
# The rule for 'includes' is written funny so that the if statement
# always returns TRUE unless there really was an error installing the
# include files.
install:
clean:
$(RM) $(OBJECTS) $(LIBRARY_NAME)
realclean distclean maintainer-clean: clean
$(RM) Makefile
mostlyclean: clean
# Dependencies
${BUILD_DIR}/version.h: ${BUILD_DIR}/config.h ${BUILD_DIR}/Makefile Makefile
-( cd ${BUILD_DIR} && ${MAKE} ${MFLAGS} version.h )
${BUILD_DIR}/pathnames.h: ${BUILD_DIR}/config.h ${BUILD_DIR}/Makefile Makefile
-( cd ${BUILD_DIR} && ${MAKE} ${MFLAGS} pathnames.h )
# rules for losing makes, like SunOS
casemod.o: casemod.c
clktck.o: clktck.c
clock.o: clock.c
eaccess.o: eaccess.c
dprintf.o: dprintf.c
fmtullong.o: fmtullong.c
fmtulong.o: fmtulong.c
fmtumax.o: fmtumax.c
fnxform.o: fnxform.c
fpurge.o: fpurge.c
getcwd.o: getcwd.c
getenv.o: getenv.c
inet_aton.o: inet_aton.c
input_avail.o: input_avail.c
itos.o: itos.c
mailstat.o: mailstat.c
makepath.o: makepath.c
mbscasecmp.o: mbscasecmp.c
mbscmp.o: mbscmp.c
memset.o: memset.c
mktime.o: mktime.c
netconn.o: netconn.c
netopen.o: netopen.c
oslib.o: oslib.c
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
spell.o: spell.c
strcasecmp.o: strcasecmp.c
strerror.o: strerror.c
strftime.o: strftime.c
strcasestr.o: strcasestr.c
stringlist.o: stringlist.c
stringvec.o: stringvec.c
strnlen.o: strnlen.c
strpbrk.o: strpbrk.c
strtod.o: strtod.c
strtoimax.o: strtoimax.c
strtol.o: strtol.c
strtoll.o: strtoll.c
strtoul.o: strtoul.c
strtoull.o: strtoull.c
strtoumax.o: strtoumax.c
strtrans.o: strtrans.c
times.o: times.c
timeval.o: timeval.c
tmpfile.o: tmpfile.c
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
zgetline.o: zgetline.c
zread.o: zread.c
zwrite.o: zwrite.c
# dependencies for c files that include other c files
fmtullong.o: fmtulong.c
fmtumax.o: fmtulong.c
strtoll.o: strtol.c
strtoul.o: strtol.c
strtoull.o: strtol.c
# all files in the library depend on config.h
casemod.o: ${BUILD_DIR}/config.h
clktck.o: ${BUILD_DIR}/config.h
clock.o: ${BUILD_DIR}/config.h
eaccess.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
fnxform.o: ${BUILD_DIR}/config.h
fpurge.o: ${BUILD_DIR}/config.h
getcwd.o: ${BUILD_DIR}/config.h
getenv.o: ${BUILD_DIR}/config.h
inet_aton.o: ${BUILD_DIR}/config.h
input_avail.o: ${BUILD_DIR}/config.h
itos.o: ${BUILD_DIR}/config.h
mailstat.o: ${BUILD_DIR}/config.h
makepath.o: ${BUILD_DIR}/config.h
mbscasecmp.o: ${BUILD_DIR}/config.h
mbscmp.o: ${BUILD_DIR}/config.h
memset.o: ${BUILD_DIR}/config.h
mktime.o: ${BUILD_DIR}/config.h
netconn.o: ${BUILD_DIR}/config.h
netopen.o: ${BUILD_DIR}/config.h
oslib.o: ${BUILD_DIR}/config.h
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
spell.o: ${BUILD_DIR}/config.h
strcasecmp.o: ${BUILD_DIR}/config.h
strerror.o: ${BUILD_DIR}/config.h
strftime.o: ${BUILD_DIR}/config.h
strcasestr.o: ${BUILD_DIR}/config.h
stringlist.o: ${BUILD_DIR}/config.h
stringvec.o: ${BUILD_DIR}/config.h
strnlen.o: ${BUILD_DIR}/config.h
strpbrk.o: ${BUILD_DIR}/config.h
strtod.o: ${BUILD_DIR}/config.h
strtoimax.o: ${BUILD_DIR}/config.h
strtol.o: ${BUILD_DIR}/config.h
strtoll.o: ${BUILD_DIR}/config.h
strtoul.o: ${BUILD_DIR}/config.h
strtoull.o: ${BUILD_DIR}/config.h
strtoumax.o: ${BUILD_DIR}/config.h
strtrans.o: ${BUILD_DIR}/config.h
times.o: ${BUILD_DIR}/config.h
timeval.o: ${BUILD_DIR}/config.h
tmpfile.o: ${BUILD_DIR}/config.h
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
zmapfd.o: ${BUILD_DIR}/config.h
zread.o: ${BUILD_DIR}/config.h
zwrite.o: ${BUILD_DIR}/config.h
clktck.o: ${topdir}/bashtypes.h
getcwd.o: ${topdir}/bashtypes.h ${topdir}/bashansi.h ${BASHINCDIR}/maxpath.h
getcwd.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/posixdir.h
getcwd.o: ${BASHINCDIR}/memalloc.h ${BASHINCDIR}/ansi_stdlib.h
getenv.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
getenv.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h
getenv.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h
getenv.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h
getenv.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h
getenv.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h
getenv.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h
getenv.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h
getenv.o: ${BUILD_DIR}/version.h
inet_aton.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
inet_aton.o: ${BASHINCDIR}/stdc.h
itos.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
itos.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h
itos.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h
itos.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h
itos.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h
itos.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h
itos.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h
itos.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h
makepath.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
makepath.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h
makepath.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h
makepath.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h
makepath.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h
makepath.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h
makepath.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h
makepath.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h
netconn.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h
netconn.o: ${topdir}/bashtypes.h
netopen.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h ${topdir}/xmalloc.h
netopen.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h
netopen.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h
netopen.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h
netopen.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h
netopen.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h
netopen.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h
netopen.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h
netopen.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
oslib.o: ${topdir}/bashtypes.h ${topdir}/bashansi.h ${BASHINCDIR}/maxpath.h
oslib.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h
oslib.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h
oslib.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h
oslib.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h
oslib.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h
oslib.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h
oslib.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h
oslib.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h
oslib.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
pathcanon.o: ${topdir}/bashtypes.h ${topdir}/bashansi.h ${BASHINCDIR}/maxpath.h
pathcanon.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h
pathcanon.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h
pathcanon.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h
pathcanon.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h
pathcanon.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h
pathcanon.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h
pathcanon.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h
pathcanon.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h
pathcanon.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
pathphys.o: ${topdir}/bashtypes.h ${topdir}/bashansi.h ${BASHINCDIR}/maxpath.h
pathphys.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h
pathphys.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h
pathphys.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h
pathphys.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h
pathphys.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h
pathphys.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h
pathphys.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h
pathphys.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h
pathphys.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
rename.o: ${topdir}/bashtypes.h ${BASHINCDIR}/stdc.h
rename.o: ${BASHINCDIR}/posixstat.h
setlinebuf.o: ${topdir}/xmalloc.h ${topdir}/bashansi.h
setlinebuf.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/stdc.h
eaccess.o: ${topdir}/bashtypes.h
eaccess.o: ${BASHINCDIR}/posixstat.h
eaccess.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
eaccess.o: ${BASHINCDIR}/filecntl.h
eaccess.o: ${BASHINCDIR}/stdc.h
eaccess.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h
eaccess.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h
eaccess.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h
eaccess.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h
eaccess.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h
eaccess.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h
eaccess.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h
shquote.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h
shquote.o: ${BASHINCDIR}/ansi_stdlib.h ${topdir}/xmalloc.h
shtty.o: ${BASHINCDIR}/shtty.h
shtty.o: ${BASHINCDIR}/stdc.h
snprintf.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h ${topdir}/xmalloc.h
snprintf.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
snprintf.o: ${BASHINCDIR}/typemax.h
spell.o: ${topdir}/bashtypes.h
spell.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/posixdir.h
spell.o: ${BASHINCDIR}/ansi_stdlib.h
strcasecmp.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h
strcasecmp.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
strerror.o: ${topdir}/bashtypes.h
strerror.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h
strerror.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h
strerror.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h
strerror.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h
strerror.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h
strerror.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h
strerror.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h
strcasestr.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h
strcasestr.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
stringlist.o: ${topdir}/bashansi.h
stringlist.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h
stringlist.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h
stringlist.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h
stringlist.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h
stringlist.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h
stringlist.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h
stringlist.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h
stringvec.o: ${topdir}/bashansi.h ${BASHINCDIR}/chartypes.h
stringvec.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h
stringvec.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h
stringvec.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h
stringvec.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h
stringvec.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h
stringvec.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h
stringvec.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h
strnlen.o: ${BASHINCDIR}/stdc.h
strpbrk.o: ${BASHINCDIR}/stdc.h
strtod.o: ${topdir}/bashansi.h
strtod.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
strtoimax.o: ${BASHINCDIR}/stdc.h
strtol.o: ${topdir}/bashansi.h
strtol.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
strtol.o: ${BASHINCDIR}/typemax.h
strtoll.o: ${topdir}/bashansi.h
strtoll.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
strtoll.o: ${BASHINCDIR}/typemax.h
strtoul.o: ${topdir}/bashansi.h
strtoul.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
strtoul.o: ${BASHINCDIR}/typemax.h
strtoull.o: ${topdir}/bashansi.h
strtoull.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
strtoull.o: ${BASHINCDIR}/typemax.h
strtoumax.o: ${BASHINCDIR}/stdc.h
strtrans.o: ${topdir}/bashansi.h
strtrans.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
strtrans.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h
strtrans.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h
strtrans.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h
strtrans.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h
strtrans.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h
strtrans.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h
strtrans.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h
times.o: ${BASHINCDIR}/systimes.h
times.o: ${BASHINCDIR}/posixtime.h
timeval.o: ${BASHINCDIR}/posixtime.h
tmpfile.o: ${topdir}/bashtypes.h
tmpfile.o: ${BASHINCDIR}/posixstat.h
tmpfile.o: ${BASHINCDIR}/filecntl.h
uconvert.o: ${topdir}/bashtypes.h
ufuncs.o: ${topdir}/bashtypes.h
clock.o: ${BASHINCDIR}/posixtime.h
mailstat.o: ${topdir}/bashansi.h
mailstat.o: ${topdir}/bashtypes.h
mailstat.o: ${BASHINCDIR}/ansi_stdlib.h
mailstat.o: ${BASHINCDIR}/posixstat.h
mailstat.o: ${BASHINCDIR}/posixdir.h
mailstat.o: ${BASHINCDIR}/maxpath.h
fmtulong.o: ${topdir}/bashansi.h
fmtulong.o: ${BASHINCDIR}/ansi_stdlib.h
fmtulong.o: ${BASHINCDIR}/chartypes.h
fmtulong.o: ${BASHINCDIR}/stdc.h
fmtulong.o: ${BASHINCDIR}/typemax.h
fmtulong.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h
fmtullong.o: ${topdir}/bashansi.h
fmtullong.o: ${BASHINCDIR}/ansi_stdlib.h
fmtullong.o: ${BASHINCDIR}/chartypes.h
fmtullong.o: ${BASHINCDIR}/stdc.h
fmtullong.o: ${BASHINCDIR}/typemax.h
fmtullong.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h
fmtumax.o: ${topdir}/bashansi.h
fmtumax.o: ${BASHINCDIR}/ansi_stdlib.h
fmtumax.o: ${BASHINCDIR}/chartypes.h
fmtumax.o: ${BASHINCDIR}/stdc.h
fmtumax.o: ${BASHINCDIR}/typemax.h
fmtumax.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h
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 ${BASHINCDIR}/shmchar.h
zgetline.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
zgetline.o: ${BASHINCDIR}/stdc.h
zgetline.o: ${topdir}/xmalloc.h
zgetline.o: ${topdir}/bashtypes.h
mbscasecmp.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
mbscasecmp.o: ${BASHINCDIR}/stdc.h
mbscasecmp.o: ${topdir}/xmalloc.h
mbscmp.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
mbscmp.o: ${BASHINCDIR}/stdc.h
mbscmp.o: ${topdir}/xmalloc.h
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 ${BASHINCDIR}/shmchar.h
casemod.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h
dprintf.o: ${BASHINCDIR}/stdc.h
input_avail.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
input_avail.o: ${BASHINCDIR}/stdc.h
input_avail.o: ${topdir}/xmalloc.h ${BASHINCDIR}/posixselect.h
mktime.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
mktime.o: ${BASHINCDIR}/stdc.h
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
-256
View File
@@ -1,256 +0,0 @@
/* casemod.c -- functions to change case of strings */
/* Copyright (C) 2008,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/>.
*/
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#include <stdc.h>
#include <bashansi.h>
#include <bashintl.h>
#include <bashtypes.h>
#include <stdio.h>
#include <ctype.h>
#include <xmalloc.h>
#include <shmbutil.h>
#include <chartypes.h>
#include <glob/strmatch.h>
#define _to_wupper(wc) (iswlower (wc) ? towupper (wc) : (wc))
#define _to_wlower(wc) (iswupper (wc) ? towlower (wc) : (wc))
#if !defined (HANDLE_MULTIBYTE)
# define cval(s, i) ((s)[(i)])
# define iswalnum(c) (isalnum(c))
# define TOGGLE(x) (ISUPPER (x) ? tolower (x) : (TOUPPER (x)))
#else
# define TOGGLE(x) (iswupper (x) ? towlower (x) : (_to_wupper(x)))
#endif
/* These must agree with the defines in externs.h */
#define CASE_NOOP 0x0000
#define CASE_LOWER 0x0001
#define CASE_UPPER 0x0002
#define CASE_CAPITALIZE 0x0004
#define CASE_UNCAP 0x0008
#define CASE_TOGGLE 0x0010
#define CASE_TOGGLEALL 0x0020
#define CASE_UPFIRST 0x0040
#define CASE_LOWFIRST 0x0080
#define CASE_USEWORDS 0x1000 /* modify behavior to act on words in passed string */
extern char *substring __P((char *, int, int));
#if defined (HANDLE_MULTIBYTE)
static wchar_t
cval (s, i)
char *s;
int i;
{
size_t tmp;
wchar_t wc;
int l;
mbstate_t mps;
if (MB_CUR_MAX == 1)
return ((wchar_t)s[i]);
l = strlen (s);
if (i >= (l - 1))
return ((wchar_t)s[i]);
memset (&mps, 0, sizeof (mbstate_t));
tmp = mbrtowc (&wc, s + i, l - i, &mps);
if (MB_INVALIDCH (tmp) || MB_NULLWCH (tmp))
return ((wchar_t)s[i]);
return wc;
}
#endif
/* Modify the case of characters in STRING matching PAT based on the value of
FLAGS. If PAT is null, modify the case of each character */
char *
sh_modcase (string, pat, flags)
const char *string;
char *pat;
int flags;
{
int start, next, end;
int inword, c, nc, nop, match, usewords;
char *ret, *s;
wchar_t wc;
#if defined (HANDLE_MULTIBYTE)
wchar_t nwc;
char mb[MB_LEN_MAX+1];
int mlen;
size_t m;
mbstate_t state;
#endif
if (string == 0 || *string == 0)
{
#if 0
ret = (char *)xmalloc (1);
ret[0] = '\0';
return ret;
#else
extern char *savestring();
return (char *)savestring ("");
#endif
}
#if defined (HANDLE_MULTIBYTE)
memset (&state, 0, sizeof (mbstate_t));
#endif
start = 0;
end = strlen (string);
ret = (char *)xmalloc (end + 1);
strcpy (ret, string);
/* See if we are supposed to split on alphanumerics and operate on each word */
usewords = (flags & CASE_USEWORDS);
flags &= ~CASE_USEWORDS;
inword = 0;
while (start < end)
{
wc = cval (ret, start);
if (iswalnum (wc) == 0)
{
inword = 0;
ADVANCE_CHAR (ret, end, start);
continue;
}
if (pat)
{
next = start;
ADVANCE_CHAR (ret, end, next);
s = substring (ret, start, next);
match = strmatch (pat, s, FNM_EXTMATCH) != FNM_NOMATCH;
free (s);
if (match == 0)
{
start = next;
inword = 1;
continue;
}
}
/* XXX - for now, the toggling operators work on the individual
words in the string, breaking on alphanumerics. Should I
leave the capitalization operators to do that also? */
if (flags == CASE_CAPITALIZE)
{
if (usewords)
nop = inword ? CASE_LOWER : CASE_UPPER;
else
nop = (start > 0) ? CASE_LOWER : CASE_UPPER;
inword = 1;
}
else if (flags == CASE_UNCAP)
{
if (usewords)
nop = inword ? CASE_UPPER : CASE_LOWER;
else
nop = (start > 0) ? CASE_UPPER : CASE_LOWER;
inword = 1;
}
else if (flags == CASE_UPFIRST)
{
if (usewords)
nop = inword ? CASE_NOOP : CASE_UPPER;
else
nop = (start > 0) ? CASE_NOOP : CASE_UPPER;
inword = 1;
}
else if (flags == CASE_LOWFIRST)
{
if (usewords)
nop = inword ? CASE_NOOP : CASE_LOWER;
else
nop = (start > 0) ? CASE_NOOP : CASE_LOWER;
inword = 1;
}
else if (flags == CASE_TOGGLE)
{
nop = inword ? CASE_NOOP : CASE_TOGGLE;
inword = 1;
}
else
nop = flags;
if (MB_CUR_MAX == 1 || isascii (wc))
{
switch (nop)
{
default:
case CASE_NOOP: nc = wc; break;
case CASE_UPPER: nc = TOUPPER (wc); break;
case CASE_LOWER: nc = TOLOWER (wc); break;
case CASE_TOGGLEALL:
case CASE_TOGGLE: nc = TOGGLE (wc); break;
}
ret[start] = nc;
}
#if defined (HANDLE_MULTIBYTE)
else
{
m = mbrtowc (&wc, string + start, end - start, &state);
if (MB_INVALIDCH (m))
wc = (wchar_t)string[start];
else if (MB_NULLWCH (m))
wc = L'\0';
switch (nop)
{
default:
case CASE_NOOP: nwc = wc; break;
case CASE_UPPER: nwc = TOUPPER (wc); break;
case CASE_LOWER: nwc = TOLOWER (wc); break;
case CASE_TOGGLEALL:
case CASE_TOGGLE: nwc = TOGGLE (wc); break;
}
if (nwc != wc) /* just skip unchanged characters */
{
mlen = wcrtomb (mb, nwc, &state);
if (mlen > 0)
mb[mlen] = '\0';
/* Assume the same width */
strncpy (ret + start, mb, mlen);
}
}
#endif
/* This assumes that the upper and lower case versions are the same width. */
ADVANCE_CHAR (ret, end, start);
}
return ret;
}
-70
View File
@@ -1,70 +0,0 @@
/* dprintf -- printf to a file descriptor */
/* Copyright (C) 2008,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/>.
*/
#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;
}
-235
View File
@@ -1,235 +0,0 @@
/* eaccess.c - eaccess replacement for the shell, plus other access functions. */
/* Copyright (C) 2006-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/>.
*/
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h>
#include "bashtypes.h"
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "bashansi.h"
#include <errno.h>
#if !defined (errno)
extern int errno;
#endif /* !errno */
#if !defined (_POSIX_VERSION) && defined (HAVE_SYS_FILE_H)
# include <sys/file.h>
#endif /* !_POSIX_VERSION */
#include "posixstat.h"
#include "filecntl.h"
#include "shell.h"
#if !defined (R_OK)
#define R_OK 4
#define W_OK 2
#define X_OK 1
#define F_OK 0
#endif /* R_OK */
static int path_is_devfd __P((const char *));
static int sh_stataccess __P((char *, int));
#if HAVE_DECL_SETREGID
static int sh_euidaccess __P((char *, int));
#endif
static int
path_is_devfd (path)
const char *path;
{
if (path[0] == '/' && path[1] == 'd' && strncmp (path, "/dev/fd/", 8) == 0)
return 1;
else if (STREQN (path, "/dev/std", 8))
{
if (STREQ (path+8, "in") || STREQ (path+8, "out") || STREQ (path+8, "err"))
return 1;
else
return 0;
}
else
return 0;
}
/* A wrapper for stat () which disallows pathnames that are empty strings
and handles /dev/fd emulation on systems that don't have it. */
int
sh_stat (path, finfo)
const char *path;
struct stat *finfo;
{
if (*path == '\0')
{
errno = ENOENT;
return (-1);
}
if (path[0] == '/' && path[1] == 'd' && strncmp (path, "/dev/fd/", 8) == 0)
{
#if !defined (HAVE_DEV_FD)
intmax_t fd;
int r;
if (legal_number (path + 8, &fd) && fd == (int)fd)
{
r = fstat ((int)fd, finfo);
if (r == 0 || errno != EBADF)
return (r);
}
errno = ENOENT;
return (-1);
#else
/* If HAVE_DEV_FD is defined, DEV_FD_PREFIX is defined also, and has a
trailing slash. Make sure /dev/fd/xx really uses DEV_FD_PREFIX/xx.
On most systems, with the notable exception of linux, this is
effectively a no-op. */
char pbuf[32];
strcpy (pbuf, DEV_FD_PREFIX);
strcat (pbuf, path + 8);
return (stat (pbuf, finfo));
#endif /* !HAVE_DEV_FD */
}
#if !defined (HAVE_DEV_STDIN)
else if (STREQN (path, "/dev/std", 8))
{
if (STREQ (path+8, "in"))
return (fstat (0, finfo));
else if (STREQ (path+8, "out"))
return (fstat (1, finfo));
else if (STREQ (path+8, "err"))
return (fstat (2, finfo));
else
return (stat (path, finfo));
}
#endif /* !HAVE_DEV_STDIN */
return (stat (path, finfo));
}
/* Do the same thing access(2) does, but use the effective uid and gid,
and don't make the mistake of telling root that any file is
executable. This version uses stat(2). */
static int
sh_stataccess (path, mode)
char *path;
int mode;
{
struct stat st;
if (sh_stat (path, &st) < 0)
return (-1);
if (current_user.euid == 0)
{
/* Root can read or write any file. */
if ((mode & X_OK) == 0)
return (0);
/* Root can execute any file that has any one of the execute
bits set. */
if (st.st_mode & S_IXUGO)
return (0);
}
if (st.st_uid == current_user.euid) /* owner */
mode <<= 6;
else if (group_member (st.st_gid))
mode <<= 3;
if (st.st_mode & mode)
return (0);
errno = EACCES;
return (-1);
}
#if HAVE_DECL_SETREGID
/* Version to call when uid != euid or gid != egid. We temporarily swap
the effective and real uid and gid as appropriate. */
static int
sh_euidaccess (path, mode)
char *path;
int mode;
{
int r, e;
if (current_user.uid != current_user.euid)
setreuid (current_user.euid, current_user.uid);
if (current_user.gid != current_user.egid)
setregid (current_user.egid, current_user.gid);
r = access (path, mode);
e = errno;
if (current_user.uid != current_user.euid)
setreuid (current_user.uid, current_user.euid);
if (current_user.gid != current_user.egid)
setregid (current_user.gid, current_user.egid);
errno = e;
return r;
}
#endif
int
sh_eaccess (path, mode)
char *path;
int mode;
{
int ret;
if (path_is_devfd (path))
return (sh_stataccess (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
if (mode == F_OK)
return (sh_stataccess (path, mode));
# if HAVE_DECL_SETREGID
if (current_user.uid != current_user.euid || current_user.gid != current_user.egid)
return (sh_euidaccess (path, mode));
# endif
if (current_user.uid == current_user.euid && current_user.gid == current_user.egid)
{
ret = access (path, mode);
if (ret == 0 && current_user.euid == 0 && mode == X_OK)
return (sh_stataccess (path, mode));
}
return (sh_stataccess (path, mode));
#endif
}
-199
View File
@@ -1,199 +0,0 @@
/* fnxform - use iconv(3) to transform strings to and from "filename" format */
/* 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_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
-301
View File
@@ -1,301 +0,0 @@
/* oslib.c - functions present only in some unix versions. */
/* Copyright (C) 1995 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>
#ifndef _MINIX
# include <sys/param.h>
#endif
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#if defined (HAVE_LIMITS_H)
# include <limits.h>
#endif
#include <posixstat.h>
#include <filecntl.h>
#include <bashansi.h>
#if !defined (HAVE_KILLPG)
# include <signal.h>
#endif
#include <stdio.h>
#include <errno.h>
#include <chartypes.h>
#include <shell.h>
#if !defined (errno)
extern int errno;
#endif /* !errno */
/* Make the functions strchr and strrchr if they do not exist. */
#if !defined (HAVE_STRCHR)
char *
strchr (string, c)
char *string;
int c;
{
register char *s;
for (s = string; s && *s; s++)
if (*s == c)
return (s);
return ((char *) NULL);
}
char *
strrchr (string, c)
char *string;
int c;
{
register char *s, *t;
for (s = string, t = (char *)NULL; s && *s; s++)
if (*s == c)
t = s;
return (t);
}
#endif /* !HAVE_STRCHR */
#if !defined (HAVE_DUP2) || defined (DUP2_BROKEN)
/* Replacement for dup2 (), for those systems which either don't have it,
or supply one with broken behaviour. */
int
dup2 (fd1, fd2)
int fd1, fd2;
{
int saved_errno, r;
/* If FD1 is not a valid file descriptor, then return immediately with
an error. */
if (fcntl (fd1, F_GETFL, 0) == -1)
return (-1);
if (fd2 < 0 || fd2 >= getdtablesize ())
{
errno = EBADF;
return (-1);
}
if (fd1 == fd2)
return (0);
saved_errno = errno;
(void) close (fd2);
r = fcntl (fd1, F_DUPFD, fd2);
if (r >= 0)
errno = saved_errno;
else
if (errno == EINVAL)
errno = EBADF;
/* Force the new file descriptor to remain open across exec () calls. */
SET_OPEN_ON_EXEC (fd2);
return (r);
}
#endif /* !HAVE_DUP2 */
/*
* Return the total number of available file descriptors.
*
* On some systems, like 4.2BSD and its descendents, there is a system call
* that returns the size of the descriptor table: getdtablesize(). There are
* lots of ways to emulate this on non-BSD systems.
*
* On System V.3, this can be obtained via a call to ulimit:
* return (ulimit(4, 0L));
*
* On other System V systems, NOFILE is defined in /usr/include/sys/param.h
* (this is what we assume below), so we can simply use it:
* return (NOFILE);
*
* On POSIX systems, there are specific functions for retrieving various
* configuration parameters:
* return (sysconf(_SC_OPEN_MAX));
*
*/
#if !defined (HAVE_GETDTABLESIZE)
int
getdtablesize ()
{
# if defined (_POSIX_VERSION) && defined (HAVE_SYSCONF) && defined (_SC_OPEN_MAX)
return (sysconf(_SC_OPEN_MAX)); /* Posix systems use sysconf */
# else /* ! (_POSIX_VERSION && HAVE_SYSCONF && _SC_OPEN_MAX) */
# if defined (ULIMIT_MAXFDS)
return (ulimit (4, 0L)); /* System V.3 systems use ulimit(4, 0L) */
# else /* !ULIMIT_MAXFDS */
# if defined (NOFILE) /* Other systems use NOFILE */
return (NOFILE);
# else /* !NOFILE */
return (20); /* XXX - traditional value is 20 */
# endif /* !NOFILE */
# endif /* !ULIMIT_MAXFDS */
# endif /* ! (_POSIX_VERSION && _SC_OPEN_MAX) */
}
#endif /* !HAVE_GETDTABLESIZE */
#if !defined (HAVE_BCOPY)
# if defined (bcopy)
# undef bcopy
# endif
void
bcopy (s,d,n)
char *d, *s;
int n;
{
FASTCOPY (s, d, n);
}
#endif /* !HAVE_BCOPY */
#if !defined (HAVE_BZERO)
# if defined (bzero)
# undef bzero
# endif
void
bzero (s, n)
char *s;
int n;
{
register int i;
register char *r;
for (i = 0, r = s; i < n; i++)
*r++ = '\0';
}
#endif
#if !defined (HAVE_GETHOSTNAME)
# if defined (HAVE_UNAME)
# include <sys/utsname.h>
int
gethostname (name, namelen)
char *name;
int namelen;
{
int i;
struct utsname ut;
--namelen;
uname (&ut);
i = strlen (ut.nodename) + 1;
strncpy (name, ut.nodename, i < namelen ? i : namelen);
name[namelen] = '\0';
return (0);
}
# else /* !HAVE_UNAME */
int
gethostname (name, namelen)
char *name;
int namelen;
{
strncpy (name, "unknown", namelen);
name[namelen] = '\0';
return 0;
}
# endif /* !HAVE_UNAME */
#endif /* !HAVE_GETHOSTNAME */
#if !defined (HAVE_KILLPG)
int
killpg (pgrp, sig)
pid_t pgrp;
int sig;
{
return (kill (-pgrp, sig));
}
#endif /* !HAVE_KILLPG */
#if !defined (HAVE_MKFIFO) && defined (PROCESS_SUBSTITUTION)
int
mkfifo (path, mode)
char *path;
int mode;
{
#if defined (S_IFIFO)
return (mknod (path, (mode | S_IFIFO), 0));
#else /* !S_IFIFO */
return (-1);
#endif /* !S_IFIFO */
}
#endif /* !HAVE_MKFIFO && PROCESS_SUBSTITUTION */
#define DEFAULT_MAXGROUPS 64
int
getmaxgroups ()
{
static int maxgroups = -1;
if (maxgroups > 0)
return maxgroups;
#if defined (HAVE_SYSCONF) && defined (_SC_NGROUPS_MAX)
maxgroups = sysconf (_SC_NGROUPS_MAX);
#else
# if defined (NGROUPS_MAX)
maxgroups = NGROUPS_MAX;
# else /* !NGROUPS_MAX */
# if defined (NGROUPS)
maxgroups = NGROUPS;
# else /* !NGROUPS */
maxgroups = DEFAULT_MAXGROUPS;
# endif /* !NGROUPS */
# endif /* !NGROUPS_MAX */
#endif /* !HAVE_SYSCONF || !SC_NGROUPS_MAX */
if (maxgroups <= 0)
maxgroups = DEFAULT_MAXGROUPS;
return maxgroups;
}
long
getmaxchild ()
{
static long maxchild = -1L;
if (maxchild > 0)
return maxchild;
#if defined (HAVE_SYSCONF) && defined (_SC_CHILD_MAX)
maxchild = sysconf (_SC_CHILD_MAX);
#else
# if defined (CHILD_MAX)
maxchild = CHILD_MAX;
# else
# if defined (MAXUPRC)
maxchild = MAXUPRC;
# endif /* MAXUPRC */
# endif /* CHILD_MAX */
#endif /* !HAVE_SYSCONF || !_SC_CHILD_MAX */
return (maxchild);
}
-120
View File
@@ -1,120 +0,0 @@
/*
* shmatch.c -- shell interface to posix regular expression matching.
*/
/* Copyright (C) 2003 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
#if defined (HAVE_POSIX_REGEXP)
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include "bashansi.h"
#include <stdio.h>
#include <regex.h>
#include "shell.h"
#include "variables.h"
#include "externs.h"
extern int glob_ignore_case, match_ignore_case;
int
sh_regmatch (string, pattern, flags)
const char *string;
const char *pattern;
int flags;
{
regex_t regex = { 0 };
regmatch_t *matches;
int rflags;
#if defined (ARRAY_VARS)
SHELL_VAR *rematch;
ARRAY *amatch;
int subexp_ind;
char *subexp_str;
int subexp_len;
#endif
int result;
#if defined (ARRAY_VARS)
rematch = (SHELL_VAR *)NULL;
#endif
rflags = REG_EXTENDED;
if (glob_ignore_case || match_ignore_case)
rflags |= REG_ICASE;
#if !defined (ARRAY_VARS)
rflags |= REG_NOSUB;
#endif
if (regcomp (&regex, pattern, rflags))
return 2; /* flag for printing a warning here. */
#if defined (ARRAY_VARS)
matches = (regmatch_t *)malloc (sizeof (regmatch_t) * (regex.re_nsub + 1));
#else
matches = NULL;
#endif
if (regexec (&regex, string, regex.re_nsub + 1, matches, 0))
result = EXECUTION_FAILURE;
else
result = EXECUTION_SUCCESS; /* match */
#if defined (ARRAY_VARS)
subexp_len = strlen (string) + 10;
subexp_str = malloc (subexp_len + 1);
/* Store the parenthesized subexpressions in the array BASH_REMATCH.
Element 0 is the portion that matched the entire regexp. Element 1
is the part that matched the first subexpression, and so on. */
unbind_variable ("BASH_REMATCH");
rematch = make_new_array_variable ("BASH_REMATCH");
amatch = array_cell (rematch);
if ((flags & SHMAT_SUBEXP) && result == EXECUTION_SUCCESS && subexp_str)
{
for (subexp_ind = 0; subexp_ind <= regex.re_nsub; subexp_ind++)
{
memset (subexp_str, 0, subexp_len);
strncpy (subexp_str, string + matches[subexp_ind].rm_so,
matches[subexp_ind].rm_eo - matches[subexp_ind].rm_so);
array_insert (amatch, subexp_ind, subexp_str);
}
}
VSETATTR (rematch, att_readonly);
free (subexp_str);
free (matches);
#endif /* ARRAY_VARS */
regfree (&regex);
return result;
}
#endif /* HAVE_POSIX_REGEXP */
-64
View File
@@ -1,64 +0,0 @@
/* 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 };
nc = 0;
while (*s && (clen = is_basic (*s) ? 1 : mbrlen(s, MB_CUR_MAX, &mbs)) != 0)
{
if (MB_INVALIDCH(clen))
{
clen = 1; /* assume single byte */
mbs = mbsbak;
}
if (is_basic (*s) == 0)
mbsbak = mbs;
s += clen;
nc++;
}
return nc;
}
#endif
-91
View File
@@ -1,91 +0,0 @@
/* 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 };
nc = 0;
while (*s && (clen = is_basic (*s) ? 1 : mbrlen(s, MB_CUR_MAX, &mbs)) != 0)
{
if (MB_INVALIDCH(clen))
{
clen = 1; /* assume single byte */
mbs = mbsbak;
}
if (is_basic (*s) == 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
-278
View File
@@ -1,278 +0,0 @@
/* shquote - functions to quote and dequote strings */
/* Copyright (C) 1999 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)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#include <stdio.h>
#include "syntax.h"
#include <xmalloc.h>
/* **************************************************************** */
/* */
/* Functions for quoting strings to be re-read as input */
/* */
/* **************************************************************** */
/* Return a new string which is the single-quoted version of STRING.
Used by alias and trap, among others. */
char *
sh_single_quote (string)
char *string;
{
register int c;
char *result, *r, *s;
result = (char *)xmalloc (3 + (4 * strlen (string)));
r = result;
*r++ = '\'';
for (s = string; s && (c = *s); s++)
{
*r++ = c;
if (c == '\'')
{
*r++ = '\\'; /* insert escaped single quote */
*r++ = '\'';
*r++ = '\''; /* start new quoted string */
}
}
*r++ = '\'';
*r = '\0';
return (result);
}
/* Quote STRING using double quotes. Return a new string. */
char *
sh_double_quote (string)
char *string;
{
register unsigned char c;
char *result, *r, *s;
result = (char *)xmalloc (3 + (2 * strlen (string)));
r = result;
*r++ = '"';
for (s = string; s && (c = *s); s++)
{
/* Backslash-newline disappears within double quotes, so don't add one. */
if ((sh_syntaxtab[c] & CBSDQUOTE) && c != '\n')
*r++ = '\\';
else if (c == CTLESC || c == CTLNUL)
*r++ = CTLESC; /* could be '\\'? */
*r++ = c;
}
*r++ = '"';
*r = '\0';
return (result);
}
/* Turn S into a simple double-quoted string. If FLAGS is non-zero, quote
double quote characters in S with backslashes. */
char *
sh_mkdoublequoted (s, slen, flags)
const char *s;
int slen, flags;
{
char *r, *ret;
int rlen;
rlen = (flags == 0) ? slen + 3 : (2 * slen) + 1;
ret = r = (char *)xmalloc (rlen);
*r++ = '"';
while (*s)
{
if (flags && *s == '"')
*r++ = '\\';
*r++ = *s++;
}
*r++ = '"';
*r = '\0';
return ret;
}
/* Remove backslashes that are quoting characters that are special between
double quotes. Return a new string. XXX - should this handle CTLESC
and CTLNUL? */
char *
sh_un_double_quote (string)
char *string;
{
register int c, pass_next;
char *result, *r, *s;
r = result = (char *)xmalloc (strlen (string) + 1);
for (pass_next = 0, s = string; s && (c = *s); s++)
{
if (pass_next)
{
*r++ = c;
pass_next = 0;
continue;
}
if (c == '\\' && (sh_syntaxtab[(unsigned char) s[1]] & CBSDQUOTE))
{
pass_next = 1;
continue;
}
*r++ = c;
}
*r = '\0';
return result;
}
/* Quote special characters in STRING using backslashes. Return a new
string. NOTE: if the string is to be further expanded, we need a
way to protect the CTLESC and CTLNUL characters. As I write this,
the current callers will never cause the string to be expanded without
going through the shell parser, which will protect the internal
quoting characters. */
char *
sh_backslash_quote (string)
char *string;
{
int c;
char *result, *r, *s;
result = (char *)xmalloc (2 * strlen (string) + 1);
for (r = result, s = string; s && (c = *s); s++)
{
switch (c)
{
case ' ': case '\t': case '\n': /* IFS white space */
case '\'': case '"': case '\\': /* quoting chars */
case '|': case '&': case ';': /* shell metacharacters */
case '(': case ')': case '<': case '>':
case '!': case '{': case '}': /* reserved words */
case '*': case '[': case '?': case ']': /* globbing chars */
case '^':
case '$': case '`': /* expansion chars */
case ',': /* brace expansion */
*r++ = '\\';
*r++ = c;
break;
#if 0
case '~': /* tilde expansion */
if (s == string || s[-1] == '=' || s[-1] == ':')
*r++ = '\\';
*r++ = c;
break;
case CTLESC: case CTLNUL: /* internal quoting characters */
*r++ = CTLESC; /* could be '\\'? */
*r++ = c;
break;
#endif
case '#': /* comment char */
if (s == string)
*r++ = '\\';
/* FALLTHROUGH */
default:
*r++ = c;
break;
}
}
*r = '\0';
return (result);
}
#if defined (PROMPT_STRING_DECODE)
/* Quote characters that get special treatment when in double quotes in STRING
using backslashes. Return a new string. */
char *
sh_backslash_quote_for_double_quotes (string)
char *string;
{
unsigned char c;
char *result, *r, *s;
result = (char *)xmalloc (2 * strlen (string) + 1);
for (r = result, s = string; s && (c = *s); s++)
{
if (sh_syntaxtab[c] & CBSDQUOTE)
*r++ = '\\';
/* I should probably add flags for these to sh_syntaxtab[] */
else if (c == CTLESC || c == CTLNUL)
*r++ = CTLESC; /* could be '\\'? */
*r++ = c;
}
*r = '\0';
return (result);
}
#endif /* PROMPT_STRING_DECODE */
int
sh_contains_shell_metas (string)
char *string;
{
char *s;
for (s = string; s && *s; s++)
{
switch (*s)
{
case ' ': case '\t': case '\n': /* IFS white space */
case '\'': case '"': case '\\': /* quoting chars */
case '|': case '&': case ';': /* shell metacharacters */
case '(': case ')': case '<': case '>':
case '!': case '{': case '}': /* reserved words */
case '*': case '[': case '?': case ']': /* globbing chars */
case '^':
case '$': case '`': /* expansion chars */
return (1);
case '~': /* tilde expansion */
if (s == string || s[-1] == '=' || s[-1] == ':')
return (1);
break;
case '#':
if (s == string) /* comment char */
return (1);
/* FALLTHROUGH */
default:
break;
}
}
return (0);
}
-2173
View File
File diff suppressed because it is too large Load Diff
-144
View File
@@ -1,144 +0,0 @@
/* 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 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;
}
-881
View File
@@ -1,881 +0,0 @@
/* strftime - formatted time and date to a string */
/*
* Modified slightly by Chet Ramey for inclusion in Bash
*/
/*
* strftime.c
*
* Public-domain implementation of ISO C library routine.
*
* If you can't do prototypes, get GCC.
*
* The C99 standard now specifies just about all of the formats
* that were additional in the earlier versions of this file.
*
* For extensions from SunOS, add SUNOS_EXT.
* For extensions from HP/UX, add HPUX_EXT.
* For VMS dates, add VMS_EXT.
* For complete POSIX semantics, add POSIX_SEMANTICS.
*
* The code for %c, %x, and %X follows the C99 specification for
* the "C" locale.
*
* This version ignores LOCALE information.
* It also doesn't worry about multi-byte characters.
* So there.
*
* Arnold Robbins
* January, February, March, 1991
* Updated March, April 1992
* Updated April, 1993
* Updated February, 1994
* Updated May, 1994
* Updated January, 1995
* Updated September, 1995
* Updated January, 1996
* 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
* Fixes from Tor Lillqvist tml@tik.vtt.fi,
* May 1993
* Further fixes from ado@elsie.nci.nih.gov,
* February 1994
* %z code from chip@chinacat.unicom.com,
* Applied September 1995
* %V code fixed (again) and %G, %g added,
* January 1996
* %v code fixed, better configuration,
* July 1997
* Moved to C99 specification.
* September 2000
* Fixes from Tanaka Akira <akr@m17n.org>
* December 2001
*/
#include <config.h>
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#if defined(TM_IN_SYS_TIME)
#include <sys/types.h>
#include <sys/time.h>
#endif
#include <stdlib.h>
#include <string.h>
/* defaults: season to taste */
#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 */
#define POSIX_SEMANTICS 1 /* call tzset() if TZ changes */
#undef strchr /* avoid AIX weirdness */
#if defined (SHELL)
extern char *get_string_value (const char *);
#endif
extern void tzset(void);
static int weeknumber(const struct tm *timeptr, int firstweekday);
static int iso8601wknum(const struct tm *timeptr);
#ifndef inline
#ifdef __GNUC__
#define inline __inline__
#else
#define inline /**/
#endif
#endif
#define range(low, item, hi) max(low, min(item, hi))
#if !defined(OS2) && !defined(MSDOS) && defined(HAVE_TZNAME)
extern char *tzname[2];
extern int daylight;
#if defined(SOLARIS) || defined(mips) || defined (M_UNIX)
extern long int timezone, altzone;
#else
# if defined (HPUX)
extern long int timezone;
# else
extern int timezone, altzone;
# endif /* !HPUX */
#endif /* !SOLARIS && !mips && !M_UNIX */
#endif
#undef min /* just in case */
/* format for %+ */
#ifndef NATIONAL_FORMAT
#define NATIONAL_FORMAT "%a %b %e %H:%M:%S %Z %Y"
#endif
/* min --- return minimum of two numbers */
static inline int
min(int a, int b)
{
return (a < b ? a : b);
}
#undef max /* also, just in case */
/* max --- return maximum of two numbers */
static inline int
max(int a, int b)
{
return (a > b ? a : b);
}
/* strftime --- produce formatted time */
size_t
strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
{
char *endp = s + maxsize;
char *start = s;
auto char tbuf[100];
long off;
int i, w;
long y;
static short first = 1;
#ifdef POSIX_SEMANTICS
static char *savetz = NULL;
static int savetzlen = 0;
char *tz;
#endif /* POSIX_SEMANTICS */
#ifndef HAVE_TM_ZONE
#ifndef HAVE_TM_NAME
#ifndef HAVE_TZNAME
extern char *timezone();
struct timeval tv;
struct timezone zone;
#endif /* HAVE_TZNAME */
#endif /* HAVE_TM_NAME */
#endif /* HAVE_TM_ZONE */
/* various tables, useful in North America */
static const char *days_a[] = {
"Sun", "Mon", "Tue", "Wed",
"Thu", "Fri", "Sat",
};
static const char *days_l[] = {
"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday",
};
static const char *months_a[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
};
static const char *months_l[] = {
"January", "February", "March", "April",
"May", "June", "July", "August", "September",
"October", "November", "December",
};
static const char *ampm[] = { "AM", "PM", };
if (s == NULL || format == NULL || timeptr == NULL || maxsize == 0)
return 0;
/* quick check if we even need to bother */
if (strchr(format, '%') == NULL && strlen(format) + 1 >= maxsize)
return 0;
#ifndef POSIX_SEMANTICS
if (first) {
tzset();
first = 0;
}
#else /* POSIX_SEMANTICS */
#if defined (SHELL)
tz = get_string_value ("TZ");
#else
tz = getenv("TZ");
#endif
if (first) {
if (tz != NULL) {
int tzlen = strlen(tz);
savetz = (char *) malloc(tzlen + 1);
if (savetz != NULL) {
savetzlen = tzlen + 1;
strcpy(savetz, tz);
}
}
tzset();
first = 0;
}
/* if we have a saved TZ, and it is different, recapture and reset */
if (tz && savetz && (tz[0] != savetz[0] || strcmp(tz, savetz) != 0)) {
i = strlen(tz) + 1;
if (i > savetzlen) {
savetz = (char *) realloc(savetz, i);
if (savetz) {
savetzlen = i;
strcpy(savetz, tz);
}
} else
strcpy(savetz, tz);
tzset();
}
#endif /* POSIX_SEMANTICS */
for (; *format && s < endp - 1; format++) {
tbuf[0] = '\0';
if (*format != '%') {
*s++ = *format;
continue;
}
again:
switch (*++format) {
case '\0':
*s++ = '%';
goto out;
case '%':
*s++ = '%';
continue;
case 'a': /* abbreviated weekday name */
if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6)
strcpy(tbuf, "?");
else
strcpy(tbuf, days_a[timeptr->tm_wday]);
break;
case 'A': /* full weekday name */
if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6)
strcpy(tbuf, "?");
else
strcpy(tbuf, days_l[timeptr->tm_wday]);
break;
case 'b': /* abbreviated month name */
short_month:
if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11)
strcpy(tbuf, "?");
else
strcpy(tbuf, months_a[timeptr->tm_mon]);
break;
case 'B': /* full month name */
if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11)
strcpy(tbuf, "?");
else
strcpy(tbuf, months_l[timeptr->tm_mon]);
break;
case 'c': /* appropriate date and time representation */
/*
* This used to be:
*
* strftime(tbuf, sizeof tbuf, "%a %b %e %H:%M:%S %Y", timeptr);
*
* Now, per the ISO 1999 C standard, it this:
*/
strftime(tbuf, sizeof tbuf, "%A %B %d %T %Y", timeptr);
break;
case 'C':
century:
sprintf(tbuf, "%02ld", (timeptr->tm_year + 1900L) / 100);
break;
case 'd': /* day of the month, 01 - 31 */
i = range(1, timeptr->tm_mday, 31);
sprintf(tbuf, "%02d", i);
break;
case 'D': /* date as %m/%d/%y */
strftime(tbuf, sizeof tbuf, "%m/%d/%y", timeptr);
break;
case 'e': /* day of month, blank padded */
sprintf(tbuf, "%2d", range(1, timeptr->tm_mday, 31));
break;
case 'E':
/* POSIX (now C99) locale extensions, ignored for now */
goto again;
case 'F': /* ISO 8601 date representation */
strftime(tbuf, sizeof tbuf, "%Y-%m-%d", timeptr);
break;
case 'g':
case 'G':
/*
* Year of ISO week.
*
* If it's December but the ISO week number is one,
* that week is in next year.
* If it's January but the ISO week number is 52 or
* 53, that week is in last year.
* Otherwise, it's this year.
*/
w = iso8601wknum(timeptr);
if (timeptr->tm_mon == 11 && w == 1)
y = 1900L + timeptr->tm_year + 1;
else if (timeptr->tm_mon == 0 && w >= 52)
y = 1900L + timeptr->tm_year - 1;
else
y = 1900L + timeptr->tm_year;
if (*format == 'G')
sprintf(tbuf, "%ld", y);
else
sprintf(tbuf, "%02ld", y % 100);
break;
case 'h': /* abbreviated month name */
goto short_month;
case 'H': /* hour, 24-hour clock, 00 - 23 */
i = range(0, timeptr->tm_hour, 23);
sprintf(tbuf, "%02d", i);
break;
case 'I': /* hour, 12-hour clock, 01 - 12 */
i = range(0, timeptr->tm_hour, 23);
if (i == 0)
i = 12;
else if (i > 12)
i -= 12;
sprintf(tbuf, "%02d", i);
break;
case 'j': /* day of the year, 001 - 366 */
sprintf(tbuf, "%03d", timeptr->tm_yday + 1);
break;
case 'm': /* month, 01 - 12 */
i = range(0, timeptr->tm_mon, 11);
sprintf(tbuf, "%02d", i + 1);
break;
case 'M': /* minute, 00 - 59 */
i = range(0, timeptr->tm_min, 59);
sprintf(tbuf, "%02d", i);
break;
case 'n': /* same as \n */
tbuf[0] = '\n';
tbuf[1] = '\0';
break;
case 'O':
/* POSIX (now C99) locale extensions, ignored for now */
goto again;
case 'p': /* am or pm based on 12-hour clock */
i = range(0, timeptr->tm_hour, 23);
if (i < 12)
strcpy(tbuf, ampm[0]);
else
strcpy(tbuf, ampm[1]);
break;
case 'r': /* time as %I:%M:%S %p */
strftime(tbuf, sizeof tbuf, "%I:%M:%S %p", timeptr);
break;
case 'R': /* time as %H:%M */
strftime(tbuf, sizeof tbuf, "%H:%M", timeptr);
break;
#if defined(HAVE_MKTIME)
case 's': /* time as seconds since the Epoch */
{
struct tm non_const_timeptr;
non_const_timeptr = *timeptr;
sprintf(tbuf, "%ld", mktime(& non_const_timeptr));
break;
}
#endif /* defined(HAVE_MKTIME) */
case 'S': /* second, 00 - 60 */
i = range(0, timeptr->tm_sec, 60);
sprintf(tbuf, "%02d", i);
break;
case 't': /* same as \t */
tbuf[0] = '\t';
tbuf[1] = '\0';
break;
case 'T': /* time as %H:%M:%S */
the_time:
strftime(tbuf, sizeof tbuf, "%H:%M:%S", timeptr);
break;
case 'u':
/* ISO 8601: Weekday as a decimal number [1 (Monday) - 7] */
sprintf(tbuf, "%d", timeptr->tm_wday == 0 ? 7 :
timeptr->tm_wday);
break;
case 'U': /* week of year, Sunday is first day of week */
sprintf(tbuf, "%02d", weeknumber(timeptr, 0));
break;
case 'V': /* week of year according ISO 8601 */
sprintf(tbuf, "%02d", iso8601wknum(timeptr));
break;
case 'w': /* weekday, Sunday == 0, 0 - 6 */
i = range(0, timeptr->tm_wday, 6);
sprintf(tbuf, "%d", i);
break;
case 'W': /* week of year, Monday is first day of week */
sprintf(tbuf, "%02d", weeknumber(timeptr, 1));
break;
case 'x': /* appropriate date representation */
strftime(tbuf, sizeof tbuf, "%A %B %d %Y", timeptr);
break;
case 'X': /* appropriate time representation */
goto the_time;
break;
case 'y': /* year without a century, 00 - 99 */
year:
i = timeptr->tm_year % 100;
sprintf(tbuf, "%02d", i);
break;
case 'Y': /* year with century */
fullyear:
sprintf(tbuf, "%ld", 1900L + timeptr->tm_year);
break;
/*
* From: Chip Rosenthal <chip@chinacat.unicom.com>
* Date: Sun, 19 Mar 1995 00:33:29 -0600 (CST)
*
* Warning: the %z [code] is implemented by inspecting the
* timezone name conditional compile settings, and
* inferring a method to get timezone offsets. I've tried
* this code on a couple of machines, but I don't doubt
* there is some system out there that won't like it.
* Maybe the easiest thing to do would be to bracket this
* with an #ifdef that can turn it off. The %z feature
* would be an admittedly obscure one that most folks can
* live without, but it would be a great help to those of
* us that muck around with various message processors.
*/
case 'z': /* time zone offset east of GMT e.g. -0600 */
if (timeptr->tm_isdst < 0)
break;
#ifdef HAVE_TM_NAME
/*
* Systems with tm_name probably have tm_tzadj as
* secs west of GMT. Convert to mins east of GMT.
*/
off = -timeptr->tm_tzadj / 60;
#else /* !HAVE_TM_NAME */
#ifdef HAVE_TM_ZONE
/*
* Systems with tm_zone probably have tm_gmtoff as
* secs east of GMT. Convert to mins east of GMT.
*/
off = timeptr->tm_gmtoff / 60;
#else /* !HAVE_TM_ZONE */
#if HAVE_TZNAME
/*
* Systems with tzname[] probably have timezone as
* secs west of GMT. Convert to mins east of GMT.
*/
# 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 */
gettimeofday(& tv, & zone);
off = -zone.tz_minuteswest;
#endif /* !HAVE_TZNAME */
#endif /* !HAVE_TM_ZONE */
#endif /* !HAVE_TM_NAME */
if (off < 0) {
tbuf[0] = '-';
off = -off;
} else {
tbuf[0] = '+';
}
sprintf(tbuf+1, "%02ld%02ld", off/60, off%60);
break;
case 'Z': /* time zone name or abbrevation */
#ifdef HAVE_TZNAME
i = (daylight && timeptr->tm_isdst > 0); /* 0 or 1 */
strcpy(tbuf, tzname[i]);
#else
#ifdef HAVE_TM_ZONE
strcpy(tbuf, timeptr->tm_zone);
#else
#ifdef HAVE_TM_NAME
strcpy(tbuf, timeptr->tm_name);
#else
gettimeofday(& tv, & zone);
strcpy(tbuf, timezone(zone.tz_minuteswest,
timeptr->tm_isdst > 0));
#endif /* HAVE_TM_NAME */
#endif /* HAVE_TM_ZONE */
#endif /* HAVE_TZNAME */
break;
#ifdef SUNOS_EXT
case 'k': /* hour, 24-hour clock, blank pad */
sprintf(tbuf, "%2d", range(0, timeptr->tm_hour, 23));
break;
case 'l': /* hour, 12-hour clock, 1 - 12, blank pad */
i = range(0, timeptr->tm_hour, 23);
if (i == 0)
i = 12;
else if (i > 12)
i -= 12;
sprintf(tbuf, "%2d", i);
break;
#endif
#ifdef HPUX_EXT
case 'N': /* Emperor/Era name */
/* this is essentially the same as the century */
goto century; /* %C */
case 'o': /* Emperor/Era year */
goto year; /* %y */
#endif /* HPUX_EXT */
#ifdef VMS_EXT
case 'v': /* date as dd-bbb-YYYY */
sprintf(tbuf, "%2d-%3.3s-%4ld",
range(1, timeptr->tm_mday, 31),
months_a[range(0, timeptr->tm_mon, 11)],
timeptr->tm_year + 1900L);
for (i = 3; i < 6; i++)
if (islower(tbuf[i]))
tbuf[i] = toupper(tbuf[i]);
break;
#endif
default:
tbuf[0] = '%';
tbuf[1] = *format;
tbuf[2] = '\0';
break;
}
i = strlen(tbuf);
if (i) {
if (s + i < endp - 1) {
strcpy(s, tbuf);
s += i;
} else
return 0;
}
}
out:
if (s < endp && *format == '\0') {
*s = '\0';
return (s - start);
} else
return 0;
}
/* isleap --- is a year a leap year? */
static int
isleap(long year)
{
return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
}
/* iso8601wknum --- compute week number according to ISO 8601 */
static int
iso8601wknum(const struct tm *timeptr)
{
/*
* From 1003.2:
* If the week (Monday to Sunday) containing January 1
* has four or more days in the new year, then it is week 1;
* otherwise it is the highest numbered week of the previous
* year (52 or 53), and the next week is week 1.
*
* ADR: This means if Jan 1 was Monday through Thursday,
* it was week 1, otherwise week 52 or 53.
*
* XPG4 erroneously included POSIX.2 rationale text in the
* main body of the standard. Thus it requires week 53.
*/
int weeknum, jan1day, diff;
/* get week number, Monday as first day of the week */
weeknum = weeknumber(timeptr, 1);
/*
* With thanks and tip of the hatlo to tml@tik.vtt.fi
*
* What day of the week does January 1 fall on?
* We know that
* (timeptr->tm_yday - jan1.tm_yday) MOD 7 ==
* (timeptr->tm_wday - jan1.tm_wday) MOD 7
* and that
* jan1.tm_yday == 0
* and that
* timeptr->tm_wday MOD 7 == timeptr->tm_wday
* from which it follows that. . .
*/
jan1day = timeptr->tm_wday - (timeptr->tm_yday % 7);
if (jan1day < 0)
jan1day += 7;
/*
* If Jan 1 was a Monday through Thursday, it was in
* week 1. Otherwise it was last year's highest week, which is
* this year's week 0.
*
* What does that mean?
* If Jan 1 was Monday, the week number is exactly right, it can
* never be 0.
* If it was Tuesday through Thursday, the weeknumber is one
* less than it should be, so we add one.
* Otherwise, Friday, Saturday or Sunday, the week number is
* OK, but if it is 0, it needs to be 52 or 53.
*/
switch (jan1day) {
case 1: /* Monday */
break;
case 2: /* Tuesday */
case 3: /* Wednesday */
case 4: /* Thursday */
weeknum++;
break;
case 5: /* Friday */
case 6: /* Saturday */
case 0: /* Sunday */
if (weeknum == 0) {
#ifdef USE_BROKEN_XPG4
/* XPG4 (as of March 1994) says 53 unconditionally */
weeknum = 53;
#else
/* get week number of last week of last year */
struct tm dec31ly; /* 12/31 last year */
dec31ly = *timeptr;
dec31ly.tm_year--;
dec31ly.tm_mon = 11;
dec31ly.tm_mday = 31;
dec31ly.tm_wday = (jan1day == 0) ? 6 : jan1day - 1;
dec31ly.tm_yday = 364 + isleap(dec31ly.tm_year + 1900L);
weeknum = iso8601wknum(& dec31ly);
#endif
}
break;
}
if (timeptr->tm_mon == 11) {
/*
* The last week of the year
* can be in week 1 of next year.
* Sigh.
*
* This can only happen if
* M T W
* 29 30 31
* 30 31
* 31
*/
int wday, mday;
wday = timeptr->tm_wday;
mday = timeptr->tm_mday;
if ( (wday == 1 && (mday >= 29 && mday <= 31))
|| (wday == 2 && (mday == 30 || mday == 31))
|| (wday == 3 && mday == 31))
weeknum = 1;
}
return weeknum;
}
/* weeknumber --- figure how many weeks into the year */
/* With thanks and tip of the hatlo to ado@elsie.nci.nih.gov */
static int
weeknumber(const struct tm *timeptr, int firstweekday)
{
int wday = timeptr->tm_wday;
int ret;
if (firstweekday == 1) {
if (wday == 0) /* sunday */
wday = 6;
else
wday--;
}
ret = ((timeptr->tm_yday + 7 - wday) / 7);
if (ret < 0)
ret = 0;
return ret;
}
#if 0
/* ADR --- I'm loathe to mess with ado's code ... */
Date: Wed, 24 Apr 91 20:54:08 MDT
From: Michal Jaegermann <audfax!emory!vm.ucs.UAlberta.CA!NTOMCZAK>
To: arnold@audiofax.com
Hi Arnold,
in a process of fixing of strftime() in libraries on Atari ST I grabbed
some pieces of code from your own strftime. When doing that it came
to mind that your weeknumber() function compiles a little bit nicer
in the following form:
/*
* firstweekday is 0 if starting in Sunday, non-zero if in Monday
*/
{
return (timeptr->tm_yday - timeptr->tm_wday +
(firstweekday ? (timeptr->tm_wday ? 8 : 1) : 7)) / 7;
}
How nicer it depends on a compiler, of course, but always a tiny bit.
Cheers,
Michal
ntomczak@vm.ucs.ualberta.ca
#endif
#ifdef TEST_STRFTIME
/*
* NAME:
* tst
*
* SYNOPSIS:
* tst
*
* DESCRIPTION:
* "tst" is a test driver for the function "strftime".
*
* OPTIONS:
* None.
*
* AUTHOR:
* Karl Vogel
* Control Data Systems, Inc.
* vogelke@c-17igp.wpafb.af.mil
*
* BUGS:
* None noticed yet.
*
* COMPILE:
* cc -o tst -DTEST_STRFTIME strftime.c
*/
/* ADR: I reformatted this to my liking, and deleted some unneeded code. */
#ifndef NULL
#include <stdio.h>
#endif
#include <sys/time.h>
#include <string.h>
#define MAXTIME 132
/*
* Array of time formats.
*/
static char *array[] =
{
"(%%A) full weekday name, var length (Sunday..Saturday) %A",
"(%%B) full month name, var length (January..December) %B",
"(%%C) Century %C",
"(%%D) date (%%m/%%d/%%y) %D",
"(%%E) Locale extensions (ignored) %E",
"(%%F) full month name, var length (January..December) %F",
"(%%H) hour (24-hour clock, 00..23) %H",
"(%%I) hour (12-hour clock, 01..12) %I",
"(%%M) minute (00..59) %M",
"(%%N) Emporer/Era Name %N",
"(%%O) Locale extensions (ignored) %O",
"(%%R) time, 24-hour (%%H:%%M) %R",
"(%%S) second (00..60) %S",
"(%%T) time, 24-hour (%%H:%%M:%%S) %T",
"(%%U) week of year, Sunday as first day of week (00..53) %U",
"(%%V) week of year according to ISO 8601 %V",
"(%%W) week of year, Monday as first day of week (00..53) %W",
"(%%X) appropriate locale time representation (%H:%M:%S) %X",
"(%%Y) year with century (1970...) %Y",
"(%%Z) timezone (EDT), or blank if timezone not determinable %Z",
"(%%a) locale's abbreviated weekday name (Sun..Sat) %a",
"(%%b) locale's abbreviated month name (Jan..Dec) %b",
"(%%c) full date (Sat Nov 4 12:02:33 1989)%n%t%t%t %c",
"(%%d) day of the month (01..31) %d",
"(%%e) day of the month, blank-padded ( 1..31) %e",
"(%%h) should be same as (%%b) %h",
"(%%j) day of the year (001..366) %j",
"(%%k) hour, 24-hour clock, blank pad ( 0..23) %k",
"(%%l) hour, 12-hour clock, blank pad ( 0..12) %l",
"(%%m) month (01..12) %m",
"(%%o) Emporer/Era Year %o",
"(%%p) locale's AM or PM based on 12-hour clock %p",
"(%%r) time, 12-hour (same as %%I:%%M:%%S %%p) %r",
"(%%u) ISO 8601: Weekday as decimal number [1 (Monday) - 7] %u",
"(%%v) VMS date (dd-bbb-YYYY) %v",
"(%%w) day of week (0..6, Sunday == 0) %w",
"(%%x) appropriate locale date representation %x",
"(%%y) last two digits of year (00..99) %y",
"(%%z) timezone offset east of GMT as HHMM (e.g. -0500) %z",
(char *) NULL
};
/* main routine. */
int
main(argc, argv)
int argc;
char **argv;
{
long time();
char *next;
char string[MAXTIME];
int k;
int length;
struct tm *tm;
long clock;
/* Call the function. */
clock = time((long *) 0);
tm = localtime(&clock);
for (k = 0; next = array[k]; k++) {
length = strftime(string, MAXTIME, next, tm);
printf("%s\n", string);
}
exit(0);
}
#endif /* TEST_STRFTIME */
-314
View File
@@ -1,314 +0,0 @@
/* strtrans.c - Translate and untranslate strings with ANSI-C escape sequences. */
/* Copyright (C) 2000-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 <chartypes.h>
#include "shell.h"
#ifdef ESC
#undef ESC
#endif
#define ESC '\033' /* ASCII */
/* Convert STRING by expanding the escape sequences specified by the
ANSI C standard. If SAWC is non-null, recognize `\c' and use that
as a string terminator. If we see \c, set *SAWC to 1 before
returning. LEN is the length of STRING. If (FLAGS&1) is non-zero,
that we're translating a string for `echo -e', and therefore should not
treat a single quote as a character that may be escaped with a backslash.
If (FLAGS&2) is non-zero, we're expanding for the parser and want to
quote CTLESC and CTLNUL with CTLESC. If (flags&4) is non-zero, we want
to remove the backslash before any unrecognized escape sequence. */
char *
ansicstr (string, len, flags, sawc, rlen)
char *string;
int 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++;
if (c != '\\' || *s == '\0')
*r++ = c;
else
{
switch (c = *s++)
{
#if defined (__STDC__)
case 'a': c = '\a'; break;
case 'v': c = '\v'; break;
#else
case 'a': c = '\007'; break;
case 'v': c = (int) 0x0B; break;
#endif
case 'b': c = '\b'; break;
case 'e': case 'E': /* ESC -- non-ANSI */
c = ESC; break;
case 'f': c = '\f'; break;
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
case '1': case '2': case '3':
case '4': case '5': case '6':
case '7':
#if 1
if (flags & 1)
{
*r++ = '\\';
break;
}
/*FALLTHROUGH*/
#endif
case '0':
/* If (FLAGS & 1), we're translating a string for echo -e (or
the equivalent xpg_echo option), so we obey the SUSv3/
POSIX-2001 requirement and accept 0-3 octal digits after
a leading `0'. */
temp = 2 + ((flags & 1) && (c == '0'));
for (c -= '0'; ISOCTAL (*s) && temp--; s++)
c = (c * 8) + OCTVALUE (*s);
c &= 0xFF;
break;
case 'x': /* Hex digit -- non-ANSI */
if ((flags & 2) && *s == '{')
{
flags |= 16; /* internal flag value */
s++;
}
/* Consume at least two hex characters */
for (temp = 2, c = 0; ISXDIGIT ((unsigned char)*s) && temp--; s++)
c = (c * 16) + HEXVALUE (*s);
/* DGK says that after a `\x{' ksh93 consumes ISXDIGIT chars
until a non-xdigit or `}', so potentially more than two
chars are consumed. */
if (flags & 16)
{
for ( ; ISXDIGIT ((unsigned char)*s); s++)
c = (c * 16) + HEXVALUE (*s);
flags &= ~16;
if (*s == '}')
s++;
}
/* \x followed by non-hex digits is passed through unchanged */
else if (temp == 2)
{
*r++ = '\\';
c = 'x';
}
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 '?':
if (flags & 1)
*r++ = '\\';
break;
case 'c':
if (sawc)
{
*sawc = 1;
*r = '\0';
if (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++; /*
c = TOCTRL(c);
break;
}
/*FALLTHROUGH*/
default:
if ((flags & 4) == 0)
*r++ = '\\';
break;
}
if ((flags & 2) && (c == CTLESC || c == CTLNUL))
*r++ = CTLESC;
*r++ = c;
}
}
*r = '\0';
if (rlen)
*rlen = r - ret;
return ret;
}
/* Take a string STR, possibly containing non-printing characters, and turn it
into a $'...' ANSI-C style quoted string. Returns a new string. */
char *
ansic_quote (str, flags, rlen)
char *str;
int flags, *rlen;
{
char *r, *ret, *s;
int l, rsize;
unsigned char c;
if (str == 0 || *str == 0)
return ((char *)0);
l = strlen (str);
rsize = 4 * l + 4;
r = ret = (char *)xmalloc (rsize);
*r++ = '$';
*r++ = '\'';
for (s = str, l = 0; *s; s++)
{
c = *s;
l = 1; /* 1 == add backslash; 0 == no backslash */
switch (c)
{
case ESC: c = 'E'; break;
#ifdef __STDC__
case '\a': c = 'a'; break;
case '\v': c = 'v'; break;
#else
case '\007': c = 'a'; break;
case 0x0b: c = 'v'; break;
#endif
case '\b': c = 'b'; break;
case '\f': c = 'f'; break;
case '\n': c = 'n'; break;
case '\r': c = 'r'; break;
case '\t': c = 't'; break;
case '\\':
case '\'':
break;
default:
if (ISPRINT (c) == 0)
{
*r++ = '\\';
*r++ = TOCHAR ((c >> 6) & 07);
*r++ = TOCHAR ((c >> 3) & 07);
*r++ = TOCHAR (c & 07);
continue;
}
l = 0;
break;
}
if (l)
*r++ = '\\';
*r++ = c;
}
*r++ = '\'';
*r = '\0';
if (rlen)
*rlen = r - ret;
return ret;
}
/* return 1 if we need to quote with $'...' because of non-printing chars. */
int
ansic_shouldquote (string)
const char *string;
{
const char *s;
unsigned char c;
if (string == 0)
return 0;
for (s = string; c = *s; s++)
if (ISPRINT (c) == 0)
return 1;
return 0;
}
/* $'...' ANSI-C expand the portion of STRING between START and END and
return the result. The result cannot be longer than the input string. */
char *
ansiexpand (string, start, end, lenp)
char *string;
int start, end, *lenp;
{
char *temp, *t;
int len, tlen;
temp = (char *)xmalloc (end - start + 1);
for (tlen = 0, len = start; len < end; )
temp[tlen++] = string[len++];
temp[tlen] = '\0';
if (*temp)
{
t = ansicstr (temp, tlen, 2, (int *)NULL, lenp);
free (temp);
return (t);
}
else
{
if (lenp)
*lenp = 0;
return (temp);
}
}
-220
View File
@@ -1,220 +0,0 @@
/*
* tmpfile.c - functions to create and safely open temp files for the shell.
*/
/* 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 <bashtypes.h>
#include <posixstat.h>
#include <posixtime.h>
#include <filecntl.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <stdio.h>
#include <errno.h>
#include <shell.h>
#ifndef errno
extern int errno;
#endif
#define BASEOPENFLAGS (O_CREAT | O_TRUNC | O_EXCL)
#define DEFAULT_TMPDIR "." /* bogus default, should be changed */
#define DEFAULT_NAMEROOT "shtmp"
extern pid_t dollar_dollar_pid;
static char *get_sys_tmpdir __P((void));
static char *get_tmpdir __P((int));
static char *sys_tmpdir = (char *)NULL;
static int ntmpfiles;
static int tmpnamelen = -1;
static unsigned long filenum = 1L;
static char *
get_sys_tmpdir ()
{
if (sys_tmpdir)
return sys_tmpdir;
#ifdef P_tmpdir
sys_tmpdir = P_tmpdir;
if (file_iswdir (sys_tmpdir))
return sys_tmpdir;
#endif
sys_tmpdir = "/tmp";
if (file_iswdir (sys_tmpdir))
return sys_tmpdir;
sys_tmpdir = "/var/tmp";
if (file_iswdir (sys_tmpdir))
return sys_tmpdir;
sys_tmpdir = "/usr/tmp";
if (file_iswdir (sys_tmpdir))
return sys_tmpdir;
sys_tmpdir = DEFAULT_TMPDIR;
return sys_tmpdir;
}
static char *
get_tmpdir (flags)
int flags;
{
char *tdir;
tdir = (flags & MT_USETMPDIR) ? get_string_value ("TMPDIR") : (char *)NULL;
if (tdir && (file_iswdir (tdir) == 0 || strlen (tdir) > PATH_MAX))
tdir = 0;
if (tdir == 0)
tdir = get_sys_tmpdir ();
#if defined (HAVE_PATHCONF) && defined (_PC_NAME_MAX)
if (tmpnamelen == -1)
tmpnamelen = pathconf (tdir, _PC_NAME_MAX);
#else
tmpnamelen = 0;
#endif
return tdir;
}
char *
sh_mktmpname (nameroot, flags)
char *nameroot;
int flags;
{
char *filename, *tdir, *lroot;
struct stat sb;
int r, tdlen;
filename = (char *)xmalloc (PATH_MAX + 1);
tdir = get_tmpdir (flags);
tdlen = strlen (tdir);
lroot = nameroot ? nameroot : DEFAULT_NAMEROOT;
#ifdef USE_MKTEMP
sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
if (mktemp (filename) == 0)
{
free (filename);
filename = NULL;
}
#else /* !USE_MKTEMP */
while (1)
{
filenum = (filenum << 1) ^
(unsigned long) time ((time_t *)0) ^
(unsigned long) dollar_dollar_pid ^
(unsigned long) ((flags & MT_USERANDOM) ? get_random_number () : ntmpfiles++);
sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum);
if (tmpnamelen > 0 && tmpnamelen < 32)
filename[tdlen + 1 + tmpnamelen] = '\0';
# ifdef HAVE_LSTAT
r = lstat (filename, &sb);
# else
r = stat (filename, &sb);
# endif
if (r < 0 && errno == ENOENT)
break;
}
#endif /* !USE_MKTEMP */
return filename;
}
int
sh_mktmpfd (nameroot, flags, namep)
char *nameroot;
int flags;
char **namep;
{
char *filename, *tdir, *lroot;
int fd, tdlen;
filename = (char *)xmalloc (PATH_MAX + 1);
tdir = get_tmpdir (flags);
tdlen = strlen (tdir);
lroot = nameroot ? nameroot : DEFAULT_NAMEROOT;
#ifdef USE_MKSTEMP
sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
fd = mkstemp (filename);
if (fd < 0 || namep == 0)
{
free (filename);
filename = NULL;
}
if (namep)
*namep = filename;
return fd;
#else /* !USE_MKSTEMP */
do
{
filenum = (filenum << 1) ^
(unsigned long) time ((time_t *)0) ^
(unsigned long) dollar_dollar_pid ^
(unsigned long) ((flags & MT_USERANDOM) ? get_random_number () : ntmpfiles++);
sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum);
if (tmpnamelen > 0 && tmpnamelen < 32)
filename[tdlen + 1 + tmpnamelen] = '\0';
fd = open (filename, BASEOPENFLAGS | ((flags & MT_READWRITE) ? O_RDWR : O_WRONLY), 0600);
}
while (fd < 0 && errno == EEXIST);
if (namep)
*namep = filename;
else
free (filename);
return fd;
#endif /* !USE_MKSTEMP */
}
FILE *
sh_mktmpfp (nameroot, flags, namep)
char *nameroot;
int flags;
char **namep;
{
int fd;
FILE *fp;
fd = sh_mktmpfd (nameroot, flags, namep);
if (fd < 0)
return ((FILE *)NULL);
fp = fdopen (fd, (flags & MT_READWRITE) ? "w+" : "w");
if (fp == 0)
close (fd);
return fp;
}
-235
View File
@@ -1,235 +0,0 @@
/* 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;
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 (wc, s);
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 */
-26
View File
@@ -1,26 +0,0 @@
#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);
}
-502
View File
@@ -1,502 +0,0 @@
/* tilde.c -- Tilde expansion code (~/foo := $HOME/foo). */
/* Copyright (C) 1988-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Readline is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#if defined (HAVE_STRING_H)
# include <string.h>
#else /* !HAVE_STRING_H */
# include <strings.h>
#endif /* !HAVE_STRING_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include <sys/types.h>
#if defined (HAVE_PWD_H)
#include <pwd.h>
#endif
#include "tilde.h"
#if defined (TEST) || defined (STATIC_MALLOC)
static void *xmalloc (), *xrealloc ();
#else
# include "xmalloc.h"
#endif /* TEST || STATIC_MALLOC */
#if !defined (HAVE_GETPW_DECLS)
# if defined (HAVE_GETPWUID)
extern struct passwd *getpwuid PARAMS((uid_t));
# endif
# if defined (HAVE_GETPWNAM)
extern struct passwd *getpwnam PARAMS((const char *));
# endif
#endif /* !HAVE_GETPW_DECLS */
#if !defined (savestring)
#define savestring(x) strcpy ((char *)xmalloc (1 + strlen (x)), (x))
#endif /* !savestring */
#if !defined (NULL)
# if defined (__STDC__)
# define NULL ((void *) 0)
# else
# define NULL 0x0
# endif /* !__STDC__ */
#endif /* !NULL */
/* If being compiled as part of bash, these will be satisfied from
variables.o. If being compiled as part of readline, they will
be satisfied from shell.o. */
extern char *sh_get_home_dir PARAMS((void));
extern char *sh_get_env_value PARAMS((const char *));
/* The default value of tilde_additional_prefixes. This is set to
whitespace preceding a tilde so that simple programs which do not
perform any word separation get desired behaviour. */
static const char *default_prefixes[] =
{ " ~", "\t~", (const char *)NULL };
/* The default value of tilde_additional_suffixes. This is set to
whitespace or newline so that simple programs which do not
perform any word separation get desired behaviour. */
static const char *default_suffixes[] =
{ " ", "\n", (const char *)NULL };
/* If non-null, this contains the address of a function that the application
wants called before trying the standard tilde expansions. The function
is called with the text sans tilde, and returns a malloc()'ed string
which is the expansion, or a NULL pointer if the expansion fails. */
tilde_hook_func_t *tilde_expansion_preexpansion_hook = (tilde_hook_func_t *)NULL;
/* If non-null, this contains the address of a function to call if the
standard meaning for expanding a tilde fails. The function is called
with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
which is the expansion, or a NULL pointer if there is no expansion. */
tilde_hook_func_t *tilde_expansion_failure_hook = (tilde_hook_func_t *)NULL;
/* When non-null, this is a NULL terminated array of strings which
are duplicates for a tilde prefix. Bash uses this to expand
`=~' and `:~'. */
char **tilde_additional_prefixes = (char **)default_prefixes;
/* When non-null, this is a NULL terminated array of strings which match
the end of a username, instead of just "/". Bash sets this to
`:' and `=~'. */
char **tilde_additional_suffixes = (char **)default_suffixes;
static int tilde_find_prefix PARAMS((const char *, int *));
static int tilde_find_suffix PARAMS((const char *));
static char *isolate_tilde_prefix PARAMS((const char *, int *));
static char *glue_prefix_and_suffix PARAMS((char *, const char *, int));
/* Find the start of a tilde expansion in STRING, and return the index of
the tilde which starts the expansion. Place the length of the text
which identified this tilde starter in LEN, excluding the tilde itself. */
static int
tilde_find_prefix (string, len)
const char *string;
int *len;
{
register int i, j, string_len;
register char **prefixes;
prefixes = tilde_additional_prefixes;
string_len = strlen (string);
*len = 0;
if (*string == '\0' || *string == '~')
return (0);
if (prefixes)
{
for (i = 0; i < string_len; i++)
{
for (j = 0; prefixes[j]; j++)
{
if (strncmp (string + i, prefixes[j], strlen (prefixes[j])) == 0)
{
*len = strlen (prefixes[j]) - 1;
return (i + *len);
}
}
}
}
return (string_len);
}
/* Find the end of a tilde expansion in STRING, and return the index of
the character which ends the tilde definition. */
static int
tilde_find_suffix (string)
const char *string;
{
register int i, j, string_len;
register char **suffixes;
suffixes = tilde_additional_suffixes;
string_len = strlen (string);
for (i = 0; i < string_len; i++)
{
#if defined (__MSDOS__)
if (string[i] == '/' || string[i] == '\\' /* || !string[i] */)
#else
if (string[i] == '/' /* || !string[i] */)
#endif
break;
for (j = 0; suffixes && suffixes[j]; j++)
{
if (strncmp (string + i, suffixes[j], strlen (suffixes[j])) == 0)
return (i);
}
}
return (i);
}
/* Return a new string which is the result of tilde expanding STRING. */
char *
tilde_expand (string)
const char *string;
{
char *result;
int result_size, result_index;
result_index = result_size = 0;
if (result = strchr (string, '~'))
result = (char *)xmalloc (result_size = (strlen (string) + 16));
else
result = (char *)xmalloc (result_size = (strlen (string) + 1));
/* Scan through STRING expanding tildes as we come to them. */
while (1)
{
register int start, end;
char *tilde_word, *expansion;
int len;
/* Make START point to the tilde which starts the expansion. */
start = tilde_find_prefix (string, &len);
/* Copy the skipped text into the result. */
if ((result_index + start + 1) > result_size)
result = (char *)xrealloc (result, 1 + (result_size += (start + 20)));
strncpy (result + result_index, string, start);
result_index += start;
/* Advance STRING to the starting tilde. */
string += start;
/* Make END be the index of one after the last character of the
username. */
end = tilde_find_suffix (string);
/* If both START and END are zero, we are all done. */
if (!start && !end)
break;
/* Expand the entire tilde word, and copy it into RESULT. */
tilde_word = (char *)xmalloc (1 + end);
strncpy (tilde_word, string, end);
tilde_word[end] = '\0';
string += end;
expansion = tilde_expand_word (tilde_word);
xfree (tilde_word);
len = strlen (expansion);
#ifdef __CYGWIN__
/* Fix for Cygwin to prevent ~user/xxx from expanding to //xxx when
$HOME for `user' is /. On cygwin, // denotes a network drive. */
if (len > 1 || *expansion != '/' || *string != '/')
#endif
{
if ((result_index + len + 1) > result_size)
result = (char *)xrealloc (result, 1 + (result_size += (len + 20)));
strcpy (result + result_index, expansion);
result_index += len;
}
xfree (expansion);
}
result[result_index] = '\0';
return (result);
}
/* Take FNAME and return the tilde prefix we want expanded. If LENP is
non-null, the index of the end of the prefix into FNAME is returned in
the location it points to. */
static char *
isolate_tilde_prefix (fname, lenp)
const char *fname;
int *lenp;
{
char *ret;
int i;
ret = (char *)xmalloc (strlen (fname));
#if defined (__MSDOS__)
for (i = 1; fname[i] && fname[i] != '/' && fname[i] != '\\'; i++)
#else
for (i = 1; fname[i] && fname[i] != '/'; i++)
#endif
ret[i - 1] = fname[i];
ret[i - 1] = '\0';
if (lenp)
*lenp = i;
return ret;
}
#if 0
/* Public function to scan a string (FNAME) beginning with a tilde and find
the portion of the string that should be passed to the tilde expansion
function. Right now, it just calls tilde_find_suffix and allocates new
memory, but it can be expanded to do different things later. */
char *
tilde_find_word (fname, flags, lenp)
const char *fname;
int flags, *lenp;
{
int x;
char *r;
x = tilde_find_suffix (fname);
if (x == 0)
{
r = savestring (fname);
if (lenp)
*lenp = 0;
}
else
{
r = (char *)xmalloc (1 + x);
strncpy (r, fname, x);
r[x] = '\0';
if (lenp)
*lenp = x;
}
return r;
}
#endif
/* Return a string that is PREFIX concatenated with SUFFIX starting at
SUFFIND. */
static char *
glue_prefix_and_suffix (prefix, suffix, suffind)
char *prefix;
const char *suffix;
int suffind;
{
char *ret;
int plen, slen;
plen = (prefix && *prefix) ? strlen (prefix) : 0;
slen = strlen (suffix + suffind);
ret = (char *)xmalloc (plen + slen + 1);
if (plen)
strcpy (ret, prefix);
strcpy (ret + plen, suffix + suffind);
return ret;
}
/* Do the work of tilde expansion on FILENAME. FILENAME starts with a
tilde. If there is no expansion, call tilde_expansion_failure_hook.
This always returns a newly-allocated string, never static storage. */
char *
tilde_expand_word (filename)
const char *filename;
{
char *dirname, *expansion, *username;
int user_len;
struct passwd *user_entry;
if (filename == 0)
return ((char *)NULL);
if (*filename != '~')
return (savestring (filename));
/* A leading `~/' or a bare `~' is *always* translated to the value of
$HOME or the home directory of the current user, regardless of any
preexpansion hook. */
if (filename[1] == '\0' || filename[1] == '/')
{
/* Prefix $HOME to the rest of the string. */
expansion = sh_get_env_value ("HOME");
/* If there is no HOME variable, look up the directory in
the password database. */
if (expansion == 0)
expansion = sh_get_home_dir ();
return (glue_prefix_and_suffix (expansion, filename, 1));
}
username = isolate_tilde_prefix (filename, &user_len);
if (tilde_expansion_preexpansion_hook)
{
expansion = (*tilde_expansion_preexpansion_hook) (username);
if (expansion)
{
dirname = glue_prefix_and_suffix (expansion, filename, user_len);
xfree (username);
free (expansion);
return (dirname);
}
}
/* No preexpansion hook, or the preexpansion hook failed. Look in the
password database. */
dirname = (char *)NULL;
#if defined (HAVE_GETPWNAM)
user_entry = getpwnam (username);
#else
user_entry = 0;
#endif
if (user_entry == 0)
{
/* If the calling program has a special syntax for expanding tildes,
and we couldn't find a standard expansion, then let them try. */
if (tilde_expansion_failure_hook)
{
expansion = (*tilde_expansion_failure_hook) (username);
if (expansion)
{
dirname = glue_prefix_and_suffix (expansion, filename, user_len);
free (expansion);
}
}
/* If we don't have a failure hook, or if the failure hook did not
expand the tilde, return a copy of what we were passed. */
if (dirname == 0)
dirname = savestring (filename);
}
#if defined (HAVE_GETPWENT)
else
dirname = glue_prefix_and_suffix (user_entry->pw_dir, filename, user_len);
#endif
xfree (username);
#if defined (HAVE_GETPWENT)
endpwent ();
#endif
return (dirname);
}
#if defined (TEST)
#undef NULL
#include <stdio.h>
main (argc, argv)
int argc;
char **argv;
{
char *result, line[512];
int done = 0;
while (!done)
{
printf ("~expand: ");
fflush (stdout);
if (!gets (line))
strcpy (line, "done");
if ((strcmp (line, "done") == 0) ||
(strcmp (line, "quit") == 0) ||
(strcmp (line, "exit") == 0))
{
done = 1;
break;
}
result = tilde_expand (line);
printf (" --> %s\n", result);
free (result);
}
exit (0);
}
static void memory_error_and_abort ();
static void *
xmalloc (bytes)
size_t bytes;
{
void *temp = (char *)malloc (bytes);
if (!temp)
memory_error_and_abort ();
return (temp);
}
static void *
xrealloc (pointer, bytes)
void *pointer;
int bytes;
{
void *temp;
if (!pointer)
temp = malloc (bytes);
else
temp = realloc (pointer, bytes);
if (!temp)
memory_error_and_abort ();
return (temp);
}
static void
memory_error_and_abort ()
{
fprintf (stderr, "readline: out of virtual memory\n");
abort ();
}
/*
* Local variables:
* compile-command: "gcc -g -DTEST -o tilde tilde.c"
* end:
*/
#endif /* TEST */